Skip to content

Commit 2b4b23b

Browse files
committed
[OlsrParser] Added support for local_addresses #34
1 parent 91cd223 commit 2b4b23b

9 files changed

+131
-13
lines changed

netdiff/parsers/olsr.py

+42-7
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ def parse(self, data):
2828
graph = networkx.Graph()
2929
if 'topology' not in data:
3030
raise ParserError('Parse error, "topology" key not found')
31+
elif 'mid' not in data:
32+
raise ParserError('Parse error, "mid" key not found')
3133

3234
# determine version and revision
3335
if 'config' in data:
@@ -38,25 +40,36 @@ def parse(self, data):
3840
version_info[-1] = version_info[-1].split('hash_')[-1]
3941
self.revision = version_info[-1]
4042

43+
# process alias list
44+
alias_dict = {}
45+
for node in data['mid']:
46+
local_addresses = [alias['ipAddress'] for alias in node['aliases']]
47+
alias_dict[node['ipAddress']] = local_addresses
48+
4149
# loop over topology section and create networkx graph
4250
for link in data['topology']:
4351
try:
4452
source = link['lastHopIP']
45-
dest = link['destinationIP']
53+
target = link['destinationIP']
4654
cost = link['tcEdgeCost']
4755
properties = {
4856
'link_quality': link['linkQuality'],
4957
'neighbor_link_quality': link['neighborLinkQuality']
5058
}
5159
except KeyError as e:
5260
raise ParserError('Parse error, "%s" key not found' % e)
61+
# add nodes with their local_addresses
62+
for node in [source, target]:
63+
if node not in alias_dict:
64+
continue
65+
graph.add_node(node, local_addresses=alias_dict[node])
5366
# skip links with infinite cost
5467
if cost == float('inf'):
5568
continue
5669
# original olsrd cost (jsoninfo multiplies by 1024)
5770
cost = float(cost) / 1024.0
5871
# add link to Graph
59-
graph.add_edge(source, dest, weight=cost, **properties)
72+
graph.add_edge(source, target, weight=cost, **properties)
6073
return graph
6174

6275
def _txtinfo_to_jsoninfo(self, data):
@@ -68,22 +81,44 @@ def _txtinfo_to_jsoninfo(self, data):
6881
# find interesting section
6982
lines = data.split('\n')
7083

84+
# process links in topology section
7185
try:
7286
start = lines.index('Table: Topology') + 2
7387
end = lines[start:].index('') + start
7488
except ValueError:
7589
raise ParserError('Unrecognized format')
76-
7790
topology_lines = lines[start:end]
78-
# convert interesting section to jsoninfo format
79-
parsed_lines = []
91+
# convert topology section to jsoninfo format
92+
topology = []
8093
for line in topology_lines:
8194
values = line.split('\t')
82-
parsed_lines.append({
95+
topology.append({
8396
'destinationIP': values[0],
8497
'lastHopIP': values[1],
8598
'linkQuality': float(values[2]),
8699
'neighborLinkQuality': float(values[3]),
87100
'tcEdgeCost': float(values[4]) * 1024.0
88101
})
89-
return {'topology': parsed_lines}
102+
103+
# process alias (MID) section
104+
try:
105+
start = lines.index('Table: MID') + 2
106+
end = lines[start:].index('') + start
107+
except ValueError:
108+
raise ParserError('Unrecognized format')
109+
mid_lines = lines[start:end]
110+
# convert mid section to jsoninfo format
111+
mid = []
112+
for line in mid_lines:
113+
values = line.split('\t')
114+
node = values[0]
115+
aliases = values[1].split(';')
116+
mid.append({
117+
'ipAddress': node,
118+
'aliases': [{'ipAddress': alias} for alias in aliases]
119+
})
120+
121+
return {
122+
'topology': topology,
123+
'mid': mid
124+
}

tests/static/olsr-2-links-cost-changed.json

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
"validityTime": 284572
1818
}
1919
],
20+
"mid": [],
2021
"config": {
2122
"olsrPort":698,
2223
"debugLevel":0,

tests/static/olsr-2-links.json

+33
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,39 @@
1717
"validityTime": 284572
1818
}
1919
],
20+
"mid": [
21+
{
22+
"ipAddress": "10.150.0.2",
23+
"aliases": [
24+
{
25+
"ipAddress": "172.16.192.2",
26+
"validityTime": 286445
27+
},
28+
{
29+
"ipAddress": "192.168.0.2",
30+
"validityTime": 286445
31+
}
32+
]
33+
},
34+
{
35+
"ipAddress": "10.150.0.3",
36+
"aliases": [
37+
{
38+
"ipAddress": "172.16.192.3",
39+
"validityTime": 286445
40+
}
41+
]
42+
},
43+
{
44+
"ipAddress": "10.150.0.4",
45+
"aliases": [
46+
{
47+
"ipAddress": "172.16.192.4",
48+
"validityTime": 286445
49+
}
50+
]
51+
}
52+
],
2053
"config": {
2154
"olsrPort":698,
2255
"debugLevel":0,

tests/static/olsr-2-links.txt

+3
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ Destination Gateway
1616

1717
Table: MID
1818
IP address Aliases
19+
10.150.0.2 172.16.192.2;192.168.0.2
20+
10.150.0.3 172.16.192.3
21+
10.150.0.4 172.16.192.4
1922

2023
Table: Routes
2124
Destination Gateway IP Metric ETX Interface

tests/static/olsr-3-links.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,6 @@
2424
"tcEdgeCost": 1024,
2525
"validityTime": 284572
2626
}
27-
]
27+
],
28+
"mid": []
2829
}

tests/static/olsr-5-links-cost-changed.json

