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