]> git.proxmox.com Git - mirror_frr.git/blob - tests/topotests/all-protocol-startup/test_all_protocol_startup.py
9658c080c0c396a5f33ba1c34533db4943eff9ec
[mirror_frr.git] / tests / topotests / all-protocol-startup / test_all_protocol_startup.py
1 #!/usr/bin/env python
2
3 #
4 # test_all_protocol_startup.py
5 # Part of NetDEF Topology Tests
6 #
7 # Copyright (c) 2017 by
8 # Network Device Education Foundation, Inc. ("NetDEF")
9 #
10 # Permission to use, copy, modify, and/or distribute this software
11 # for any purpose with or without fee is hereby granted, provided
12 # that the above copyright notice and this permission notice appear
13 # in all copies.
14 #
15 # THE SOFTWARE IS PROVIDED "AS IS" AND NETDEF DISCLAIMS ALL WARRANTIES
16 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
17 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF BE LIABLE FOR
18 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
19 # DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
20 # WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
21 # ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
22 # OF THIS SOFTWARE.
23 #
24
25 """
26 test_all_protocol_startup.py: Test of all protocols at same time
27
28 """
29
30 import os
31 import re
32 import sys
33 import pytest
34 import glob
35 from time import sleep
36
37 from mininet.topo import Topo
38 from mininet.net import Mininet
39 from mininet.node import Node, OVSSwitch, Host
40 from mininet.log import setLogLevel, info
41 from mininet.cli import CLI
42 from mininet.link import Intf
43
44 from functools import partial
45
46 sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
47 from lib import topotest
48
49 fatal_error = ""
50
51
52 #####################################################
53 ##
54 ## Network Topology Definition
55 ##
56 #####################################################
57
58 class NetworkTopo(Topo):
59 "All Protocol Startup Test"
60
61 def build(self, **_opts):
62
63 # Setup Routers
64 router = {}
65 #
66 # Setup Main Router
67 router[1] = topotest.addRouter(self, 'r1')
68 #
69
70 # Setup Switches
71 switch = {}
72 #
73 for i in range(0, 10):
74 switch[i] = self.addSwitch('sw%s' % i, cls=topotest.LegacySwitch)
75 self.addLink(switch[i], router[1], intfName2='r1-eth%s' % i )
76
77
78 #####################################################
79 ##
80 ## Tests starting
81 ##
82 #####################################################
83
84 def setup_module(module):
85 global topo, net
86 global fatal_error
87
88 print("\n\n** %s: Setup Topology" % module.__name__)
89 print("******************************************\n")
90
91 print("Cleanup old Mininet runs")
92 os.system('sudo mn -c > /dev/null 2>&1')
93 os.system('sudo rm /tmp/r* > /dev/null 2>&1')
94
95 thisDir = os.path.dirname(os.path.realpath(__file__))
96 topo = NetworkTopo()
97
98 net = Mininet(controller=None, topo=topo)
99 net.start()
100
101 if net['r1'].get_routertype() != 'frr':
102 fatal_error = "Test is only implemented for FRR"
103 sys.stderr.write('\n\nTest is only implemented for FRR - Skipping\n\n')
104 pytest.skip(fatal_error)
105
106 # Starting Routers
107 #
108 # Main router
109 for i in range(1, 2):
110 net['r%s' % i].loadConf('zebra', '%s/r%s/zebra.conf' % (thisDir, i))
111 net['r%s' % i].loadConf('ripd', '%s/r%s/ripd.conf' % (thisDir, i))
112 net['r%s' % i].loadConf('ripngd', '%s/r%s/ripngd.conf' % (thisDir, i))
113 net['r%s' % i].loadConf('ospfd', '%s/r%s/ospfd.conf' % (thisDir, i))
114 if net['r1'].checkRouterVersion('<', '4.0'):
115 net['r%s' % i].loadConf('ospf6d', '%s/r%s/ospf6d.conf-pre-v4' % (thisDir, i))
116 else:
117 net['r%s' % i].loadConf('ospf6d', '%s/r%s/ospf6d.conf' % (thisDir, i))
118 net['r%s' % i].loadConf('isisd', '%s/r%s/isisd.conf' % (thisDir, i))
119 net['r%s' % i].loadConf('bgpd', '%s/r%s/bgpd.conf' % (thisDir, i))
120 if net['r%s' % i].daemon_available('ldpd'):
121 # Only test LDPd if it's installed and Kernel >= 4.5
122 net['r%s' % i].loadConf('ldpd', '%s/r%s/ldpd.conf' % (thisDir, i))
123 net['r%s' % i].startRouter()
124
125 # For debugging after starting Quagga/FRR daemons, uncomment the next line
126 # CLI(net)
127
128
129 def teardown_module(module):
130 global net
131
132 print("\n\n** %s: Shutdown Topology" % module.__name__)
133 print("******************************************\n")
134
135 # End - Shutdown network
136 net.stop()
137
138
139 def test_router_running():
140 global fatal_error
141 global net
142
143 # Skip if previous fatal error condition is raised
144 if (fatal_error != ""):
145 pytest.skip(fatal_error)
146
147 print("\n\n** Check if FRR/Quagga is running on each Router node")
148 print("******************************************\n")
149 sleep(5)
150
151 # Starting Routers
152 for i in range(1, 2):
153 fatal_error = net['r%s' % i].checkRouterRunning()
154 assert fatal_error == "", fatal_error
155
156 # For debugging after starting FRR/Quagga daemons, uncomment the next line
157 # CLI(net)
158
159
160 def test_error_messages_vtysh():
161 global fatal_error
162 global net
163
164 # Skip if previous fatal error condition is raised
165 if (fatal_error != ""):
166 pytest.skip(fatal_error)
167
168 print("\n\n** Check for error messages on VTYSH")
169 print("******************************************\n")
170
171 failures = 0
172 for i in range(1, 2):
173 #
174 # First checking Standard Output
175 #
176
177 # VTYSH output from router
178 vtystdout = net['r%s' % i].cmd('vtysh -c "show version" 2> /dev/null').rstrip()
179
180 # Fix newlines (make them all the same)
181 vtystdout = ('\n'.join(vtystdout.splitlines()) + '\n').rstrip()
182 # Drop everything starting with "FRRouting X.xx" message
183 vtystdout = re.sub(r"FRRouting [0-9]+.*", "", vtystdout, flags=re.DOTALL)
184
185 if (vtystdout == ''):
186 print("r%s StdOut ok" % i)
187
188 assert vtystdout == '', "Vtysh StdOut Output check failed for router r%s" % i
189
190 #
191 # Second checking Standard Error
192 #
193
194 # VTYSH StdErr output from router
195 vtystderr = net['r%s' % i].cmd('vtysh -c "show version" > /dev/null').rstrip()
196
197 # Fix newlines (make them all the same)
198 vtystderr = ('\n'.join(vtystderr.splitlines()) + '\n').rstrip()
199 # # Drop everything starting with "FRRouting X.xx" message
200 # vtystderr = re.sub(r"FRRouting [0-9]+.*", "", vtystderr, flags=re.DOTALL)
201
202 if (vtystderr == ''):
203 print("r%s StdErr ok" % i)
204
205 assert vtystderr == '', "Vtysh StdErr Output check failed for router r%s" % i
206
207 # Make sure that all daemons are running
208 for i in range(1, 2):
209 fatal_error = net['r%s' % i].checkRouterRunning()
210 assert fatal_error == "", fatal_error
211
212 # For debugging after starting FRR/Quagga daemons, uncomment the next line
213 # CLI(net)
214
215
216 def test_error_messages_daemons():
217 global fatal_error
218 global net
219
220 # Skip if previous fatal error condition is raised
221 if (fatal_error != ""):
222 pytest.skip(fatal_error)
223
224 print("\n\n** Check for error messages in daemons")
225 print("******************************************\n")
226
227 error_logs = ""
228
229 for i in range(1, 2):
230 log = net['r%s' % i].getStdErr('ripd')
231 if log:
232 error_logs += "r%s RIPd StdErr Output:\n" % i
233 error_logs += log
234 log = net['r%s' % i].getStdErr('ripngd')
235 if log:
236 error_logs += "r%s RIPngd StdErr Output:\n" % i
237 error_logs += log
238 log = net['r%s' % i].getStdErr('ospfd')
239 if log:
240 error_logs += "r%s OSPFd StdErr Output:\n" % i
241 error_logs += log
242 log = net['r%s' % i].getStdErr('ospf6d')
243 if log:
244 error_logs += "r%s OSPF6d StdErr Output:\n" % i
245 error_logs += log
246 log = net['r%s' % i].getStdErr('isisd')
247 # ISIS shows debugging enabled status on StdErr
248 # Remove these messages
249 log = re.sub(r"^IS-IS .* debugging is on.*", "", log).rstrip()
250 if log:
251 error_logs += "r%s ISISd StdErr Output:\n" % i
252 error_logs += log
253 log = net['r%s' % i].getStdErr('bgpd')
254 if log:
255 error_logs += "r%s BGPd StdErr Output:\n" % i
256 error_logs += log
257 if (net['r%s' % i].daemon_available('ldpd')):
258 log = net['r%s' % i].getStdErr('ldpd')
259 if log:
260 error_logs += "r%s LDPd StdErr Output:\n" % i
261 error_logs += log
262 log = net['r%s' % i].getStdErr('zebra')
263 if log:
264 error_logs += "r%s Zebra StdErr Output:\n"
265 error_logs += log
266
267 if error_logs:
268 sys.stderr.write('Failed check for StdErr Output on daemons:\n%s\n' % error_logs)
269
270 # Ignoring the issue if told to ignore (ie not yet fixed)
271 if (error_logs != ""):
272 if (os.environ.get('bamboo_TOPOTESTS_ISSUE_349') == "IGNORE"):
273 sys.stderr.write('Known issue - IGNORING. See https://github.com/FRRouting/frr/issues/349\n')
274 pytest.skip('Known issue - IGNORING. See https://github.com/FRRouting/frr/issues/349')
275
276 assert error_logs == "", "Daemons report errors to StdErr"
277
278 # For debugging after starting FRR/Quagga daemons, uncomment the next line
279 # CLI(net)
280
281
282 def test_converge_protocols():
283 global fatal_error
284 global net
285
286 # Skip if previous fatal error condition is raised
287 if (fatal_error != ""):
288 pytest.skip(fatal_error)
289
290 thisDir = os.path.dirname(os.path.realpath(__file__))
291
292 print("\n\n** Waiting for protocols convergence")
293 print("******************************************\n")
294
295 # Not really implemented yet - just sleep 60 secs for now
296 sleep(60)
297
298 # Make sure that all daemons are running
299 failures = 0
300 for i in range(1, 2):
301 fatal_error = net['r%s' % i].checkRouterRunning()
302 assert fatal_error == "", fatal_error
303
304 print("Show that v4 routes are right\n");
305 v4_routesFile = '%s/r%s/ipv4_routes.ref' % (thisDir, i)
306 expected = open(v4_routesFile).read().rstrip()
307 expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1)
308
309 actual = net['r%s' %i].cmd('vtysh -c "show ip route" | /usr/bin/tail -n +7 | sort 2> /dev/null').rstrip()
310 # Drop time in last update
311 actual = re.sub(r" [0-2][0-9]:[0-5][0-9]:[0-5][0-9]", " XX:XX:XX", actual)
312 actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
313 diff = topotest.get_textdiff(actual, expected,
314 title1="Actual IP Routing Table",
315 title2="Expected IP RoutingTable")
316 if diff:
317 sys.stderr.write('r%s failed IP Routing table check:\n%s\n' % (i, diff))
318 failures += 1
319 else:
320 print("r%s ok" %i)
321
322 assert failures == 0, "IP Routing table failed for r%s\n%s" % (i, diff)
323
324 failures = 0
325
326 print("Show that v6 routes are right\n")
327 v6_routesFile = '%s/r%s/ipv6_routes.ref' % (thisDir, i)
328 expected = open(v6_routesFile).read().rstrip()
329 expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1)
330
331 actual = net['r%s' %i].cmd('vtysh -c "show ipv6 route" | /usr/bin/tail -n +7 | sort 2> /dev/null').rstrip()
332 # Drop time in last update
333 actual = re.sub(r" [0-2][0-9]:[0-5][0-9]:[0-5][0-9]", " XX:XX:XX", actual)
334 actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
335 diff = topotest.get_textdiff(actual, expected,
336 title1="Actual IPv6 Routing Table",
337 title2="Expected IPv6 RoutingTable")
338 if diff:
339 sys.stderr.write('r%s failed IPv6 Routing table check:\n%s\n' % (i, diff))
340 failures += 1
341 else:
342 print("r%s ok" %i)
343
344 assert failures == 0, "IPv6 Routing table failed for r%s\n%s" % (i, diff)
345
346 # For debugging after starting FRR/Quagga daemons, uncomment the next line
347 ## CLI(net)
348
349
350 def test_rip_status():
351 global fatal_error
352 global net
353
354 # Skip if previous fatal error condition is raised
355 if (fatal_error != ""):
356 pytest.skip(fatal_error)
357
358 thisDir = os.path.dirname(os.path.realpath(__file__))
359
360 print("\n\n** Verifying RIP status")
361 print("******************************************\n")
362 failures = 0
363 for i in range(1, 2):
364 refTableFile = '%s/r%s/rip_status.ref' % (thisDir, i)
365 if os.path.isfile(refTableFile):
366 # Read expected result from file
367 expected = open(refTableFile).read().rstrip()
368 # Fix newlines (make them all the same)
369 expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1)
370
371 # Actual output from router
372 actual = net['r%s' % i].cmd('vtysh -c "show ip rip status" 2> /dev/null').rstrip()
373 # Drop time in next due
374 actual = re.sub(r"in [0-9]+ seconds", "in XX seconds", actual)
375 # Drop time in last update
376 actual = re.sub(r" [0-2][0-9]:[0-5][0-9]:[0-5][0-9]", " XX:XX:XX", actual)
377 # Fix newlines (make them all the same)
378 actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
379
380 # Generate Diff
381 diff = topotest.get_textdiff(actual, expected,
382 title1="actual IP RIP status",
383 title2="expected IP RIP status")
384
385 # Empty string if it matches, otherwise diff contains unified diff
386 if diff:
387 sys.stderr.write('r%s failed IP RIP status check:\n%s\n' % (i, diff))
388 failures += 1
389 else:
390 print("r%s ok" % i)
391
392 assert failures == 0, "IP RIP status failed for router r%s:\n%s" % (i, diff)
393
394 # Make sure that all daemons are running
395 for i in range(1, 2):
396 fatal_error = net['r%s' % i].checkRouterRunning()
397 assert fatal_error == "", fatal_error
398
399 # For debugging after starting FRR/Quagga daemons, uncomment the next line
400 # CLI(net)
401
402
403 def test_ripng_status():
404 global fatal_error
405 global net
406
407 # Skip if previous fatal error condition is raised
408 if (fatal_error != ""):
409 pytest.skip(fatal_error)
410
411 thisDir = os.path.dirname(os.path.realpath(__file__))
412
413 print("\n\n** Verifying RIPng status")
414 print("******************************************\n")
415 failures = 0
416 for i in range(1, 2):
417 refTableFile = '%s/r%s/ripng_status.ref' % (thisDir, i)
418 if os.path.isfile(refTableFile):
419 # Read expected result from file
420 expected = open(refTableFile).read().rstrip()
421 # Fix newlines (make them all the same)
422 expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1)
423
424 # Actual output from router
425 actual = net['r%s' % i].cmd('vtysh -c "show ipv6 ripng status" 2> /dev/null').rstrip()
426 # Mask out Link-Local mac address portion. They are random...
427 actual = re.sub(r" fe80::[0-9a-f:]+", " fe80::XXXX:XXXX:XXXX:XXXX", actual)
428 # Drop time in next due
429 actual = re.sub(r"in [0-9]+ seconds", "in XX seconds", actual)
430 # Drop time in last update
431 actual = re.sub(r" [0-2][0-9]:[0-5][0-9]:[0-5][0-9]", " XX:XX:XX", actual)
432 # Fix newlines (make them all the same)
433 actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
434
435 # Generate Diff
436 diff = topotest.get_textdiff(actual, expected,
437 title1="actual IPv6 RIPng status",
438 title2="expected IPv6 RIPng status")
439
440 # Empty string if it matches, otherwise diff contains unified diff
441 if diff:
442 sys.stderr.write('r%s failed IPv6 RIPng status check:\n%s\n' % (i, diff))
443 failures += 1
444 else:
445 print("r%s ok" % i)
446
447 assert failures == 0, "IPv6 RIPng status failed for router r%s:\n%s" % (i, diff)
448
449 # Make sure that all daemons are running
450 for i in range(1, 2):
451 fatal_error = net['r%s' % i].checkRouterRunning()
452 assert fatal_error == "", fatal_error
453
454 # For debugging after starting FRR/Quagga daemons, uncomment the next line
455 # CLI(net)
456
457
458 def test_ospfv2_interfaces():
459 global fatal_error
460 global net
461
462 # Skip if previous fatal error condition is raised
463 if (fatal_error != ""):
464 pytest.skip(fatal_error)
465
466 thisDir = os.path.dirname(os.path.realpath(__file__))
467
468 print("\n\n** Verifying OSPFv2 interfaces")
469 print("******************************************\n")
470 failures = 0
471 for i in range(1, 2):
472 refTableFile = '%s/r%s/show_ip_ospf_interface.ref' % (thisDir, i)
473 if os.path.isfile(refTableFile):
474 # Read expected result from file
475 expected = open(refTableFile).read().rstrip()
476 # Fix newlines (make them all the same)
477 expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1)
478
479 # Actual output from router
480 actual = net['r%s' % i].cmd('vtysh -c "show ip ospf interface" 2> /dev/null').rstrip()
481 # Mask out Bandwidth portion. They may change..
482 actual = re.sub(r"BW [0-9]+ Mbit", "BW XX Mbit", actual)
483 actual = re.sub(r"ifindex [0-9]", "ifindex X", actual)
484
485 # Drop time in next due
486 actual = re.sub(r"Hello due in [0-9\.]+s", "Hello due in XX.XXXs", actual)
487 # Fix 'MTU mismatch detection: enabled' vs 'MTU mismatch detection:enabled' - accept both
488 actual = re.sub(r"MTU mismatch detection:([a-z]+.*)", r"MTU mismatch detection: \1", actual)
489 # Fix newlines (make them all the same)
490 actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
491
492 # Generate Diff
493 diff = topotest.get_textdiff(actual, expected,
494 title1="actual SHOW IP OSPF INTERFACE",
495 title2="expected SHOW IP OSPF INTERFACE")
496
497 # Empty string if it matches, otherwise diff contains unified diff
498 if diff:
499 sys.stderr.write('r%s failed SHOW IP OSPF INTERFACE check:\n%s\n' % (i, diff))
500 failures += 1
501 else:
502 print("r%s ok" % i)
503
504 # Ignoring the issue if told to ignore (ie not yet fixed)
505 if (failures != 0):
506 if (os.environ.get('bamboo_TOPOTESTS_ISSUE_348') == "IGNORE"):
507 sys.stderr.write('Known issue - IGNORING. See https://github.com/FRRouting/frr/issues/348\n')
508 pytest.skip('Known issue - IGNORING. See https://github.com/FRRouting/frr/issues/348')
509
510 assert failures == 0, "SHOW IP OSPF INTERFACE failed for router r%s:\n%s" % (i, diff)
511
512 # Make sure that all daemons are running
513 for i in range(1, 2):
514 fatal_error = net['r%s' % i].checkRouterRunning()
515 assert fatal_error == "", fatal_error
516
517 # For debugging after starting FRR/Quagga daemons, uncomment the next line
518 # CLI(net)
519
520
521 def test_isis_interfaces():
522 global fatal_error
523 global net
524
525 # Skip if previous fatal error condition is raised
526 if (fatal_error != ""):
527 pytest.skip(fatal_error)
528
529 thisDir = os.path.dirname(os.path.realpath(__file__))
530
531 print("\n\n** Verifying ISIS interfaces")
532 print("******************************************\n")
533 failures = 0
534 for i in range(1, 2):
535 refTableFile = '%s/r%s/show_isis_interface_detail.ref' % (thisDir, i)
536 if os.path.isfile(refTableFile):
537 # Read expected result from file
538 expected = open(refTableFile).read().rstrip()
539 # Fix newlines (make them all the same)
540 expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1)
541
542 # Actual output from router
543 actual = net['r%s' % i].cmd('vtysh -c "show isis interface detail" 2> /dev/null').rstrip()
544 # Mask out Link-Local mac address portion. They are random...
545 actual = re.sub(r"fe80::[0-9a-f:]+", "fe80::XXXX:XXXX:XXXX:XXXX", actual)
546 # Mask out SNPA mac address portion. They are random...
547 actual = re.sub(r"SNPA: [0-9a-f\.]+", "SNPA: XXXX.XXXX.XXXX", actual)
548 # Mask out Circuit ID number
549 actual = re.sub(r"Circuit Id: 0x[0-9]+", "Circuit Id: 0xXX", actual)
550 # Fix newlines (make them all the same)
551 actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
552
553 # Generate Diff
554 diff = topotest.get_textdiff(actual, expected,
555 title1="actual SHOW ISIS INTERFACE DETAIL",
556 title2="expected SHOW ISIS OSPF6 INTERFACE DETAIL")
557
558 # Empty string if it matches, otherwise diff contains unified diff
559 if diff:
560 sys.stderr.write('r%s failed SHOW ISIS INTERFACE DETAIL check:\n%s\n' % (i, diff))
561 failures += 1
562 else:
563 print("r%s ok" % i)
564
565 assert failures == 0, "SHOW ISIS INTERFACE DETAIL failed for router r%s:\n%s" % (i, diff)
566
567 # Make sure that all daemons are running
568 for i in range(1, 2):
569 fatal_error = net['r%s' % i].checkRouterRunning()
570 assert fatal_error == "", fatal_error
571
572 # For debugging after starting FRR/Quagga daemons, uncomment the next line
573 # CLI(net)
574
575
576 def test_bgp_summary():
577 global fatal_error
578 global net
579
580 # Skip if previous fatal error condition is raised
581 if (fatal_error != ""):
582 pytest.skip(fatal_error)
583
584 thisDir = os.path.dirname(os.path.realpath(__file__))
585
586 print("\n\n** Verifying BGP Summary")
587 print("******************************************\n")
588 failures = 0
589 for i in range(1, 2):
590 refTableFile = '%s/r%s/show_ip_bgp_summary.ref' % (thisDir, i)
591 if os.path.isfile(refTableFile):
592 # Read expected result from file
593 expected = open(refTableFile).read().rstrip()
594 # Fix newlines (make them all the same)
595 expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1)
596
597 # Actual output from router
598 actual = net['r%s' % i].cmd('vtysh -c "show ip bgp summary" 2> /dev/null').rstrip()
599 # Mask out "using XXiXX bytes" portion. They are random...
600 actual = re.sub(r"using [0-9]+ bytes", "using XXXX bytes", actual)
601 # Mask out "using XiXXX KiB" portion. They are random...
602 actual = re.sub(r"using [0-9]+ KiB", "using XXXX KiB", actual)
603 #
604 # Remove extra summaries which exist with newer versions
605 #
606 # Remove summary lines (changed recently)
607 actual = re.sub(r'Total number.*', '', actual)
608 actual = re.sub(r'Displayed.*', '', actual)
609 # Remove IPv4 Unicast Summary (Title only)
610 actual = re.sub(r'IPv4 Unicast Summary:', '', actual)
611 # Remove IPv4 Multicast Summary (all of it)
612 actual = re.sub(r'IPv4 Multicast Summary:', '', actual)
613 actual = re.sub(r'No IPv4 Multicast neighbor is configured', '', actual)
614 # Remove IPv4 VPN Summary (all of it)
615 actual = re.sub(r'IPv4 VPN Summary:', '', actual)
616 actual = re.sub(r'No IPv4 VPN neighbor is configured', '', actual)
617 # Remove IPv4 Encap Summary (all of it)
618 actual = re.sub(r'IPv4 Encap Summary:', '', actual)
619 actual = re.sub(r'No IPv4 Encap neighbor is configured', '', actual)
620 # Remove Unknown Summary (all of it)
621 actual = re.sub(r'Unknown Summary:', '', actual)
622 actual = re.sub(r'No Unknown neighbor is configured', '', actual)
623
624 actual = re.sub(r'IPv4 labeled-unicast Summary:', '', actual)
625 actual = re.sub(r'No IPv4 labeled-unicast neighbor is configured', '', actual)
626
627 # Strip empty lines
628 actual = actual.lstrip()
629 actual = actual.rstrip()
630 #
631 # Fix newlines (make them all the same)
632 actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
633
634 # Generate Diff
635 diff = topotest.get_textdiff(actual, expected,
636 title1="actual SHOW IP BGP SUMMARY",
637 title2="expected SHOW IP BGP SUMMARY")
638
639 # Empty string if it matches, otherwise diff contains unified diff
640 if diff:
641 sys.stderr.write('r%s failed SHOW IP BGP SUMMARY check:\n%s\n' % (i, diff))
642 failures += 1
643 else:
644 print("r%s ok" % i)
645
646 assert failures == 0, "SHOW IP BGP SUMMARY failed for router r%s:\n%s" % (i, diff)
647
648 # Make sure that all daemons are running
649 for i in range(1, 2):
650 fatal_error = net['r%s' % i].checkRouterRunning()
651 assert fatal_error == "", fatal_error
652
653 # For debugging after starting FRR/Quagga daemons, uncomment the next line
654 # CLI(net)
655
656
657 def test_bgp_ipv6_summary():
658 global fatal_error
659 global net
660
661 # Skip if previous fatal error condition is raised
662 if (fatal_error != ""):
663 pytest.skip(fatal_error)
664
665 thisDir = os.path.dirname(os.path.realpath(__file__))
666
667 print("\n\n** Verifying BGP IPv6 Summary")
668 print("******************************************\n")
669 failures = 0
670 for i in range(1, 2):
671 refTableFile = '%s/r%s/show_bgp_ipv6_summary.ref' % (thisDir, i)
672 if os.path.isfile(refTableFile):
673 # Read expected result from file
674 expected = open(refTableFile).read().rstrip()
675 # Fix newlines (make them all the same)
676 expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1)
677
678 # Actual output from router
679 actual = net['r%s' % i].cmd('vtysh -c "show bgp ipv6 summary" 2> /dev/null').rstrip()
680 # Mask out "using XXiXX bytes" portion. They are random...
681 actual = re.sub(r"using [0-9]+ bytes", "using XXXX bytes", actual)
682 # Mask out "using XiXXX KiB" portion. They are random...
683 actual = re.sub(r"using [0-9]+ KiB", "using XXXX KiB", actual)
684 #
685 # Remove extra summaries which exist with newer versions
686 #
687 # Remove summary lines (changed recently)
688 actual = re.sub(r'Total number.*', '', actual)
689 actual = re.sub(r'Displayed.*', '', actual)
690 # Remove IPv4 Unicast Summary (Title only)
691 actual = re.sub(r'IPv6 Unicast Summary:', '', actual)
692 # Remove IPv4 Multicast Summary (all of it)
693 actual = re.sub(r'IPv6 Multicast Summary:', '', actual)
694 actual = re.sub(r'No IPv6 Multicast neighbor is configured', '', actual)
695 # Remove IPv4 VPN Summary (all of it)
696 actual = re.sub(r'IPv6 VPN Summary:', '', actual)
697 actual = re.sub(r'No IPv6 VPN neighbor is configured', '', actual)
698 # Remove IPv4 Encap Summary (all of it)
699 actual = re.sub(r'IPv6 Encap Summary:', '', actual)
700 actual = re.sub(r'No IPv6 Encap neighbor is configured', '', actual)
701 # Remove Unknown Summary (all of it)
702 actual = re.sub(r'Unknown Summary:', '', actual)
703 actual = re.sub(r'No Unknown neighbor is configured', '', actual)
704
705 # Remove Labeled Unicast Summary (all of it)
706 actual = re.sub(r'IPv6 labeled-unicast Summary:', '', actual)
707 actual = re.sub(r'No IPv6 labeled-unicast neighbor is configured', '', actual)
708
709 # Strip empty lines
710 actual = actual.lstrip()
711 actual = actual.rstrip()
712 #
713 # Fix newlines (make them all the same)
714 actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
715
716 # Generate Diff
717 diff = topotest.get_textdiff(actual, expected,
718 title1="actual SHOW BGP IPv6 SUMMARY",
719 title2="expected SHOW BGP IPv6 SUMMARY")
720
721 # Empty string if it matches, otherwise diff contains unified diff
722 if diff:
723 sys.stderr.write('r%s failed SHOW BGP IPv6 SUMMARY check:\n%s\n' % (i, diff))
724 failures += 1
725 else:
726 print("r%s ok" % i)
727
728 assert failures == 0, "SHOW BGP IPv6 SUMMARY failed for router r%s:\n%s" % (i, diff)
729
730 # Make sure that all daemons are running
731 for i in range(1, 2):
732 fatal_error = net['r%s' % i].checkRouterRunning()
733 assert fatal_error == "", fatal_error
734
735 # For debugging after starting FRR/Quagga daemons, uncomment the next line
736 # CLI(net)
737
738
739 def test_bgp_ipv4():
740 global fatal_error
741 global net
742
743 # Skip if previous fatal error condition is raised
744 if (fatal_error != ""):
745 pytest.skip(fatal_error)
746
747 thisDir = os.path.dirname(os.path.realpath(__file__))
748
749 print("\n\n** Verifying BGP IPv4")
750 print("******************************************\n")
751 diffresult = {}
752 for i in range(1, 2):
753 success = 0
754 for refTableFile in (glob.glob(
755 '%s/r%s/show_bgp_ipv4*.ref' % (thisDir, i))):
756 if os.path.isfile(refTableFile):
757 # Read expected result from file
758 expected = open(refTableFile).read().rstrip()
759 # Fix newlines (make them all the same)
760 expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1)
761
762 # Actual output from router
763 actual = net['r%s' % i].cmd('vtysh -c "show bgp ipv4" 2> /dev/null').rstrip()
764 # Remove summary line (changed recently)
765 actual = re.sub(r'Total number.*', '', actual)
766 actual = re.sub(r'Displayed.*', '', actual)
767 actual = actual.rstrip()
768 # Fix newlines (make them all the same)
769 actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
770
771 # Generate Diff
772 diff = topotest.get_textdiff(actual, expected,
773 title1="actual SHOW BGP IPv4",
774 title2="expected SHOW BGP IPv4")
775
776 # Empty string if it matches, otherwise diff contains unified diff
777 if diff:
778 diffresult[refTableFile] = diff
779 else:
780 success = 1
781 print("template %s matched: r%s ok" % (refTableFile, i))
782 break
783
784 if not success:
785 resultstr = 'No template matched.\n'
786 for f in diffresult.iterkeys():
787 resultstr += (
788 'template %s: r%s failed SHOW BGP IPv4 check:\n%s\n'
789 % (f, i, diffresult[f]))
790 raise AssertionError(
791 "SHOW BGP IPv4 failed for router r%s:\n%s" % (i, resultstr))
792
793 # Make sure that all daemons are running
794 for i in range(1, 2):
795 fatal_error = net['r%s' % i].checkRouterRunning()
796 assert fatal_error == "", fatal_error
797
798 # For debugging after starting FRR/Quagga daemons, uncomment the next line
799 # CLI(net)
800
801
802 def test_bgp_ipv6():
803 global fatal_error
804 global net
805
806 # Skip if previous fatal error condition is raised
807 if (fatal_error != ""):
808 pytest.skip(fatal_error)
809
810 thisDir = os.path.dirname(os.path.realpath(__file__))
811
812 print("\n\n** Verifying BGP IPv6")
813 print("******************************************\n")
814 diffresult = {}
815 for i in range(1, 2):
816 success = 0
817 for refTableFile in (glob.glob(
818 '%s/r%s/show_bgp_ipv6*.ref' % (thisDir, i))):
819 if os.path.isfile(refTableFile):
820 # Read expected result from file
821 expected = open(refTableFile).read().rstrip()
822 # Fix newlines (make them all the same)
823 expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1)
824
825 # Actual output from router
826 actual = net['r%s' % i].cmd('vtysh -c "show bgp ipv6" 2> /dev/null').rstrip()
827 # Remove summary line (changed recently)
828 actual = re.sub(r'Total number.*', '', actual)
829 actual = re.sub(r'Displayed.*', '', actual)
830 actual = actual.rstrip()
831 # Fix newlines (make them all the same)
832 actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
833
834 # Generate Diff
835 diff = topotest.get_textdiff(actual, expected,
836 title1="actual SHOW BGP IPv6",
837 title2="expected SHOW BGP IPv6")
838
839 # Empty string if it matches, otherwise diff contains unified diff
840 if diff:
841 diffresult[refTableFile] = diff
842 else:
843 success = 1
844 print("template %s matched: r%s ok" % (refTableFile, i))
845
846 if not success:
847 resultstr = 'No template matched.\n'
848 for f in diffresult.iterkeys():
849 resultstr += (
850 'template %s: r%s failed SHOW BGP IPv6 check:\n%s\n'
851 % (f, i, diffresult[f]))
852 raise AssertionError(
853 "SHOW BGP IPv6 failed for router r%s:\n%s" % (i, resultstr))
854
855 # Make sure that all daemons are running
856 for i in range(1, 2):
857 fatal_error = net['r%s' % i].checkRouterRunning()
858 assert fatal_error == "", fatal_error
859
860 # For debugging after starting FRR/Quagga daemons, uncomment the next line
861 # CLI(net)
862
863
864
865 def test_mpls_interfaces():
866 global fatal_error
867 global net
868
869 # Skip if previous fatal error condition is raised
870 if (fatal_error != ""):
871 pytest.skip(fatal_error)
872
873 # Skip if no LDP installed or old kernel
874 if (net['r1'].daemon_available('ldpd') == False):
875 pytest.skip("No MPLS or kernel < 4.5")
876
877 thisDir = os.path.dirname(os.path.realpath(__file__))
878
879 print("\n\n** Verifying MPLS Interfaces")
880 print("******************************************\n")
881 failures = 0
882 for i in range(1, 2):
883 refTableFile = '%s/r%s/show_mpls_ldp_interface.ref' % (thisDir, i)
884 if os.path.isfile(refTableFile):
885 # Read expected result from file
886 expected = open(refTableFile).read().rstrip()
887 # Fix newlines (make them all the same)
888 expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1)
889
890 # Actual output from router
891 actual = net['r%s' % i].cmd('vtysh -c "show mpls ldp interface" 2> /dev/null').rstrip()
892 # Mask out Timer in Uptime
893 actual = re.sub(r" [0-9][0-9]:[0-9][0-9]:[0-9][0-9] ", " xx:xx:xx ", actual)
894 # Fix newlines (make them all the same)
895 actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
896
897 # Generate Diff
898 diff = topotest.get_textdiff(actual, expected,
899 title1="actual MPLS LDP interface status",
900 title2="expected MPLS LDP interface status")
901
902 # Empty string if it matches, otherwise diff contains unified diff
903 if diff:
904 sys.stderr.write('r%s failed MPLS LDP Interface status Check:\n%s\n' % (i, diff))
905 failures += 1
906 else:
907 print("r%s ok" % i)
908
909 if failures>0:
910 fatal_error = "MPLS LDP Interface status failed"
911
912 assert failures == 0, "MPLS LDP Interface status failed for router r%s:\n%s" % (i, diff)
913
914 # Make sure that all daemons are running
915 for i in range(1, 2):
916 fatal_error = net['r%s' % i].checkRouterRunning()
917 assert fatal_error == "", fatal_error
918
919 # For debugging after starting FRR/Quagga daemons, uncomment the next line
920 # CLI(net)
921
922
923 def test_shutdown_check_stderr():
924 global fatal_error
925 global net
926
927 # Skip if previous fatal error condition is raised
928 if (fatal_error != ""):
929 pytest.skip(fatal_error)
930
931 print("\n\n** Verifying unexpected STDERR output from daemons")
932 print("******************************************\n")
933
934 if os.environ.get('TOPOTESTS_CHECK_STDERR') is None:
935 print("SKIPPED final check on StdErr output: Disabled (TOPOTESTS_CHECK_STDERR undefined)\n")
936 pytest.skip('Skipping test for Stderr output')
937
938 thisDir = os.path.dirname(os.path.realpath(__file__))
939
940 print("thisDir=" + thisDir)
941
942 net['r1'].stopRouter()
943
944 log = net['r1'].getStdErr('ripd')
945 if log:
946 print("\nRIPd StdErr Log:\n" + log)
947 log = net['r1'].getStdErr('ripngd')
948 if log:
949 print("\nRIPngd StdErr Log:\n" + log)
950 log = net['r1'].getStdErr('ospfd')
951 if log:
952 print("\nOSPFd StdErr Log:\n" + log)
953 log = net['r1'].getStdErr('ospf6d')
954 if log:
955 print("\nOSPF6d StdErr Log:\n" + log)
956 log = net['r1'].getStdErr('isisd')
957 if log:
958 print("\nISISd StdErr Log:\n" + log)
959 log = net['r1'].getStdErr('bgpd')
960 if log:
961 print("\nBGPd StdErr Log:\n" + log)
962 if (net['r1'].daemon_available('ldpd')):
963 log = net['r1'].getStdErr('ldpd')
964 if log:
965 print("\nLDPd StdErr Log:\n" + log)
966 log = net['r1'].getStdErr('zebra')
967 if log:
968 print("\nZebra StdErr Log:\n" + log)
969
970
971 def test_shutdown_check_memleak():
972 global fatal_error
973 global net
974
975 # Skip if previous fatal error condition is raised
976 if (fatal_error != ""):
977 pytest.skip(fatal_error)
978
979 if os.environ.get('TOPOTESTS_CHECK_MEMLEAK') is None:
980 print("SKIPPED final check on Memory leaks: Disabled (TOPOTESTS_CHECK_MEMLEAK undefined)\n")
981 pytest.skip('Skipping test for memory leaks')
982
983 thisDir = os.path.dirname(os.path.realpath(__file__))
984
985 for i in range(1, 2):
986 net['r%s' % i].stopRouter()
987 net['r%s' % i].report_memory_leaks(os.environ.get('TOPOTESTS_CHECK_MEMLEAK'), os.path.basename(__file__))
988
989
990 if __name__ == '__main__':
991
992 setLogLevel('info')
993 # To suppress tracebacks, either use the following pytest call or add "--tb=no" to cli
994 # retval = pytest.main(["-s", "--tb=no"])
995 retval = pytest.main(["-s"])
996 sys.exit(retval)