]>
git.proxmox.com Git - mirror_frr.git/blob - tests/topotests/all-protocol-startup/test_all_protocol_startup.py
4 # test_all_protocol_startup.py
5 # Part of NetDEF Topology Tests
7 # Copyright (c) 2017 by
8 # Network Device Education Foundation, Inc. ("NetDEF")
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
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
26 test_all_protocol_startup.py: Test of all protocols at same time
35 from time
import sleep
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
44 from functools
import partial
46 sys
.path
.append(os
.path
.dirname(os
.path
.dirname(os
.path
.abspath(__file__
))))
47 from lib
import topotest
52 #####################################################
54 ## Network Topology Definition
56 #####################################################
58 class NetworkTopo(Topo
):
59 "All Protocol Startup Test"
61 def build(self
, **_opts
):
67 router
[1] = topotest
.addRouter(self
, 'r1')
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
)
78 #####################################################
82 #####################################################
84 def setup_module(module
):
88 print("\n\n** %s: Setup Topology" % module
.__name
__)
89 print("******************************************\n")
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')
95 thisDir
= os
.path
.dirname(os
.path
.realpath(__file__
))
98 net
= Mininet(controller
=None, topo
=topo
)
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
)
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
))
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()
125 # For debugging after starting Quagga/FRR daemons, uncomment the next line
129 def teardown_module(module
):
132 print("\n\n** %s: Shutdown Topology" % module
.__name
__)
133 print("******************************************\n")
135 # End - Shutdown network
139 def test_router_running():
143 # Skip if previous fatal error condition is raised
144 if (fatal_error
!= ""):
145 pytest
.skip(fatal_error
)
147 print("\n\n** Check if FRR/Quagga is running on each Router node")
148 print("******************************************\n")
152 for i
in range(1, 2):
153 fatal_error
= net
['r%s' % i
].checkRouterRunning()
154 assert fatal_error
== "", fatal_error
156 # For debugging after starting FRR/Quagga daemons, uncomment the next line
160 def test_error_messages_vtysh():
164 # Skip if previous fatal error condition is raised
165 if (fatal_error
!= ""):
166 pytest
.skip(fatal_error
)
168 print("\n\n** Check for error messages on VTYSH")
169 print("******************************************\n")
172 for i
in range(1, 2):
174 # First checking Standard Output
177 # VTYSH output from router
178 vtystdout
= net
['r%s' % i
].cmd('vtysh -c "show version" 2> /dev/null').rstrip()
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
)
185 if (vtystdout
== ''):
186 print("r%s StdOut ok" % i
)
188 assert vtystdout
== '', "Vtysh StdOut Output check failed for router r%s" % i
191 # Second checking Standard Error
194 # VTYSH StdErr output from router
195 vtystderr
= net
['r%s' % i
].cmd('vtysh -c "show version" > /dev/null').rstrip()
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)
202 if (vtystderr
== ''):
203 print("r%s StdErr ok" % i
)
205 assert vtystderr
== '', "Vtysh StdErr Output check failed for router r%s" % i
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
212 # For debugging after starting FRR/Quagga daemons, uncomment the next line
216 def test_error_messages_daemons():
220 # Skip if previous fatal error condition is raised
221 if (fatal_error
!= ""):
222 pytest
.skip(fatal_error
)
224 print("\n\n** Check for error messages in daemons")
225 print("******************************************\n")
229 for i
in range(1, 2):
230 log
= net
['r%s' % i
].getStdErr('ripd')
232 error_logs
+= "r%s RIPd StdErr Output:\n" % i
234 log
= net
['r%s' % i
].getStdErr('ripngd')
236 error_logs
+= "r%s RIPngd StdErr Output:\n" % i
238 log
= net
['r%s' % i
].getStdErr('ospfd')
240 error_logs
+= "r%s OSPFd StdErr Output:\n" % i
242 log
= net
['r%s' % i
].getStdErr('ospf6d')
244 error_logs
+= "r%s OSPF6d StdErr Output:\n" % i
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()
251 error_logs
+= "r%s ISISd StdErr Output:\n" % i
253 log
= net
['r%s' % i
].getStdErr('bgpd')
255 error_logs
+= "r%s BGPd StdErr Output:\n" % i
257 if (net
['r%s' % i
].daemon_available('ldpd')):
258 log
= net
['r%s' % i
].getStdErr('ldpd')
260 error_logs
+= "r%s LDPd StdErr Output:\n" % i
262 log
= net
['r%s' % i
].getStdErr('zebra')
264 error_logs
+= "r%s Zebra StdErr Output:\n"
268 sys
.stderr
.write('Failed check for StdErr Output on daemons:\n%s\n' % error_logs
)
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')
276 assert error_logs
== "", "Daemons report errors to StdErr"
278 # For debugging after starting FRR/Quagga daemons, uncomment the next line
282 def test_converge_protocols():
286 # Skip if previous fatal error condition is raised
287 if (fatal_error
!= ""):
288 pytest
.skip(fatal_error
)
290 thisDir
= os
.path
.dirname(os
.path
.realpath(__file__
))
292 print("\n\n** Waiting for protocols convergence")
293 print("******************************************\n")
295 # Not really implemented yet - just sleep 60 secs for now
298 # Make sure that all daemons are running
300 for i
in range(1, 2):
301 fatal_error
= net
['r%s' % i
].checkRouterRunning()
302 assert fatal_error
== "", fatal_error
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)
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")
317 sys
.stderr
.write('r%s failed IP Routing table check:\n%s\n' % (i
, diff
))
322 assert failures
== 0, "IP Routing table failed for r%s\n%s" % (i
, diff
)
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)
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")
339 sys
.stderr
.write('r%s failed IPv6 Routing table check:\n%s\n' % (i
, diff
))
344 assert failures
== 0, "IPv6 Routing table failed for r%s\n%s" % (i
, diff
)
346 # For debugging after starting FRR/Quagga daemons, uncomment the next line
350 def test_rip_status():
354 # Skip if previous fatal error condition is raised
355 if (fatal_error
!= ""):
356 pytest
.skip(fatal_error
)
358 thisDir
= os
.path
.dirname(os
.path
.realpath(__file__
))
360 print("\n\n** Verifying RIP status")
361 print("******************************************\n")
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)
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)
381 diff
= topotest
.get_textdiff(actual
, expected
,
382 title1
="actual IP RIP status",
383 title2
="expected IP RIP status")
385 # Empty string if it matches, otherwise diff contains unified diff
387 sys
.stderr
.write('r%s failed IP RIP status check:\n%s\n' % (i
, diff
))
392 assert failures
== 0, "IP RIP status failed for router r%s:\n%s" % (i
, diff
)
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
399 # For debugging after starting FRR/Quagga daemons, uncomment the next line
403 def test_ripng_status():
407 # Skip if previous fatal error condition is raised
408 if (fatal_error
!= ""):
409 pytest
.skip(fatal_error
)
411 thisDir
= os
.path
.dirname(os
.path
.realpath(__file__
))
413 print("\n\n** Verifying RIPng status")
414 print("******************************************\n")
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)
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)
436 diff
= topotest
.get_textdiff(actual
, expected
,
437 title1
="actual IPv6 RIPng status",
438 title2
="expected IPv6 RIPng status")
440 # Empty string if it matches, otherwise diff contains unified diff
442 sys
.stderr
.write('r%s failed IPv6 RIPng status check:\n%s\n' % (i
, diff
))
447 assert failures
== 0, "IPv6 RIPng status failed for router r%s:\n%s" % (i
, diff
)
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
454 # For debugging after starting FRR/Quagga daemons, uncomment the next line
458 def test_ospfv2_interfaces():
462 # Skip if previous fatal error condition is raised
463 if (fatal_error
!= ""):
464 pytest
.skip(fatal_error
)
466 thisDir
= os
.path
.dirname(os
.path
.realpath(__file__
))
468 print("\n\n** Verifying OSPFv2 interfaces")
469 print("******************************************\n")
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)
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
)
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)
493 diff
= topotest
.get_textdiff(actual
, expected
,
494 title1
="actual SHOW IP OSPF INTERFACE",
495 title2
="expected SHOW IP OSPF INTERFACE")
497 # Empty string if it matches, otherwise diff contains unified diff
499 sys
.stderr
.write('r%s failed SHOW IP OSPF INTERFACE check:\n%s\n' % (i
, diff
))
504 # Ignoring the issue if told to ignore (ie not yet fixed)
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')
510 assert failures
== 0, "SHOW IP OSPF INTERFACE failed for router r%s:\n%s" % (i
, diff
)
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
517 # For debugging after starting FRR/Quagga daemons, uncomment the next line
521 def test_isis_interfaces():
525 # Skip if previous fatal error condition is raised
526 if (fatal_error
!= ""):
527 pytest
.skip(fatal_error
)
529 thisDir
= os
.path
.dirname(os
.path
.realpath(__file__
))
531 print("\n\n** Verifying ISIS interfaces")
532 print("******************************************\n")
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)
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)
554 diff
= topotest
.get_textdiff(actual
, expected
,
555 title1
="actual SHOW ISIS INTERFACE DETAIL",
556 title2
="expected SHOW ISIS OSPF6 INTERFACE DETAIL")
558 # Empty string if it matches, otherwise diff contains unified diff
560 sys
.stderr
.write('r%s failed SHOW ISIS INTERFACE DETAIL check:\n%s\n' % (i
, diff
))
565 assert failures
== 0, "SHOW ISIS INTERFACE DETAIL failed for router r%s:\n%s" % (i
, diff
)
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
572 # For debugging after starting FRR/Quagga daemons, uncomment the next line
576 def test_bgp_summary():
580 # Skip if previous fatal error condition is raised
581 if (fatal_error
!= ""):
582 pytest
.skip(fatal_error
)
584 thisDir
= os
.path
.dirname(os
.path
.realpath(__file__
))
586 print("\n\n** Verifying BGP Summary")
587 print("******************************************\n")
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)
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
)
604 # Remove extra summaries which exist with newer versions
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
)
624 actual
= re
.sub(r
'IPv4 labeled-unicast Summary:', '', actual
)
625 actual
= re
.sub(r
'No IPv4 labeled-unicast neighbor is configured', '', actual
)
628 actual
= actual
.lstrip()
629 actual
= actual
.rstrip()
631 # Fix newlines (make them all the same)
632 actual
= ('\n'.join(actual
.splitlines()) + '\n').splitlines(1)
635 diff
= topotest
.get_textdiff(actual
, expected
,
636 title1
="actual SHOW IP BGP SUMMARY",
637 title2
="expected SHOW IP BGP SUMMARY")
639 # Empty string if it matches, otherwise diff contains unified diff
641 sys
.stderr
.write('r%s failed SHOW IP BGP SUMMARY check:\n%s\n' % (i
, diff
))
646 assert failures
== 0, "SHOW IP BGP SUMMARY failed for router r%s:\n%s" % (i
, diff
)
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
653 # For debugging after starting FRR/Quagga daemons, uncomment the next line
657 def test_bgp_ipv6_summary():
661 # Skip if previous fatal error condition is raised
662 if (fatal_error
!= ""):
663 pytest
.skip(fatal_error
)
665 thisDir
= os
.path
.dirname(os
.path
.realpath(__file__
))
667 print("\n\n** Verifying BGP IPv6 Summary")
668 print("******************************************\n")
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)
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
)
685 # Remove extra summaries which exist with newer versions
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
)
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
)
710 actual
= actual
.lstrip()
711 actual
= actual
.rstrip()
713 # Fix newlines (make them all the same)
714 actual
= ('\n'.join(actual
.splitlines()) + '\n').splitlines(1)
717 diff
= topotest
.get_textdiff(actual
, expected
,
718 title1
="actual SHOW BGP IPv6 SUMMARY",
719 title2
="expected SHOW BGP IPv6 SUMMARY")
721 # Empty string if it matches, otherwise diff contains unified diff
723 sys
.stderr
.write('r%s failed SHOW BGP IPv6 SUMMARY check:\n%s\n' % (i
, diff
))
728 assert failures
== 0, "SHOW BGP IPv6 SUMMARY failed for router r%s:\n%s" % (i
, diff
)
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
735 # For debugging after starting FRR/Quagga daemons, uncomment the next line
743 # Skip if previous fatal error condition is raised
744 if (fatal_error
!= ""):
745 pytest
.skip(fatal_error
)
747 thisDir
= os
.path
.dirname(os
.path
.realpath(__file__
))
749 print("\n\n** Verifying BGP IPv4")
750 print("******************************************\n")
752 for i
in range(1, 2):
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)
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)
772 diff
= topotest
.get_textdiff(actual
, expected
,
773 title1
="actual SHOW BGP IPv4",
774 title2
="expected SHOW BGP IPv4")
776 # Empty string if it matches, otherwise diff contains unified diff
778 diffresult
[refTableFile
] = diff
781 print("template %s matched: r%s ok" % (refTableFile
, i
))
785 resultstr
= 'No template matched.\n'
786 for f
in diffresult
.iterkeys():
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
))
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
798 # For debugging after starting FRR/Quagga daemons, uncomment the next line
806 # Skip if previous fatal error condition is raised
807 if (fatal_error
!= ""):
808 pytest
.skip(fatal_error
)
810 thisDir
= os
.path
.dirname(os
.path
.realpath(__file__
))
812 print("\n\n** Verifying BGP IPv6")
813 print("******************************************\n")
815 for i
in range(1, 2):
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)
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)
835 diff
= topotest
.get_textdiff(actual
, expected
,
836 title1
="actual SHOW BGP IPv6",
837 title2
="expected SHOW BGP IPv6")
839 # Empty string if it matches, otherwise diff contains unified diff
841 diffresult
[refTableFile
] = diff
844 print("template %s matched: r%s ok" % (refTableFile
, i
))
847 resultstr
= 'No template matched.\n'
848 for f
in diffresult
.iterkeys():
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
))
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
860 # For debugging after starting FRR/Quagga daemons, uncomment the next line
865 def test_mpls_interfaces():
869 # Skip if previous fatal error condition is raised
870 if (fatal_error
!= ""):
871 pytest
.skip(fatal_error
)
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")
877 thisDir
= os
.path
.dirname(os
.path
.realpath(__file__
))
879 print("\n\n** Verifying MPLS Interfaces")
880 print("******************************************\n")
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)
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)
898 diff
= topotest
.get_textdiff(actual
, expected
,
899 title1
="actual MPLS LDP interface status",
900 title2
="expected MPLS LDP interface status")
902 # Empty string if it matches, otherwise diff contains unified diff
904 sys
.stderr
.write('r%s failed MPLS LDP Interface status Check:\n%s\n' % (i
, diff
))
910 fatal_error
= "MPLS LDP Interface status failed"
912 assert failures
== 0, "MPLS LDP Interface status failed for router r%s:\n%s" % (i
, diff
)
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
919 # For debugging after starting FRR/Quagga daemons, uncomment the next line
923 def test_shutdown_check_stderr():
927 # Skip if previous fatal error condition is raised
928 if (fatal_error
!= ""):
929 pytest
.skip(fatal_error
)
931 print("\n\n** Verifying unexpected STDERR output from daemons")
932 print("******************************************\n")
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')
938 thisDir
= os
.path
.dirname(os
.path
.realpath(__file__
))
940 print("thisDir=" + thisDir
)
942 net
['r1'].stopRouter()
944 log
= net
['r1'].getStdErr('ripd')
946 print("\nRIPd StdErr Log:\n" + log
)
947 log
= net
['r1'].getStdErr('ripngd')
949 print("\nRIPngd StdErr Log:\n" + log
)
950 log
= net
['r1'].getStdErr('ospfd')
952 print("\nOSPFd StdErr Log:\n" + log
)
953 log
= net
['r1'].getStdErr('ospf6d')
955 print("\nOSPF6d StdErr Log:\n" + log
)
956 log
= net
['r1'].getStdErr('isisd')
958 print("\nISISd StdErr Log:\n" + log
)
959 log
= net
['r1'].getStdErr('bgpd')
961 print("\nBGPd StdErr Log:\n" + log
)
962 if (net
['r1'].daemon_available('ldpd')):
963 log
= net
['r1'].getStdErr('ldpd')
965 print("\nLDPd StdErr Log:\n" + log
)
966 log
= net
['r1'].getStdErr('zebra')
968 print("\nZebra StdErr Log:\n" + log
)
971 def test_shutdown_check_memleak():
975 # Skip if previous fatal error condition is raised
976 if (fatal_error
!= ""):
977 pytest
.skip(fatal_error
)
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')
983 thisDir
= os
.path
.dirname(os
.path
.realpath(__file__
))
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__
))
990 if __name__
== '__main__':
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"])