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