]>
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
].loadConf('nhrpd', '%s/r%s/nhrpd.conf' % (thisDir
, i
))
125 net
['r%s' % i
].loadConf('babeld', '%s/r%s/babeld.conf' % (thisDir
, i
))
126 net
['r%s' % i
].loadConf('pbrd', '%s/r%s/pbrd.conf' % (thisDir
, i
))
127 net
['r%s' % i
].startRouter()
129 # For debugging after starting Quagga/FRR daemons, uncomment the next line
133 def teardown_module(module
):
136 print("\n\n** %s: Shutdown Topology" % module
.__name
__)
137 print("******************************************\n")
139 # End - Shutdown network
143 def test_router_running():
147 # Skip if previous fatal error condition is raised
148 if (fatal_error
!= ""):
149 pytest
.skip(fatal_error
)
151 print("\n\n** Check if FRR/Quagga is running on each Router node")
152 print("******************************************\n")
156 for i
in range(1, 2):
157 fatal_error
= net
['r%s' % i
].checkRouterRunning()
158 assert fatal_error
== "", fatal_error
160 # For debugging after starting FRR/Quagga daemons, uncomment the next line
164 def test_error_messages_vtysh():
168 # Skip if previous fatal error condition is raised
169 if (fatal_error
!= ""):
170 pytest
.skip(fatal_error
)
172 print("\n\n** Check for error messages on VTYSH")
173 print("******************************************\n")
176 for i
in range(1, 2):
178 # First checking Standard Output
181 # VTYSH output from router
182 vtystdout
= net
['r%s' % i
].cmd('vtysh -c "show version" 2> /dev/null').rstrip()
184 # Fix newlines (make them all the same)
185 vtystdout
= ('\n'.join(vtystdout
.splitlines()) + '\n').rstrip()
186 # Drop everything starting with "FRRouting X.xx" message
187 vtystdout
= re
.sub(r
"FRRouting [0-9]+.*", "", vtystdout
, flags
=re
.DOTALL
)
189 if (vtystdout
== ''):
190 print("r%s StdOut ok" % i
)
192 assert vtystdout
== '', "Vtysh StdOut Output check failed for router r%s" % i
195 # Second checking Standard Error
198 # VTYSH StdErr output from router
199 vtystderr
= net
['r%s' % i
].cmd('vtysh -c "show version" > /dev/null').rstrip()
201 # Fix newlines (make them all the same)
202 vtystderr
= ('\n'.join(vtystderr
.splitlines()) + '\n').rstrip()
203 # # Drop everything starting with "FRRouting X.xx" message
204 # vtystderr = re.sub(r"FRRouting [0-9]+.*", "", vtystderr, flags=re.DOTALL)
206 if (vtystderr
== ''):
207 print("r%s StdErr ok" % i
)
209 assert vtystderr
== '', "Vtysh StdErr Output check failed for router r%s" % i
211 # Make sure that all daemons are running
212 for i
in range(1, 2):
213 fatal_error
= net
['r%s' % i
].checkRouterRunning()
214 assert fatal_error
== "", fatal_error
216 # For debugging after starting FRR/Quagga daemons, uncomment the next line
220 def test_error_messages_daemons():
224 # Skip if previous fatal error condition is raised
225 if (fatal_error
!= ""):
226 pytest
.skip(fatal_error
)
228 print("\n\n** Check for error messages in daemons")
229 print("******************************************\n")
233 for i
in range(1, 2):
234 log
= net
['r%s' % i
].getStdErr('ripd')
236 error_logs
+= "r%s RIPd StdErr Output:\n" % i
238 log
= net
['r%s' % i
].getStdErr('ripngd')
240 error_logs
+= "r%s RIPngd StdErr Output:\n" % i
242 log
= net
['r%s' % i
].getStdErr('ospfd')
244 error_logs
+= "r%s OSPFd StdErr Output:\n" % i
246 log
= net
['r%s' % i
].getStdErr('ospf6d')
248 error_logs
+= "r%s OSPF6d StdErr Output:\n" % i
250 log
= net
['r%s' % i
].getStdErr('isisd')
251 # ISIS shows debugging enabled status on StdErr
252 # Remove these messages
253 log
= re
.sub(r
"^IS-IS .* debugging is on.*", "", log
).rstrip()
255 error_logs
+= "r%s ISISd StdErr Output:\n" % i
257 log
= net
['r%s' % i
].getStdErr('bgpd')
259 error_logs
+= "r%s BGPd StdErr Output:\n" % i
261 if (net
['r%s' % i
].daemon_available('ldpd')):
262 log
= net
['r%s' % i
].getStdErr('ldpd')
264 error_logs
+= "r%s LDPd StdErr Output:\n" % i
267 log
= net
['r1'].getStdErr('nhrpd')
269 error_logs
+= "r%s NHRPd StdErr Output:\n" % i
272 log
= net
['r1'].getStdErr('babeld')
274 error_logs
+= "r%s BABELd StdErr Output:\n" % i
277 log
= net
['r1'].getStdErr('pbrd')
279 error_logs
+= "r%s PBRd StdErr Output:\n" % i
282 log
= net
['r%s' % i
].getStdErr('zebra')
284 error_logs
+= "r%s Zebra StdErr Output:\n"
288 sys
.stderr
.write('Failed check for StdErr Output on daemons:\n%s\n' % error_logs
)
290 # Ignoring the issue if told to ignore (ie not yet fixed)
291 if (error_logs
!= ""):
292 if (os
.environ
.get('bamboo_TOPOTESTS_ISSUE_349') == "IGNORE"):
293 sys
.stderr
.write('Known issue - IGNORING. See https://github.com/FRRouting/frr/issues/349\n')
294 pytest
.skip('Known issue - IGNORING. See https://github.com/FRRouting/frr/issues/349')
296 assert error_logs
== "", "Daemons report errors to StdErr"
298 # For debugging after starting FRR/Quagga daemons, uncomment the next line
302 def test_converge_protocols():
306 # Skip if previous fatal error condition is raised
307 if (fatal_error
!= ""):
308 pytest
.skip(fatal_error
)
310 thisDir
= os
.path
.dirname(os
.path
.realpath(__file__
))
312 print("\n\n** Waiting for protocols convergence")
313 print("******************************************\n")
315 # Not really implemented yet - just sleep 60 secs for now
318 # Make sure that all daemons are running
320 for i
in range(1, 2):
321 fatal_error
= net
['r%s' % i
].checkRouterRunning()
322 assert fatal_error
== "", fatal_error
324 print("Show that v4 routes are right\n");
325 v4_routesFile
= '%s/r%s/ipv4_routes.ref' % (thisDir
, i
)
326 expected
= open(v4_routesFile
).read().rstrip()
327 expected
= ('\n'.join(expected
.splitlines()) + '\n').splitlines(1)
329 actual
= net
['r%s' %i].cmd('vtysh -c "show ip route" | /usr/bin/tail -n +7 | env LC_ALL=en_US.UTF-8 sort 2> /dev/null').rstrip()
330 # Drop time in last update
331 actual
= re
.sub(r
" [0-2][0-9]:[0-5][0-9]:[0-5][0-9]", " XX:XX:XX", actual
)
332 actual
= ('\n'.join(actual
.splitlines()) + '\n').splitlines(1)
333 diff
= topotest
.get_textdiff(actual
, expected
,
334 title1
="Actual IP Routing Table",
335 title2
="Expected IP RoutingTable")
337 sys
.stderr
.write('r%s failed IP Routing table check:\n%s\n' % (i
, diff
))
342 assert failures
== 0, "IP Routing table failed for r%s\n%s" % (i
, diff
)
346 print("Show that v6 routes are right\n")
347 v6_routesFile
= '%s/r%s/ipv6_routes.ref' % (thisDir
, i
)
348 expected
= open(v6_routesFile
).read().rstrip()
349 expected
= ('\n'.join(expected
.splitlines()) + '\n').splitlines(1)
351 actual
= net
['r%s' %i].cmd('vtysh -c "show ipv6 route" | /usr/bin/tail -n +7 | env LC_ALL=en_US.UTF-8 sort 2> /dev/null').rstrip()
352 # Drop time in last update
353 actual
= re
.sub(r
" [0-2][0-9]:[0-5][0-9]:[0-5][0-9]", " XX:XX:XX", actual
)
354 actual
= ('\n'.join(actual
.splitlines()) + '\n').splitlines(1)
355 diff
= topotest
.get_textdiff(actual
, expected
,
356 title1
="Actual IPv6 Routing Table",
357 title2
="Expected IPv6 RoutingTable")
359 sys
.stderr
.write('r%s failed IPv6 Routing table check:\n%s\n' % (i
, diff
))
364 assert failures
== 0, "IPv6 Routing table failed for r%s\n%s" % (i
, diff
)
366 # For debugging after starting FRR/Quagga daemons, uncomment the next line
369 def route_get_nhg_id(route_str
):
370 output
= net
["r1"].cmd('vtysh -c "show ip route %s nexthop-group"' % route_str
)
371 match
= re
.search(r
"Nexthop Group ID: (\d+)", output
)
372 assert match
is not None, "Nexthop Group ID not found for sharpd route %s" % route_str
374 nhg_id
= int(match
.group(1))
377 def verify_nexthop_group(nhg_id
, recursive
=False):
378 # Verify NHG is valid/installed
379 output
= net
["r1"].cmd('vtysh -c "show nexthop-group rib %d"' % nhg_id
)
381 match
= re
.search(r
"Valid", output
)
382 assert match
is not None, "Nexthop Group ID=%d not marked Valid" % nhg_id
384 # If recursive, we need to look at its resolved group
386 match
= re
.search(r
"Depends: \((\d+)\)", output
)
387 resolved_id
= int(match
.group(1))
388 verify_nexthop_group(resolved_id
, False)
390 match
= re
.search(r
"Installed", output
)
391 assert match
is not None, "Nexthop Group ID=%d not marked Installed" % nhg_id
393 def verify_route_nexthop_group(route_str
, recursive
=False):
394 # Verify route and that zebra created NHGs for and they are valid/installed
395 nhg_id
= route_get_nhg_id(route_str
)
396 verify_nexthop_group(nhg_id
, recursive
)
398 def test_nexthop_groups():
402 # Skip if previous fatal error condition is raised
403 if (fatal_error
!= ""):
404 pytest
.skip(fatal_error
)
406 print("\n\n** Verifying Nexthop Groups")
407 print("******************************************\n")
409 ### Nexthop Group Tests
413 # Create a lib nexthop-group
414 net
["r1"].cmd('vtysh -c "c t" -c "nexthop-group basic" -c "nexthop 1.1.1.1" -c "nexthop 1.1.1.2"')
416 # Create with sharpd using nexthop-group
417 net
["r1"].cmd('vtysh -c "sharp install routes 2.2.2.1 nexthop-group basic 1"')
419 verify_route_nexthop_group("2.2.2.1/32")
423 net
["r1"].cmd('vtysh -c "c t" -c "nexthop-group connected" -c "nexthop r1-eth1" -c "nexthop r1-eth2"')
425 net
["r1"].cmd('vtysh -c "sharp install routes 2.2.2.2 nexthop-group connected 1"')
427 verify_route_nexthop_group("2.2.2.2/32")
431 net
["r1"].cmd('vtysh -c "c t" -c "nexthop-group basic-recursive" -c "nexthop 2.2.2.1"')
433 net
["r1"].cmd('vtysh -c "sharp install routes 3.3.3.1 nexthop-group basic-recursive 1"')
435 verify_route_nexthop_group("3.3.3.1/32", True)
439 net
["r1"].cmd('vtysh -c "c t" -c "nexthop-group duplicate" -c "nexthop 2.2.2.1" -c "nexthop 1.1.1.1"')
441 net
["r1"].cmd('vtysh -c "sharp install routes 3.3.3.2 nexthop-group duplicate 1"')
443 verify_route_nexthop_group("3.3.3.2/32")
447 net
["r1"].cmd('vtysh -c "c t" -c "nexthop-group fourA" -c "nexthop 1.1.1.1" -c "nexthop 1.1.1.2" \
448 -c "nexthop 1.1.1.3" -c "nexthop 1.1.1.4"')
450 net
["r1"].cmd('vtysh -c "sharp install routes 4.4.4.1 nexthop-group fourA 1"')
452 verify_route_nexthop_group("4.4.4.1/32")
454 net
["r1"].cmd('vtysh -c "c t" -c "nexthop-group fourB" -c "nexthop 1.1.1.5" -c "nexthop 1.1.1.6" \
455 -c "nexthop 1.1.1.7" -c "nexthop 1.1.1.8"')
457 net
["r1"].cmd('vtysh -c "sharp install routes 4.4.4.2 nexthop-group fourB 1"')
459 verify_route_nexthop_group("4.4.4.2/32")
461 ## Recursive to 8-Way ECMP
463 net
["r1"].cmd('vtysh -c "c t" -c "nexthop-group eight-recursive" -c "nexthop 4.4.4.1" -c "nexthop 4.4.4.2"')
465 net
["r1"].cmd('vtysh -c "sharp install routes 5.5.5.1 nexthop-group eight-recursive 1"')
467 verify_route_nexthop_group("5.5.5.1/32")
471 ## Remove all NHG routes
473 net
["r1"].cmd('vtysh -c "sharp remove routes 2.2.2.1 1"')
474 net
["r1"].cmd('vtysh -c "sharp remove routes 2.2.2.2 1"')
475 net
["r1"].cmd('vtysh -c "sharp remove routes 3.3.3.1 1"')
476 net
["r1"].cmd('vtysh -c "sharp remove routes 3.3.3.2 1"')
477 net
["r1"].cmd('vtysh -c "sharp remove routes 4.4.4.1 1"')
478 net
["r1"].cmd('vtysh -c "sharp remove routes 4.4.4.2 1"')
479 net
["r1"].cmd('vtysh -c "sharp remove routes 5.5.5.1 1"')
481 def test_rip_status():
485 # Skip if previous fatal error condition is raised
486 if (fatal_error
!= ""):
487 pytest
.skip(fatal_error
)
489 thisDir
= os
.path
.dirname(os
.path
.realpath(__file__
))
491 print("\n\n** Verifying RIP status")
492 print("******************************************\n")
494 for i
in range(1, 2):
495 refTableFile
= '%s/r%s/rip_status.ref' % (thisDir
, i
)
496 if os
.path
.isfile(refTableFile
):
497 # Read expected result from file
498 expected
= open(refTableFile
).read().rstrip()
499 # Fix newlines (make them all the same)
500 expected
= ('\n'.join(expected
.splitlines()) + '\n').splitlines(1)
502 # Actual output from router
503 actual
= net
['r%s' % i
].cmd('vtysh -c "show ip rip status" 2> /dev/null').rstrip()
504 # Drop time in next due
505 actual
= re
.sub(r
"in [0-9]+ seconds", "in XX seconds", actual
)
506 # Drop time in last update
507 actual
= re
.sub(r
" [0-2][0-9]:[0-5][0-9]:[0-5][0-9]", " XX:XX:XX", actual
)
508 # Fix newlines (make them all the same)
509 actual
= ('\n'.join(actual
.splitlines()) + '\n').splitlines(1)
512 diff
= topotest
.get_textdiff(actual
, expected
,
513 title1
="actual IP RIP status",
514 title2
="expected IP RIP status")
516 # Empty string if it matches, otherwise diff contains unified diff
518 sys
.stderr
.write('r%s failed IP RIP status check:\n%s\n' % (i
, diff
))
523 assert failures
== 0, "IP RIP status failed for router r%s:\n%s" % (i
, diff
)
525 # Make sure that all daemons are running
526 for i
in range(1, 2):
527 fatal_error
= net
['r%s' % i
].checkRouterRunning()
528 assert fatal_error
== "", fatal_error
530 # For debugging after starting FRR/Quagga daemons, uncomment the next line
534 def test_ripng_status():
538 # Skip if previous fatal error condition is raised
539 if (fatal_error
!= ""):
540 pytest
.skip(fatal_error
)
542 thisDir
= os
.path
.dirname(os
.path
.realpath(__file__
))
544 print("\n\n** Verifying RIPng status")
545 print("******************************************\n")
547 for i
in range(1, 2):
548 refTableFile
= '%s/r%s/ripng_status.ref' % (thisDir
, i
)
549 if os
.path
.isfile(refTableFile
):
550 # Read expected result from file
551 expected
= open(refTableFile
).read().rstrip()
552 # Fix newlines (make them all the same)
553 expected
= ('\n'.join(expected
.splitlines()) + '\n').splitlines(1)
555 # Actual output from router
556 actual
= net
['r%s' % i
].cmd('vtysh -c "show ipv6 ripng status" 2> /dev/null').rstrip()
557 # Mask out Link-Local mac address portion. They are random...
558 actual
= re
.sub(r
" fe80::[0-9a-f:]+", " fe80::XXXX:XXXX:XXXX:XXXX", actual
)
559 # Drop time in next due
560 actual
= re
.sub(r
"in [0-9]+ seconds", "in XX seconds", actual
)
561 # Drop time in last update
562 actual
= re
.sub(r
" [0-2][0-9]:[0-5][0-9]:[0-5][0-9]", " XX:XX:XX", actual
)
563 # Fix newlines (make them all the same)
564 actual
= ('\n'.join(actual
.splitlines()) + '\n').splitlines(1)
567 diff
= topotest
.get_textdiff(actual
, expected
,
568 title1
="actual IPv6 RIPng status",
569 title2
="expected IPv6 RIPng status")
571 # Empty string if it matches, otherwise diff contains unified diff
573 sys
.stderr
.write('r%s failed IPv6 RIPng status check:\n%s\n' % (i
, diff
))
578 assert failures
== 0, "IPv6 RIPng status failed for router r%s:\n%s" % (i
, diff
)
580 # Make sure that all daemons are running
581 for i
in range(1, 2):
582 fatal_error
= net
['r%s' % i
].checkRouterRunning()
583 assert fatal_error
== "", fatal_error
585 # For debugging after starting FRR/Quagga daemons, uncomment the next line
589 def test_ospfv2_interfaces():
593 # Skip if previous fatal error condition is raised
594 if (fatal_error
!= ""):
595 pytest
.skip(fatal_error
)
597 thisDir
= os
.path
.dirname(os
.path
.realpath(__file__
))
599 print("\n\n** Verifying OSPFv2 interfaces")
600 print("******************************************\n")
602 for i
in range(1, 2):
603 refTableFile
= '%s/r%s/show_ip_ospf_interface.ref' % (thisDir
, i
)
604 if os
.path
.isfile(refTableFile
):
605 # Read expected result from file
606 expected
= open(refTableFile
).read().rstrip()
607 # Fix newlines (make them all the same)
608 expected
= ('\n'.join(expected
.splitlines()) + '\n').splitlines(1)
610 # Actual output from router
611 actual
= net
['r%s' % i
].cmd('vtysh -c "show ip ospf interface" 2> /dev/null').rstrip()
612 # Mask out Bandwidth portion. They may change..
613 actual
= re
.sub(r
"BW [0-9]+ Mbit", "BW XX Mbit", actual
)
614 actual
= re
.sub(r
"ifindex [0-9]", "ifindex X", actual
)
616 # Drop time in next due
617 actual
= re
.sub(r
"Hello due in [0-9\.]+s", "Hello due in XX.XXXs", actual
)
618 actual
= re
.sub(r
"Hello due in [0-9\.]+ usecs", "Hello due in XX.XXXs", actual
)
619 # Fix 'MTU mismatch detection: enabled' vs 'MTU mismatch detection:enabled' - accept both
620 actual
= re
.sub(r
"MTU mismatch detection:([a-z]+.*)", r
"MTU mismatch detection: \1", actual
)
621 # Fix newlines (make them all the same)
622 actual
= ('\n'.join(actual
.splitlines()) + '\n').splitlines(1)
625 diff
= topotest
.get_textdiff(actual
, expected
,
626 title1
="actual SHOW IP OSPF INTERFACE",
627 title2
="expected SHOW IP OSPF INTERFACE")
629 # Empty string if it matches, otherwise diff contains unified diff
631 sys
.stderr
.write('r%s failed SHOW IP OSPF INTERFACE check:\n%s\n' % (i
, diff
))
636 # Ignoring the issue if told to ignore (ie not yet fixed)
638 if (os
.environ
.get('bamboo_TOPOTESTS_ISSUE_348') == "IGNORE"):
639 sys
.stderr
.write('Known issue - IGNORING. See https://github.com/FRRouting/frr/issues/348\n')
640 pytest
.skip('Known issue - IGNORING. See https://github.com/FRRouting/frr/issues/348')
642 assert failures
== 0, "SHOW IP OSPF INTERFACE failed for router r%s:\n%s" % (i
, diff
)
644 # Make sure that all daemons are running
645 for i
in range(1, 2):
646 fatal_error
= net
['r%s' % i
].checkRouterRunning()
647 assert fatal_error
== "", fatal_error
649 # For debugging after starting FRR/Quagga daemons, uncomment the next line
653 def test_isis_interfaces():
657 # Skip if previous fatal error condition is raised
658 if (fatal_error
!= ""):
659 pytest
.skip(fatal_error
)
661 thisDir
= os
.path
.dirname(os
.path
.realpath(__file__
))
663 print("\n\n** Verifying ISIS interfaces")
664 print("******************************************\n")
666 for i
in range(1, 2):
667 refTableFile
= '%s/r%s/show_isis_interface_detail.ref' % (thisDir
, i
)
668 if os
.path
.isfile(refTableFile
):
669 # Read expected result from file
670 expected
= open(refTableFile
).read().rstrip()
671 # Fix newlines (make them all the same)
672 expected
= ('\n'.join(expected
.splitlines()) + '\n').splitlines(1)
674 # Actual output from router
675 actual
= net
['r%s' % i
].cmd('vtysh -c "show isis interface detail" 2> /dev/null').rstrip()
676 # Mask out Link-Local mac address portion. They are random...
677 actual
= re
.sub(r
"fe80::[0-9a-f:]+", "fe80::XXXX:XXXX:XXXX:XXXX", actual
)
678 # Mask out SNPA mac address portion. They are random...
679 actual
= re
.sub(r
"SNPA: [0-9a-f\.]+", "SNPA: XXXX.XXXX.XXXX", actual
)
680 # Mask out Circuit ID number
681 actual
= re
.sub(r
"Circuit Id: 0x[0-9]+", "Circuit Id: 0xXX", actual
)
682 # Fix newlines (make them all the same)
683 actual
= ('\n'.join(actual
.splitlines()) + '\n').splitlines(1)
686 diff
= topotest
.get_textdiff(actual
, expected
,
687 title1
="actual SHOW ISIS INTERFACE DETAIL",
688 title2
="expected SHOW ISIS OSPF6 INTERFACE DETAIL")
690 # Empty string if it matches, otherwise diff contains unified diff
692 sys
.stderr
.write('r%s failed SHOW ISIS INTERFACE DETAIL check:\n%s\n' % (i
, diff
))
697 assert failures
== 0, "SHOW ISIS INTERFACE DETAIL failed for router r%s:\n%s" % (i
, diff
)
699 # Make sure that all daemons are running
700 for i
in range(1, 2):
701 fatal_error
= net
['r%s' % i
].checkRouterRunning()
702 assert fatal_error
== "", fatal_error
704 # For debugging after starting FRR/Quagga daemons, uncomment the next line
708 def test_bgp_summary():
712 # Skip if previous fatal error condition is raised
713 if (fatal_error
!= ""):
714 pytest
.skip(fatal_error
)
716 thisDir
= os
.path
.dirname(os
.path
.realpath(__file__
))
718 print("\n\n** Verifying BGP Summary")
719 print("******************************************\n")
721 for i
in range(1, 2):
722 refTableFile
= '%s/r%s/show_ip_bgp_summary.ref' % (thisDir
, i
)
723 if os
.path
.isfile(refTableFile
):
724 # Read expected result from file
725 expected
= open(refTableFile
).read().rstrip()
726 # Fix newlines (make them all the same)
727 expected
= ('\n'.join(expected
.splitlines()) + '\n').splitlines(1)
729 # Actual output from router
730 actual
= net
['r%s' % i
].cmd('vtysh -c "show ip bgp summary" 2> /dev/null').rstrip()
731 # Mask out "using XXiXX bytes" portion. They are random...
732 actual
= re
.sub(r
"using [0-9]+ bytes", "using XXXX bytes", actual
)
733 # Mask out "using XiXXX KiB" portion. They are random...
734 actual
= re
.sub(r
"using [0-9]+ KiB", "using XXXX KiB", actual
)
736 # Remove extra summaries which exist with newer versions
738 # Remove summary lines (changed recently)
739 actual
= re
.sub(r
'Total number.*', '', actual
)
740 actual
= re
.sub(r
'Displayed.*', '', actual
)
741 # Remove IPv4 Unicast Summary (Title only)
742 actual
= re
.sub(r
'IPv4 Unicast Summary:', '', actual
)
743 # Remove IPv4 Multicast Summary (all of it)
744 actual
= re
.sub(r
'IPv4 Multicast Summary:', '', actual
)
745 actual
= re
.sub(r
'No IPv4 Multicast neighbor is configured', '', actual
)
746 # Remove IPv4 VPN Summary (all of it)
747 actual
= re
.sub(r
'IPv4 VPN Summary:', '', actual
)
748 actual
= re
.sub(r
'No IPv4 VPN neighbor is configured', '', actual
)
749 # Remove IPv4 Encap Summary (all of it)
750 actual
= re
.sub(r
'IPv4 Encap Summary:', '', actual
)
751 actual
= re
.sub(r
'No IPv4 Encap neighbor is configured', '', actual
)
752 # Remove Unknown Summary (all of it)
753 actual
= re
.sub(r
'Unknown Summary:', '', actual
)
754 actual
= re
.sub(r
'No Unknown neighbor is configured', '', actual
)
756 actual
= re
.sub(r
'IPv4 labeled-unicast Summary:', '', actual
)
757 actual
= re
.sub(r
'No IPv4 labeled-unicast neighbor is configured', '', actual
)
760 actual
= actual
.lstrip()
761 actual
= actual
.rstrip()
763 # Fix newlines (make them all the same)
764 actual
= ('\n'.join(actual
.splitlines()) + '\n').splitlines(1)
767 diff
= topotest
.get_textdiff(actual
, expected
,
768 title1
="actual SHOW IP BGP SUMMARY",
769 title2
="expected SHOW IP BGP SUMMARY")
771 # Empty string if it matches, otherwise diff contains unified diff
773 sys
.stderr
.write('r%s failed SHOW IP BGP SUMMARY check:\n%s\n' % (i
, diff
))
778 assert failures
== 0, "SHOW IP BGP SUMMARY failed for router r%s:\n%s" % (i
, diff
)
780 # Make sure that all daemons are running
781 for i
in range(1, 2):
782 fatal_error
= net
['r%s' % i
].checkRouterRunning()
783 assert fatal_error
== "", fatal_error
785 # For debugging after starting FRR/Quagga daemons, uncomment the next line
789 def test_bgp_ipv6_summary():
793 # Skip if previous fatal error condition is raised
794 if (fatal_error
!= ""):
795 pytest
.skip(fatal_error
)
797 thisDir
= os
.path
.dirname(os
.path
.realpath(__file__
))
799 print("\n\n** Verifying BGP IPv6 Summary")
800 print("******************************************\n")
802 for i
in range(1, 2):
803 refTableFile
= '%s/r%s/show_bgp_ipv6_summary.ref' % (thisDir
, i
)
804 if os
.path
.isfile(refTableFile
):
805 # Read expected result from file
806 expected
= open(refTableFile
).read().rstrip()
807 # Fix newlines (make them all the same)
808 expected
= ('\n'.join(expected
.splitlines()) + '\n').splitlines(1)
810 # Actual output from router
811 actual
= net
['r%s' % i
].cmd('vtysh -c "show bgp ipv6 summary" 2> /dev/null').rstrip()
812 # Mask out "using XXiXX bytes" portion. They are random...
813 actual
= re
.sub(r
"using [0-9]+ bytes", "using XXXX bytes", actual
)
814 # Mask out "using XiXXX KiB" portion. They are random...
815 actual
= re
.sub(r
"using [0-9]+ KiB", "using XXXX KiB", actual
)
817 # Remove extra summaries which exist with newer versions
819 # Remove summary lines (changed recently)
820 actual
= re
.sub(r
'Total number.*', '', actual
)
821 actual
= re
.sub(r
'Displayed.*', '', actual
)
822 # Remove IPv4 Unicast Summary (Title only)
823 actual
= re
.sub(r
'IPv6 Unicast Summary:', '', actual
)
824 # Remove IPv4 Multicast Summary (all of it)
825 actual
= re
.sub(r
'IPv6 Multicast Summary:', '', actual
)
826 actual
= re
.sub(r
'No IPv6 Multicast neighbor is configured', '', actual
)
827 # Remove IPv4 VPN Summary (all of it)
828 actual
= re
.sub(r
'IPv6 VPN Summary:', '', actual
)
829 actual
= re
.sub(r
'No IPv6 VPN neighbor is configured', '', actual
)
830 # Remove IPv4 Encap Summary (all of it)
831 actual
= re
.sub(r
'IPv6 Encap Summary:', '', actual
)
832 actual
= re
.sub(r
'No IPv6 Encap neighbor is configured', '', actual
)
833 # Remove Unknown Summary (all of it)
834 actual
= re
.sub(r
'Unknown Summary:', '', actual
)
835 actual
= re
.sub(r
'No Unknown neighbor is configured', '', actual
)
837 # Remove Labeled Unicast Summary (all of it)
838 actual
= re
.sub(r
'IPv6 labeled-unicast Summary:', '', actual
)
839 actual
= re
.sub(r
'No IPv6 labeled-unicast neighbor is configured', '', actual
)
842 actual
= actual
.lstrip()
843 actual
= actual
.rstrip()
845 # Fix newlines (make them all the same)
846 actual
= ('\n'.join(actual
.splitlines()) + '\n').splitlines(1)
849 diff
= topotest
.get_textdiff(actual
, expected
,
850 title1
="actual SHOW BGP IPv6 SUMMARY",
851 title2
="expected SHOW BGP IPv6 SUMMARY")
853 # Empty string if it matches, otherwise diff contains unified diff
855 sys
.stderr
.write('r%s failed SHOW BGP IPv6 SUMMARY check:\n%s\n' % (i
, diff
))
860 assert failures
== 0, "SHOW BGP IPv6 SUMMARY failed for router r%s:\n%s" % (i
, diff
)
862 # Make sure that all daemons are running
863 for i
in range(1, 2):
864 fatal_error
= net
['r%s' % i
].checkRouterRunning()
865 assert fatal_error
== "", fatal_error
867 # For debugging after starting FRR/Quagga daemons, uncomment the next line
875 # Skip if previous fatal error condition is raised
876 if (fatal_error
!= ""):
877 pytest
.skip(fatal_error
)
879 thisDir
= os
.path
.dirname(os
.path
.realpath(__file__
))
881 print("\n\n** Verifying BGP IPv4")
882 print("******************************************\n")
884 for i
in range(1, 2):
886 for refTableFile
in (glob
.glob(
887 '%s/r%s/show_bgp_ipv4*.ref' % (thisDir
, i
))):
888 if os
.path
.isfile(refTableFile
):
889 # Read expected result from file
890 expected
= open(refTableFile
).read().rstrip()
891 # Fix newlines (make them all the same)
892 expected
= ('\n'.join(expected
.splitlines()) + '\n').splitlines(1)
894 # Actual output from router
895 actual
= net
['r%s' % i
].cmd('vtysh -c "show bgp ipv4" 2> /dev/null').rstrip()
896 # Remove summary line (changed recently)
897 actual
= re
.sub(r
'Total number.*', '', actual
)
898 actual
= re
.sub(r
'Displayed.*', '', actual
)
899 actual
= actual
.rstrip()
900 # Fix newlines (make them all the same)
901 actual
= ('\n'.join(actual
.splitlines()) + '\n').splitlines(1)
904 diff
= topotest
.get_textdiff(actual
, expected
,
905 title1
="actual SHOW BGP IPv4",
906 title2
="expected SHOW BGP IPv4")
908 # Empty string if it matches, otherwise diff contains unified diff
910 diffresult
[refTableFile
] = diff
913 print("template %s matched: r%s ok" % (refTableFile
, i
))
917 resultstr
= 'No template matched.\n'
918 for f
in diffresult
.iterkeys():
920 'template %s: r%s failed SHOW BGP IPv4 check:\n%s\n'
921 % (f
, i
, diffresult
[f
]))
922 raise AssertionError(
923 "SHOW BGP IPv4 failed for router r%s:\n%s" % (i
, resultstr
))
925 # Make sure that all daemons are running
926 for i
in range(1, 2):
927 fatal_error
= net
['r%s' % i
].checkRouterRunning()
928 assert fatal_error
== "", fatal_error
930 # For debugging after starting FRR/Quagga daemons, uncomment the next line
938 # Skip if previous fatal error condition is raised
939 if (fatal_error
!= ""):
940 pytest
.skip(fatal_error
)
942 thisDir
= os
.path
.dirname(os
.path
.realpath(__file__
))
944 print("\n\n** Verifying BGP IPv6")
945 print("******************************************\n")
947 for i
in range(1, 2):
949 for refTableFile
in (glob
.glob(
950 '%s/r%s/show_bgp_ipv6*.ref' % (thisDir
, i
))):
951 if os
.path
.isfile(refTableFile
):
952 # Read expected result from file
953 expected
= open(refTableFile
).read().rstrip()
954 # Fix newlines (make them all the same)
955 expected
= ('\n'.join(expected
.splitlines()) + '\n').splitlines(1)
957 # Actual output from router
958 actual
= net
['r%s' % i
].cmd('vtysh -c "show bgp ipv6" 2> /dev/null').rstrip()
959 # Remove summary line (changed recently)
960 actual
= re
.sub(r
'Total number.*', '', actual
)
961 actual
= re
.sub(r
'Displayed.*', '', actual
)
962 actual
= actual
.rstrip()
963 # Fix newlines (make them all the same)
964 actual
= ('\n'.join(actual
.splitlines()) + '\n').splitlines(1)
967 diff
= topotest
.get_textdiff(actual
, expected
,
968 title1
="actual SHOW BGP IPv6",
969 title2
="expected SHOW BGP IPv6")
971 # Empty string if it matches, otherwise diff contains unified diff
973 diffresult
[refTableFile
] = diff
976 print("template %s matched: r%s ok" % (refTableFile
, i
))
979 resultstr
= 'No template matched.\n'
980 for f
in diffresult
.iterkeys():
982 'template %s: r%s failed SHOW BGP IPv6 check:\n%s\n'
983 % (f
, i
, diffresult
[f
]))
984 raise AssertionError(
985 "SHOW BGP IPv6 failed for router r%s:\n%s" % (i
, resultstr
))
987 # Make sure that all daemons are running
988 for i
in range(1, 2):
989 fatal_error
= net
['r%s' % i
].checkRouterRunning()
990 assert fatal_error
== "", fatal_error
992 # For debugging after starting FRR/Quagga daemons, uncomment the next line
995 def test_route_map():
999 if (fatal_error
!= ""):
1000 pytest
.skip(fatal_error
)
1002 thisDir
= os
.path
.dirname(os
.path
.realpath(__file__
))
1004 print("\n\n** Verifying some basic routemap forward references\n")
1005 print("*******************************************************\n")
1007 for i
in range(1, 2):
1008 refroutemap
= '%s/r%s/show_route_map.ref' % (thisDir
, i
)
1009 if os
.path
.isfile(refroutemap
):
1010 expected
= open(refroutemap
).read().rstrip()
1011 expected
= ('\n'.join(expected
.splitlines()) + '\n').splitlines(1)
1013 actual
= net
['r%s' %i].cmd('vtysh -c "show route-map" 2> /dev/null').rstrip()
1014 actual
= ('\n'.join(actual
.splitlines()) + '\n').splitlines(1)
1016 diff
= topotest
.get_textdiff(actual
, expected
,
1017 title1
="actual show route-map",
1018 title2
="expected show route-map")
1021 sys
.stderr
.write('r%s failed show route-map command Check:\n%s\n' % (i
, diff
))
1026 assert failures
== 0, "Show route-map command failed for router r%s:\n%s" % (i
, diff
)
1028 def test_nexthop_groups_with_route_maps():
1032 # Skip if previous fatal error condition is raised
1033 if (fatal_error
!= ""):
1034 pytest
.skip(fatal_error
)
1036 print("\n\n** Verifying Nexthop Groups With Route-Maps")
1037 print("******************************************\n")
1039 ### Nexthop Group With Route-Map Tests
1041 # Create a lib nexthop-group
1042 net
["r1"].cmd('vtysh -c "c t" -c "nexthop-group test" -c "nexthop 1.1.1.1" -c "nexthop 1.1.1.2"')
1044 ## Route-Map Proto Source
1046 route_str
= "2.2.2.1"
1047 src_str
= "192.168.0.1"
1049 net
["r1"].cmd('vtysh -c "c t" -c "route-map NH-SRC permit 111" -c "set src %s"' % src_str
)
1050 net
["r1"].cmd('vtysh -c "c t" -c "ip protocol sharp route-map NH-SRC"')
1052 net
["r1"].cmd('vtysh -c "sharp install routes %s nexthop-group test 1"' % route_str
)
1054 verify_route_nexthop_group("%s/32" % route_str
)
1056 # Only a valid test on linux using nexthop objects
1057 if sys
.platform
.startswith("linux"):
1058 output
= net
["r1"].cmd('ip route show %s/32' % route_str
)
1059 match
= re
.search(r
"src %s" % src_str
, output
)
1060 assert match
is not None, "Route %s/32 not installed with src %s" % (route_str
, src_str
)
1062 # Remove NHG routes and route-map
1063 net
["r1"].cmd('vtysh -c "sharp remove routes %s 1"' % route_str
)
1064 net
["r1"].cmd('vtysh -c "c t" -c "no ip protocol sharp route-map NH-SRC"')
1065 net
["r1"].cmd('vtysh -c "c t" -c "no route-map NH-SRC permit 111" -c "set src %s"' % src_str
)
1066 net
["r1"].cmd('vtysh -c "c t" -c "no route-map NH-SRC"')
1068 ## Route-Map Deny/Permit with same nexthop group
1070 permit_route_str
= "3.3.3.1"
1071 deny_route_str
= "3.3.3.2"
1073 net
["r1"].cmd('vtysh -c "c t" -c "ip prefix-list NOPE seq 5 permit %s/32"' % permit_route_str
)
1074 net
["r1"].cmd('vtysh -c "c t" -c "route-map NOPE permit 111" -c "match ip address prefix-list NOPE"')
1075 net
["r1"].cmd('vtysh -c "c t" -c "route-map NOPE deny 222"')
1076 net
["r1"].cmd('vtysh -c "c t" -c "ip protocol sharp route-map NOPE"')
1078 # This route should be permitted
1079 net
["r1"].cmd('vtysh -c "sharp install routes %s nexthop-group test 1"' % permit_route_str
)
1081 verify_route_nexthop_group("%s/32" % permit_route_str
)
1083 # This route should be denied
1084 net
["r1"].cmd('vtysh -c "sharp install routes %s nexthop-group test 1"' % deny_route_str
)
1086 nhg_id
= route_get_nhg_id(deny_route_str
)
1087 output
= net
["r1"].cmd('vtysh -c "show nexthop-group rib %d"' % nhg_id
)
1089 match
= re
.search(r
"Valid", output
)
1090 assert match
is None, "Nexthop Group ID=%d should not be marked Valid" % nhg_id
1092 match
= re
.search(r
"Installed", output
)
1093 assert match
is None, "Nexthop Group ID=%d should not be marked Installed" % nhg_id
1095 # Remove NHG routes and route-map
1096 net
["r1"].cmd('vtysh -c "sharp remove routes %s 1"' % permit_route_str
)
1097 net
["r1"].cmd('vtysh -c "sharp remove routes %s 1"' % deny_route_str
)
1098 net
["r1"].cmd('vtysh -c "c t" -c "no ip protocol sharp route-map NOPE"')
1099 net
["r1"].cmd('vtysh -c "c t" -c "no route-map NOPE permit 111"')
1100 net
["r1"].cmd('vtysh -c "c t" -c "no route-map NOPE deny 222"')
1101 net
["r1"].cmd('vtysh -c "c t" -c "no route-map NOPE"')
1102 net
["r1"].cmd('vtysh -c "c t" -c "no ip prefix-list NOPE seq 5 permit %s/32"' % permit_route_str
)
1104 def test_mpls_interfaces():
1108 # Skip if previous fatal error condition is raised
1109 if (fatal_error
!= ""):
1110 pytest
.skip(fatal_error
)
1112 # Skip if no LDP installed or old kernel
1113 if (net
['r1'].daemon_available('ldpd') == False):
1114 pytest
.skip("No MPLS or kernel < 4.5")
1116 thisDir
= os
.path
.dirname(os
.path
.realpath(__file__
))
1118 print("\n\n** Verifying MPLS Interfaces")
1119 print("******************************************\n")
1121 for i
in range(1, 2):
1122 refTableFile
= '%s/r%s/show_mpls_ldp_interface.ref' % (thisDir
, i
)
1123 if os
.path
.isfile(refTableFile
):
1124 # Read expected result from file
1125 expected
= open(refTableFile
).read().rstrip()
1126 # Fix newlines (make them all the same)
1127 expected
= ('\n'.join(expected
.splitlines()) + '\n').splitlines(1)
1129 # Actual output from router
1130 actual
= net
['r%s' % i
].cmd('vtysh -c "show mpls ldp interface" 2> /dev/null').rstrip()
1131 # Mask out Timer in Uptime
1132 actual
= re
.sub(r
" [0-9][0-9]:[0-9][0-9]:[0-9][0-9] ", " xx:xx:xx ", actual
)
1133 # Fix newlines (make them all the same)
1134 actual
= ('\n'.join(actual
.splitlines()) + '\n').splitlines(1)
1137 diff
= topotest
.get_textdiff(actual
, expected
,
1138 title1
="actual MPLS LDP interface status",
1139 title2
="expected MPLS LDP interface status")
1141 # Empty string if it matches, otherwise diff contains unified diff
1143 sys
.stderr
.write('r%s failed MPLS LDP Interface status Check:\n%s\n' % (i
, diff
))
1149 fatal_error
= "MPLS LDP Interface status failed"
1151 assert failures
== 0, "MPLS LDP Interface status failed for router r%s:\n%s" % (i
, diff
)
1153 # Make sure that all daemons are running
1154 for i
in range(1, 2):
1155 fatal_error
= net
['r%s' % i
].checkRouterRunning()
1156 assert fatal_error
== "", fatal_error
1158 # For debugging after starting FRR/Quagga daemons, uncomment the next line
1162 def test_shutdown_check_stderr():
1166 # Skip if previous fatal error condition is raised
1167 if (fatal_error
!= ""):
1168 pytest
.skip(fatal_error
)
1170 print("\n\n** Verifying unexpected STDERR output from daemons")
1171 print("******************************************\n")
1173 if os
.environ
.get('TOPOTESTS_CHECK_STDERR') is None:
1174 print("SKIPPED final check on StdErr output: Disabled (TOPOTESTS_CHECK_STDERR undefined)\n")
1175 pytest
.skip('Skipping test for Stderr output')
1177 thisDir
= os
.path
.dirname(os
.path
.realpath(__file__
))
1179 print("thisDir=" + thisDir
)
1181 net
['r1'].stopRouter()
1183 log
= net
['r1'].getStdErr('ripd')
1185 print("\nRIPd StdErr Log:\n" + log
)
1186 log
= net
['r1'].getStdErr('ripngd')
1188 print("\nRIPngd StdErr Log:\n" + log
)
1189 log
= net
['r1'].getStdErr('ospfd')
1191 print("\nOSPFd StdErr Log:\n" + log
)
1192 log
= net
['r1'].getStdErr('ospf6d')
1194 print("\nOSPF6d StdErr Log:\n" + log
)
1195 log
= net
['r1'].getStdErr('isisd')
1197 print("\nISISd StdErr Log:\n" + log
)
1198 log
= net
['r1'].getStdErr('bgpd')
1200 print("\nBGPd StdErr Log:\n" + log
)
1202 log
= net
['r1'].getStdErr('nhrpd')
1204 print("\nNHRPd StdErr Log:\n" + log
)
1206 log
= net
['r1'].getStdErr('pbrd')
1208 print("\nPBRd StdErr Log:\n" + log
)
1210 log
= net
['r1'].getStdErr('babeld')
1212 print("\nBABELd StdErr Log:\n" + log
)
1214 if (net
['r1'].daemon_available('ldpd')):
1215 log
= net
['r1'].getStdErr('ldpd')
1217 print("\nLDPd StdErr Log:\n" + log
)
1218 log
= net
['r1'].getStdErr('zebra')
1220 print("\nZebra StdErr Log:\n" + log
)
1223 def test_shutdown_check_memleak():
1227 # Skip if previous fatal error condition is raised
1228 if (fatal_error
!= ""):
1229 pytest
.skip(fatal_error
)
1231 if os
.environ
.get('TOPOTESTS_CHECK_MEMLEAK') is None:
1232 print("SKIPPED final check on Memory leaks: Disabled (TOPOTESTS_CHECK_MEMLEAK undefined)\n")
1233 pytest
.skip('Skipping test for memory leaks')
1235 thisDir
= os
.path
.dirname(os
.path
.realpath(__file__
))
1237 for i
in range(1, 2):
1238 net
['r%s' % i
].stopRouter()
1239 net
['r%s' % i
].report_memory_leaks(os
.environ
.get('TOPOTESTS_CHECK_MEMLEAK'), os
.path
.basename(__file__
))
1242 if __name__
== '__main__':
1245 # To suppress tracebacks, either use the following pytest call or add "--tb=no" to cli
1246 # retval = pytest.main(["-s", "--tb=no"])
1247 retval
= pytest
.main(["-s"])