]>
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
].loadConf('sharpd')
124 net
['r%s' % i
].startRouter()
126 # For debugging after starting Quagga/FRR daemons, uncomment the next line
130 def teardown_module(module
):
133 print("\n\n** %s: Shutdown Topology" % module
.__name
__)
134 print("******************************************\n")
136 # End - Shutdown network
140 def test_router_running():
144 # Skip if previous fatal error condition is raised
145 if (fatal_error
!= ""):
146 pytest
.skip(fatal_error
)
148 print("\n\n** Check if FRR/Quagga is running on each Router node")
149 print("******************************************\n")
153 for i
in range(1, 2):
154 fatal_error
= net
['r%s' % i
].checkRouterRunning()
155 assert fatal_error
== "", fatal_error
157 # For debugging after starting FRR/Quagga daemons, uncomment the next line
161 def test_error_messages_vtysh():
165 # Skip if previous fatal error condition is raised
166 if (fatal_error
!= ""):
167 pytest
.skip(fatal_error
)
169 print("\n\n** Check for error messages on VTYSH")
170 print("******************************************\n")
173 for i
in range(1, 2):
175 # First checking Standard Output
178 # VTYSH output from router
179 vtystdout
= net
['r%s' % i
].cmd('vtysh -c "show version" 2> /dev/null').rstrip()
181 # Fix newlines (make them all the same)
182 vtystdout
= ('\n'.join(vtystdout
.splitlines()) + '\n').rstrip()
183 # Drop everything starting with "FRRouting X.xx" message
184 vtystdout
= re
.sub(r
"FRRouting [0-9]+.*", "", vtystdout
, flags
=re
.DOTALL
)
186 if (vtystdout
== ''):
187 print("r%s StdOut ok" % i
)
189 assert vtystdout
== '', "Vtysh StdOut Output check failed for router r%s" % i
192 # Second checking Standard Error
195 # VTYSH StdErr output from router
196 vtystderr
= net
['r%s' % i
].cmd('vtysh -c "show version" > /dev/null').rstrip()
198 # Fix newlines (make them all the same)
199 vtystderr
= ('\n'.join(vtystderr
.splitlines()) + '\n').rstrip()
200 # # Drop everything starting with "FRRouting X.xx" message
201 # vtystderr = re.sub(r"FRRouting [0-9]+.*", "", vtystderr, flags=re.DOTALL)
203 if (vtystderr
== ''):
204 print("r%s StdErr ok" % i
)
206 assert vtystderr
== '', "Vtysh StdErr Output check failed for router r%s" % i
208 # Make sure that all daemons are running
209 for i
in range(1, 2):
210 fatal_error
= net
['r%s' % i
].checkRouterRunning()
211 assert fatal_error
== "", fatal_error
213 # For debugging after starting FRR/Quagga daemons, uncomment the next line
217 def test_error_messages_daemons():
221 # Skip if previous fatal error condition is raised
222 if (fatal_error
!= ""):
223 pytest
.skip(fatal_error
)
225 print("\n\n** Check for error messages in daemons")
226 print("******************************************\n")
230 for i
in range(1, 2):
231 log
= net
['r%s' % i
].getStdErr('ripd')
233 error_logs
+= "r%s RIPd StdErr Output:\n" % i
235 log
= net
['r%s' % i
].getStdErr('ripngd')
237 error_logs
+= "r%s RIPngd StdErr Output:\n" % i
239 log
= net
['r%s' % i
].getStdErr('ospfd')
241 error_logs
+= "r%s OSPFd StdErr Output:\n" % i
243 log
= net
['r%s' % i
].getStdErr('ospf6d')
245 error_logs
+= "r%s OSPF6d StdErr Output:\n" % i
247 log
= net
['r%s' % i
].getStdErr('isisd')
248 # ISIS shows debugging enabled status on StdErr
249 # Remove these messages
250 log
= re
.sub(r
"^IS-IS .* debugging is on.*", "", log
).rstrip()
252 error_logs
+= "r%s ISISd StdErr Output:\n" % i
254 log
= net
['r%s' % i
].getStdErr('bgpd')
256 error_logs
+= "r%s BGPd StdErr Output:\n" % i
258 if (net
['r%s' % i
].daemon_available('ldpd')):
259 log
= net
['r%s' % i
].getStdErr('ldpd')
261 error_logs
+= "r%s LDPd StdErr Output:\n" % i
263 log
= net
['r%s' % i
].getStdErr('zebra')
265 error_logs
+= "r%s Zebra StdErr Output:\n"
269 sys
.stderr
.write('Failed check for StdErr Output on daemons:\n%s\n' % error_logs
)
271 # Ignoring the issue if told to ignore (ie not yet fixed)
272 if (error_logs
!= ""):
273 if (os
.environ
.get('bamboo_TOPOTESTS_ISSUE_349') == "IGNORE"):
274 sys
.stderr
.write('Known issue - IGNORING. See https://github.com/FRRouting/frr/issues/349\n')
275 pytest
.skip('Known issue - IGNORING. See https://github.com/FRRouting/frr/issues/349')
277 assert error_logs
== "", "Daemons report errors to StdErr"
279 # For debugging after starting FRR/Quagga daemons, uncomment the next line
283 def test_converge_protocols():
287 # Skip if previous fatal error condition is raised
288 if (fatal_error
!= ""):
289 pytest
.skip(fatal_error
)
291 thisDir
= os
.path
.dirname(os
.path
.realpath(__file__
))
293 print("\n\n** Waiting for protocols convergence")
294 print("******************************************\n")
296 # Not really implemented yet - just sleep 60 secs for now
299 # Make sure that all daemons are running
301 for i
in range(1, 2):
302 fatal_error
= net
['r%s' % i
].checkRouterRunning()
303 assert fatal_error
== "", fatal_error
305 print("Show that v4 routes are right\n");
306 v4_routesFile
= '%s/r%s/ipv4_routes.ref' % (thisDir
, i
)
307 expected
= open(v4_routesFile
).read().rstrip()
308 expected
= ('\n'.join(expected
.splitlines()) + '\n').splitlines(1)
310 actual
= net
['r%s' %i].cmd('vtysh -c "show ip route" | /usr/bin/tail -n +7 | sort 2> /dev/null').rstrip()
311 # Drop time in last update
312 actual
= re
.sub(r
" [0-2][0-9]:[0-5][0-9]:[0-5][0-9]", " XX:XX:XX", actual
)
313 actual
= ('\n'.join(actual
.splitlines()) + '\n').splitlines(1)
314 diff
= topotest
.get_textdiff(actual
, expected
,
315 title1
="Actual IP Routing Table",
316 title2
="Expected IP RoutingTable")
318 sys
.stderr
.write('r%s failed IP Routing table check:\n%s\n' % (i
, diff
))
323 assert failures
== 0, "IP Routing table failed for r%s\n%s" % (i
, diff
)
327 print("Show that v6 routes are right\n")
328 v6_routesFile
= '%s/r%s/ipv6_routes.ref' % (thisDir
, i
)
329 expected
= open(v6_routesFile
).read().rstrip()
330 expected
= ('\n'.join(expected
.splitlines()) + '\n').splitlines(1)
332 actual
= net
['r%s' %i].cmd('vtysh -c "show ipv6 route" | /usr/bin/tail -n +7 | sort 2> /dev/null').rstrip()
333 # Drop time in last update
334 actual
= re
.sub(r
" [0-2][0-9]:[0-5][0-9]:[0-5][0-9]", " XX:XX:XX", actual
)
335 actual
= ('\n'.join(actual
.splitlines()) + '\n').splitlines(1)
336 diff
= topotest
.get_textdiff(actual
, expected
,
337 title1
="Actual IPv6 Routing Table",
338 title2
="Expected IPv6 RoutingTable")
340 sys
.stderr
.write('r%s failed IPv6 Routing table check:\n%s\n' % (i
, diff
))
345 assert failures
== 0, "IPv6 Routing table failed for r%s\n%s" % (i
, diff
)
347 # For debugging after starting FRR/Quagga daemons, uncomment the next line
350 def test_nexthop_groups():
354 # Skip if previous fatal error condition is raised
355 if (fatal_error
!= ""):
356 pytest
.skip(fatal_error
)
358 print("\n\n** Verifying Nexthop Groups")
359 print("******************************************\n")
361 # Create a lib nexthop-group
362 net
["r1"].cmd('vtysh -c "c t" -c "nexthop-group red" -c "nexthop 1.1.1.1" -c "nexthop 1.1.1.2"')
364 # Create with sharpd using nexthop-group
365 net
["r1"].cmd('vtysh -c "sharp install routes 2.2.2.1 nexthop-group red 1"')
367 # Verify route and that zebra created NHGs for and they are valid/installed
368 output
= net
["r1"].cmd('vtysh -c "show ip route 2.2.2.1/32 nexthop-group"')
369 match
= re
.search(r
"Nexthop Group ID: (\d+)", output
);
370 assert match
is not None, "Nexthop Group ID not found for sharpd route 2.2.2.1/32"
372 nhe_id
= int(match
.group(1))
374 output
= net
["r1"].cmd('vtysh -c "show nexthop-group rib %d"' % nhe_id
)
375 match
= re
.search(r
"Valid", output
)
376 assert match
is not None, "Nexthop Group ID=%d not marked Valid" % nhe_id
378 match
= re
.search(r
"Installed", output
)
379 assert match
is not None, "Nexthop Group ID=%d not marked Installed" % nhe_id
381 def test_rip_status():
385 # Skip if previous fatal error condition is raised
386 if (fatal_error
!= ""):
387 pytest
.skip(fatal_error
)
389 thisDir
= os
.path
.dirname(os
.path
.realpath(__file__
))
391 print("\n\n** Verifying RIP status")
392 print("******************************************\n")
394 for i
in range(1, 2):
395 refTableFile
= '%s/r%s/rip_status.ref' % (thisDir
, i
)
396 if os
.path
.isfile(refTableFile
):
397 # Read expected result from file
398 expected
= open(refTableFile
).read().rstrip()
399 # Fix newlines (make them all the same)
400 expected
= ('\n'.join(expected
.splitlines()) + '\n').splitlines(1)
402 # Actual output from router
403 actual
= net
['r%s' % i
].cmd('vtysh -c "show ip rip status" 2> /dev/null').rstrip()
404 # Drop time in next due
405 actual
= re
.sub(r
"in [0-9]+ seconds", "in XX seconds", actual
)
406 # Drop time in last update
407 actual
= re
.sub(r
" [0-2][0-9]:[0-5][0-9]:[0-5][0-9]", " XX:XX:XX", actual
)
408 # Fix newlines (make them all the same)
409 actual
= ('\n'.join(actual
.splitlines()) + '\n').splitlines(1)
412 diff
= topotest
.get_textdiff(actual
, expected
,
413 title1
="actual IP RIP status",
414 title2
="expected IP RIP status")
416 # Empty string if it matches, otherwise diff contains unified diff
418 sys
.stderr
.write('r%s failed IP RIP status check:\n%s\n' % (i
, diff
))
423 assert failures
== 0, "IP RIP status failed for router r%s:\n%s" % (i
, diff
)
425 # Make sure that all daemons are running
426 for i
in range(1, 2):
427 fatal_error
= net
['r%s' % i
].checkRouterRunning()
428 assert fatal_error
== "", fatal_error
430 # For debugging after starting FRR/Quagga daemons, uncomment the next line
434 def test_ripng_status():
438 # Skip if previous fatal error condition is raised
439 if (fatal_error
!= ""):
440 pytest
.skip(fatal_error
)
442 thisDir
= os
.path
.dirname(os
.path
.realpath(__file__
))
444 print("\n\n** Verifying RIPng status")
445 print("******************************************\n")
447 for i
in range(1, 2):
448 refTableFile
= '%s/r%s/ripng_status.ref' % (thisDir
, i
)
449 if os
.path
.isfile(refTableFile
):
450 # Read expected result from file
451 expected
= open(refTableFile
).read().rstrip()
452 # Fix newlines (make them all the same)
453 expected
= ('\n'.join(expected
.splitlines()) + '\n').splitlines(1)
455 # Actual output from router
456 actual
= net
['r%s' % i
].cmd('vtysh -c "show ipv6 ripng status" 2> /dev/null').rstrip()
457 # Mask out Link-Local mac address portion. They are random...
458 actual
= re
.sub(r
" fe80::[0-9a-f:]+", " fe80::XXXX:XXXX:XXXX:XXXX", actual
)
459 # Drop time in next due
460 actual
= re
.sub(r
"in [0-9]+ seconds", "in XX seconds", actual
)
461 # Drop time in last update
462 actual
= re
.sub(r
" [0-2][0-9]:[0-5][0-9]:[0-5][0-9]", " XX:XX:XX", actual
)
463 # Fix newlines (make them all the same)
464 actual
= ('\n'.join(actual
.splitlines()) + '\n').splitlines(1)
467 diff
= topotest
.get_textdiff(actual
, expected
,
468 title1
="actual IPv6 RIPng status",
469 title2
="expected IPv6 RIPng status")
471 # Empty string if it matches, otherwise diff contains unified diff
473 sys
.stderr
.write('r%s failed IPv6 RIPng status check:\n%s\n' % (i
, diff
))
478 assert failures
== 0, "IPv6 RIPng status failed for router r%s:\n%s" % (i
, diff
)
480 # Make sure that all daemons are running
481 for i
in range(1, 2):
482 fatal_error
= net
['r%s' % i
].checkRouterRunning()
483 assert fatal_error
== "", fatal_error
485 # For debugging after starting FRR/Quagga daemons, uncomment the next line
489 def test_ospfv2_interfaces():
493 # Skip if previous fatal error condition is raised
494 if (fatal_error
!= ""):
495 pytest
.skip(fatal_error
)
497 thisDir
= os
.path
.dirname(os
.path
.realpath(__file__
))
499 print("\n\n** Verifying OSPFv2 interfaces")
500 print("******************************************\n")
502 for i
in range(1, 2):
503 refTableFile
= '%s/r%s/show_ip_ospf_interface.ref' % (thisDir
, i
)
504 if os
.path
.isfile(refTableFile
):
505 # Read expected result from file
506 expected
= open(refTableFile
).read().rstrip()
507 # Fix newlines (make them all the same)
508 expected
= ('\n'.join(expected
.splitlines()) + '\n').splitlines(1)
510 # Actual output from router
511 actual
= net
['r%s' % i
].cmd('vtysh -c "show ip ospf interface" 2> /dev/null').rstrip()
512 # Mask out Bandwidth portion. They may change..
513 actual
= re
.sub(r
"BW [0-9]+ Mbit", "BW XX Mbit", actual
)
514 actual
= re
.sub(r
"ifindex [0-9]", "ifindex X", actual
)
516 # Drop time in next due
517 actual
= re
.sub(r
"Hello due in [0-9\.]+s", "Hello due in XX.XXXs", actual
)
518 # Fix 'MTU mismatch detection: enabled' vs 'MTU mismatch detection:enabled' - accept both
519 actual
= re
.sub(r
"MTU mismatch detection:([a-z]+.*)", r
"MTU mismatch detection: \1", actual
)
520 # Fix newlines (make them all the same)
521 actual
= ('\n'.join(actual
.splitlines()) + '\n').splitlines(1)
524 diff
= topotest
.get_textdiff(actual
, expected
,
525 title1
="actual SHOW IP OSPF INTERFACE",
526 title2
="expected SHOW IP OSPF INTERFACE")
528 # Empty string if it matches, otherwise diff contains unified diff
530 sys
.stderr
.write('r%s failed SHOW IP OSPF INTERFACE check:\n%s\n' % (i
, diff
))
535 # Ignoring the issue if told to ignore (ie not yet fixed)
537 if (os
.environ
.get('bamboo_TOPOTESTS_ISSUE_348') == "IGNORE"):
538 sys
.stderr
.write('Known issue - IGNORING. See https://github.com/FRRouting/frr/issues/348\n')
539 pytest
.skip('Known issue - IGNORING. See https://github.com/FRRouting/frr/issues/348')
541 assert failures
== 0, "SHOW IP OSPF INTERFACE failed for router r%s:\n%s" % (i
, diff
)
543 # Make sure that all daemons are running
544 for i
in range(1, 2):
545 fatal_error
= net
['r%s' % i
].checkRouterRunning()
546 assert fatal_error
== "", fatal_error
548 # For debugging after starting FRR/Quagga daemons, uncomment the next line
552 def test_isis_interfaces():
556 # Skip if previous fatal error condition is raised
557 if (fatal_error
!= ""):
558 pytest
.skip(fatal_error
)
560 thisDir
= os
.path
.dirname(os
.path
.realpath(__file__
))
562 print("\n\n** Verifying ISIS interfaces")
563 print("******************************************\n")
565 for i
in range(1, 2):
566 refTableFile
= '%s/r%s/show_isis_interface_detail.ref' % (thisDir
, i
)
567 if os
.path
.isfile(refTableFile
):
568 # Read expected result from file
569 expected
= open(refTableFile
).read().rstrip()
570 # Fix newlines (make them all the same)
571 expected
= ('\n'.join(expected
.splitlines()) + '\n').splitlines(1)
573 # Actual output from router
574 actual
= net
['r%s' % i
].cmd('vtysh -c "show isis interface detail" 2> /dev/null').rstrip()
575 # Mask out Link-Local mac address portion. They are random...
576 actual
= re
.sub(r
"fe80::[0-9a-f:]+", "fe80::XXXX:XXXX:XXXX:XXXX", actual
)
577 # Mask out SNPA mac address portion. They are random...
578 actual
= re
.sub(r
"SNPA: [0-9a-f\.]+", "SNPA: XXXX.XXXX.XXXX", actual
)
579 # Mask out Circuit ID number
580 actual
= re
.sub(r
"Circuit Id: 0x[0-9]+", "Circuit Id: 0xXX", actual
)
581 # Fix newlines (make them all the same)
582 actual
= ('\n'.join(actual
.splitlines()) + '\n').splitlines(1)
585 diff
= topotest
.get_textdiff(actual
, expected
,
586 title1
="actual SHOW ISIS INTERFACE DETAIL",
587 title2
="expected SHOW ISIS OSPF6 INTERFACE DETAIL")
589 # Empty string if it matches, otherwise diff contains unified diff
591 sys
.stderr
.write('r%s failed SHOW ISIS INTERFACE DETAIL check:\n%s\n' % (i
, diff
))
596 assert failures
== 0, "SHOW ISIS INTERFACE DETAIL failed for router r%s:\n%s" % (i
, diff
)
598 # Make sure that all daemons are running
599 for i
in range(1, 2):
600 fatal_error
= net
['r%s' % i
].checkRouterRunning()
601 assert fatal_error
== "", fatal_error
603 # For debugging after starting FRR/Quagga daemons, uncomment the next line
607 def test_bgp_summary():
611 # Skip if previous fatal error condition is raised
612 if (fatal_error
!= ""):
613 pytest
.skip(fatal_error
)
615 thisDir
= os
.path
.dirname(os
.path
.realpath(__file__
))
617 print("\n\n** Verifying BGP Summary")
618 print("******************************************\n")
620 for i
in range(1, 2):
621 refTableFile
= '%s/r%s/show_ip_bgp_summary.ref' % (thisDir
, i
)
622 if os
.path
.isfile(refTableFile
):
623 # Read expected result from file
624 expected
= open(refTableFile
).read().rstrip()
625 # Fix newlines (make them all the same)
626 expected
= ('\n'.join(expected
.splitlines()) + '\n').splitlines(1)
628 # Actual output from router
629 actual
= net
['r%s' % i
].cmd('vtysh -c "show ip bgp summary" 2> /dev/null').rstrip()
630 # Mask out "using XXiXX bytes" portion. They are random...
631 actual
= re
.sub(r
"using [0-9]+ bytes", "using XXXX bytes", actual
)
632 # Mask out "using XiXXX KiB" portion. They are random...
633 actual
= re
.sub(r
"using [0-9]+ KiB", "using XXXX KiB", actual
)
635 # Remove extra summaries which exist with newer versions
637 # Remove summary lines (changed recently)
638 actual
= re
.sub(r
'Total number.*', '', actual
)
639 actual
= re
.sub(r
'Displayed.*', '', actual
)
640 # Remove IPv4 Unicast Summary (Title only)
641 actual
= re
.sub(r
'IPv4 Unicast Summary:', '', actual
)
642 # Remove IPv4 Multicast Summary (all of it)
643 actual
= re
.sub(r
'IPv4 Multicast Summary:', '', actual
)
644 actual
= re
.sub(r
'No IPv4 Multicast neighbor is configured', '', actual
)
645 # Remove IPv4 VPN Summary (all of it)
646 actual
= re
.sub(r
'IPv4 VPN Summary:', '', actual
)
647 actual
= re
.sub(r
'No IPv4 VPN neighbor is configured', '', actual
)
648 # Remove IPv4 Encap Summary (all of it)
649 actual
= re
.sub(r
'IPv4 Encap Summary:', '', actual
)
650 actual
= re
.sub(r
'No IPv4 Encap neighbor is configured', '', actual
)
651 # Remove Unknown Summary (all of it)
652 actual
= re
.sub(r
'Unknown Summary:', '', actual
)
653 actual
= re
.sub(r
'No Unknown neighbor is configured', '', actual
)
655 actual
= re
.sub(r
'IPv4 labeled-unicast Summary:', '', actual
)
656 actual
= re
.sub(r
'No IPv4 labeled-unicast neighbor is configured', '', actual
)
659 actual
= actual
.lstrip()
660 actual
= actual
.rstrip()
662 # Fix newlines (make them all the same)
663 actual
= ('\n'.join(actual
.splitlines()) + '\n').splitlines(1)
666 diff
= topotest
.get_textdiff(actual
, expected
,
667 title1
="actual SHOW IP BGP SUMMARY",
668 title2
="expected SHOW IP BGP SUMMARY")
670 # Empty string if it matches, otherwise diff contains unified diff
672 sys
.stderr
.write('r%s failed SHOW IP BGP SUMMARY check:\n%s\n' % (i
, diff
))
677 assert failures
== 0, "SHOW IP BGP SUMMARY failed for router r%s:\n%s" % (i
, diff
)
679 # Make sure that all daemons are running
680 for i
in range(1, 2):
681 fatal_error
= net
['r%s' % i
].checkRouterRunning()
682 assert fatal_error
== "", fatal_error
684 # For debugging after starting FRR/Quagga daemons, uncomment the next line
688 def test_bgp_ipv6_summary():
692 # Skip if previous fatal error condition is raised
693 if (fatal_error
!= ""):
694 pytest
.skip(fatal_error
)
696 thisDir
= os
.path
.dirname(os
.path
.realpath(__file__
))
698 print("\n\n** Verifying BGP IPv6 Summary")
699 print("******************************************\n")
701 for i
in range(1, 2):
702 refTableFile
= '%s/r%s/show_bgp_ipv6_summary.ref' % (thisDir
, i
)
703 if os
.path
.isfile(refTableFile
):
704 # Read expected result from file
705 expected
= open(refTableFile
).read().rstrip()
706 # Fix newlines (make them all the same)
707 expected
= ('\n'.join(expected
.splitlines()) + '\n').splitlines(1)
709 # Actual output from router
710 actual
= net
['r%s' % i
].cmd('vtysh -c "show bgp ipv6 summary" 2> /dev/null').rstrip()
711 # Mask out "using XXiXX bytes" portion. They are random...
712 actual
= re
.sub(r
"using [0-9]+ bytes", "using XXXX bytes", actual
)
713 # Mask out "using XiXXX KiB" portion. They are random...
714 actual
= re
.sub(r
"using [0-9]+ KiB", "using XXXX KiB", actual
)
716 # Remove extra summaries which exist with newer versions
718 # Remove summary lines (changed recently)
719 actual
= re
.sub(r
'Total number.*', '', actual
)
720 actual
= re
.sub(r
'Displayed.*', '', actual
)
721 # Remove IPv4 Unicast Summary (Title only)
722 actual
= re
.sub(r
'IPv6 Unicast Summary:', '', actual
)
723 # Remove IPv4 Multicast Summary (all of it)
724 actual
= re
.sub(r
'IPv6 Multicast Summary:', '', actual
)
725 actual
= re
.sub(r
'No IPv6 Multicast neighbor is configured', '', actual
)
726 # Remove IPv4 VPN Summary (all of it)
727 actual
= re
.sub(r
'IPv6 VPN Summary:', '', actual
)
728 actual
= re
.sub(r
'No IPv6 VPN neighbor is configured', '', actual
)
729 # Remove IPv4 Encap Summary (all of it)
730 actual
= re
.sub(r
'IPv6 Encap Summary:', '', actual
)
731 actual
= re
.sub(r
'No IPv6 Encap neighbor is configured', '', actual
)
732 # Remove Unknown Summary (all of it)
733 actual
= re
.sub(r
'Unknown Summary:', '', actual
)
734 actual
= re
.sub(r
'No Unknown neighbor is configured', '', actual
)
736 # Remove Labeled Unicast Summary (all of it)
737 actual
= re
.sub(r
'IPv6 labeled-unicast Summary:', '', actual
)
738 actual
= re
.sub(r
'No IPv6 labeled-unicast neighbor is configured', '', actual
)
741 actual
= actual
.lstrip()
742 actual
= actual
.rstrip()
744 # Fix newlines (make them all the same)
745 actual
= ('\n'.join(actual
.splitlines()) + '\n').splitlines(1)
748 diff
= topotest
.get_textdiff(actual
, expected
,
749 title1
="actual SHOW BGP IPv6 SUMMARY",
750 title2
="expected SHOW BGP IPv6 SUMMARY")
752 # Empty string if it matches, otherwise diff contains unified diff
754 sys
.stderr
.write('r%s failed SHOW BGP IPv6 SUMMARY check:\n%s\n' % (i
, diff
))
759 assert failures
== 0, "SHOW BGP IPv6 SUMMARY failed for router r%s:\n%s" % (i
, diff
)
761 # Make sure that all daemons are running
762 for i
in range(1, 2):
763 fatal_error
= net
['r%s' % i
].checkRouterRunning()
764 assert fatal_error
== "", fatal_error
766 # For debugging after starting FRR/Quagga daemons, uncomment the next line
774 # Skip if previous fatal error condition is raised
775 if (fatal_error
!= ""):
776 pytest
.skip(fatal_error
)
778 thisDir
= os
.path
.dirname(os
.path
.realpath(__file__
))
780 print("\n\n** Verifying BGP IPv4")
781 print("******************************************\n")
783 for i
in range(1, 2):
785 for refTableFile
in (glob
.glob(
786 '%s/r%s/show_bgp_ipv4*.ref' % (thisDir
, i
))):
787 if os
.path
.isfile(refTableFile
):
788 # Read expected result from file
789 expected
= open(refTableFile
).read().rstrip()
790 # Fix newlines (make them all the same)
791 expected
= ('\n'.join(expected
.splitlines()) + '\n').splitlines(1)
793 # Actual output from router
794 actual
= net
['r%s' % i
].cmd('vtysh -c "show bgp ipv4" 2> /dev/null').rstrip()
795 # Remove summary line (changed recently)
796 actual
= re
.sub(r
'Total number.*', '', actual
)
797 actual
= re
.sub(r
'Displayed.*', '', actual
)
798 actual
= actual
.rstrip()
799 # Fix newlines (make them all the same)
800 actual
= ('\n'.join(actual
.splitlines()) + '\n').splitlines(1)
803 diff
= topotest
.get_textdiff(actual
, expected
,
804 title1
="actual SHOW BGP IPv4",
805 title2
="expected SHOW BGP IPv4")
807 # Empty string if it matches, otherwise diff contains unified diff
809 diffresult
[refTableFile
] = diff
812 print("template %s matched: r%s ok" % (refTableFile
, i
))
816 resultstr
= 'No template matched.\n'
817 for f
in diffresult
.iterkeys():
819 'template %s: r%s failed SHOW BGP IPv4 check:\n%s\n'
820 % (f
, i
, diffresult
[f
]))
821 raise AssertionError(
822 "SHOW BGP IPv4 failed for router r%s:\n%s" % (i
, resultstr
))
824 # Make sure that all daemons are running
825 for i
in range(1, 2):
826 fatal_error
= net
['r%s' % i
].checkRouterRunning()
827 assert fatal_error
== "", fatal_error
829 # For debugging after starting FRR/Quagga daemons, uncomment the next line
837 # Skip if previous fatal error condition is raised
838 if (fatal_error
!= ""):
839 pytest
.skip(fatal_error
)
841 thisDir
= os
.path
.dirname(os
.path
.realpath(__file__
))
843 print("\n\n** Verifying BGP IPv6")
844 print("******************************************\n")
846 for i
in range(1, 2):
848 for refTableFile
in (glob
.glob(
849 '%s/r%s/show_bgp_ipv6*.ref' % (thisDir
, i
))):
850 if os
.path
.isfile(refTableFile
):
851 # Read expected result from file
852 expected
= open(refTableFile
).read().rstrip()
853 # Fix newlines (make them all the same)
854 expected
= ('\n'.join(expected
.splitlines()) + '\n').splitlines(1)
856 # Actual output from router
857 actual
= net
['r%s' % i
].cmd('vtysh -c "show bgp ipv6" 2> /dev/null').rstrip()
858 # Remove summary line (changed recently)
859 actual
= re
.sub(r
'Total number.*', '', actual
)
860 actual
= re
.sub(r
'Displayed.*', '', actual
)
861 actual
= actual
.rstrip()
862 # Fix newlines (make them all the same)
863 actual
= ('\n'.join(actual
.splitlines()) + '\n').splitlines(1)
866 diff
= topotest
.get_textdiff(actual
, expected
,
867 title1
="actual SHOW BGP IPv6",
868 title2
="expected SHOW BGP IPv6")
870 # Empty string if it matches, otherwise diff contains unified diff
872 diffresult
[refTableFile
] = diff
875 print("template %s matched: r%s ok" % (refTableFile
, i
))
878 resultstr
= 'No template matched.\n'
879 for f
in diffresult
.iterkeys():
881 'template %s: r%s failed SHOW BGP IPv6 check:\n%s\n'
882 % (f
, i
, diffresult
[f
]))
883 raise AssertionError(
884 "SHOW BGP IPv6 failed for router r%s:\n%s" % (i
, resultstr
))
886 # Make sure that all daemons are running
887 for i
in range(1, 2):
888 fatal_error
= net
['r%s' % i
].checkRouterRunning()
889 assert fatal_error
== "", fatal_error
891 # For debugging after starting FRR/Quagga daemons, uncomment the next line
896 def test_mpls_interfaces():
900 # Skip if previous fatal error condition is raised
901 if (fatal_error
!= ""):
902 pytest
.skip(fatal_error
)
904 # Skip if no LDP installed or old kernel
905 if (net
['r1'].daemon_available('ldpd') == False):
906 pytest
.skip("No MPLS or kernel < 4.5")
908 thisDir
= os
.path
.dirname(os
.path
.realpath(__file__
))
910 print("\n\n** Verifying MPLS Interfaces")
911 print("******************************************\n")
913 for i
in range(1, 2):
914 refTableFile
= '%s/r%s/show_mpls_ldp_interface.ref' % (thisDir
, i
)
915 if os
.path
.isfile(refTableFile
):
916 # Read expected result from file
917 expected
= open(refTableFile
).read().rstrip()
918 # Fix newlines (make them all the same)
919 expected
= ('\n'.join(expected
.splitlines()) + '\n').splitlines(1)
921 # Actual output from router
922 actual
= net
['r%s' % i
].cmd('vtysh -c "show mpls ldp interface" 2> /dev/null').rstrip()
923 # Mask out Timer in Uptime
924 actual
= re
.sub(r
" [0-9][0-9]:[0-9][0-9]:[0-9][0-9] ", " xx:xx:xx ", actual
)
925 # Fix newlines (make them all the same)
926 actual
= ('\n'.join(actual
.splitlines()) + '\n').splitlines(1)
929 diff
= topotest
.get_textdiff(actual
, expected
,
930 title1
="actual MPLS LDP interface status",
931 title2
="expected MPLS LDP interface status")
933 # Empty string if it matches, otherwise diff contains unified diff
935 sys
.stderr
.write('r%s failed MPLS LDP Interface status Check:\n%s\n' % (i
, diff
))
941 fatal_error
= "MPLS LDP Interface status failed"
943 assert failures
== 0, "MPLS LDP Interface status failed for router r%s:\n%s" % (i
, diff
)
945 # Make sure that all daemons are running
946 for i
in range(1, 2):
947 fatal_error
= net
['r%s' % i
].checkRouterRunning()
948 assert fatal_error
== "", fatal_error
950 # For debugging after starting FRR/Quagga daemons, uncomment the next line
954 def test_shutdown_check_stderr():
958 # Skip if previous fatal error condition is raised
959 if (fatal_error
!= ""):
960 pytest
.skip(fatal_error
)
962 print("\n\n** Verifying unexpected STDERR output from daemons")
963 print("******************************************\n")
965 if os
.environ
.get('TOPOTESTS_CHECK_STDERR') is None:
966 print("SKIPPED final check on StdErr output: Disabled (TOPOTESTS_CHECK_STDERR undefined)\n")
967 pytest
.skip('Skipping test for Stderr output')
969 thisDir
= os
.path
.dirname(os
.path
.realpath(__file__
))
971 print("thisDir=" + thisDir
)
973 net
['r1'].stopRouter()
975 log
= net
['r1'].getStdErr('ripd')
977 print("\nRIPd StdErr Log:\n" + log
)
978 log
= net
['r1'].getStdErr('ripngd')
980 print("\nRIPngd StdErr Log:\n" + log
)
981 log
= net
['r1'].getStdErr('ospfd')
983 print("\nOSPFd StdErr Log:\n" + log
)
984 log
= net
['r1'].getStdErr('ospf6d')
986 print("\nOSPF6d StdErr Log:\n" + log
)
987 log
= net
['r1'].getStdErr('isisd')
989 print("\nISISd StdErr Log:\n" + log
)
990 log
= net
['r1'].getStdErr('bgpd')
992 print("\nBGPd StdErr Log:\n" + log
)
993 if (net
['r1'].daemon_available('ldpd')):
994 log
= net
['r1'].getStdErr('ldpd')
996 print("\nLDPd StdErr Log:\n" + log
)
997 log
= net
['r1'].getStdErr('zebra')
999 print("\nZebra StdErr Log:\n" + log
)
1002 def test_shutdown_check_memleak():
1006 # Skip if previous fatal error condition is raised
1007 if (fatal_error
!= ""):
1008 pytest
.skip(fatal_error
)
1010 if os
.environ
.get('TOPOTESTS_CHECK_MEMLEAK') is None:
1011 print("SKIPPED final check on Memory leaks: Disabled (TOPOTESTS_CHECK_MEMLEAK undefined)\n")
1012 pytest
.skip('Skipping test for memory leaks')
1014 thisDir
= os
.path
.dirname(os
.path
.realpath(__file__
))
1016 for i
in range(1, 2):
1017 net
['r%s' % i
].stopRouter()
1018 net
['r%s' % i
].report_memory_leaks(os
.environ
.get('TOPOTESTS_CHECK_MEMLEAK'), os
.path
.basename(__file__
))
1021 if __name__
== '__main__':
1024 # To suppress tracebacks, either use the following pytest call or add "--tb=no" to cli
1025 # retval = pytest.main(["-s", "--tb=no"])
1026 retval
= pytest
.main(["-s"])