]> git.proxmox.com Git - mirror_frr.git/blame - tests/topotests/all_protocol_startup/test_all_protocol_startup.py
Merge pull request #9582 from LabNConsulting/chopps/fix-xterm-windows
[mirror_frr.git] / tests / topotests / all_protocol_startup / test_all_protocol_startup.py
CommitLineData
4501fbca
MW
1#!/usr/bin/env python
2
3#
4# test_all_protocol_startup.py
5# Part of NetDEF Topology Tests
6#
7# Copyright (c) 2017 by
8# Network Device Education Foundation, Inc. ("NetDEF")
9#
10# Permission to use, copy, modify, and/or distribute this software
11# for any purpose with or without fee is hereby granted, provided
12# that the above copyright notice and this permission notice appear
13# in all copies.
14#
15# THE SOFTWARE IS PROVIDED "AS IS" AND NETDEF DISCLAIMS ALL WARRANTIES
16# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
17# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF BE LIABLE FOR
18# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
19# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
20# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
21# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
22# OF THIS SOFTWARE.
23#
24
25"""
26test_all_protocol_startup.py: Test of all protocols at same time
27
28"""
29
30import os
31import re
32import sys
4501fbca 33import pytest
6a57e103 34import glob
4501fbca
MW
35from time import sleep
36
4501fbca 37
2c647bcd
DS
38pytestmark = [
39 pytest.mark.babeld,
40 pytest.mark.bgpd,
41 pytest.mark.isisd,
42 pytest.mark.nhrpd,
43 pytest.mark.ospfd,
44 pytest.mark.pbrd,
45 pytest.mark.ripd,
46]
6907ac7e 47
4501fbca
MW
48sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
49from lib import topotest
e82b531d 50from lib.topogen import Topogen, get_topogen
4501fbca
MW
51
52fatal_error = ""
53
54
55#####################################################
56##
57## Network Topology Definition
58##
59#####################################################
60
701a0192 61
e82b531d
CH
62def build_topo(tgen):
63 router = tgen.add_router("r1")
64 for i in range(0, 10):
65 tgen.add_switch("sw%d" % i).add_link(router)
4501fbca
MW
66
67
68#####################################################
69##
70## Tests starting
71##
72#####################################################
73
13f93db3 74
4501fbca 75def setup_module(module):
4501fbca
MW
76 global fatal_error
77
78 print("\n\n** %s: Setup Topology" % module.__name__)
79 print("******************************************\n")
80
4501fbca 81 thisDir = os.path.dirname(os.path.realpath(__file__))
e82b531d
CH
82 tgen = Topogen(build_topo, module.__name__)
83 tgen.start_topology()
4501fbca 84
e82b531d 85 net = tgen.net
4501fbca 86
701a0192 87 if net["r1"].get_routertype() != "frr":
4501fbca 88 fatal_error = "Test is only implemented for FRR"
701a0192 89 sys.stderr.write("\n\nTest is only implemented for FRR - Skipping\n\n")
4501fbca 90 pytest.skip(fatal_error)
701a0192 91
4501fbca
MW
92 # Starting Routers
93 #
94 # Main router
95 for i in range(1, 2):
701a0192 96 net["r%s" % i].loadConf("zebra", "%s/r%s/zebra.conf" % (thisDir, i))
97 net["r%s" % i].loadConf("ripd", "%s/r%s/ripd.conf" % (thisDir, i))
98 net["r%s" % i].loadConf("ripngd", "%s/r%s/ripngd.conf" % (thisDir, i))
99 net["r%s" % i].loadConf("ospfd", "%s/r%s/ospfd.conf" % (thisDir, i))
100 if net["r1"].checkRouterVersion("<", "4.0"):
101 net["r%s" % i].loadConf(
102 "ospf6d", "%s/r%s/ospf6d.conf-pre-v4" % (thisDir, i)
103 )
11761ab0 104 else:
701a0192 105 net["r%s" % i].loadConf("ospf6d", "%s/r%s/ospf6d.conf" % (thisDir, i))
106 net["r%s" % i].loadConf("isisd", "%s/r%s/isisd.conf" % (thisDir, i))
107 net["r%s" % i].loadConf("bgpd", "%s/r%s/bgpd.conf" % (thisDir, i))
108 if net["r%s" % i].daemon_available("ldpd"):
4501fbca 109 # Only test LDPd if it's installed and Kernel >= 4.5
701a0192 110 net["r%s" % i].loadConf("ldpd", "%s/r%s/ldpd.conf" % (thisDir, i))
111 net["r%s" % i].loadConf("sharpd")
112 net["r%s" % i].loadConf("nhrpd", "%s/r%s/nhrpd.conf" % (thisDir, i))
113 net["r%s" % i].loadConf("babeld", "%s/r%s/babeld.conf" % (thisDir, i))
114 net["r%s" % i].loadConf("pbrd", "%s/r%s/pbrd.conf" % (thisDir, i))
e82b531d 115 tgen.gears["r%s" % i].start()
4501fbca 116
622c4996 117 # For debugging after starting FRR daemons, uncomment the next line
4501fbca
MW
118 # CLI(net)
119
120
121def teardown_module(module):
4501fbca
MW
122 print("\n\n** %s: Shutdown Topology" % module.__name__)
123 print("******************************************\n")
e82b531d
CH
124 tgen = get_topogen()
125 tgen.stop_topology()
4501fbca
MW
126
127
128def test_router_running():
129 global fatal_error
e82b531d 130 net = get_topogen().net
4501fbca
MW
131
132 # Skip if previous fatal error condition is raised
701a0192 133 if fatal_error != "":
4501fbca
MW
134 pytest.skip(fatal_error)
135
622c4996 136 print("\n\n** Check if FRR is running on each Router node")
4501fbca
MW
137 print("******************************************\n")
138 sleep(5)
139
140 # Starting Routers
141 for i in range(1, 2):
701a0192 142 fatal_error = net["r%s" % i].checkRouterRunning()
4501fbca
MW
143 assert fatal_error == "", fatal_error
144
622c4996 145 # For debugging after starting FRR daemons, uncomment the next line
4501fbca
MW
146 # CLI(net)
147
148
149def test_error_messages_vtysh():
150 global fatal_error
e82b531d 151 net = get_topogen().net
4501fbca
MW
152
153 # Skip if previous fatal error condition is raised
701a0192 154 if fatal_error != "":
4501fbca
MW
155 pytest.skip(fatal_error)
156
157 print("\n\n** Check for error messages on VTYSH")
158 print("******************************************\n")
159
160 failures = 0
161 for i in range(1, 2):
162 #
163 # First checking Standard Output
164 #
165
166 # VTYSH output from router
701a0192 167 vtystdout = net["r%s" % i].cmd('vtysh -c "show version" 2> /dev/null').rstrip()
4501fbca
MW
168
169 # Fix newlines (make them all the same)
701a0192 170 vtystdout = ("\n".join(vtystdout.splitlines()) + "\n").rstrip()
4501fbca
MW
171 # Drop everything starting with "FRRouting X.xx" message
172 vtystdout = re.sub(r"FRRouting [0-9]+.*", "", vtystdout, flags=re.DOTALL)
173
701a0192 174 if vtystdout == "":
4501fbca
MW
175 print("r%s StdOut ok" % i)
176
701a0192 177 assert vtystdout == "", "Vtysh StdOut Output check failed for router r%s" % i
798fb593 178
4501fbca
MW
179 #
180 # Second checking Standard Error
181 #
182
183 # VTYSH StdErr output from router
701a0192 184 vtystderr = net["r%s" % i].cmd('vtysh -c "show version" > /dev/null').rstrip()
4501fbca
MW
185
186 # Fix newlines (make them all the same)
701a0192 187 vtystderr = ("\n".join(vtystderr.splitlines()) + "\n").rstrip()
4501fbca 188 # # Drop everything starting with "FRRouting X.xx" message
701a0192 189 # vtystderr = re.sub(r"FRRouting [0-9]+.*", "", vtystderr, flags=re.DOTALL)
4501fbca 190
701a0192 191 if vtystderr == "":
4501fbca
MW
192 print("r%s StdErr ok" % i)
193
701a0192 194 assert vtystderr == "", "Vtysh StdErr Output check failed for router r%s" % i
4501fbca 195
7e7fc73b
MW
196 # Make sure that all daemons are running
197 for i in range(1, 2):
701a0192 198 fatal_error = net["r%s" % i].checkRouterRunning()
7e7fc73b
MW
199 assert fatal_error == "", fatal_error
200
622c4996 201 # For debugging after starting FRR daemons, uncomment the next line
4501fbca
MW
202 # CLI(net)
203
204
205def test_error_messages_daemons():
206 global fatal_error
e82b531d 207 net = get_topogen().net
4501fbca
MW
208
209 # Skip if previous fatal error condition is raised
701a0192 210 if fatal_error != "":
4501fbca
MW
211 pytest.skip(fatal_error)
212
213 print("\n\n** Check for error messages in daemons")
214 print("******************************************\n")
215
216 error_logs = ""
217
218 for i in range(1, 2):
701a0192 219 log = net["r%s" % i].getStdErr("ripd")
4501fbca
MW
220 if log:
221 error_logs += "r%s RIPd StdErr Output:\n" % i
222 error_logs += log
701a0192 223 log = net["r%s" % i].getStdErr("ripngd")
4501fbca
MW
224 if log:
225 error_logs += "r%s RIPngd StdErr Output:\n" % i
226 error_logs += log
701a0192 227 log = net["r%s" % i].getStdErr("ospfd")
4501fbca
MW
228 if log:
229 error_logs += "r%s OSPFd StdErr Output:\n" % i
230 error_logs += log
701a0192 231 log = net["r%s" % i].getStdErr("ospf6d")
4501fbca
MW
232 if log:
233 error_logs += "r%s OSPF6d StdErr Output:\n" % i
234 error_logs += log
701a0192 235 log = net["r%s" % i].getStdErr("isisd")
4501fbca
MW
236 # ISIS shows debugging enabled status on StdErr
237 # Remove these messages
238 log = re.sub(r"^IS-IS .* debugging is on.*", "", log).rstrip()
239 if log:
240 error_logs += "r%s ISISd StdErr Output:\n" % i
241 error_logs += log
701a0192 242 log = net["r%s" % i].getStdErr("bgpd")
4501fbca
MW
243 if log:
244 error_logs += "r%s BGPd StdErr Output:\n" % i
245 error_logs += log
701a0192 246 if net["r%s" % i].daemon_available("ldpd"):
247 log = net["r%s" % i].getStdErr("ldpd")
4501fbca
MW
248 if log:
249 error_logs += "r%s LDPd StdErr Output:\n" % i
250 error_logs += log
af39fbe7 251
701a0192 252 log = net["r1"].getStdErr("nhrpd")
960c3f25
MW
253 # NHRPD shows YANG model not embedded messages
254 # Ignore these
255 log = re.sub(r".*YANG model.*not embedded.*", "", log).rstrip()
af39fbe7
MS
256 if log:
257 error_logs += "r%s NHRPd StdErr Output:\n" % i
258 error_logs += log
259
701a0192 260 log = net["r1"].getStdErr("babeld")
af39fbe7
MS
261 if log:
262 error_logs += "r%s BABELd StdErr Output:\n" % i
263 error_logs += log
264
701a0192 265 log = net["r1"].getStdErr("pbrd")
af39fbe7
MS
266 if log:
267 error_logs += "r%s PBRd StdErr Output:\n" % i
268 error_logs += log
269
701a0192 270 log = net["r%s" % i].getStdErr("zebra")
4501fbca 271 if log:
960c3f25 272 error_logs += "r%s Zebra StdErr Output:\n" % i
4501fbca
MW
273 error_logs += log
274
275 if error_logs:
701a0192 276 sys.stderr.write(
277 "Failed check for StdErr Output on daemons:\n%s\n" % error_logs
278 )
4501fbca 279
08fa1af7 280 # Ignoring the issue if told to ignore (ie not yet fixed)
701a0192 281 if error_logs != "":
282 if os.environ.get("bamboo_TOPOTESTS_ISSUE_349") == "IGNORE":
283 sys.stderr.write(
284 "Known issue - IGNORING. See https://github.com/FRRouting/frr/issues/349\n"
285 )
286 pytest.skip(
287 "Known issue - IGNORING. See https://github.com/FRRouting/frr/issues/349"
288 )
08fa1af7 289
4501fbca
MW
290 assert error_logs == "", "Daemons report errors to StdErr"
291
622c4996 292 # For debugging after starting FRR daemons, uncomment the next line
4501fbca
MW
293 # CLI(net)
294
295
296def test_converge_protocols():
297 global fatal_error
e82b531d 298 net = get_topogen().net
4501fbca
MW
299
300 # Skip if previous fatal error condition is raised
701a0192 301 if fatal_error != "":
4501fbca
MW
302 pytest.skip(fatal_error)
303
304 thisDir = os.path.dirname(os.path.realpath(__file__))
305
306 print("\n\n** Waiting for protocols convergence")
307 print("******************************************\n")
308
309 # Not really implemented yet - just sleep 60 secs for now
310 sleep(60)
311
7e7fc73b 312 # Make sure that all daemons are running
556f76e1 313 failures = 0
7e7fc73b 314 for i in range(1, 2):
701a0192 315 fatal_error = net["r%s" % i].checkRouterRunning()
7e7fc73b
MW
316 assert fatal_error == "", fatal_error
317
701a0192 318 print("Show that v4 routes are right\n")
319 v4_routesFile = "%s/r%s/ipv4_routes.ref" % (thisDir, i)
0b25370e
DS
320 expected = (
321 net["r%s" % i].cmd("sort {} 2> /dev/null".format(v4_routesFile)).rstrip()
322 )
701a0192 323 expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1)
324
325 actual = (
326 net["r%s" % i]
327 .cmd(
00756aa3 328 "vtysh -c \"show ip route\" | sed -e '/^Codes: /,/^\s*$/d' | sort 2> /dev/null"
701a0192 329 )
330 .rstrip()
331 )
556f76e1
DS
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)
701a0192 334 actual = ("\n".join(actual.splitlines()) + "\n").splitlines(1)
335 diff = topotest.get_textdiff(
336 actual,
337 expected,
338 title1="Actual IP Routing Table",
339 title2="Expected IP RoutingTable",
340 )
556f76e1 341 if diff:
701a0192 342 sys.stderr.write("r%s failed IP Routing table check:\n%s\n" % (i, diff))
556f76e1
DS
343 failures += 1
344 else:
701a0192 345 print("r%s ok" % i)
556f76e1
DS
346
347 assert failures == 0, "IP Routing table failed for r%s\n%s" % (i, diff)
348
349 failures = 0
350
351 print("Show that v6 routes are right\n")
701a0192 352 v6_routesFile = "%s/r%s/ipv6_routes.ref" % (thisDir, i)
0b25370e
DS
353 expected = (
354 net["r%s" % i].cmd("sort {} 2> /dev/null".format(v6_routesFile)).rstrip()
355 )
701a0192 356 expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1)
357
358 actual = (
359 net["r%s" % i]
360 .cmd(
00756aa3 361 "vtysh -c \"show ipv6 route\" | sed -e '/^Codes: /,/^\s*$/d' | sort 2> /dev/null"
701a0192 362 )
363 .rstrip()
364 )
556f76e1
DS
365 # Drop time in last update
366 actual = re.sub(r" [0-2][0-9]:[0-5][0-9]:[0-5][0-9]", " XX:XX:XX", actual)
701a0192 367 actual = ("\n".join(actual.splitlines()) + "\n").splitlines(1)
368 diff = topotest.get_textdiff(
369 actual,
370 expected,
371 title1="Actual IPv6 Routing Table",
372 title2="Expected IPv6 RoutingTable",
373 )
556f76e1 374 if diff:
701a0192 375 sys.stderr.write("r%s failed IPv6 Routing table check:\n%s\n" % (i, diff))
556f76e1
DS
376 failures += 1
377 else:
701a0192 378 print("r%s ok" % i)
556f76e1
DS
379
380 assert failures == 0, "IPv6 Routing table failed for r%s\n%s" % (i, diff)
381
622c4996 382 # For debugging after starting FRR daemons, uncomment the next line
4501fbca
MW
383 ## CLI(net)
384
701a0192 385
887a232c 386def route_get_nhg_id(route_str):
e82b531d 387 net = get_topogen().net
887a232c
SW
388 output = net["r1"].cmd('vtysh -c "show ip route %s nexthop-group"' % route_str)
389 match = re.search(r"Nexthop Group ID: (\d+)", output)
701a0192 390 assert match is not None, (
391 "Nexthop Group ID not found for sharpd route %s" % route_str
392 )
887a232c
SW
393
394 nhg_id = int(match.group(1))
395 return nhg_id
396
701a0192 397
8f4d7212 398def verify_nexthop_group(nhg_id, recursive=False, ecmp=0):
e82b531d 399 net = get_topogen().net
887a232c
SW
400 # Verify NHG is valid/installed
401 output = net["r1"].cmd('vtysh -c "show nexthop-group rib %d"' % nhg_id)
402
403 match = re.search(r"Valid", output)
404 assert match is not None, "Nexthop Group ID=%d not marked Valid" % nhg_id
405
8f4d7212
SW
406 if ecmp or recursive:
407 match = re.search(r"Depends:.*\n", output)
408 assert match is not None, "Nexthop Group ID=%d has no depends" % nhg_id
409
410 # list of IDs in group
411 depends = re.findall(r"\((\d+)\)", match.group(0))
412
413 if ecmp:
701a0192 414 assert len(depends) == ecmp, (
415 "Nexthop Group ID=%d doesn't match ecmp size" % nhg_id
416 )
8f4d7212
SW
417 else:
418 # If recursive, we need to look at its resolved group
701a0192 419 assert len(depends) == 1, (
420 "Nexthop Group ID=%d should only have one recursive depend" % nhg_id
421 )
8f4d7212
SW
422 resolved_id = int(depends[0])
423 verify_nexthop_group(resolved_id, False)
424
887a232c
SW
425 else:
426 match = re.search(r"Installed", output)
427 assert match is not None, "Nexthop Group ID=%d not marked Installed" % nhg_id
428
701a0192 429
8f4d7212 430def verify_route_nexthop_group(route_str, recursive=False, ecmp=0):
887a232c
SW
431 # Verify route and that zebra created NHGs for and they are valid/installed
432 nhg_id = route_get_nhg_id(route_str)
8f4d7212 433 verify_nexthop_group(nhg_id, recursive, ecmp)
887a232c 434
701a0192 435
8058df22
SW
436def test_nexthop_groups():
437 global fatal_error
e82b531d 438 net = get_topogen().net
8058df22
SW
439
440 # Skip if previous fatal error condition is raised
701a0192 441 if fatal_error != "":
8058df22
SW
442 pytest.skip(fatal_error)
443
444 print("\n\n** Verifying Nexthop Groups")
445 print("******************************************\n")
446
887a232c
SW
447 ### Nexthop Group Tests
448
449 ## Basic test
450
8058df22 451 # Create a lib nexthop-group
701a0192 452 net["r1"].cmd(
453 'vtysh -c "c t" -c "nexthop-group basic" -c "nexthop 1.1.1.1" -c "nexthop 1.1.1.2"'
454 )
8058df22
SW
455
456 # Create with sharpd using nexthop-group
887a232c 457 net["r1"].cmd('vtysh -c "sharp install routes 2.2.2.1 nexthop-group basic 1"')
8058df22 458
887a232c 459 verify_route_nexthop_group("2.2.2.1/32")
8058df22 460
887a232c 461 ## Connected
8058df22 462
701a0192 463 net["r1"].cmd(
464 'vtysh -c "c t" -c "nexthop-group connected" -c "nexthop r1-eth1" -c "nexthop r1-eth2"'
465 )
8058df22 466
887a232c
SW
467 net["r1"].cmd('vtysh -c "sharp install routes 2.2.2.2 nexthop-group connected 1"')
468
469 verify_route_nexthop_group("2.2.2.2/32")
470
471 ## Recursive
472
701a0192 473 net["r1"].cmd(
474 'vtysh -c "c t" -c "nexthop-group basic-recursive" -c "nexthop 2.2.2.1"'
475 )
887a232c 476
701a0192 477 net["r1"].cmd(
478 'vtysh -c "sharp install routes 3.3.3.1 nexthop-group basic-recursive 1"'
479 )
887a232c
SW
480
481 verify_route_nexthop_group("3.3.3.1/32", True)
482
483 ## Duplicate
484
701a0192 485 net["r1"].cmd(
486 'vtysh -c "c t" -c "nexthop-group duplicate" -c "nexthop 2.2.2.1" -c "nexthop 1.1.1.1"'
487 )
887a232c
SW
488
489 net["r1"].cmd('vtysh -c "sharp install routes 3.3.3.2 nexthop-group duplicate 1"')
490
491 verify_route_nexthop_group("3.3.3.2/32")
492
493 ## Two 4-Way ECMP
494
701a0192 495 net["r1"].cmd(
496 'vtysh -c "c t" -c "nexthop-group fourA" -c "nexthop 1.1.1.1" -c "nexthop 1.1.1.2" \
497 -c "nexthop 1.1.1.3" -c "nexthop 1.1.1.4"'
498 )
887a232c
SW
499
500 net["r1"].cmd('vtysh -c "sharp install routes 4.4.4.1 nexthop-group fourA 1"')
501
502 verify_route_nexthop_group("4.4.4.1/32")
503
701a0192 504 net["r1"].cmd(
505 'vtysh -c "c t" -c "nexthop-group fourB" -c "nexthop 1.1.1.5" -c "nexthop 1.1.1.6" \
506 -c "nexthop 1.1.1.7" -c "nexthop 1.1.1.8"'
507 )
887a232c
SW
508
509 net["r1"].cmd('vtysh -c "sharp install routes 4.4.4.2 nexthop-group fourB 1"')
510
511 verify_route_nexthop_group("4.4.4.2/32")
512
513 ## Recursive to 8-Way ECMP
514
701a0192 515 net["r1"].cmd(
516 'vtysh -c "c t" -c "nexthop-group eight-recursive" -c "nexthop 4.4.4.1" -c "nexthop 4.4.4.2"'
517 )
887a232c 518
701a0192 519 net["r1"].cmd(
520 'vtysh -c "sharp install routes 5.5.5.1 nexthop-group eight-recursive 1"'
521 )
887a232c
SW
522
523 verify_route_nexthop_group("5.5.5.1/32")
524
13f93db3
SW
525 ## 4-way ECMP Routes Pointing to Each Other
526
527 # This is to check for a bug with NH resolution where
528 # routes would infintely resolve to each other blowing
529 # up the resolved-> nexthop pointer.
530
531 net["r1"].cmd(
532 'vtysh -c "c t" -c "nexthop-group infinite-recursive" -c "nexthop 6.6.6.1" -c "nexthop 6.6.6.2" \
533 -c "nexthop 6.6.6.3" -c "nexthop 6.6.6.4"'
534 )
535
536 # static route nexthops can recurse to
537
538 net["r1"].cmd('vtysh -c "c t" -c "ip route 6.6.6.0/24 1.1.1.1"')
539
540 # Make routes that point to themselves in ecmp
541
542 net["r1"].cmd(
543 'vtysh -c "sharp install routes 6.6.6.4 nexthop-group infinite-recursive 1"'
544 )
545
546 net["r1"].cmd(
547 'vtysh -c "sharp install routes 6.6.6.3 nexthop-group infinite-recursive 1"'
548 )
549
550 net["r1"].cmd(
551 'vtysh -c "sharp install routes 6.6.6.2 nexthop-group infinite-recursive 1"'
552 )
553
554 net["r1"].cmd(
555 'vtysh -c "sharp install routes 6.6.6.1 nexthop-group infinite-recursive 1"'
556 )
557
558 # Get routes and test if has too many (duplicate) nexthops
559 nhg_id = route_get_nhg_id("6.6.6.1/32")
560 output = net["r1"].cmd('vtysh -c "show nexthop-group rib %d"' % nhg_id)
561
562 dups = re.findall(r"(via 1\.1\.1\.1)", output)
563
564 # Should find 3, itself is inactive
565 assert len(dups) == 3, (
566 "Route 6.6.6.1/32 with Nexthop Group ID=%d has wrong number of resolved nexthops"
567 % nhg_id
568 )
569
887a232c
SW
570 ##CLI(net)
571
572 ## Remove all NHG routes
573
574 net["r1"].cmd('vtysh -c "sharp remove routes 2.2.2.1 1"')
575 net["r1"].cmd('vtysh -c "sharp remove routes 2.2.2.2 1"')
576 net["r1"].cmd('vtysh -c "sharp remove routes 3.3.3.1 1"')
577 net["r1"].cmd('vtysh -c "sharp remove routes 3.3.3.2 1"')
578 net["r1"].cmd('vtysh -c "sharp remove routes 4.4.4.1 1"')
579 net["r1"].cmd('vtysh -c "sharp remove routes 4.4.4.2 1"')
580 net["r1"].cmd('vtysh -c "sharp remove routes 5.5.5.1 1"')
13f93db3
SW
581 net["r1"].cmd('vtysh -c "sharp remove routes 6.6.6.1 4"')
582 net["r1"].cmd('vtysh -c "c t" -c "no ip route 6.6.6.0/24 1.1.1.1"')
4501fbca 583
701a0192 584
4501fbca
MW
585def test_rip_status():
586 global fatal_error
e82b531d 587 net = get_topogen().net
4501fbca
MW
588
589 # Skip if previous fatal error condition is raised
701a0192 590 if fatal_error != "":
4501fbca
MW
591 pytest.skip(fatal_error)
592
593 thisDir = os.path.dirname(os.path.realpath(__file__))
594
b2764f90 595 print("\n\n** Verifying RIP status")
4501fbca
MW
596 print("******************************************\n")
597 failures = 0
598 for i in range(1, 2):
701a0192 599 refTableFile = "%s/r%s/rip_status.ref" % (thisDir, i)
4501fbca
MW
600 if os.path.isfile(refTableFile):
601 # Read expected result from file
602 expected = open(refTableFile).read().rstrip()
603 # Fix newlines (make them all the same)
701a0192 604 expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1)
4501fbca
MW
605
606 # Actual output from router
701a0192 607 actual = (
608 net["r%s" % i]
609 .cmd('vtysh -c "show ip rip status" 2> /dev/null')
610 .rstrip()
611 )
612 # Drop time in next due
4501fbca
MW
613 actual = re.sub(r"in [0-9]+ seconds", "in XX seconds", actual)
614 # Drop time in last update
615 actual = re.sub(r" [0-2][0-9]:[0-5][0-9]:[0-5][0-9]", " XX:XX:XX", actual)
616 # Fix newlines (make them all the same)
701a0192 617 actual = ("\n".join(actual.splitlines()) + "\n").splitlines(1)
4501fbca
MW
618
619 # Generate Diff
701a0192 620 diff = topotest.get_textdiff(
621 actual,
622 expected,
17070436 623 title1="actual IP RIP status",
701a0192 624 title2="expected IP RIP status",
625 )
4501fbca
MW
626
627 # Empty string if it matches, otherwise diff contains unified diff
628 if diff:
701a0192 629 sys.stderr.write("r%s failed IP RIP status check:\n%s\n" % (i, diff))
4501fbca
MW
630 failures += 1
631 else:
632 print("r%s ok" % i)
633
634 assert failures == 0, "IP RIP status failed for router r%s:\n%s" % (i, diff)
635
7e7fc73b
MW
636 # Make sure that all daemons are running
637 for i in range(1, 2):
701a0192 638 fatal_error = net["r%s" % i].checkRouterRunning()
7e7fc73b
MW
639 assert fatal_error == "", fatal_error
640
622c4996 641 # For debugging after starting FRR daemons, uncomment the next line
4501fbca
MW
642 # CLI(net)
643
644
645def test_ripng_status():
646 global fatal_error
e82b531d 647 net = get_topogen().net
4501fbca
MW
648
649 # Skip if previous fatal error condition is raised
701a0192 650 if fatal_error != "":
4501fbca
MW
651 pytest.skip(fatal_error)
652
653 thisDir = os.path.dirname(os.path.realpath(__file__))
654
b2764f90 655 print("\n\n** Verifying RIPng status")
4501fbca
MW
656 print("******************************************\n")
657 failures = 0
658 for i in range(1, 2):
701a0192 659 refTableFile = "%s/r%s/ripng_status.ref" % (thisDir, i)
4501fbca
MW
660 if os.path.isfile(refTableFile):
661 # Read expected result from file
662 expected = open(refTableFile).read().rstrip()
663 # Fix newlines (make them all the same)
701a0192 664 expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1)
4501fbca
MW
665
666 # Actual output from router
701a0192 667 actual = (
668 net["r%s" % i]
669 .cmd('vtysh -c "show ipv6 ripng status" 2> /dev/null')
670 .rstrip()
671 )
4501fbca
MW
672 # Mask out Link-Local mac address portion. They are random...
673 actual = re.sub(r" fe80::[0-9a-f:]+", " fe80::XXXX:XXXX:XXXX:XXXX", actual)
701a0192 674 # Drop time in next due
4501fbca
MW
675 actual = re.sub(r"in [0-9]+ seconds", "in XX seconds", actual)
676 # Drop time in last update
677 actual = re.sub(r" [0-2][0-9]:[0-5][0-9]:[0-5][0-9]", " XX:XX:XX", actual)
678 # Fix newlines (make them all the same)
701a0192 679 actual = ("\n".join(actual.splitlines()) + "\n").splitlines(1)
4501fbca
MW
680
681 # Generate Diff
701a0192 682 diff = topotest.get_textdiff(
683 actual,
684 expected,
17070436 685 title1="actual IPv6 RIPng status",
701a0192 686 title2="expected IPv6 RIPng status",
687 )
4501fbca
MW
688
689 # Empty string if it matches, otherwise diff contains unified diff
690 if diff:
701a0192 691 sys.stderr.write(
692 "r%s failed IPv6 RIPng status check:\n%s\n" % (i, diff)
693 )
4501fbca
MW
694 failures += 1
695 else:
696 print("r%s ok" % i)
697
701a0192 698 assert failures == 0, "IPv6 RIPng status failed for router r%s:\n%s" % (
699 i,
700 diff,
701 )
4501fbca 702
7e7fc73b
MW
703 # Make sure that all daemons are running
704 for i in range(1, 2):
701a0192 705 fatal_error = net["r%s" % i].checkRouterRunning()
7e7fc73b
MW
706 assert fatal_error == "", fatal_error
707
622c4996 708 # For debugging after starting FRR daemons, uncomment the next line
4501fbca
MW
709 # CLI(net)
710
711
712def test_ospfv2_interfaces():
713 global fatal_error
e82b531d 714 net = get_topogen().net
4501fbca
MW
715
716 # Skip if previous fatal error condition is raised
701a0192 717 if fatal_error != "":
4501fbca
MW
718 pytest.skip(fatal_error)
719
720 thisDir = os.path.dirname(os.path.realpath(__file__))
721
b2764f90 722 print("\n\n** Verifying OSPFv2 interfaces")
4501fbca
MW
723 print("******************************************\n")
724 failures = 0
725 for i in range(1, 2):
701a0192 726 refTableFile = "%s/r%s/show_ip_ospf_interface.ref" % (thisDir, i)
4501fbca
MW
727 if os.path.isfile(refTableFile):
728 # Read expected result from file
729 expected = open(refTableFile).read().rstrip()
730 # Fix newlines (make them all the same)
701a0192 731 expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1)
4501fbca
MW
732
733 # Actual output from router
701a0192 734 actual = (
735 net["r%s" % i]
736 .cmd('vtysh -c "show ip ospf interface" 2> /dev/null')
737 .rstrip()
738 )
4501fbca
MW
739 # Mask out Bandwidth portion. They may change..
740 actual = re.sub(r"BW [0-9]+ Mbit", "BW XX Mbit", actual)
8db751b8 741 actual = re.sub(r"ifindex [0-9]+", "ifindex X", actual)
c9d72a0b 742
701a0192 743 # Drop time in next due
4501fbca 744 actual = re.sub(r"Hello due in [0-9\.]+s", "Hello due in XX.XXXs", actual)
701a0192 745 actual = re.sub(
746 r"Hello due in [0-9\.]+ usecs", "Hello due in XX.XXXs", actual
747 )
985e6d50 748 # Fix 'MTU mismatch detection: enabled' vs 'MTU mismatch detection:enabled' - accept both
701a0192 749 actual = re.sub(
750 r"MTU mismatch detection:([a-z]+.*)",
751 r"MTU mismatch detection: \1",
752 actual,
753 )
4501fbca 754 # Fix newlines (make them all the same)
701a0192 755 actual = ("\n".join(actual.splitlines()) + "\n").splitlines(1)
4501fbca
MW
756
757 # Generate Diff
701a0192 758 diff = topotest.get_textdiff(
759 actual,
760 expected,
17070436 761 title1="actual SHOW IP OSPF INTERFACE",
701a0192 762 title2="expected SHOW IP OSPF INTERFACE",
763 )
4501fbca
MW
764
765 # Empty string if it matches, otherwise diff contains unified diff
766 if diff:
701a0192 767 sys.stderr.write(
768 "r%s failed SHOW IP OSPF INTERFACE check:\n%s\n" % (i, diff)
769 )
4501fbca
MW
770 failures += 1
771 else:
772 print("r%s ok" % i)
773
08fa1af7 774 # Ignoring the issue if told to ignore (ie not yet fixed)
701a0192 775 if failures != 0:
776 if os.environ.get("bamboo_TOPOTESTS_ISSUE_348") == "IGNORE":
777 sys.stderr.write(
778 "Known issue - IGNORING. See https://github.com/FRRouting/frr/issues/348\n"
779 )
780 pytest.skip(
781 "Known issue - IGNORING. See https://github.com/FRRouting/frr/issues/348"
782 )
783
784 assert (
785 failures == 0
786 ), "SHOW IP OSPF INTERFACE failed for router r%s:\n%s" % (i, diff)
4501fbca 787
7e7fc73b
MW
788 # Make sure that all daemons are running
789 for i in range(1, 2):
701a0192 790 fatal_error = net["r%s" % i].checkRouterRunning()
7e7fc73b
MW
791 assert fatal_error == "", fatal_error
792
622c4996 793 # For debugging after starting FRR daemons, uncomment the next line
4501fbca
MW
794 # CLI(net)
795
796
797def test_isis_interfaces():
798 global fatal_error
e82b531d 799 net = get_topogen().net
4501fbca
MW
800
801 # Skip if previous fatal error condition is raised
701a0192 802 if fatal_error != "":
4501fbca
MW
803 pytest.skip(fatal_error)
804
805 thisDir = os.path.dirname(os.path.realpath(__file__))
806
b2764f90 807 print("\n\n** Verifying ISIS interfaces")
4501fbca
MW
808 print("******************************************\n")
809 failures = 0
810 for i in range(1, 2):
701a0192 811 refTableFile = "%s/r%s/show_isis_interface_detail.ref" % (thisDir, i)
4501fbca
MW
812 if os.path.isfile(refTableFile):
813 # Read expected result from file
814 expected = open(refTableFile).read().rstrip()
815 # Fix newlines (make them all the same)
701a0192 816 expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1)
4501fbca
MW
817
818 # Actual output from router
701a0192 819 actual = (
820 net["r%s" % i]
821 .cmd('vtysh -c "show isis interface detail" 2> /dev/null')
822 .rstrip()
823 )
4501fbca
MW
824 # Mask out Link-Local mac address portion. They are random...
825 actual = re.sub(r"fe80::[0-9a-f:]+", "fe80::XXXX:XXXX:XXXX:XXXX", actual)
826 # Mask out SNPA mac address portion. They are random...
827 actual = re.sub(r"SNPA: [0-9a-f\.]+", "SNPA: XXXX.XXXX.XXXX", actual)
6ae351e8 828 # Mask out Circuit ID number
701a0192 829 actual = re.sub(r"Circuit Id: 0x[0-9a-f]+", "Circuit Id: 0xXX", actual)
4501fbca 830 # Fix newlines (make them all the same)
701a0192 831 actual = ("\n".join(actual.splitlines()) + "\n").splitlines(1)
4501fbca
MW
832
833 # Generate Diff
701a0192 834 diff = topotest.get_textdiff(
835 actual,
836 expected,
17070436 837 title1="actual SHOW ISIS INTERFACE DETAIL",
701a0192 838 title2="expected SHOW ISIS OSPF6 INTERFACE DETAIL",
839 )
4501fbca
MW
840
841 # Empty string if it matches, otherwise diff contains unified diff
842 if diff:
701a0192 843 sys.stderr.write(
844 "r%s failed SHOW ISIS INTERFACE DETAIL check:\n%s\n" % (i, diff)
845 )
4501fbca
MW
846 failures += 1
847 else:
848 print("r%s ok" % i)
849
701a0192 850 assert (
851 failures == 0
852 ), "SHOW ISIS INTERFACE DETAIL failed for router r%s:\n%s" % (i, diff)
4501fbca 853
7e7fc73b
MW
854 # Make sure that all daemons are running
855 for i in range(1, 2):
701a0192 856 fatal_error = net["r%s" % i].checkRouterRunning()
7e7fc73b
MW
857 assert fatal_error == "", fatal_error
858
622c4996 859 # For debugging after starting FRR daemons, uncomment the next line
4501fbca
MW
860 # CLI(net)
861
862
863def test_bgp_summary():
864 global fatal_error
e82b531d 865 net = get_topogen().net
4501fbca
MW
866
867 # Skip if previous fatal error condition is raised
701a0192 868 if fatal_error != "":
4501fbca
MW
869 pytest.skip(fatal_error)
870
871 thisDir = os.path.dirname(os.path.realpath(__file__))
872
b2764f90 873 print("\n\n** Verifying BGP Summary")
4501fbca
MW
874 print("******************************************\n")
875 failures = 0
876 for i in range(1, 2):
701a0192 877 refTableFile = "%s/r%s/show_ip_bgp_summary.ref" % (thisDir, i)
4501fbca
MW
878 if os.path.isfile(refTableFile):
879 # Read expected result from file
8c1d4cd5
LS
880 expected_original = open(refTableFile).read().rstrip()
881
a53c08bc
CH
882 for arguments in [
883 "",
884 "remote-as internal",
885 "remote-as external",
886 "remote-as 100",
887 "remote-as 123",
888 "neighbor 192.168.7.10",
889 "neighbor 192.168.7.10",
890 "neighbor fc00:0:0:8::1000",
891 "neighbor 10.0.0.1",
892 "terse",
893 "remote-as internal terse",
894 "remote-as external terse",
895 "remote-as 100 terse",
896 "remote-as 123 terse",
897 "neighbor 192.168.7.10 terse",
898 "neighbor 192.168.7.10 terse",
899 "neighbor fc00:0:0:8::1000 terse",
900 "neighbor 10.0.0.1 terse",
901 ]:
8c1d4cd5
LS
902 # Actual output from router
903 actual = (
904 net["r%s" % i]
a53c08bc
CH
905 .cmd(
906 'vtysh -c "show ip bgp summary ' + arguments + '" 2> /dev/null'
907 )
8c1d4cd5
LS
908 .rstrip()
909 )
96c81f66 910
8c1d4cd5
LS
911 # Mask out "using XXiXX bytes" portion. They are random...
912 actual = re.sub(r"using [0-9]+ bytes", "using XXXX bytes", actual)
913 # Mask out "using XiXXX KiB" portion. They are random...
914 actual = re.sub(r"using [0-9]+ KiB", "using XXXX KiB", actual)
915
916 # Remove extra summaries which exist with newer versions
917
918 # Remove summary lines (changed recently)
919 actual = re.sub(r"Total number.*", "", actual)
920 actual = re.sub(r"Displayed.*", "", actual)
921 # Remove IPv4 Unicast Summary (Title only)
6cac2fcc 922 actual = re.sub(r"IPv4 Unicast Summary \(VRF default\):", "", actual)
8c1d4cd5 923 # Remove IPv4 Multicast Summary (all of it)
6cac2fcc 924 actual = re.sub(r"IPv4 Multicast Summary \(VRF default\):", "", actual)
8c1d4cd5
LS
925 actual = re.sub(r"No IPv4 Multicast neighbor is configured", "", actual)
926 # Remove IPv4 VPN Summary (all of it)
6cac2fcc 927 actual = re.sub(r"IPv4 VPN Summary \(VRF default\):", "", actual)
8c1d4cd5
LS
928 actual = re.sub(r"No IPv4 VPN neighbor is configured", "", actual)
929 # Remove IPv4 Encap Summary (all of it)
6cac2fcc 930 actual = re.sub(r"IPv4 Encap Summary \(VRF default\):", "", actual)
8c1d4cd5
LS
931 actual = re.sub(r"No IPv4 Encap neighbor is configured", "", actual)
932 # Remove Unknown Summary (all of it)
6cac2fcc 933 actual = re.sub(r"Unknown Summary \(VRF default\):", "", actual)
8c1d4cd5
LS
934 actual = re.sub(r"No Unknown neighbor is configured", "", actual)
935
a53c08bc
CH
936 actual = re.sub(
937 r"IPv4 labeled-unicast Summary \(VRF default\):", "", actual
938 )
8c1d4cd5
LS
939 actual = re.sub(
940 r"No IPv4 labeled-unicast neighbor is configured", "", actual
941 )
8b2e59e9 942
8c1d4cd5 943 expected = expected_original
96c81f66
LS
944 # apply argumentss on expected output
945 if "internal" in arguments or "remote-as 100" in arguments:
8c1d4cd5 946 expected = re.sub(r".+\s+200\s+.+", "", expected)
96c81f66 947 elif "external" in arguments:
8c1d4cd5 948 expected = re.sub(r".+\s+100\s+.+Active.+", "", expected)
96c81f66 949 elif "remote-as 123" in arguments:
8c1d4cd5
LS
950 expected = re.sub(
951 r"(192.168.7.(1|2)0|fc00:0:0:8::(1|2)000).+Active.+",
a53c08bc
CH
952 "",
953 expected,
8c1d4cd5 954 )
96c81f66 955 expected = re.sub(r"\nNeighbor.+Desc", "", expected)
ce1944f0 956 expected = expected + "% No matching neighbor\n"
96c81f66 957 elif "192.168.7.10" in arguments:
8c1d4cd5 958 expected = re.sub(
a53c08bc 959 r"(192.168.7.20|fc00:0:0:8::(1|2)000).+Active.+", "", expected
8c1d4cd5 960 )
96c81f66 961 elif "fc00:0:0:8::1000" in arguments:
8c1d4cd5 962 expected = re.sub(
a53c08bc 963 r"(192.168.7.(1|2)0|fc00:0:0:8::2000).+Active.+", "", expected
8c1d4cd5 964 )
96c81f66 965 elif "10.0.0.1" in arguments:
c3c4e528 966 expected = "No such neighbor in VRF default"
8c1d4cd5 967
96c81f66
LS
968 if "terse" in arguments:
969 expected = re.sub(r"BGP table version .+", "", expected)
970 expected = re.sub(r"RIB entries .+", "", expected)
971 expected = re.sub(r"Peers [0-9]+, using .+", "", expected)
972
8c1d4cd5
LS
973 # Strip empty lines
974 actual = actual.lstrip().rstrip()
975 expected = expected.lstrip().rstrip()
976 actual = re.sub(r"\n+", "\n", actual)
977 expected = re.sub(r"\n+", "\n", expected)
978
979 # reapply initial formatting
96c81f66
LS
980 if "terse" in arguments:
981 actual = re.sub(r" vrf-id 0\n", " vrf-id 0\n\n", actual)
982 expected = re.sub(r" vrf-id 0\n", " vrf-id 0\n\n", expected)
983 else:
984 actual = re.sub(r"KiB of memory\n", "KiB of memory\n\n", actual)
985 expected = re.sub(r"KiB of memory\n", "KiB of memory\n\n", expected)
8c1d4cd5
LS
986
987 # realign expected neighbor columns if needed
988 try:
a53c08bc
CH
989 idx_actual = (
990 re.search(r"(Neighbor\s+V\s+)", actual).group(1).find("V")
991 )
992 idx_expected = (
993 re.search(r"(Neighbor\s+V\s+)", expected).group(1).find("V")
994 )
8c1d4cd5
LS
995 idx_diff = idx_expected - idx_actual
996 if idx_diff > 0:
997 # Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd
998 expected = re.sub(" " * idx_diff + "V ", "V ", expected)
999 # 192.168.7.10 4 100 0 0 0 0 0 never Active
1000 expected = re.sub(" " * idx_diff + "4 ", "4 ", expected)
1001 except AttributeError:
1002 pass
1003
1004 # Fix newlines (make them all the same)
1005 actual = ("\n".join(actual.splitlines()) + "\n").splitlines(1)
1006 expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1)
1007
1008 # Generate Diff
1009 diff = topotest.get_textdiff(
1010 actual,
1011 expected,
a53c08bc 1012 title1="actual SHOW IP BGP SUMMARY " + arguments.upper(),
96c81f66 1013 title2="expected SHOW IP BGP SUMMARY " + arguments.upper(),
8c1d4cd5 1014 )
4501fbca 1015
8c1d4cd5
LS
1016 # Empty string if it matches, otherwise diff contains unified diff
1017 if diff:
1018 sys.stderr.write(
1019 "r%s failed SHOW IP BGP SUMMARY check:\n%s\n" % (i, diff)
1020 )
1021 failures += 1
1022 else:
1023 print("r%s ok" % i)
4501fbca 1024
a53c08bc
CH
1025 assert (
1026 failures == 0
1027 ), "SHOW IP BGP SUMMARY failed for router r%s:\n%s" % (
8c1d4cd5
LS
1028 i,
1029 diff,
701a0192 1030 )
4501fbca 1031
7e7fc73b
MW
1032 # Make sure that all daemons are running
1033 for i in range(1, 2):
701a0192 1034 fatal_error = net["r%s" % i].checkRouterRunning()
7e7fc73b
MW
1035 assert fatal_error == "", fatal_error
1036
622c4996 1037 # For debugging after starting FRR daemons, uncomment the next line
4501fbca
MW
1038 # CLI(net)
1039
1040
1041def test_bgp_ipv6_summary():
1042 global fatal_error
e82b531d 1043 net = get_topogen().net
4501fbca
MW
1044
1045 # Skip if previous fatal error condition is raised
701a0192 1046 if fatal_error != "":
4501fbca
MW
1047 pytest.skip(fatal_error)
1048
1049 thisDir = os.path.dirname(os.path.realpath(__file__))
1050
b2764f90 1051 print("\n\n** Verifying BGP IPv6 Summary")
4501fbca
MW
1052 print("******************************************\n")
1053 failures = 0
1054 for i in range(1, 2):
701a0192 1055 refTableFile = "%s/r%s/show_bgp_ipv6_summary.ref" % (thisDir, i)
4501fbca
MW
1056 if os.path.isfile(refTableFile):
1057 # Read expected result from file
1058 expected = open(refTableFile).read().rstrip()
1059 # Fix newlines (make them all the same)
701a0192 1060 expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1)
4501fbca
MW
1061
1062 # Actual output from router
701a0192 1063 actual = (
1064 net["r%s" % i]
1065 .cmd('vtysh -c "show bgp ipv6 summary" 2> /dev/null')
1066 .rstrip()
1067 )
4501fbca
MW
1068 # Mask out "using XXiXX bytes" portion. They are random...
1069 actual = re.sub(r"using [0-9]+ bytes", "using XXXX bytes", actual)
1070 # Mask out "using XiXXX KiB" portion. They are random...
1071 actual = re.sub(r"using [0-9]+ KiB", "using XXXX KiB", actual)
08fa1af7
MW
1072 #
1073 # Remove extra summaries which exist with newer versions
1074 #
1075 # Remove summary lines (changed recently)
701a0192 1076 actual = re.sub(r"Total number.*", "", actual)
1077 actual = re.sub(r"Displayed.*", "", actual)
08fa1af7 1078 # Remove IPv4 Unicast Summary (Title only)
6cac2fcc 1079 actual = re.sub(r"IPv6 Unicast Summary \(VRF default\):", "", actual)
08fa1af7 1080 # Remove IPv4 Multicast Summary (all of it)
6cac2fcc 1081 actual = re.sub(r"IPv6 Multicast Summary \(VRF default\):", "", actual)
701a0192 1082 actual = re.sub(r"No IPv6 Multicast neighbor is configured", "", actual)
08fa1af7 1083 # Remove IPv4 VPN Summary (all of it)
6cac2fcc 1084 actual = re.sub(r"IPv6 VPN Summary \(VRF default\):", "", actual)
701a0192 1085 actual = re.sub(r"No IPv6 VPN neighbor is configured", "", actual)
08fa1af7 1086 # Remove IPv4 Encap Summary (all of it)
6cac2fcc 1087 actual = re.sub(r"IPv6 Encap Summary \(VRF default\):", "", actual)
701a0192 1088 actual = re.sub(r"No IPv6 Encap neighbor is configured", "", actual)
08fa1af7 1089 # Remove Unknown Summary (all of it)
6cac2fcc 1090 actual = re.sub(r"Unknown Summary \(VRF default\):", "", actual)
701a0192 1091 actual = re.sub(r"No Unknown neighbor is configured", "", actual)
8b2e59e9
DS
1092
1093 # Remove Labeled Unicast Summary (all of it)
a53c08bc
CH
1094 actual = re.sub(
1095 r"IPv6 labeled-unicast Summary \(VRF default\):", "", actual
1096 )
701a0192 1097 actual = re.sub(
1098 r"No IPv6 labeled-unicast neighbor is configured", "", actual
1099 )
8b2e59e9 1100
08fa1af7
MW
1101 # Strip empty lines
1102 actual = actual.lstrip()
1103 actual = actual.rstrip()
1104 #
4501fbca 1105 # Fix newlines (make them all the same)
701a0192 1106 actual = ("\n".join(actual.splitlines()) + "\n").splitlines(1)
4501fbca
MW
1107
1108 # Generate Diff
701a0192 1109 diff = topotest.get_textdiff(
1110 actual,
1111 expected,
17070436 1112 title1="actual SHOW BGP IPv6 SUMMARY",
701a0192 1113 title2="expected SHOW BGP IPv6 SUMMARY",
1114 )
4501fbca
MW
1115
1116 # Empty string if it matches, otherwise diff contains unified diff
1117 if diff:
701a0192 1118 sys.stderr.write(
1119 "r%s failed SHOW BGP IPv6 SUMMARY check:\n%s\n" % (i, diff)
1120 )
4501fbca
MW
1121 failures += 1
1122 else:
1123 print("r%s ok" % i)
1124
701a0192 1125 assert failures == 0, "SHOW BGP IPv6 SUMMARY failed for router r%s:\n%s" % (
1126 i,
1127 diff,
1128 )
4501fbca 1129
7e7fc73b
MW
1130 # Make sure that all daemons are running
1131 for i in range(1, 2):
701a0192 1132 fatal_error = net["r%s" % i].checkRouterRunning()
7e7fc73b
MW
1133 assert fatal_error == "", fatal_error
1134
622c4996 1135 # For debugging after starting FRR daemons, uncomment the next line
4501fbca
MW
1136 # CLI(net)
1137
9fa6ec14 1138
dda33b6e 1139def test_nht():
e82b531d 1140 net = get_topogen().net
dda33b6e
DS
1141 print("\n\n**** Test that nexthop tracking is at least nominally working ****\n")
1142
1143 thisDir = os.path.dirname(os.path.realpath(__file__))
1144
1145 for i in range(1, 2):
1146 nhtFile = "%s/r%s/ip_nht.ref" % (thisDir, i)
1147 expected = open(nhtFile).read().rstrip()
1148 expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1)
1149
9fa6ec14 1150 actual = net["r%s" % i].cmd('vtysh -c "show ip nht" 2> /dev/null').rstrip()
8db751b8 1151 actual = re.sub(r"fd [0-9]+", "fd XX", actual)
dda33b6e
DS
1152 actual = ("\n".join(actual.splitlines()) + "\n").splitlines(1)
1153
9fa6ec14 1154 diff = topotest.get_textdiff(
1155 actual,
1156 expected,
1157 title1="Actual `show ip nht`",
1158 title2="Expected `show ip nht`",
1159 )
dda33b6e
DS
1160
1161 if diff:
1162 assert 0, "r%s failed ip nht check:\n%s\n" % (i, diff)
1163 else:
1164 print("show ip nht is ok\n")
1165
1166 nhtFile = "%s/r%s/ipv6_nht.ref" % (thisDir, i)
1167 expected = open(nhtFile).read().rstrip()
1168 expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1)
1169
9fa6ec14 1170 actual = net["r%s" % i].cmd('vtysh -c "show ipv6 nht" 2> /dev/null').rstrip()
8db751b8 1171 actual = re.sub(r"fd [0-9]+", "fd XX", actual)
dda33b6e
DS
1172 actual = ("\n".join(actual.splitlines()) + "\n").splitlines(1)
1173
9fa6ec14 1174 diff = topotest.get_textdiff(
1175 actual,
1176 expected,
1177 title1="Actual `show ip nht`",
1178 title2="Expected `show ip nht`",
1179 )
dda33b6e
DS
1180
1181 if diff:
1182 assert 0, "r%s failed ipv6 nht check:\n%s\n" % (i, diff)
1183 else:
1184 print("show ipv6 nht is ok\n")
4501fbca 1185
9fa6ec14 1186
4501fbca
MW
1187def test_bgp_ipv4():
1188 global fatal_error
e82b531d 1189 net = get_topogen().net
4501fbca
MW
1190
1191 # Skip if previous fatal error condition is raised
701a0192 1192 if fatal_error != "":
4501fbca
MW
1193 pytest.skip(fatal_error)
1194
1195 thisDir = os.path.dirname(os.path.realpath(__file__))
1196
b2764f90 1197 print("\n\n** Verifying BGP IPv4")
4501fbca 1198 print("******************************************\n")
6a57e103 1199 diffresult = {}
4501fbca 1200 for i in range(1, 2):
11761ab0 1201 success = 0
701a0192 1202 for refTableFile in glob.glob("%s/r%s/show_bgp_ipv4*.ref" % (thisDir, i)):
11761ab0
MS
1203 if os.path.isfile(refTableFile):
1204 # Read expected result from file
1205 expected = open(refTableFile).read().rstrip()
1206 # Fix newlines (make them all the same)
701a0192 1207 expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1)
11761ab0
MS
1208
1209 # Actual output from router
701a0192 1210 actual = (
1211 net["r%s" % i].cmd('vtysh -c "show bgp ipv4" 2> /dev/null').rstrip()
1212 )
11761ab0 1213 # Remove summary line (changed recently)
701a0192 1214 actual = re.sub(r"Total number.*", "", actual)
1215 actual = re.sub(r"Displayed.*", "", actual)
11761ab0
MS
1216 actual = actual.rstrip()
1217 # Fix newlines (make them all the same)
701a0192 1218 actual = ("\n".join(actual.splitlines()) + "\n").splitlines(1)
11761ab0
MS
1219
1220 # Generate Diff
701a0192 1221 diff = topotest.get_textdiff(
1222 actual,
1223 expected,
11761ab0 1224 title1="actual SHOW BGP IPv4",
701a0192 1225 title2="expected SHOW BGP IPv4",
1226 )
11761ab0
MS
1227
1228 # Empty string if it matches, otherwise diff contains unified diff
1229 if diff:
1230 diffresult[refTableFile] = diff
1231 else:
1232 success = 1
1233 print("template %s matched: r%s ok" % (refTableFile, i))
1234 break
1235
1236 if not success:
701a0192 1237 resultstr = "No template matched.\n"
e7294b32 1238 for f in diffresult.keys():
701a0192 1239 resultstr += "template %s: r%s failed SHOW BGP IPv4 check:\n%s\n" % (
1240 f,
1241 i,
1242 diffresult[f],
1243 )
11761ab0 1244 raise AssertionError(
701a0192 1245 "SHOW BGP IPv4 failed for router r%s:\n%s" % (i, resultstr)
1246 )
4501fbca 1247
7e7fc73b
MW
1248 # Make sure that all daemons are running
1249 for i in range(1, 2):
701a0192 1250 fatal_error = net["r%s" % i].checkRouterRunning()
7e7fc73b
MW
1251 assert fatal_error == "", fatal_error
1252
622c4996 1253 # For debugging after starting FRR daemons, uncomment the next line
4501fbca
MW
1254 # CLI(net)
1255
1256
1257def test_bgp_ipv6():
1258 global fatal_error
e82b531d 1259 net = get_topogen().net
4501fbca
MW
1260
1261 # Skip if previous fatal error condition is raised
701a0192 1262 if fatal_error != "":
4501fbca
MW
1263 pytest.skip(fatal_error)
1264
1265 thisDir = os.path.dirname(os.path.realpath(__file__))
1266
b2764f90 1267 print("\n\n** Verifying BGP IPv6")
4501fbca 1268 print("******************************************\n")
6a57e103 1269 diffresult = {}
4501fbca 1270 for i in range(1, 2):
11761ab0 1271 success = 0
701a0192 1272 for refTableFile in glob.glob("%s/r%s/show_bgp_ipv6*.ref" % (thisDir, i)):
11761ab0
MS
1273 if os.path.isfile(refTableFile):
1274 # Read expected result from file
1275 expected = open(refTableFile).read().rstrip()
1276 # Fix newlines (make them all the same)
701a0192 1277 expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1)
11761ab0
MS
1278
1279 # Actual output from router
701a0192 1280 actual = (
1281 net["r%s" % i].cmd('vtysh -c "show bgp ipv6" 2> /dev/null').rstrip()
1282 )
11761ab0 1283 # Remove summary line (changed recently)
701a0192 1284 actual = re.sub(r"Total number.*", "", actual)
1285 actual = re.sub(r"Displayed.*", "", actual)
11761ab0
MS
1286 actual = actual.rstrip()
1287 # Fix newlines (make them all the same)
701a0192 1288 actual = ("\n".join(actual.splitlines()) + "\n").splitlines(1)
11761ab0
MS
1289
1290 # Generate Diff
701a0192 1291 diff = topotest.get_textdiff(
1292 actual,
1293 expected,
11761ab0 1294 title1="actual SHOW BGP IPv6",
701a0192 1295 title2="expected SHOW BGP IPv6",
1296 )
11761ab0
MS
1297
1298 # Empty string if it matches, otherwise diff contains unified diff
1299 if diff:
1300 diffresult[refTableFile] = diff
1301 else:
1302 success = 1
1303 print("template %s matched: r%s ok" % (refTableFile, i))
1304
1305 if not success:
701a0192 1306 resultstr = "No template matched.\n"
e7294b32 1307 for f in diffresult.keys():
701a0192 1308 resultstr += "template %s: r%s failed SHOW BGP IPv6 check:\n%s\n" % (
1309 f,
1310 i,
1311 diffresult[f],
1312 )
11761ab0 1313 raise AssertionError(
701a0192 1314 "SHOW BGP IPv6 failed for router r%s:\n%s" % (i, resultstr)
1315 )
4501fbca 1316
7e7fc73b
MW
1317 # Make sure that all daemons are running
1318 for i in range(1, 2):
701a0192 1319 fatal_error = net["r%s" % i].checkRouterRunning()
7e7fc73b
MW
1320 assert fatal_error == "", fatal_error
1321
622c4996 1322 # For debugging after starting FRR daemons, uncomment the next line
4501fbca
MW
1323 # CLI(net)
1324
701a0192 1325
41fce07c
DS
1326def test_route_map():
1327 global fatal_error
e82b531d 1328 net = get_topogen().net
41fce07c 1329
701a0192 1330 if fatal_error != "":
41fce07c
DS
1331 pytest.skip(fatal_error)
1332
1333 thisDir = os.path.dirname(os.path.realpath(__file__))
1334
1335 print("\n\n** Verifying some basic routemap forward references\n")
1336 print("*******************************************************\n")
1337 failures = 0
1338 for i in range(1, 2):
701a0192 1339 refroutemap = "%s/r%s/show_route_map.ref" % (thisDir, i)
41fce07c
DS
1340 if os.path.isfile(refroutemap):
1341 expected = open(refroutemap).read().rstrip()
701a0192 1342 expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1)
41fce07c 1343
701a0192 1344 actual = (
1345 net["r%s" % i].cmd('vtysh -c "show route-map" 2> /dev/null').rstrip()
1346 )
1347 actual = ("\n".join(actual.splitlines()) + "\n").splitlines(1)
41fce07c 1348
701a0192 1349 diff = topotest.get_textdiff(
1350 actual,
1351 expected,
1352 title1="actual show route-map",
1353 title2="expected show route-map",
1354 )
41fce07c
DS
1355
1356 if diff:
701a0192 1357 sys.stderr.write(
1358 "r%s failed show route-map command Check:\n%s\n" % (i, diff)
1359 )
41fce07c
DS
1360 failures += 1
1361 else:
701a0192 1362 print("r%s ok" % i)
1363
1364 assert (
1365 failures == 0
1366 ), "Show route-map command failed for router r%s:\n%s" % (i, diff)
4501fbca
MW
1367
1368
887a232c
SW
1369def test_nexthop_groups_with_route_maps():
1370 global fatal_error
e82b531d 1371 net = get_topogen().net
887a232c
SW
1372
1373 # Skip if previous fatal error condition is raised
701a0192 1374 if fatal_error != "":
887a232c
SW
1375 pytest.skip(fatal_error)
1376
1377 print("\n\n** Verifying Nexthop Groups With Route-Maps")
1378 print("******************************************\n")
1379
1380 ### Nexthop Group With Route-Map Tests
1381
1382 # Create a lib nexthop-group
701a0192 1383 net["r1"].cmd(
1384 'vtysh -c "c t" -c "nexthop-group test" -c "nexthop 1.1.1.1" -c "nexthop 1.1.1.2"'
1385 )
887a232c
SW
1386
1387 ## Route-Map Proto Source
1388
1389 route_str = "2.2.2.1"
1390 src_str = "192.168.0.1"
1391
701a0192 1392 net["r1"].cmd(
1393 'vtysh -c "c t" -c "route-map NH-SRC permit 111" -c "set src %s"' % src_str
1394 )
887a232c
SW
1395 net["r1"].cmd('vtysh -c "c t" -c "ip protocol sharp route-map NH-SRC"')
1396
1397 net["r1"].cmd('vtysh -c "sharp install routes %s nexthop-group test 1"' % route_str)
1398
1399 verify_route_nexthop_group("%s/32" % route_str)
1400
1401 # Only a valid test on linux using nexthop objects
1402 if sys.platform.startswith("linux"):
701a0192 1403 output = net["r1"].cmd("ip route show %s/32" % route_str)
887a232c 1404 match = re.search(r"src %s" % src_str, output)
701a0192 1405 assert match is not None, "Route %s/32 not installed with src %s" % (
1406 route_str,
1407 src_str,
1408 )
887a232c
SW
1409
1410 # Remove NHG routes and route-map
1411 net["r1"].cmd('vtysh -c "sharp remove routes %s 1"' % route_str)
1412 net["r1"].cmd('vtysh -c "c t" -c "no ip protocol sharp route-map NH-SRC"')
701a0192 1413 net["r1"].cmd(
8db751b8 1414 'vtysh -c "c t" -c "no route-map NH-SRC permit 111" # -c "set src %s"' % src_str
701a0192 1415 )
887a232c
SW
1416 net["r1"].cmd('vtysh -c "c t" -c "no route-map NH-SRC"')
1417
1418 ## Route-Map Deny/Permit with same nexthop group
1419
1420 permit_route_str = "3.3.3.1"
1421 deny_route_str = "3.3.3.2"
1422
701a0192 1423 net["r1"].cmd(
1424 'vtysh -c "c t" -c "ip prefix-list NOPE seq 5 permit %s/32"' % permit_route_str
1425 )
1426 net["r1"].cmd(
1427 'vtysh -c "c t" -c "route-map NOPE permit 111" -c "match ip address prefix-list NOPE"'
1428 )
887a232c
SW
1429 net["r1"].cmd('vtysh -c "c t" -c "route-map NOPE deny 222"')
1430 net["r1"].cmd('vtysh -c "c t" -c "ip protocol sharp route-map NOPE"')
1431
1432 # This route should be permitted
701a0192 1433 net["r1"].cmd(
1434 'vtysh -c "sharp install routes %s nexthop-group test 1"' % permit_route_str
1435 )
887a232c
SW
1436
1437 verify_route_nexthop_group("%s/32" % permit_route_str)
1438
1439 # This route should be denied
701a0192 1440 net["r1"].cmd(
1441 'vtysh -c "sharp install routes %s nexthop-group test 1"' % deny_route_str
1442 )
887a232c
SW
1443
1444 nhg_id = route_get_nhg_id(deny_route_str)
1445 output = net["r1"].cmd('vtysh -c "show nexthop-group rib %d"' % nhg_id)
1446
1447 match = re.search(r"Valid", output)
1448 assert match is None, "Nexthop Group ID=%d should not be marked Valid" % nhg_id
1449
1450 match = re.search(r"Installed", output)
1451 assert match is None, "Nexthop Group ID=%d should not be marked Installed" % nhg_id
1452
1453 # Remove NHG routes and route-map
1454 net["r1"].cmd('vtysh -c "sharp remove routes %s 1"' % permit_route_str)
1455 net["r1"].cmd('vtysh -c "sharp remove routes %s 1"' % deny_route_str)
1456 net["r1"].cmd('vtysh -c "c t" -c "no ip protocol sharp route-map NOPE"')
1457 net["r1"].cmd('vtysh -c "c t" -c "no route-map NOPE permit 111"')
1458 net["r1"].cmd('vtysh -c "c t" -c "no route-map NOPE deny 222"')
1459 net["r1"].cmd('vtysh -c "c t" -c "no route-map NOPE"')
701a0192 1460 net["r1"].cmd(
1461 'vtysh -c "c t" -c "no ip prefix-list NOPE seq 5 permit %s/32"'
1462 % permit_route_str
1463 )
1464
887a232c 1465
8f4d7212
SW
1466def test_nexthop_group_replace():
1467 global fatal_error
e82b531d 1468 net = get_topogen().net
8f4d7212
SW
1469
1470 # Skip if previous fatal error condition is raised
701a0192 1471 if fatal_error != "":
8f4d7212
SW
1472 pytest.skip(fatal_error)
1473
1474 print("\n\n** Verifying Nexthop Groups")
1475 print("******************************************\n")
1476
1477 ### Nexthop Group Tests
1478
1479 ## 2-Way ECMP Directly Connected
1480
701a0192 1481 net["r1"].cmd(
1482 'vtysh -c "c t" -c "nexthop-group replace" -c "nexthop 1.1.1.1 r1-eth1 onlink" -c "nexthop 1.1.1.2 r1-eth2 onlink"'
1483 )
8f4d7212
SW
1484
1485 # Create with sharpd using nexthop-group
1486 net["r1"].cmd('vtysh -c "sharp install routes 3.3.3.1 nexthop-group replace 1"')
1487
1488 verify_route_nexthop_group("3.3.3.1/32")
1489
1490 # Change the nexthop group
701a0192 1491 net["r1"].cmd(
1492 'vtysh -c "c t" -c "nexthop-group replace" -c "no nexthop 1.1.1.1 r1-eth1 onlink" -c "nexthop 1.1.1.3 r1-eth1 onlink" -c "nexthop 1.1.1.4 r1-eth4 onlink"'
1493 )
8f4d7212
SW
1494
1495 # Verify it updated. We can just check install and ecmp count here.
1496 verify_route_nexthop_group("3.3.3.1/32", False, 3)
1497
701a0192 1498
4501fbca
MW
1499def test_mpls_interfaces():
1500 global fatal_error
e82b531d 1501 net = get_topogen().net
4501fbca
MW
1502
1503 # Skip if previous fatal error condition is raised
701a0192 1504 if fatal_error != "":
4501fbca
MW
1505 pytest.skip(fatal_error)
1506
1507 # Skip if no LDP installed or old kernel
701a0192 1508 if net["r1"].daemon_available("ldpd") == False:
4501fbca
MW
1509 pytest.skip("No MPLS or kernel < 4.5")
1510
1511 thisDir = os.path.dirname(os.path.realpath(__file__))
1512
b2764f90 1513 print("\n\n** Verifying MPLS Interfaces")
4501fbca
MW
1514 print("******************************************\n")
1515 failures = 0
1516 for i in range(1, 2):
701a0192 1517 refTableFile = "%s/r%s/show_mpls_ldp_interface.ref" % (thisDir, i)
4501fbca
MW
1518 if os.path.isfile(refTableFile):
1519 # Read expected result from file
1520 expected = open(refTableFile).read().rstrip()
1521 # Fix newlines (make them all the same)
701a0192 1522 expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1)
4501fbca
MW
1523
1524 # Actual output from router
701a0192 1525 actual = (
1526 net["r%s" % i]
1527 .cmd('vtysh -c "show mpls ldp interface" 2> /dev/null')
1528 .rstrip()
1529 )
4501fbca
MW
1530 # Mask out Timer in Uptime
1531 actual = re.sub(r" [0-9][0-9]:[0-9][0-9]:[0-9][0-9] ", " xx:xx:xx ", actual)
1532 # Fix newlines (make them all the same)
701a0192 1533 actual = ("\n".join(actual.splitlines()) + "\n").splitlines(1)
4501fbca
MW
1534
1535 # Generate Diff
701a0192 1536 diff = topotest.get_textdiff(
1537 actual,
1538 expected,
17070436 1539 title1="actual MPLS LDP interface status",
701a0192 1540 title2="expected MPLS LDP interface status",
1541 )
4501fbca
MW
1542
1543 # Empty string if it matches, otherwise diff contains unified diff
1544 if diff:
701a0192 1545 sys.stderr.write(
1546 "r%s failed MPLS LDP Interface status Check:\n%s\n" % (i, diff)
1547 )
4501fbca
MW
1548 failures += 1
1549 else:
1550 print("r%s ok" % i)
1551
701a0192 1552 if failures > 0:
4501fbca
MW
1553 fatal_error = "MPLS LDP Interface status failed"
1554
701a0192 1555 assert (
1556 failures == 0
1557 ), "MPLS LDP Interface status failed for router r%s:\n%s" % (i, diff)
4501fbca 1558
7e7fc73b
MW
1559 # Make sure that all daemons are running
1560 for i in range(1, 2):
701a0192 1561 fatal_error = net["r%s" % i].checkRouterRunning()
7e7fc73b
MW
1562 assert fatal_error == "", fatal_error
1563
622c4996 1564 # For debugging after starting FRR daemons, uncomment the next line
4501fbca
MW
1565 # CLI(net)
1566
1567
1568def test_shutdown_check_stderr():
1569 global fatal_error
e82b531d 1570 net = get_topogen().net
4501fbca
MW
1571
1572 # Skip if previous fatal error condition is raised
701a0192 1573 if fatal_error != "":
4501fbca
MW
1574 pytest.skip(fatal_error)
1575
b2764f90 1576 print("\n\n** Verifying unexpected STDERR output from daemons")
4501fbca
MW
1577 print("******************************************\n")
1578
701a0192 1579 if os.environ.get("TOPOTESTS_CHECK_STDERR") is None:
1580 print(
1581 "SKIPPED final check on StdErr output: Disabled (TOPOTESTS_CHECK_STDERR undefined)\n"
1582 )
1583 pytest.skip("Skipping test for Stderr output")
4501fbca
MW
1584
1585 thisDir = os.path.dirname(os.path.realpath(__file__))
1586
50c40bde
MW
1587 print("thisDir=" + thisDir)
1588
701a0192 1589 net["r1"].stopRouter()
4501fbca 1590
701a0192 1591 log = net["r1"].getStdErr("ripd")
8e957dbb
MW
1592 if log:
1593 print("\nRIPd StdErr Log:\n" + log)
701a0192 1594 log = net["r1"].getStdErr("ripngd")
8e957dbb
MW
1595 if log:
1596 print("\nRIPngd StdErr Log:\n" + log)
701a0192 1597 log = net["r1"].getStdErr("ospfd")
8e957dbb
MW
1598 if log:
1599 print("\nOSPFd StdErr Log:\n" + log)
701a0192 1600 log = net["r1"].getStdErr("ospf6d")
8e957dbb
MW
1601 if log:
1602 print("\nOSPF6d StdErr Log:\n" + log)
701a0192 1603 log = net["r1"].getStdErr("isisd")
8e957dbb
MW
1604 if log:
1605 print("\nISISd StdErr Log:\n" + log)
701a0192 1606 log = net["r1"].getStdErr("bgpd")
8e957dbb
MW
1607 if log:
1608 print("\nBGPd StdErr Log:\n" + log)
af39fbe7 1609
701a0192 1610 log = net["r1"].getStdErr("nhrpd")
af39fbe7
MS
1611 if log:
1612 print("\nNHRPd StdErr Log:\n" + log)
1613
701a0192 1614 log = net["r1"].getStdErr("pbrd")
af39fbe7
MS
1615 if log:
1616 print("\nPBRd StdErr Log:\n" + log)
1617
701a0192 1618 log = net["r1"].getStdErr("babeld")
af39fbe7
MS
1619 if log:
1620 print("\nBABELd StdErr Log:\n" + log)
1621
701a0192 1622 if net["r1"].daemon_available("ldpd"):
1623 log = net["r1"].getStdErr("ldpd")
8e957dbb
MW
1624 if log:
1625 print("\nLDPd StdErr Log:\n" + log)
701a0192 1626 log = net["r1"].getStdErr("zebra")
8e957dbb
MW
1627 if log:
1628 print("\nZebra StdErr Log:\n" + log)
4501fbca
MW
1629
1630
50c40bde
MW
1631def test_shutdown_check_memleak():
1632 global fatal_error
e82b531d 1633 net = get_topogen().net
50c40bde
MW
1634
1635 # Skip if previous fatal error condition is raised
701a0192 1636 if fatal_error != "":
50c40bde
MW
1637 pytest.skip(fatal_error)
1638
701a0192 1639 if os.environ.get("TOPOTESTS_CHECK_MEMLEAK") is None:
1640 print(
1641 "SKIPPED final check on Memory leaks: Disabled (TOPOTESTS_CHECK_MEMLEAK undefined)\n"
1642 )
1643 pytest.skip("Skipping test for memory leaks")
1644
50c40bde
MW
1645 thisDir = os.path.dirname(os.path.realpath(__file__))
1646
1647 for i in range(1, 2):
701a0192 1648 net["r%s" % i].stopRouter()
1649 net["r%s" % i].report_memory_leaks(
1650 os.environ.get("TOPOTESTS_CHECK_MEMLEAK"), os.path.basename(__file__)
1651 )
50c40bde
MW
1652
1653
701a0192 1654if __name__ == "__main__":
4501fbca
MW
1655 # To suppress tracebacks, either use the following pytest call or add "--tb=no" to cli
1656 # retval = pytest.main(["-s", "--tb=no"])
1657 retval = pytest.main(["-s"])
1658 sys.exit(retval)