feat: Add route quality analysis and detailed router performance statistics to reports.

This commit is contained in:
eddieoz
2025-11-28 00:51:44 +02:00
parent 992745b50c
commit 800c839bf7
5 changed files with 229 additions and 51 deletions
+47
View File
@@ -0,0 +1,47 @@
import unittest
from mesh_monitor.analyzer import NetworkHealthAnalyzer
class TestRouteQuality(unittest.TestCase):
def setUp(self):
self.analyzer = NetworkHealthAnalyzer()
def test_long_path(self):
nodes = {
'!11111111': {'user': {'longName': 'FarNode'}}
}
test_results = [
{'node_id': '!11111111', 'hops_to': 4, 'route': []}
]
issues = self.analyzer.check_route_quality(nodes, test_results)
print("\nLong Path Issues:", issues)
self.assertTrue(any("Long path" in i for i in issues))
def test_favorite_router_usage(self):
nodes = {
'!22222222': {'user': {'longName': 'TargetNode'}},
'!33333333': {'user': {'longName': 'FavRouter'}, 'is_favorite': True}
}
# Route uses FavRouter (ID !33333333 -> 0x33333333 = 858993459)
test_results = [
{'node_id': '!22222222', 'hops_to': 2, 'route': [858993459]}
]
issues = self.analyzer.check_route_quality(nodes, test_results)
print("\nFavorite Router Issues:", issues)
self.assertTrue(any("Favorite Router" in i for i in issues))
def test_weak_signal(self):
nodes = {
'!44444444': {'user': {'longName': 'WeakNode'}}
}
test_results = [
{'node_id': '!44444444', 'snr': -15}
]
issues = self.analyzer.check_route_quality(nodes, test_results)
print("\nWeak Signal Issues:", issues)
self.assertTrue(any("Weak signal" in i for i in issues))
if __name__ == '__main__':
unittest.main()
+35
View File
@@ -99,5 +99,40 @@ class TestRouterEfficiency(unittest.TestCase):
print("\nEffective Issues (Should be empty):", issues)
self.assertFalse(any("GoodRouter" in i for i in issues))
def test_get_router_stats(self):
nodes = {
'!77777777': {
'user': {'id': '!77777777', 'longName': 'StatsRouter', 'role': 'ROUTER'},
'position': {'latitude': 44.0, 'longitude': -78.0},
'deviceMetrics': {'channelUtilization': 25}
}
}
# Add 3 router neighbors
for i in range(3):
nodes[f'!r_neighbor{i}'] = {
'user': {'id': f'!r_neighbor{i}', 'role': 'ROUTER'},
'position': {'latitude': 44.001, 'longitude': -78.001}
}
"""Test that get_router_stats returns correct structure and calculations."""
# Create a mock route where StatsRouter (!77777777) is used as a relay
# 0x77777777 = 2004318071
test_results = [
{'route': [2004318071], 'status': 'success'}
]
stats = self.analyzer.get_router_stats(nodes, test_results)
print("\nRouter Stats:", stats)
self.assertEqual(len(stats), 4) # StatsRouter + 3 neighbors
target = next(s for s in stats if s['id'] == '!77777777')
self.assertEqual(target['neighbors_2km'], 3)
self.assertEqual(target['routers_2km'], 3)
self.assertEqual(target['ch_util'], 25.0)
self.assertEqual(target['relay_count'], 1) # Should be 1 now
self.assertIn('Redundant', target['status'])
self.assertIn('Congested', target['status'])
if __name__ == '__main__':
unittest.main()