+1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
"validityTime": 284572
4242
}
4343
],
44+
"mid": [],
4445
"config": {
4546
"olsrPort":698,
4647
"debugLevel":0,

tests/static/olsr-5-links.json

+1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
"validityTime": 284572
4242
}
4343
],
44+
"mid": [],
4445
"config": {
4546
"olsrPort":698,
4647
"debugLevel":0,

tests/test_olsr.py

+21-3
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ def test_parse(self):
2626
self.assertIsInstance(properties['weight'], float)
2727
self.assertIsInstance(properties['link_quality'], float)
2828
self.assertIsInstance(properties['neighbor_link_quality'], float)
29+
# test additional node properties
30+
properties = p.graph.nodes(data=True)[0][1]
31+
self.assertIsInstance(properties['local_addresses'], list)
2932

3033
def test_init(self):
3134
p = OlsrParser(links3, version='0.6.3', metric='ETC')
@@ -41,7 +44,11 @@ def test_parse_exception(self):
4144

4245
def test_parse_exception2(self):
4346
with self.assertRaises(ParserError):
44-
OlsrParser('{ "topology": [{ "a": "a" }] }')
47+
OlsrParser('{ "topology": [{ "a": "a" }], "mid": [] }')
48+
49+
def test_parse_exception_mid(self):
50+
with self.assertRaises(ParserError):
51+
OlsrParser('{ "topology": [], "missing_mid": [] }')
4552

4653
def test_json_dict(self):
4754
p = OlsrParser(links2)
@@ -57,10 +64,20 @@ def test_json_dict(self):
5764
self.assertEqual(len(data['nodes']), 3)
5865
self.assertEqual(len(data['links']), 2)
5966
self.assertIsInstance(data['links'][0]['cost'], float)
60-
# test additional properties
67+
# test additional link properties
6168
properties = data['links'][0]['properties']
6269
self.assertIsInstance(properties['link_quality'], float)
6370
self.assertIsInstance(properties['neighbor_link_quality'], float)
71+
# test local_addresses
72+
self.assertIsInstance(data['nodes'][0]['local_addresses'], list)
73+
found = False
74+
for node in data['nodes']:
75+
if node['id'] == '10.150.0.2':
76+
self.assertEqual(len(node['local_addresses']), 2)
77+
self.assertEqual(node['local_addresses'][0], '172.16.192.2')
78+
self.assertEqual(node['local_addresses'][1], '192.168.0.2')
79+
found = True
80+
self.assertTrue(found)
6481

6582
def test_json_string(self):
6683
p = OlsrParser(links2)
@@ -233,7 +250,8 @@ def test_link_with_infinite_cost(self):
233250
"tcEdgeCost": float('inf'),
234251
"validityTime": 284572
235252
}
236-
]
253+
],
254+
"mid": []
237255
})
238256
# ensure link is ignored
239257
self.assertEqual(len(p.graph.edges()), 0)

tests/test_olsr_txtinfo.py

+27-2
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,20 @@ def test_parse(self):
2525
self.assertIsInstance(properties['weight'], float)
2626
self.assertIsInstance(properties['link_quality'], float)
2727
self.assertIsInstance(properties['neighbor_link_quality'], float)
28+
# test additional node properties
29+
properties = p.graph.nodes(data=True)[0][1]
30+
self.assertIsInstance(properties['local_addresses'], list)
2831

29-
def test_parse_exception(self):
32+
def test_parse_exception_topology(self):
3033
with self.assertRaises(ParserError):
3134
OlsrParser('clearly wrong')
35+
with self.assertRaises(ParserError):
3236
OlsrParser('Table: Topology\n......')
3337

38+
def test_parse_exception_mid(self):
39+
with self.assertRaises(ParserError):
40+
OlsrParser('Table: Topology\n\n\nMISSING MID')
41+
3442
def test_json_dict(self):
3543
p = OlsrParser(links2)
3644
data = p.json(dict=True)
@@ -49,6 +57,16 @@ def test_json_dict(self):
4957
properties = data['links'][0]['properties']
5058
self.assertIsInstance(properties['link_quality'], float)
5159
self.assertIsInstance(properties['neighbor_link_quality'], float)
60+
# test local_addresses
61+
self.assertIsInstance(data['nodes'][0]['local_addresses'], list)
62+
found = False
63+
for node in data['nodes']:
64+
if node['id'] == '10.150.0.2':
65+
self.assertEqual(len(node['local_addresses']), 2)
66+
self.assertEqual(node['local_addresses'][0], '172.16.192.2')
67+
self.assertEqual(node['local_addresses'][1], '192.168.0.2')
68+
found = True
69+
self.assertTrue(found)
5270

5371
def test_json_string(self):
5472
p = OlsrParser(links2)
@@ -195,7 +213,14 @@ def test_cost_changes_1(self):
195213
self.assertTrue(1.023 in (links[0]['cost'], links[1]['cost']))
196214

197215
def test_link_with_infinite_cost(self):
198-
data = 'Table: Topology\nDest. IP\tLast hop IP\tLQ\tNLQ\tCost\n10.150.0.3\t10.150.0.2\t0.195\t0.184\tINFINITE\n\n'
216+
data = """Table: Topology
217+
Dest. IP\tLast hop IP\tLQ\tNLQ\tCost
218+
10.150.0.3\t10.150.0.2\t0.195\t0.184\tINFINITE
219+
220+
Table: MID
221+
IP address\tAliases
222+
223+
"""
199224
p = OlsrParser(data)
200225
# ensure link is ignored
201226
self.assertEqual(len(p.graph.edges()), 0)

0 commit comments

Comments
 (0)