]>
Commit | Line | Data |
---|---|---|
e0a84778 | 1 | import pytest |
a54f6012 | 2 | import shlex |
e0a84778 VB |
3 | import time |
4 | import re | |
5 | import platform | |
6 | import json | |
7 | import xml.etree.ElementTree as ET | |
8 | ||
9 | ||
10 | @pytest.fixture(scope='session') | |
11 | def uname(): | |
12 | return "{} {} {} {}".format( | |
13 | platform.system(), | |
14 | platform.release(), | |
15 | platform.version(), | |
16 | platform.machine()) | |
17 | ||
a54f6012 SW |
18 | @pytest.mark.parametrize("command, expected", [ |
19 | ("neighbors", | |
20 | """------------------------------------------------------------------------------- | |
e0a84778 VB |
21 | LLDP neighbors: |
22 | ------------------------------------------------------------------------------- | |
23 | Interface: eth0, via: LLDP, RID: 1, Time: 0 day, 00:00:{seconds} | |
24 | Chassis: | |
25 | ChassisID: mac 00:00:00:00:00:02 | |
26 | SysName: ns-2.example.com | |
27 | SysDescr: Spectacular GNU/Linux 2016 {uname} | |
28 | MgmtIP: fe80::200:ff:fe00:2 | |
29 | Capability: Bridge, off | |
30 | Capability: Router, {router} | |
31 | Capability: Wlan, off | |
32 | Capability: Station, {station} | |
33 | Port: | |
34 | PortID: mac 00:00:00:00:00:02 | |
78346c89 VB |
35 | PortDescr: eth1 |
36 | TTL: 120{dot3} | |
e0a84778 | 37 | ------------------------------------------------------------------------------- |
a54f6012 SW |
38 | """), |
39 | ("interfaces", | |
40 | """------------------------------------------------------------------------------- | |
41 | LLDP interfaces: | |
42 | ------------------------------------------------------------------------------- | |
43 | Interface: eth0, via: unknown, Time: {time} | |
44 | Chassis: | |
45 | ChassisID: mac 00:00:00:00:00:01 | |
46 | SysName: ns-1.example.com | |
47 | SysDescr: Spectacular GNU/Linux 2016 {uname} | |
48 | MgmtIP: fe80::200:ff:fe00:1 | |
49 | Capability: Bridge, off | |
50 | Capability: Router, {router} | |
51 | Capability: Wlan, off | |
52 | Capability: Station, {station} | |
53 | Port: | |
54 | PortID: mac 00:00:00:00:00:01 | |
55 | PortDescr: eth0{dot3} | |
56 | TTL: 120 | |
57 | ------------------------------------------------------------------------------- | |
58 | """)], ids=["neighbors", "interfaces"]) | |
59 | def test_text_output(lldpd1, lldpd, lldpcli, namespaces, uname, command, | |
60 | expected): | |
61 | with namespaces(2): | |
62 | lldpd() | |
63 | with namespaces(1): | |
64 | result = lldpcli( | |
65 | *shlex.split("show {} details".format(command))) | |
66 | assert result.returncode == 0 | |
e0a84778 | 67 | out = result.stdout.decode('ascii') |
a54f6012 SW |
68 | |
69 | if 'Dot3' in pytest.config.lldpd.features: | |
70 | dot3 = """ | |
71 | PMD autoneg: supported: no, enabled: no | |
72 | MAU oper type: 10GigBaseCX4 - X copper over 8 pair 100-Ohm balanced cable""" | |
73 | else: | |
74 | dot3 = "" | |
75 | ||
76 | out = result.stdout.decode('ascii') | |
77 | time = re.search(r'^Interface: .*Time: (.*)$', | |
78 | out, | |
79 | re.MULTILINE).group(1) | |
e0a84778 VB |
80 | seconds = re.search(r'^Interface: .*(\d\d)$', |
81 | out, | |
82 | re.MULTILINE).group(1) | |
83 | router = re.search(r'^ Capability: Router, (.*)$', | |
84 | out, | |
85 | re.MULTILINE).group(1) | |
86 | station = re.search(r'^ Capability: Station, (.*)$', | |
87 | out, | |
88 | re.MULTILINE).group(1) | |
89 | out = re.sub(r' *$', '', out, flags=re.MULTILINE) | |
90 | assert out == expected.format(seconds=seconds, | |
a54f6012 | 91 | time=time, |
e0a84778 VB |
92 | router=router, |
93 | station=station, | |
7181aba5 VB |
94 | uname=uname, |
95 | dot3=dot3) | |
e0a84778 | 96 | |
e0a84778 VB |
97 | @pytest.mark.skipif('JSON' not in pytest.config.lldpcli.outputs, |
98 | reason="JSON not supported") | |
a54f6012 SW |
99 | @pytest.mark.parametrize("command, expected", [ |
100 | ("neighbors", | |
101 | {"lldp": { | |
102 | "interface": { | |
103 | "eth0": { | |
104 | "via": "LLDP", | |
105 | "rid": "1", | |
106 | "chassis": { | |
107 | "ns-2.example.com": { | |
108 | "id": { | |
109 | "type": "mac", | |
110 | "value": "00:00:00:00:00:02"}, | |
111 | "descr": "Spectacular GNU/Linux 2016 {}".format(uname), | |
112 | "mgmt-ip": "fe80::200:ff:fe00:2", | |
113 | "capability": [ | |
114 | {"type": "Bridge", "enabled": False}, | |
115 | {"type": "Wlan", "enabled": False},]}}, | |
116 | "port": { | |
117 | "id": { | |
118 | "type": "mac", | |
119 | "value": "00:00:00:00:00:02"}, | |
120 | "descr": "eth1", | |
121 | "ttl": "120"}}}}}), | |
122 | ("interfaces", | |
123 | {"lldp": { | |
124 | "interface": { | |
125 | "eth0": { | |
126 | "via": "unknown", | |
127 | "chassis": { | |
128 | "ns-1.example.com": { | |
129 | "id": { | |
130 | "type": "mac", | |
131 | "value": "00:00:00:00:00:01"}, | |
132 | "descr": "Spectacular GNU/Linux 2016 {}".format(uname), | |
133 | "mgmt-ip": "fe80::200:ff:fe00:1", | |
134 | "capability": [ | |
135 | {"type": "Bridge", "enabled": False}, | |
136 | {"type": "Wlan", "enabled": False},]}}, | |
137 | "port": { | |
138 | "id": { | |
139 | "type": "mac", | |
140 | "value": "00:00:00:00:00:01"}, | |
141 | "descr": "eth0"}, | |
142 | "ttl": { | |
143 | "ttl": "120"}}}}})], ids=["neighbors", "interfaces"]) | |
144 | def test_json_output(lldpd1, lldpd, lldpcli, namespaces, uname, command, | |
145 | expected): | |
e0a84778 VB |
146 | with namespaces(2): |
147 | lldpd() | |
148 | with namespaces(1): | |
a54f6012 SW |
149 | result = lldpcli( |
150 | *shlex.split("-f json show {} details".format(command))) | |
e0a84778 VB |
151 | assert result.returncode == 0 |
152 | out = result.stdout.decode('ascii') | |
153 | j = json.loads(out) | |
154 | ||
155 | eth0 = j['lldp']['interface']['eth0'] | |
a54f6012 | 156 | name = next(k for k,v in eth0['chassis'].items() if k.startswith('ns')) |
e0a84778 | 157 | del eth0['age'] |
a54f6012 SW |
158 | del eth0['chassis'][name]['capability'][3] |
159 | del eth0['chassis'][name]['capability'][1] | |
160 | ||
161 | descr = "Spectacular GNU/Linux 2016 {}".format(uname) | |
162 | expected['lldp']['interface']['eth0']['chassis'][name]["descr"] = descr | |
e0a84778 | 163 | |
7181aba5 VB |
164 | if 'Dot3' in pytest.config.lldpd.features: |
165 | expected['lldp']['interface']['eth0']['port']['auto-negotiation'] = { | |
166 | "enabled": False, | |
167 | "supported": False, | |
168 | "current": "10GigBaseCX4 - X copper over 8 pair 100-Ohm balanced cable" | |
169 | } | |
e0a84778 | 170 | |
a54f6012 | 171 | assert j == expected |
e0a84778 | 172 | |
479d4985 VB |
173 | @pytest.mark.skipif('JSON' not in pytest.config.lldpcli.outputs, |
174 | reason="JSON not supported") | |
a54f6012 SW |
175 | @pytest.mark.parametrize("command, expected", [ |
176 | ("neighbors", | |
177 | {"lldp": [{ | |
479d4985 VB |
178 | "interface": [{ |
179 | "name": "eth0", | |
180 | "via": "LLDP", | |
181 | "rid": "1", | |
182 | "chassis": [{ | |
183 | "id": [{ | |
184 | "type": "mac", | |
185 | "value": "00:00:00:00:00:02" | |
186 | }], | |
187 | "name": [{"value": "ns-2.example.com"}], | |
188 | "descr": [{"value": "Spectacular GNU/Linux 2016 {}".format(uname)}], | |
189 | "mgmt-ip": [{"value": "fe80::200:ff:fe00:2"}], | |
190 | "capability": [ | |
191 | {"type": "Bridge", "enabled": False}, | |
192 | {"type": "Wlan", "enabled": False}, | |
193 | ]} | |
194 | ], | |
195 | "port": [{ | |
196 | "id": [{ | |
197 | "type": "mac", | |
198 | "value": "00:00:00:00:00:02" | |
199 | }], | |
200 | "descr": [{"value": "eth1"}], | |
201 | "ttl": [{"value": "120"}] | |
202 | }] | |
203 | }]} | |
a54f6012 SW |
204 | ]}), |
205 | ("interfaces", | |
206 | {"lldp": [{ | |
207 | "interface": [{ | |
208 | "name": "eth0", | |
209 | "via": "unknown", | |
210 | "chassis": [{ | |
211 | "id": [{ | |
212 | "type": "mac", | |
213 | "value": "00:00:00:00:00:01" | |
214 | }], | |
215 | "name": [{"value": "ns-1.example.com"}], | |
216 | "descr": [{"value": "Spectacular GNU/Linux 2016 {}".format(uname)}], | |
217 | "mgmt-ip": [{"value": "fe80::200:ff:fe00:1"}], | |
218 | "capability": [ | |
219 | {"type": "Bridge", "enabled": False}, | |
220 | {"type": "Wlan", "enabled": False}, | |
221 | ]} | |
222 | ], | |
223 | "port": [{ | |
224 | "id": [{ | |
225 | "type": "mac", | |
226 | "value": "00:00:00:00:00:01" | |
227 | }], | |
228 | "descr": [{"value": "eth0"}] | |
229 | }], | |
230 | "ttl": [{"ttl": "120"}] | |
231 | }]} | |
232 | ]})], ids=["neighbors", "interfaces"]) | |
233 | def test_json0_output(lldpd1, lldpd, lldpcli, namespaces, uname, command, | |
234 | expected): | |
235 | with namespaces(2): | |
236 | lldpd() | |
237 | with namespaces(1): | |
238 | result = lldpcli( | |
239 | *shlex.split("-f json0 show {} details".format(command))) | |
240 | assert result.returncode == 0 | |
241 | out = result.stdout.decode('ascii') | |
242 | j = json.loads(out) | |
243 | ||
244 | eth0 = j['lldp'][0]['interface'][0] | |
245 | del eth0['age'] | |
246 | del eth0['chassis'][0]['capability'][3] | |
247 | del eth0['chassis'][0]['capability'][1] | |
248 | ||
249 | descr = "Spectacular GNU/Linux 2016 {}".format(uname) | |
250 | expected['lldp'][0]['interface'][0]['chassis'][0]["descr"][0]['value'] = descr | |
479d4985 VB |
251 | |
252 | if 'Dot3' in pytest.config.lldpd.features: | |
253 | expected['lldp'][0]['interface'][0]['port'][0]['auto-negotiation'] = [{ | |
254 | "enabled": False, | |
255 | "supported": False, | |
256 | "current": [{"value": | |
257 | "10GigBaseCX4 - X copper over 8 pair 100-Ohm balanced cable"}] | |
258 | }] | |
259 | assert j == expected | |
260 | ||
261 | ||
e0a84778 VB |
262 | @pytest.mark.skipif('XML' not in pytest.config.lldpcli.outputs, |
263 | reason="XML not supported") | |
a54f6012 SW |
264 | @pytest.mark.parametrize("command, expected", [ |
265 | ("neighbors", | |
266 | """<?xml version="1.0" encoding="UTF-8"?> | |
e0a84778 VB |
267 | <lldp label="LLDP neighbors"> |
268 | <interface label="Interface" name="eth0" via="LLDP" rid="1" age="{age}"> | |
269 | <chassis label="Chassis"> | |
270 | <id label="ChassisID" type="mac">00:00:00:00:00:02</id> | |
271 | <name label="SysName">ns-2.example.com</name> | |
272 | <descr label="SysDescr">Spectacular GNU/Linux 2016 {uname}</descr> | |
273 | <mgmt-ip label="MgmtIP">fe80::200:ff:fe00:2</mgmt-ip> | |
274 | <capability label="Capability" type="Bridge" enabled="off"/> | |
275 | <capability label="Capability" type="Router" enabled="{router}"/> | |
276 | <capability label="Capability" type="Wlan" enabled="off"/> | |
277 | <capability label="Capability" type="Station" enabled="{station}"/> | |
278 | </chassis> | |
279 | <port label="Port"> | |
280 | <id label="PortID" type="mac">00:00:00:00:00:02</id> | |
78346c89 VB |
281 | <descr label="PortDescr">eth1</descr> |
282 | <ttl label="TTL">120</ttl>{dot3} | |
e0a84778 VB |
283 | </port> |
284 | </interface> | |
285 | </lldp> | |
a54f6012 SW |
286 | """), |
287 | ("interfaces", | |
288 | """<?xml version="1.0" encoding="UTF-8"?> | |
289 | <lldp label="LLDP interfaces"> | |
290 | <interface label="Interface" name="eth0" via="unknown" age="{age}"> | |
291 | <chassis label="Chassis"> | |
292 | <id label="ChassisID" type="mac">00:00:00:00:00:01</id> | |
293 | <name label="SysName">ns-1.example.com</name> | |
294 | <descr label="SysDescr">Spectacular GNU/Linux 2016 {uname}</descr> | |
295 | <mgmt-ip label="MgmtIP">fe80::200:ff:fe00:1</mgmt-ip> | |
296 | <capability label="Capability" type="Bridge" enabled="off"/> | |
297 | <capability label="Capability" type="Router" enabled="{router}"/> | |
298 | <capability label="Capability" type="Wlan" enabled="off"/> | |
299 | <capability label="Capability" type="Station" enabled="{station}"/> | |
300 | </chassis> | |
301 | <port label="Port"> | |
302 | <id label="PortID" type="mac">00:00:00:00:00:01</id> | |
303 | <descr label="PortDescr">eth0</descr>{dot3} | |
304 | </port> | |
305 | <ttl label="TTL" ttl="120"/> | |
306 | </interface> | |
307 | </lldp> | |
308 | """)], ids=["neighbors", "interfaces"]) | |
309 | def test_xml_output(lldpd1, lldpd, lldpcli, namespaces, uname, command, | |
310 | expected): | |
311 | with namespaces(2): | |
312 | lldpd() | |
313 | with namespaces(1): | |
314 | result = lldpcli( | |
315 | *shlex.split("-f xml show {} details".format(command))) | |
316 | assert result.returncode == 0 | |
317 | out = result.stdout.decode('ascii') | |
318 | xml = ET.fromstring(out) | |
319 | ||
320 | age = xml.findall('./interface[1]')[0].attrib['age'] | |
321 | router = xml.findall("./interface[1]/chassis/" | |
322 | "capability[@type='Router']")[0].attrib['enabled'] | |
323 | station = xml.findall("./interface[1]/chassis/" | |
324 | "capability[@type='Station']")[0].attrib['enabled'] | |
325 | if 'Dot3' in pytest.config.lldpd.features: | |
326 | dot3 = """ | |
327 | <auto-negotiation enabled="no" label="PMD autoneg" supported="no"> | |
328 | <current label="MAU oper type">10GigBaseCX4 - X copper over 8 pair 100-Ohm balanced cable</current> | |
329 | </auto-negotiation>""" | |
330 | else: | |
331 | dot3 = "" | |
332 | expected = ET.fromstring(expected.format(age=age, | |
333 | router=router, | |
334 | station=station, | |
335 | uname=uname, | |
336 | dot3=dot3)) | |
e0a84778 VB |
337 | assert ET.tostring(xml) == ET.tostring(expected) |
338 | ||
339 | ||
340 | @pytest.mark.skipif('Dot3' not in pytest.config.lldpd.features, | |
341 | reason="Dot3 not supported") | |
342 | def test_configure_one_port(lldpd1, lldpd, lldpcli, namespaces, links): | |
343 | links(namespaces(1), namespaces(2)) | |
344 | with namespaces(2): | |
345 | lldpd() | |
346 | result = lldpcli(*("configure ports eth3 dot3 power " | |
347 | "pse supported enabled paircontrol powerpairs " | |
348 | "spare class class-3").split()) | |
349 | assert result.returncode == 0 | |
4af75e55 | 350 | time.sleep(3) |
a54f6012 SW |
351 | out = lldpcli("-f", "keyvalue", "show", "interfaces", "details") |
352 | assert 'lldp.eth1.port.power.device-type' not in out | |
353 | assert out['lldp.eth3.port.power.device-type'] == 'PSE' | |
e0a84778 VB |
354 | with namespaces(1): |
355 | out = lldpcli("-f", "keyvalue", "show", "neighbors", "details") | |
356 | assert out['lldp.eth0.port.descr'] == 'eth1' | |
357 | assert 'lldp.eth0.port.power.device-type' not in out | |
358 | assert out['lldp.eth2.port.descr'] == 'eth3' | |
359 | assert out['lldp.eth2.port.power.device-type'] == 'PSE' | |
360 | ||
361 | ||
362 | @pytest.mark.skipif('Dot3' not in pytest.config.lldpd.features, | |
363 | reason="Dot3 not supported") | |
364 | def test_new_port_take_default(lldpd1, lldpd, lldpcli, namespaces, links): | |
365 | with namespaces(2): | |
366 | lldpd() | |
367 | result = lldpcli(*("configure dot3 power " | |
368 | "pse supported enabled paircontrol powerpairs " | |
369 | "spare class class-3").split()) | |
370 | assert result.returncode == 0 | |
4af75e55 | 371 | time.sleep(3) |
a54f6012 SW |
372 | out = lldpcli("-f", "keyvalue", "show", "interfaces", "details") |
373 | assert out['lldp.eth1.port.power.device-type'] == 'PSE' | |
e0a84778 VB |
374 | with namespaces(1): |
375 | # Check this worked | |
376 | out = lldpcli("-f", "keyvalue", "show", "neighbors", "details") | |
377 | assert out['lldp.eth0.port.descr'] == 'eth1' | |
378 | assert out['lldp.eth0.port.power.device-type'] == 'PSE' | |
36d0c286 VB |
379 | links(namespaces(1), namespaces(2), 4) |
380 | time.sleep(6) | |
e0a84778 VB |
381 | with namespaces(1): |
382 | out = lldpcli("-f", "keyvalue", "show", "neighbors", "details") | |
383 | assert out['lldp.eth2.port.descr'] == 'eth3' | |
384 | assert out['lldp.eth2.port.power.device-type'] == 'PSE' | |
a54f6012 SW |
385 | with namespaces(2): |
386 | out = lldpcli("-f", "keyvalue", "show", "interfaces", "details") | |
387 | assert out['lldp.eth3.port.power.device-type'] == 'PSE' | |
e0a84778 VB |
388 | |
389 | ||
390 | @pytest.mark.skipif('Dot3' not in pytest.config.lldpd.features, | |
391 | reason="Dot3 not supported") | |
246d1538 VB |
392 | def test_port_keep_configuration_when_down(lldpd, lldpcli, namespaces, links): |
393 | with namespaces(1): | |
394 | links.dummy('eth3') | |
e0a84778 VB |
395 | lldpd() |
396 | result = lldpcli(*("configure ports eth3 dot3 power " | |
397 | "pse supported enabled paircontrol powerpairs " | |
398 | "spare class class-3").split()) | |
399 | assert result.returncode == 0 | |
e0a84778 | 400 | time.sleep(3) |
4af75e55 VB |
401 | links.down('eth3') |
402 | time.sleep(4) | |
246d1538 VB |
403 | # eth3 configuration is kept because the port still exists. |
404 | out = lldpcli("-f", "keyvalue", "show", "interfaces", "details") | |
405 | assert out['lldp.eth3.port.power.device-type'] == 'PSE' | |
406 | ||
e0a84778 | 407 | links.up('eth3') |
4af75e55 | 408 | time.sleep(4) |
246d1538 | 409 | # eth3 configuration is unchanged |
a54f6012 SW |
410 | out = lldpcli("-f", "keyvalue", "show", "interfaces", "details") |
411 | assert out['lldp.eth3.port.power.device-type'] == 'PSE' | |
246d1538 VB |
412 | |
413 | ||
414 | @pytest.mark.skipif('Dot3' not in pytest.config.lldpd.features, | |
415 | reason="Dot3 not supported") | |
416 | def test_port_forget_configuration(lldpd, lldpcli, | |
417 | namespaces, links): | |
e0a84778 | 418 | with namespaces(1): |
246d1538 VB |
419 | links.dummy('eth3') |
420 | lldpd() | |
421 | result = lldpcli(*("configure dot3 power " | |
422 | "pse supported enabled paircontrol powerpairs " | |
423 | "spare class class-3").split()) | |
424 | assert result.returncode == 0 | |
425 | time.sleep(3) | |
426 | links.remove('eth3') | |
427 | time.sleep(4) | |
428 | # eth3 configuration was forgotten because it disappeared. | |
429 | out = lldpcli("-f", "keyvalue", "show", "interfaces", "details") | |
430 | assert 'lldp.eth3.port.power.device-type' not in out | |
d12b1391 VB |
431 | |
432 | ||
0a78e14f VB |
433 | @pytest.mark.skipif('Dot3' not in pytest.config.lldpd.features, |
434 | reason="Dot3 not supported") | |
435 | def test_port_keep_configuration_of_permanent_ports(lldpd, lldpcli, | |
436 | namespaces, links): | |
437 | with namespaces(1): | |
438 | links.dummy('eth3') | |
439 | links.dummy('noteth3') | |
440 | lldpd() | |
441 | result = lldpcli(*("configure system interface permanent e*").split()) | |
442 | assert result.returncode == 0 | |
443 | result = lldpcli(*("configure dot3 power " | |
444 | "pse supported enabled paircontrol powerpairs " | |
445 | "spare class class-3").split()) | |
446 | assert result.returncode == 0 | |
447 | time.sleep(3) | |
448 | links.remove('eth3') | |
449 | links.remove('noteth3') | |
450 | time.sleep(4) | |
451 | # eth3 configuration is kept because it matches the permanent | |
452 | # port pattern. | |
453 | out = lldpcli("-f", "keyvalue", "show", "interfaces", "details") | |
454 | assert out['lldp.eth3.port.power.device-type'] == 'PSE' | |
455 | assert 'lldp.noteth3.port.power.device-type' not in out | |
456 | ||
457 | links.dummy('eth3') | |
458 | links.dummy('noteth3') | |
459 | time.sleep(4) | |
460 | # eth3 configuration is unchanged | |
461 | out = lldpcli("-f", "keyvalue", "show", "interfaces", "details") | |
462 | assert out['lldp.eth3.port.power.device-type'] == 'PSE' | |
463 | # noteth3 inherited from default | |
464 | assert out['lldp.noteth3.port.power.device-type'] == 'PSE' | |
465 | ||
466 | ||
d12b1391 VB |
467 | def test_watch(lldpd1, lldpd, lldpcli, namespaces, links): |
468 | with namespaces(2): | |
469 | lldpd() | |
470 | with namespaces(1): | |
471 | result = lldpcli("show", "neighbors") | |
472 | assert result.returncode == 0 | |
473 | out = result.stdout.decode('ascii') | |
474 | assert "ns-2.example.com" in out | |
475 | ||
476 | # Put a link down and immediately watch for a change | |
477 | links.down('eth0') | |
478 | result = lldpcli("watch", "limit", "1") | |
479 | assert result.returncode == 0 | |
480 | expected = out.replace('LLDP neighbors:', 'LLDP neighbor deleted:') | |
481 | expected = re.sub(r', Time: 0 day, 00:.*$', '', expected, | |
482 | flags=re.MULTILINE) | |
483 | got = result.stdout.decode('ascii') | |
484 | got = re.sub(r', Time: 0 day, 00:.*$', '', got, | |
485 | flags=re.MULTILINE) | |
486 | assert got == expected | |
487 | ||
488 | ||
489 | @pytest.mark.skipif('XML' not in pytest.config.lldpcli.outputs, | |
490 | reason="XML not supported") | |
491 | def test_watch_xml(lldpd1, lldpd, lldpcli, namespaces, links): | |
492 | with namespaces(2): | |
493 | lldpd() | |
494 | with namespaces(1): | |
495 | result = lldpcli("-f", "xml", "show", "neighbors") | |
496 | assert result.returncode == 0 | |
5b13beee | 497 | expected = result.stdout.decode('ascii') |
d12b1391 VB |
498 | expected = ET.fromstring(expected) |
499 | assert [x.text | |
500 | for x in expected.findall("./interface/chassis/name")] == \ | |
501 | ["ns-2.example.com"] | |
502 | ||
503 | # Put a link down and immediately watch for a change | |
504 | links.down('eth0') | |
505 | result = lldpcli("-f", "xml", "watch", "limit", "1") | |
506 | assert result.returncode == 0 | |
507 | expected.tag = 'lldp-deleted' | |
508 | expected.set('label', 'LLDP neighbor deleted') | |
509 | expected.find('./interface').set('age', '') | |
510 | got = result.stdout.decode('ascii') | |
511 | got = ET.fromstring(got) | |
512 | got.find('./interface').set('age', '') | |
513 | assert ET.tostring(got) == ET.tostring(expected) | |
514 | ||
515 | ||
516 | @pytest.mark.skipif('JSON' not in pytest.config.lldpcli.outputs, | |
517 | reason="JSON not supported") | |
518 | def test_watch_json(lldpd1, lldpd, lldpcli, namespaces, links): | |
519 | with namespaces(2): | |
520 | lldpd() | |
521 | with namespaces(1): | |
522 | result = lldpcli("-f", "json", "show", "neighbors") | |
523 | assert result.returncode == 0 | |
524 | expected = result.stdout.decode('ascii') | |
525 | expected = json.loads(expected) | |
526 | assert 'ns-2.example.com' in \ | |
527 | expected['lldp']['interface']['eth0']['chassis'] | |
528 | ||
529 | # Put a link down and immediately watch for a change | |
530 | links.down('eth0') | |
531 | result = lldpcli("-f", "json", "watch", "limit", "1") | |
532 | assert result.returncode == 0 | |
533 | got = result.stdout.decode('ascii') | |
534 | got = json.loads(got) | |
535 | expected['lldp-deleted'] = expected['lldp'] | |
536 | del expected['lldp'] | |
537 | del expected['lldp-deleted']['interface']['eth0']['age'] | |
538 | del got['lldp-deleted']['interface']['eth0']['age'] | |
539 | assert got == expected | |
fe64f8e5 VB |
540 | |
541 | ||
542 | def test_return_code(lldpd1, lldpcli, namespaces): | |
543 | with namespaces(1): | |
544 | result = lldpcli("show", "neighbors") | |
545 | assert result.returncode == 0 | |
a54f6012 SW |
546 | result = lldpcli("show", "interfaces") |
547 | assert result.returncode == 0 | |
fe64f8e5 VB |
548 | result = lldpcli("unknown", "command") |
549 | assert result.returncode == 1 |