]> git.proxmox.com Git - mirror_frr.git/blob - tests/topotests/ldp_topo1/test_ldp_topo1.py
Merge pull request #12818 from imzyxwvu/fix/other-table-inactive
[mirror_frr.git] / tests / topotests / ldp_topo1 / test_ldp_topo1.py
1 #!/usr/bin/env python
2 # SPDX-License-Identifier: ISC
3
4 #
5 # test_bgp_multiview_topo1.py
6 # Part of NetDEF Topology Tests
7 #
8 # Copyright (c) 2016 by
9 # Network Device Education Foundation, Inc. ("NetDEF")
10 #
11
12 r"""
13 test_ldp_topo1.py: Simple FRR LDP Test
14
15 +---------+
16 | r1 |
17 | 1.1.1.1 |
18 +----+----+
19 | .1 r1-eth0
20 |
21 ~~~~~~~~~~~~~
22 ~~ sw0 ~~
23 ~~ 10.0.1.0/24 ~~
24 ~~~~~~~~~~~~~
25 |10.0.1.0/24
26 |
27 | .2 r2-eth0
28 +----+----+
29 | r2 |
30 | 2.2.2.2 |
31 +--+---+--+
32 r2-eth2 .2 | | .2 r2-eth1
33 ______/ \______
34 / \
35 ~~~~~~~~~~~~~ ~~~~~~~~~~~~~
36 ~~ sw2 ~~ ~~ sw1 ~~
37 ~~ 10.0.3.0/24 ~~ ~~ 10.0.2.0/24 ~~
38 ~~~~~~~~~~~~~ ~~~~~~~~~~~~~
39 | / |
40 \ _________/ |
41 \ / \
42 r3-eth1 .3 | | .3 r3-eth0 | .4 r4-eth0
43 +----+--+---+ +----+----+
44 | r3 | | r4 |
45 | 3.3.3.3 | | 4.4.4.4 |
46 +-----------+ +---------+
47 """
48
49 import os
50 import re
51 import sys
52 import pytest
53 import json
54 from functools import partial
55 from time import sleep
56 from lib.topolog import logger
57
58 # Save the Current Working Directory to find configuration files.
59 CWD = os.path.dirname(os.path.realpath(__file__))
60 sys.path.append(os.path.join(CWD, "../"))
61
62 sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
63 from lib import topotest
64 from lib.topogen import Topogen, get_topogen
65
66 fatal_error = ""
67
68 pytestmark = [pytest.mark.ldpd, pytest.mark.ospfd]
69
70 #####################################################
71 ##
72 ## Network Topology Definition
73 ##
74 #####################################################
75
76
77 def build_topo(tgen):
78
79 # Setup Routers
80 for i in range(1, 5):
81 tgen.add_router("r%s" % i)
82
83 # First switch
84 switch = tgen.add_switch("sw0")
85 switch.add_link(tgen.gears["r1"])
86 switch.add_link(tgen.gears["r2"])
87 # Second switch
88 switch = tgen.add_switch("sw1")
89 switch.add_link(tgen.gears["r2"])
90 switch.add_link(tgen.gears["r3"])
91 switch.add_link(tgen.gears["r4"])
92 # Third switch
93 switch = tgen.add_switch("sw2")
94 switch.add_link(tgen.gears["r2"])
95 switch.add_link(tgen.gears["r3"])
96
97
98 #####################################################
99 ##
100 ## Helper functions
101 ##
102 #####################################################
103
104
105 def router_compare_json_output(rname, command, reference, count=60, wait=1):
106 "Compare router JSON output"
107
108 logger.info('Comparing router "%s" "%s" output', rname, command)
109
110 tgen = get_topogen()
111 filename = "{}/{}/{}".format(CWD, rname, reference)
112 expected = json.loads(open(filename).read())
113
114 # Run test function until we get an result.
115 test_func = partial(topotest.router_json_cmp, tgen.gears[rname], command, expected)
116 _, diff = topotest.run_and_expect(test_func, None, count, wait)
117 assertmsg = '"{}" JSON output mismatches the expected result'.format(rname)
118 assert diff is None, assertmsg
119
120
121 #####################################################
122 ##
123 ## Tests starting
124 ##
125 #####################################################
126
127
128 def setup_module(module):
129 print("\n\n** %s: Setup Topology" % module.__name__)
130 print("******************************************\n")
131
132 thisDir = os.path.dirname(os.path.realpath(__file__))
133 tgen = Topogen(build_topo, module.__name__)
134 tgen.start_topology()
135
136 net = tgen.net
137
138 # Starting Routers
139 for i in range(1, 5):
140 net["r%s" % i].loadConf("zebra", "%s/r%s/zebra.conf" % (thisDir, i))
141 net["r%s" % i].loadConf("ospfd", "%s/r%s/ospfd.conf" % (thisDir, i))
142 net["r%s" % i].loadConf("ldpd", "%s/r%s/ldpd.conf" % (thisDir, i))
143 tgen.gears["r%s" % i].start()
144
145 # For debugging after starting FRR daemons, uncomment the next line
146 # tgen.mininet_cli()
147
148
149 def teardown_module(module):
150 print("\n\n** %s: Shutdown Topology" % module.__name__)
151 print("******************************************\n")
152 tgen = get_topogen()
153 tgen.stop_topology()
154
155
156 def test_router_running():
157 global fatal_error
158 net = get_topogen().net
159
160 # Skip if previous fatal error condition is raised
161 if fatal_error != "":
162 pytest.skip(fatal_error)
163
164 print("\n\n** Check if FRR is running on each Router node")
165 print("******************************************\n")
166 sleep(5)
167
168 # Starting Routers
169 for i in range(1, 5):
170 fatal_error = net["r%s" % i].checkRouterRunning()
171 assert fatal_error == "", fatal_error
172
173
174 def test_mpls_interfaces():
175 global fatal_error
176 net = get_topogen().net
177
178 # Skip if previous fatal error condition is raised
179 if fatal_error != "":
180 pytest.skip(fatal_error)
181
182 thisDir = os.path.dirname(os.path.realpath(__file__))
183
184 # Verify MPLS Interfaces
185 print("\n\n** Verifying MPLS Interfaces")
186 print("******************************************\n")
187 failures = 0
188 for i in range(1, 5):
189 refTableFile = "%s/r%s/show_mpls_ldp_interface.ref"
190 if os.path.isfile(refTableFile):
191 # Read expected result from file
192 expected = open(refTableFile).read().rstrip()
193 # Fix newlines (make them all the same)
194 expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1)
195
196 # Actual output from router
197 actual = (
198 net["r%s" % i]
199 .cmd('vtysh -c "show mpls ldp interface" 2> /dev/null')
200 .rstrip()
201 )
202 # Mask out Timer in Uptime
203 actual = re.sub(r" [0-9][0-9]:[0-9][0-9]:[0-9][0-9] ", " xx:xx:xx ", actual)
204 # Fix newlines (make them all the same)
205 actual = ("\n".join(actual.splitlines()) + "\n").splitlines(1)
206
207 # Generate Diff
208 diff = topotest.get_textdiff(
209 actual,
210 expected,
211 title1="actual MPLS LDP interface status",
212 title2="expected MPLS LDP interface status",
213 )
214
215 # Empty string if it matches, otherwise diff contains unified diff
216 if diff:
217 sys.stderr.write(
218 "r%s failed MPLS LDP Interface status Check:\n%s\n" % (i, diff)
219 )
220 failures += 1
221 else:
222 print("r%s ok" % i)
223
224 if failures > 0:
225 fatal_error = "MPLS LDP Interface status failed"
226
227 assert (
228 failures == 0
229 ), "MPLS LDP Interface status failed for router r%s:\n%s" % (i, diff)
230
231 # Make sure that all daemons are running
232 for i in range(1, 5):
233 fatal_error = net["r%s" % i].checkRouterRunning()
234 assert fatal_error == "", fatal_error
235
236
237 def test_ospf_convergence():
238 logger.info("Test: check OSPF adjacencies")
239
240 # Skip if previous fatal error condition is raised
241 if fatal_error != "":
242 pytest.skip(fatal_error)
243
244 for rname in ["r1", "r2", "r3", "r4"]:
245 router_compare_json_output(
246 rname, "show ip ospf neighbor json", "show_ip_ospf_neighbor.json"
247 )
248
249
250 def test_mpls_ldp_neighbor_establish():
251 global fatal_error
252 net = get_topogen().net
253
254 # Skip if previous fatal error condition is raised
255 if fatal_error != "":
256 pytest.skip(fatal_error)
257
258 neighbors_operational = {
259 1: 1,
260 2: 3,
261 3: 2,
262 4: 2,
263 }
264
265 # Wait for MPLS LDP neighbors to establish.
266 print("\n\n** Verify MPLS LDP neighbors to establish")
267 print("******************************************\n")
268 timeout = 90
269 while timeout > 0:
270 print("Timeout in %s: " % timeout),
271 sys.stdout.flush()
272 # Look for any node not yet converged
273 for i in range(1, 5):
274 established = (
275 net["r%s" % i]
276 .cmd('vtysh -c "show mpls ldp neighbor" 2> /dev/null')
277 .rstrip()
278 )
279
280 # On current version, we need to make sure they all turn to OPERATIONAL on all lines
281 #
282 lines = ("\n".join(established.splitlines()) + "\n").splitlines(1)
283 # Check all lines to be either table header (starting with ^AF or show OPERATIONAL)
284 header = r"^AF.*"
285 operational = r"^ip.*OPERATIONAL.*"
286 found_operational = 0
287 for j in range(1, len(lines)):
288 if (not re.search(header, lines[j])) and (
289 not re.search(operational, lines[j])
290 ):
291 established = "" # Empty string shows NOT established
292 if re.search(operational, lines[j]):
293 found_operational += 1
294
295 logger.info("Found operational %d" % found_operational)
296 if found_operational < 1:
297 # Need at least one operational neighbor
298 established = "" # Empty string shows NOT established
299 else:
300 if found_operational != neighbors_operational[i]:
301 established = ""
302 if not established:
303 print("Waiting for r%s" % i)
304 sys.stdout.flush()
305 break
306 if not established:
307 sleep(5)
308 timeout -= 5
309 else:
310 print("Done")
311 break
312 else:
313 # Bail out with error if a router fails to converge
314 fatal_error = "MPLS LDP neighbors did not establish"
315 assert False, "MPLS LDP neighbors did not establish"
316
317 print("MPLS LDP neighbors established.")
318
319 if timeout < 60:
320 # Only wait if we actually went through a convergence
321 print("\nwaiting 15s for LDP sessions to establish")
322 sleep(15)
323
324 # Make sure that all daemons are running
325 for i in range(1, 5):
326 fatal_error = net["r%s" % i].checkRouterRunning()
327 assert fatal_error == "", fatal_error
328
329
330 def test_mpls_ldp_discovery():
331 global fatal_error
332 net = get_topogen().net
333
334 # Skip if previous fatal error condition is raised
335 if fatal_error != "":
336 pytest.skip(fatal_error)
337
338 thisDir = os.path.dirname(os.path.realpath(__file__))
339
340 # Verify MPLS LDP discovery
341 print("\n\n** Verifying MPLS LDP discovery")
342 print("******************************************\n")
343 failures = 0
344 for i in range(1, 5):
345 refTableFile = "%s/r%s/show_mpls_ldp_discovery.ref" % (thisDir, i)
346 if os.path.isfile(refTableFile):
347 # Actual output from router
348 actual = (
349 net["r%s" % i]
350 .cmd('vtysh -c "show mpls ldp discovery" 2> /dev/null')
351 .rstrip()
352 )
353
354 # Read expected result from file
355 expected = open(refTableFile).read().rstrip()
356 # Fix newlines (make them all the same)
357 expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1)
358
359 # Actual output from router
360 actual = (
361 net["r%s" % i]
362 .cmd('vtysh -c "show mpls ldp discovery" 2> /dev/null')
363 .rstrip()
364 )
365
366 # Fix newlines (make them all the same)
367 actual = ("\n".join(actual.splitlines()) + "\n").splitlines(1)
368
369 # Generate Diff
370 diff = topotest.get_textdiff(
371 actual,
372 expected,
373 title1="actual MPLS LDP discovery output",
374 title2="expected MPLS LDP discovery output",
375 )
376
377 # Empty string if it matches, otherwise diff contains unified diff
378 if diff:
379 sys.stderr.write(
380 "r%s failed MPLS LDP discovery output Check:\n%s\n" % (i, diff)
381 )
382 failures += 1
383 else:
384 print("r%s ok" % i)
385
386 assert (
387 failures == 0
388 ), "MPLS LDP Interface discovery output for router r%s:\n%s" % (i, diff)
389
390 # Make sure that all daemons are running
391 for i in range(1, 5):
392 fatal_error = net["r%s" % i].checkRouterRunning()
393 assert fatal_error == "", fatal_error
394
395
396 def test_mpls_ldp_neighbor():
397 global fatal_error
398 net = get_topogen().net
399
400 # Skip if previous fatal error condition is raised
401 if fatal_error != "":
402 pytest.skip(fatal_error)
403
404 thisDir = os.path.dirname(os.path.realpath(__file__))
405
406 # Verify MPLS LDP neighbor
407 print("\n\n** Verifying MPLS LDP neighbor")
408 print("******************************************\n")
409 failures = 0
410 for i in range(1, 5):
411 refTableFile = "%s/r%s/show_mpls_ldp_neighbor.ref" % (thisDir, i)
412 if os.path.isfile(refTableFile):
413 # Read expected result from file
414 expected = open(refTableFile).read().rstrip()
415 # Fix newlines (make them all the same)
416 expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1)
417
418 # Actual output from router
419 actual = (
420 net["r%s" % i]
421 .cmd('vtysh -c "show mpls ldp neighbor" 2> /dev/null')
422 .rstrip()
423 )
424
425 # Mask out changing parts in output
426 # Mask out Timer in Uptime
427 actual = re.sub(
428 r"(ipv4 [0-9\.]+ +OPERATIONAL [0-9\.]+ +)[0-9][0-9]:[0-9][0-9]:[0-9][0-9]",
429 r"\1xx:xx:xx",
430 actual,
431 )
432
433 # Fix newlines (make them all the same)
434 actual = ("\n".join(actual.splitlines()) + "\n").splitlines(1)
435
436 # Generate Diff
437 diff = topotest.get_textdiff(
438 actual,
439 expected,
440 title1="actual MPLS LDP neighbor output",
441 title2="expected MPLS LDP neighbor output",
442 )
443
444 # Empty string if it matches, otherwise diff contains unified diff
445 if diff:
446 sys.stderr.write(
447 "r%s failed MPLS LDP neighbor output Check:\n%s\n" % (i, diff)
448 )
449 failures += 1
450 else:
451 print("r%s ok" % i)
452
453 assert (
454 failures == 0
455 ), "MPLS LDP Interface neighbor output for router r%s:\n%s" % (i, diff)
456
457 # Make sure that all daemons are running
458 for i in range(1, 5):
459 fatal_error = net["r%s" % i].checkRouterRunning()
460 assert fatal_error == "", fatal_error
461
462
463 def test_mpls_ldp_binding():
464 global fatal_error
465 net = get_topogen().net
466
467 # Skip this test for now until proper sorting of the output
468 # is implemented
469 # pytest.skip("Skipping test_mpls_ldp_binding")
470
471 # Skip if previous fatal error condition is raised
472 if fatal_error != "":
473 pytest.skip(fatal_error)
474
475 thisDir = os.path.dirname(os.path.realpath(__file__))
476
477 # Verify MPLS LDP binding
478 print("\n\n** Verifying MPLS LDP binding")
479 print("******************************************\n")
480 failures = 0
481 for i in range(1, 5):
482 refTableFile = "%s/r%s/show_mpls_ldp_binding.ref" % (thisDir, i)
483 if os.path.isfile(refTableFile):
484 # Read expected result from file
485 expected = open(refTableFile).read().rstrip()
486 # Fix newlines (make them all the same)
487 expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1)
488
489 # Actual output from router
490 actual = (
491 net["r%s" % i]
492 .cmd('vtysh -c "show mpls ldp binding" 2> /dev/null')
493 .rstrip()
494 )
495
496 # Mask out changing parts in output
497 # Mask out label
498 actual = re.sub(
499 r"(ipv4 [0-9\./]+ +[0-9\.]+ +)[0-9][0-9] (.*)", r"\1xxx\2", actual
500 )
501 actual = re.sub(
502 r"(ipv4 [0-9\./]+ +[0-9\.]+ +[a-z\-]+ +)[0-9][0-9] (.*)",
503 r"\1xxx\2",
504 actual,
505 )
506
507 # Fix newlines (make them all the same)
508 actual = ("\n".join(actual.splitlines()) + "\n").splitlines(1)
509
510 # Sort lines which start with "xx via inet "
511 pattern = r"^\s+[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+\s+"
512 swapped = True
513 while swapped:
514 swapped = False
515 for j in range(1, len(actual)):
516 if re.search(pattern, actual[j]) and re.search(
517 pattern, actual[j - 1]
518 ):
519 if actual[j - 1] > actual[j]:
520 temp = actual[j - 1]
521 actual[j - 1] = actual[j]
522 actual[j] = temp
523 swapped = True
524
525 # Generate Diff
526 diff = topotest.get_textdiff(
527 actual,
528 expected,
529 title1="actual MPLS LDP binding output",
530 title2="expected MPLS LDP binding output",
531 )
532
533 # Empty string if it matches, otherwise diff contains unified diff
534 if diff:
535 sys.stderr.write(
536 "r%s failed MPLS LDP binding output Check:\n%s\n" % (i, diff)
537 )
538 failures += 1
539 else:
540 print("r%s ok" % i)
541
542 assert failures == 0, "MPLS LDP binding output for router r%s:\n%s" % (
543 i,
544 diff,
545 )
546
547 # Make sure that all daemons are running
548 for i in range(1, 5):
549 fatal_error = net["r%s" % i].checkRouterRunning()
550 assert fatal_error == "", fatal_error
551
552
553 def test_zebra_ipv4_routingTable():
554 global fatal_error
555 net = get_topogen().net
556
557 # Skip if previous fatal error condition is raised
558 if fatal_error != "":
559 pytest.skip(fatal_error)
560
561 thisDir = os.path.dirname(os.path.realpath(__file__))
562
563 # Verify Zebra IPv4 Routing Table
564 print("\n\n** Verifying Zebra IPv4 Routing Table")
565 print("******************************************\n")
566 failures = 0
567 for i in range(1, 5):
568 refTableFile = "%s/r%s/show_ipv4_route.ref" % (thisDir, i)
569 if os.path.isfile(refTableFile):
570 # Read expected result from file
571 expected = open(refTableFile).read().rstrip()
572
573 # Actual output from router
574 actual = (
575 net["r%s" % i]
576 .cmd('vtysh -c "show ip route" 2> /dev/null | grep "^O"')
577 .rstrip()
578 )
579 # Drop timers on end of line
580 actual = re.sub(r", [0-2][0-9]:[0-5][0-9]:[0-5][0-9]", "", actual)
581
582 # Mask out label - all LDP labels should be >= 10 (2-digit)
583 # leaving the implicit labels unmasked
584 actual = re.sub(r" label [0-9][0-9]+", " label xxx", actual)
585 # and translating remaining implicit (single-digit) labels to label implicit-null
586 actual = re.sub(r" label [0-9]+", " label implicit-null", actual)
587 # Check if we have implicit labels - if not, then remove them from reference
588 if not re.search(r" label implicit-null", actual):
589 expected = re.sub(r", label implicit-null", "", expected)
590
591 # now fix newlines of expected (make them all the same)
592 expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1)
593
594 # Fix newlines (make them all the same)
595 actual = ("\n".join(actual.splitlines()) + "\n").splitlines(1)
596
597 # Generate Diff
598 diff = topotest.get_textdiff(
599 actual,
600 expected,
601 title1="actual IPv4 zebra routing table",
602 title2="expected IPv4 zebra routing table",
603 )
604
605 # Empty string if it matches, otherwise diff contains unified diff
606 if diff:
607 sys.stderr.write(
608 "r%s failed IPv4 Zebra Routing Table Check:\n%s\n" % (i, diff)
609 )
610 failures += 1
611 else:
612 print("r%s ok" % i)
613
614 assert (
615 failures == 0
616 ), "IPv4 Zebra Routing Table verification failed for router r%s:\n%s" % (
617 i,
618 diff,
619 )
620
621 # Make sure that all daemons are running
622 for i in range(1, 5):
623 fatal_error = net["r%s" % i].checkRouterRunning()
624 assert fatal_error == "", fatal_error
625
626
627 def test_mpls_table():
628 global fatal_error
629 net = get_topogen().net
630
631 # Skip if previous fatal error condition is raised
632 if fatal_error != "":
633 pytest.skip(fatal_error)
634
635 thisDir = os.path.dirname(os.path.realpath(__file__))
636
637 # Verify MPLS table
638 print("\n\n** Verifying MPLS table")
639 print("******************************************\n")
640 failures = 0
641
642 for i in range(1, 5):
643 refTableFile = "%s/r%s/show_mpls_table.ref" % (thisDir, i)
644 if os.path.isfile(refTableFile):
645 # Read expected result from file
646 expected = open(refTableFile).read()
647 # Fix newlines (make them all the same)
648 expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1)
649
650 # Actual output from router
651 actual = net["r%s" % i].cmd('vtysh -c "show mpls table" 2> /dev/null')
652
653 # Fix inconsistent Label numbers at beginning of line
654 actual = re.sub(r"(\s+)[0-9]+(\s+LDP)", r"\1XX\2", actual)
655 # Fix inconsistent Label numbers at end of line
656 actual = re.sub(
657 r"(\s+[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+\s+)[0-9][0-9]", r"\1XX", actual
658 )
659
660 # Fix newlines (make them all the same)
661 actual = ("\n".join(actual.splitlines()) + "\n").splitlines(1)
662
663 # Sort lines which start with " XX LDP"
664 pattern = r"^\s+[0-9X]+\s+LDP"
665 swapped = True
666 while swapped:
667 swapped = False
668 for j in range(1, len(actual)):
669 if re.search(pattern, actual[j]) and re.search(
670 pattern, actual[j - 1]
671 ):
672 if actual[j - 1] > actual[j]:
673 temp = actual[j - 1]
674 actual[j - 1] = actual[j]
675 actual[j] = temp
676 swapped = True
677
678 # Generate Diff
679 diff = topotest.get_textdiff(
680 actual,
681 expected,
682 title1="actual MPLS table output",
683 title2="expected MPLS table output",
684 )
685
686 # Empty string if it matches, otherwise diff contains unified diff
687 if diff:
688 sys.stderr.write(
689 "r%s failed MPLS table output Check:\n%s\n" % (i, diff)
690 )
691 failures += 1
692 else:
693 print("r%s ok" % i)
694
695 assert failures == 0, "MPLS table output for router r%s:\n%s" % (i, diff)
696
697 # Make sure that all daemons are running
698 for i in range(1, 5):
699 fatal_error = net["r%s" % i].checkRouterRunning()
700 assert fatal_error == "", fatal_error
701
702
703 def test_linux_mpls_routes():
704 global fatal_error
705 net = get_topogen().net
706
707 # Skip if previous fatal error condition is raised
708 if fatal_error != "":
709 pytest.skip(fatal_error)
710
711 thisDir = os.path.dirname(os.path.realpath(__file__))
712
713 # Verify Linux Kernel MPLS routes
714 print("\n\n** Verifying Linux Kernel MPLS routes")
715 print("******************************************\n")
716 failures = 0
717 for i in range(1, 5):
718 refTableFile = "%s/r%s/ip_mpls_route.ref" % (thisDir, i)
719 if os.path.isfile(refTableFile):
720 # Read expected result from file
721 expected = open(refTableFile).read().rstrip()
722 # Fix newlines (make them all the same)
723 expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1)
724
725 # Actual output from router
726 actual = (
727 net["r%s" % i].cmd("ip -o -family mpls route 2> /dev/null").rstrip()
728 )
729
730 # Mask out label and protocol
731 actual = re.sub(r"[0-9][0-9] via inet ", "xx via inet ", actual)
732 actual = re.sub(r"[0-9][0-9] +proto", "xx proto", actual)
733 actual = re.sub(r"[0-9][0-9] as to ", "xx as to ", actual)
734 actual = re.sub(r"[ ]+proto \w+", " proto xx", actual)
735
736 # Sort nexthops
737 nexthop_sorted = []
738 for line in actual.splitlines():
739 tokens = re.split(r"\\\t", line.strip())
740 nexthop_sorted.append(
741 "{} {}".format(
742 tokens[0].strip(),
743 " ".join([token.strip() for token in sorted(tokens[1:])]),
744 ).strip()
745 )
746
747 # Sort lines and fixup differences between old and new iproute
748 actual = "\n".join(sorted(nexthop_sorted))
749 actual = re.sub(r"nexthop via", "nexthopvia", actual)
750 actual = re.sub(r" nexthop as to xx via inet ", " nexthopvia inet ", actual)
751 actual = re.sub(r" weight 1", "", actual)
752 actual = re.sub(r" [ ]+", " ", actual)
753
754 # put \n back at line ends
755 actual = ("\n".join(actual.splitlines()) + "\n").splitlines(1)
756
757 # Generate Diff
758 diff = topotest.get_textdiff(
759 actual,
760 expected,
761 title1="actual Linux Kernel MPLS route",
762 title2="expected Linux Kernel MPLS route",
763 )
764
765 # Empty string if it matches, otherwise diff contains unified diff
766 if diff:
767 sys.stderr.write(
768 "r%s failed Linux Kernel MPLS route output Check:\n%s\n" % (i, diff)
769 )
770 failures += 1
771 else:
772 print("r%s ok" % i)
773
774 assert (
775 failures == 0
776 ), "Linux Kernel MPLS route output for router r%s:\n%s" % (i, diff)
777
778 # Make sure that all daemons are running
779 for i in range(1, 5):
780 fatal_error = net["r%s" % i].checkRouterRunning()
781 assert fatal_error == "", fatal_error
782
783
784 def test_shutdown_check_stderr():
785 global fatal_error
786 net = get_topogen().net
787
788 # Skip if previous fatal error condition is raised
789 if fatal_error != "":
790 pytest.skip(fatal_error)
791
792 if os.environ.get("TOPOTESTS_CHECK_STDERR") is None:
793 print(
794 "SKIPPED final check on StdErr output: Disabled (TOPOTESTS_CHECK_STDERR undefined)\n"
795 )
796 pytest.skip("Skipping test for Stderr output")
797
798 thisDir = os.path.dirname(os.path.realpath(__file__))
799
800 print("\n\n** Verifying unexpected STDERR output from daemons")
801 print("******************************************\n")
802
803 for i in range(1, 5):
804 net["r%s" % i].stopRouter()
805 log = net["r%s" % i].getStdErr("ldpd")
806 if log:
807 print("\nRouter r%s LDPd StdErr Log:\n%s" % (i, log))
808 log = net["r%s" % i].getStdErr("ospfd")
809 if log:
810 print("\nRouter r%s OSPFd StdErr Log:\n%s" % (i, log))
811 log = net["r%s" % i].getStdErr("zebra")
812 if log:
813 print("\nRouter r%s Zebra StdErr Log:\n%s" % (i, log))
814
815
816 def test_shutdown_check_memleak():
817 global fatal_error
818 net = get_topogen().net
819
820 # Skip if previous fatal error condition is raised
821 if fatal_error != "":
822 pytest.skip(fatal_error)
823
824 if os.environ.get("TOPOTESTS_CHECK_MEMLEAK") is None:
825 print(
826 "SKIPPED final check on Memory leaks: Disabled (TOPOTESTS_CHECK_MEMLEAK undefined)\n"
827 )
828 pytest.skip("Skipping test for memory leaks")
829
830 thisDir = os.path.dirname(os.path.realpath(__file__))
831
832 for i in range(1, 5):
833 net["r%s" % i].stopRouter()
834 net["r%s" % i].report_memory_leaks(
835 os.environ.get("TOPOTESTS_CHECK_MEMLEAK"), os.path.basename(__file__)
836 )
837
838
839 if __name__ == "__main__":
840
841 # To suppress tracebacks, either use the following pytest call or add "--tb=no" to cli
842 # retval = pytest.main(["-s", "--tb=no"])
843 retval = pytest.main(["-s"])
844 sys.exit(retval)