]>
git.proxmox.com Git - mirror_frr.git/blob - tests/topotests/ldp-topo1/test_ldp_topo1.py
4 # test_bgp_multiview_topo1.py
5 # Part of NetDEF Topology Tests
7 # Copyright (c) 2016 by
8 # Network Device Education Foundation, Inc. ("NetDEF")
10 # Permission to use, copy, modify, and/or distribute this software
11 # for any purpose with or without fee is hereby granted, provided
12 # that the above copyright notice and this permission notice appear
15 # THE SOFTWARE IS PROVIDED "AS IS" AND NETDEF DISCLAIMS ALL WARRANTIES
16 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
17 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF BE LIABLE FOR
18 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
19 # DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
20 # WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
21 # ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
26 test_ldp_topo1.py: Simple FRR/Quagga LDP Test
45 r2-eth2 .2 | | .2 r2-eth1
48 ~~~~~~~~~~~~~ ~~~~~~~~~~~~~
50 ~~ 10.0.3.0/24 ~~ ~~ 10.0.2.0/24 ~~
51 ~~~~~~~~~~~~~ ~~~~~~~~~~~~~
55 r3-eth1 .3 | | .3 r3-eth0 | .4 r4-eth0
56 +----+--+---+ +----+----+
58 | 3.3.3.3 | | 4.4.4.4 |
59 +-----------+ +---------+
66 from time
import sleep
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
75 sys
.path
.append(os
.path
.dirname(os
.path
.dirname(os
.path
.abspath(__file__
))))
76 from lib
import topotest
80 # Expected version of CLI Output - Appendix to filename
81 # empty string = current, latest output (default)
82 # "-1" ... "-NNN" previous versions (incrementing with each version)
86 #####################################################
88 ## Network Topology Definition
90 #####################################################
92 class NetworkTopo(Topo
):
95 def build(self
, **_opts
):
100 router
[i
] = topotest
.addRouter(self
, 'r%s' % i
)
102 # Setup Switches, add Interfaces and Connections
105 switch
[0] = self
.addSwitch('sw0', cls
=topotest
.LegacySwitch
)
106 self
.addLink(switch
[0], router
[1], intfName2
='r1-eth0', addr1
='80:AA:00:00:00:00', addr2
='00:11:00:01:00:00')
107 self
.addLink(switch
[0], router
[2], intfName2
='r2-eth0', addr1
='80:AA:00:00:00:01', addr2
='00:11:00:02:00:00')
109 switch
[1] = self
.addSwitch('sw1', cls
=topotest
.LegacySwitch
)
110 self
.addLink(switch
[1], router
[2], intfName2
='r2-eth1', addr1
='80:AA:00:01:00:00', addr2
='00:11:00:02:00:01')
111 self
.addLink(switch
[1], router
[3], intfName2
='r3-eth0', addr1
='80:AA:00:01:00:01', addr2
='00:11:00:03:00:00')
112 self
.addLink(switch
[1], router
[4], intfName2
='r4-eth0', addr1
='80:AA:00:01:00:02', addr2
='00:11:00:04:00:00')
114 switch
[2] = self
.addSwitch('sw2', cls
=topotest
.LegacySwitch
)
115 self
.addLink(switch
[2], router
[2], intfName2
='r2-eth2', addr1
='80:AA:00:02:00:00', addr2
='00:11:00:02:00:02')
116 self
.addLink(switch
[2], router
[3], intfName2
='r3-eth1', addr1
='80:AA:00:02:00:01', addr2
='00:11:00:03:00:01')
119 #####################################################
123 #####################################################
125 def setup_module(module
):
129 print("\n\n** %s: Setup Topology" % module
.__name
__)
130 print("******************************************\n")
132 print("Cleanup old Mininet runs")
133 os
.system('sudo mn -c > /dev/null 2>&1')
135 thisDir
= os
.path
.dirname(os
.path
.realpath(__file__
))
138 net
= Mininet(controller
=None, topo
=topo
)
142 for i
in range(1, 5):
143 net
['r%s' % i
].loadConf('zebra', '%s/r%s/zebra.conf' % (thisDir
, i
))
144 net
['r%s' % i
].loadConf('ospfd', '%s/r%s/ospfd.conf' % (thisDir
, i
))
145 net
['r%s' % i
].loadConf('ldpd', '%s/r%s/ldpd.conf' % (thisDir
, i
))
146 fatal_error
= net
['r%s' % i
].startRouter()
148 if fatal_error
!= "":
151 # For debugging after starting FRR/Quagga daemons, uncomment the next line
154 def teardown_module(module
):
157 print("\n\n** %s: Shutdown Topology" % module
.__name
__)
158 print("******************************************\n")
160 # End - Shutdown network
164 def test_router_running():
169 # Skip if previous fatal error condition is raised
170 if (fatal_error
!= ""):
171 pytest
.skip(fatal_error
)
173 print("\n\n** Check if FRR/Quagga is running on each Router node")
174 print("******************************************\n")
178 for i
in range(1, 5):
179 fatal_error
= net
['r%s' % i
].checkRouterRunning()
180 assert fatal_error
== "", fatal_error
183 # At this time, there are only 2 possible outputs, so simple check
184 output
= net
['r1'].cmd('vtysh -c "show mpls ldp discovery" 2> /dev/null').rstrip()
186 # Check if old or new format of CLI Output. Default is to current format
188 # Old (v1) output looks like this:
189 # Local LDP Identifier: 1.1.1.1:0
193 # LDP Id: 2.2.2.2:0, Transport address: 2.2.2.2
197 # Current (v0) output looks like this:
198 # AF ID Type Source Holdtime
199 # ipv4 2.2.2.2 Link r1-eth0 15
200 pattern
= re
.compile("^Local LDP Identifier.*")
201 if pattern
.match(output
):
204 # For debugging after starting FRR/Quagga daemons, uncomment the next line
207 def test_mpls_interfaces():
212 # Skip if previous fatal error condition is raised
213 if (fatal_error
!= ""):
214 pytest
.skip(fatal_error
)
216 thisDir
= os
.path
.dirname(os
.path
.realpath(__file__
))
218 # Verify OSPFv3 Routing Table
219 print("\n\n** Verifying MPLS Interfaces")
220 print("******************************************\n")
222 for i
in range(1, 5):
223 refTableFile
= '%s/r%s/show_mpls_ldp_interface.ref%s' % (thisDir
, i
, cli_version
)
224 if os
.path
.isfile(refTableFile
):
225 # Read expected result from file
226 expected
= open(refTableFile
).read().rstrip()
227 # Fix newlines (make them all the same)
228 expected
= ('\n'.join(expected
.splitlines()) + '\n').splitlines(1)
230 # Actual output from router
231 actual
= net
['r%s' % i
].cmd('vtysh -c "show mpls ldp interface" 2> /dev/null').rstrip()
232 # Mask out Timer in Uptime
233 actual
= re
.sub(r
" [0-9][0-9]:[0-9][0-9]:[0-9][0-9] ", " xx:xx:xx ", actual
)
234 # Fix newlines (make them all the same)
235 actual
= ('\n'.join(actual
.splitlines()) + '\n').splitlines(1)
238 diff
= topotest
.get_textdiff(actual
, expected
,
239 title1
="actual MPLS LDP interface status",
240 title2
="expected MPLS LDP interface status")
242 # Empty string if it matches, otherwise diff contains unified diff
244 sys
.stderr
.write('r%s failed MPLS LDP Interface status Check:\n%s\n' % (i
, diff
))
250 fatal_error
= "MPLS LDP Interface status failed"
252 assert failures
== 0, "MPLS LDP Interface status failed for router r%s:\n%s" % (i
, diff
)
254 # Make sure that all daemons are running
255 for i
in range(1, 5):
256 fatal_error
= net
['r%s' % i
].checkRouterRunning()
257 assert fatal_error
== "", fatal_error
259 # For debugging after starting FRR/Quagga daemons, uncomment the next line
263 def test_mpls_ldp_neighbor_establish():
268 # Skip if previous fatal error condition is raised
269 if (fatal_error
!= ""):
270 pytest
.skip(fatal_error
)
272 # Wait for OSPF6 to converge (All Neighbors in either Full or TwoWay State)
273 print("\n\n** Verify MPLS LDP neighbors to establish")
274 print("******************************************\n")
277 print("Timeout in %s: " % timeout
),
279 # Look for any node not yet converged
280 for i
in range(1, 5):
281 established
= net
['r%s' % i
].cmd('vtysh -c "show mpls ldp neighbor" 2> /dev/null').rstrip()
282 if cli_version
!= "-1":
283 # On current version, we need to make sure they all turn to OPERATIONAL on all lines
285 lines
= ('\n'.join(established
.splitlines()) + '\n').splitlines(1)
286 # Check all lines to be either table header (starting with ^AF or show OPERATIONAL)
288 operational
= r
'^ip.*OPERATIONAL.*'
289 found_operational
= 0
290 for j
in range(1, len(lines
)):
291 if (not re
.search(header
, lines
[j
])) and (not re
.search(operational
, lines
[j
])):
292 established
= "" # Empty string shows NOT established
293 if re
.search(operational
, lines
[j
]):
294 found_operational
+= 1
295 if found_operational
< 1:
296 # Need at least one operational neighbor
297 established
= "" # Empty string shows NOT established
299 print('Waiting for r%s' %i)
309 # Bail out with error if a router fails to converge
310 fatal_error
= "MPLS LDP neighbors did not establish"
311 assert False, "MPLS LDP neighbors did not establish" % ospfStatus
313 print("MPLS LDP neighbors established.")
316 # Only wait if we actually went through a convergence
317 print("\nwaiting 15s for LDP sessions to establish")
320 # Make sure that all daemons are running
321 for i
in range(1, 5):
322 fatal_error
= net
['r%s' % i
].checkRouterRunning()
323 assert fatal_error
== "", fatal_error
326 def test_mpls_ldp_discovery():
331 # Skip if previous fatal error condition is raised
332 if (fatal_error
!= ""):
333 pytest
.skip(fatal_error
)
335 thisDir
= os
.path
.dirname(os
.path
.realpath(__file__
))
337 # Verify OSPFv3 Routing Table
338 print("\n\n** Verifying MPLS LDP discovery")
339 print("******************************************\n")
341 for i
in range(1, 5):
342 refTableFile
= '%s/r%s/show_mpls_ldp_discovery.ref%s' % (thisDir
, i
, cli_version
)
343 if os
.path
.isfile(refTableFile
):
344 # Actual output from router
345 actual
= net
['r%s' % i
].cmd('vtysh -c "show mpls ldp discovery" 2> /dev/null').rstrip()
347 # Read expected result from file
348 expected
= open(refTableFile
).read().rstrip()
349 # Fix newlines (make them all the same)
350 expected
= ('\n'.join(expected
.splitlines()) + '\n').splitlines(1)
352 # Actual output from router
353 actual
= net
['r%s' % i
].cmd('vtysh -c "show mpls ldp discovery" 2> /dev/null').rstrip()
355 # Fix newlines (make them all the same)
356 actual
= ('\n'.join(actual
.splitlines()) + '\n').splitlines(1)
359 diff
= topotest
.get_textdiff(actual
, expected
,
360 title1
="actual MPLS LDP discovery output",
361 title2
="expected MPLS LDP discovery output")
363 # Empty string if it matches, otherwise diff contains unified diff
365 sys
.stderr
.write('r%s failed MPLS LDP discovery output Check:\n%s\n' % (i
, diff
))
370 assert failures
== 0, "MPLS LDP Interface discovery output for router r%s:\n%s" % (i
, diff
)
372 # Make sure that all daemons are running
373 for i
in range(1, 5):
374 fatal_error
= net
['r%s' % i
].checkRouterRunning()
375 assert fatal_error
== "", fatal_error
377 # For debugging after starting FRR/Quagga daemons, uncomment the next line
381 def test_mpls_ldp_neighbor():
386 # Skip if previous fatal error condition is raised
387 if (fatal_error
!= ""):
388 pytest
.skip(fatal_error
)
390 thisDir
= os
.path
.dirname(os
.path
.realpath(__file__
))
392 # Verify OSPFv3 Routing Table
393 print("\n\n** Verifying MPLS LDP neighbor")
394 print("******************************************\n")
396 for i
in range(1, 5):
397 refTableFile
= '%s/r%s/show_mpls_ldp_neighbor.ref%s' % (thisDir
, i
, cli_version
)
398 if os
.path
.isfile(refTableFile
):
399 # Read expected result from file
400 expected
= open(refTableFile
).read().rstrip()
401 # Fix newlines (make them all the same)
402 expected
= ('\n'.join(expected
.splitlines()) + '\n').splitlines(1)
404 # Actual output from router
405 actual
= net
['r%s' % i
].cmd('vtysh -c "show mpls ldp neighbor" 2> /dev/null').rstrip()
407 # Mask out changing parts in output
408 if cli_version
== "-1":
409 # Mask out Timer in Uptime
410 actual
= re
.sub(r
"Up time: [0-9][0-9]:[0-9][0-9]:[0-9][0-9]", "Up time: xx:xx:xx", actual
)
411 # Mask out Port numbers in TCP connection
412 actual
= re
.sub(r
"TCP connection: ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]):[0-9]+ - ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]):[0-9]+",
413 r
"TCP connection: \1:xxx - \2:xxx", actual
)
417 # Mask out Timer in Uptime
418 actual
= re
.sub(r
"(ipv4 [0-9\.]+ +OPERATIONAL [0-9\.]+ +)[0-9][0-9]:[0-9][0-9]:[0-9][0-9]", r
"\1xx:xx:xx", actual
)
420 # Fix newlines (make them all the same)
421 actual
= ('\n'.join(actual
.splitlines()) + '\n').splitlines(1)
424 diff
= topotest
.get_textdiff(actual
, expected
,
425 title1
="actual MPLS LDP neighbor output",
426 title2
="expected MPLS LDP neighbor output")
428 # Empty string if it matches, otherwise diff contains unified diff
430 sys
.stderr
.write('r%s failed MPLS LDP neighbor output Check:\n%s\n' % (i
, diff
))
435 assert failures
== 0, "MPLS LDP Interface neighbor output for router r%s:\n%s" % (i
, diff
)
437 # Make sure that all daemons are running
438 for i
in range(1, 5):
439 fatal_error
= net
['r%s' % i
].checkRouterRunning()
440 assert fatal_error
== "", fatal_error
442 # For debugging after starting FRR/Quagga daemons, uncomment the next line
446 def test_mpls_ldp_binding():
451 # Skip this test for now until proper sorting of the output
453 # pytest.skip("Skipping test_mpls_ldp_binding")
455 # Skip if previous fatal error condition is raised
456 if (fatal_error
!= ""):
457 pytest
.skip(fatal_error
)
459 thisDir
= os
.path
.dirname(os
.path
.realpath(__file__
))
461 # Verify OSPFv3 Routing Table
462 print("\n\n** Verifying MPLS LDP binding")
463 print("******************************************\n")
465 for i
in range(1, 5):
466 refTableFile
= '%s/r%s/show_mpls_ldp_binding.ref%s' % (thisDir
, i
, cli_version
)
467 if os
.path
.isfile(refTableFile
):
468 # Read expected result from file
469 expected
= open(refTableFile
).read().rstrip()
470 # Fix newlines (make them all the same)
471 expected
= ('\n'.join(expected
.splitlines()) + '\n').splitlines(1)
473 # Actual output from router
474 actual
= net
['r%s' % i
].cmd('vtysh -c "show mpls ldp binding" 2> /dev/null').rstrip()
476 # Mask out changing parts in output
477 if cli_version
== "-1":
479 actual
= re
.sub(r
"label: [0-9]+", "label: xxx", actual
)
480 actual
= re
.sub(r
"(\s+[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+[ ]+)[0-9]+", r
"\1xxx", actual
)
485 actual
= re
.sub(r
"(ipv4 [0-9\./]+ +[0-9\.]+ +)[0-9][0-9] (.*)", r
"\1xxx\2", actual
)
486 actual
= re
.sub(r
"(ipv4 [0-9\./]+ +[0-9\.]+ +[a-z\-]+ +)[0-9][0-9] (.*)", r
"\1xxx\2", actual
)
488 # Fix newlines (make them all the same)
489 actual
= ('\n'.join(actual
.splitlines()) + '\n').splitlines(1)
491 # Sort lines which start with "xx via inet "
492 pattern
= r
'^\s+[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+\s+'
496 for j
in range(1, len(actual
)):
497 if re
.search(pattern
, actual
[j
]) and re
.search(pattern
, actual
[j
-1]):
498 if actual
[j
-1] > actual
[j
]:
500 actual
[j
-1] = actual
[j
]
505 diff
= topotest
.get_textdiff(actual
, expected
,
506 title1
="actual MPLS LDP binding output",
507 title2
="expected MPLS LDP binding output")
509 # Empty string if it matches, otherwise diff contains unified diff
511 sys
.stderr
.write('r%s failed MPLS LDP binding output Check:\n%s\n' % (i
, diff
))
516 assert failures
== 0, "MPLS LDP Interface binding output for router r%s:\n%s" % (i
, diff
)
518 # Make sure that all daemons are running
519 for i
in range(1, 5):
520 fatal_error
= net
['r%s' % i
].checkRouterRunning()
521 assert fatal_error
== "", fatal_error
523 # For debugging after starting FRR/Quagga daemons, uncomment the next line
527 def test_zebra_ipv4_routingTable():
532 # Skip if previous fatal error condition is raised
533 if (fatal_error
!= ""):
534 pytest
.skip(fatal_error
)
536 thisDir
= os
.path
.dirname(os
.path
.realpath(__file__
))
538 # Verify OSPFv3 Routing Table
539 print("\n\n** Verifying Zebra IPv4 Routing Table")
540 print("******************************************\n")
542 for i
in range(1, 5):
543 refTableFile
= '%s/r%s/show_ipv4_route.ref%s' % (thisDir
, i
, cli_version
)
544 if os
.path
.isfile(refTableFile
):
545 # Read expected result from file
546 expected
= open(refTableFile
).read().rstrip()
548 # Actual output from router
549 actual
= net
['r%s' % i
].cmd('vtysh -c "show ip route" 2> /dev/null | grep "^O"').rstrip()
550 # Drop timers on end of line (older Quagga Versions)
551 actual
= re
.sub(r
", [0-2][0-9]:[0-5][0-9]:[0-5][0-9]", "", actual
)
553 # Mask out label - all LDP labels should be >= 10 (2-digit)
554 # leaving the implicit labels unmasked
555 actual
= re
.sub(r
" label [0-9][0-9]+", " label xxx", actual
)
556 # and translating remaining implicit (single-digit) labels to label y
557 actual
= re
.sub(r
" label [0-9]+", " label y", actual
)
558 # Check if we have implicit labels - if not, then remove them from reference
559 if (not re
.search(r
" label y", actual
)):
560 expected
= re
.sub(r
", label y", "", expected
)
562 # now fix newlines of expected (make them all the same)
563 expected
= ('\n'.join(expected
.splitlines()) + '\n').splitlines(1)
565 # Add missing comma before label (for old version)
566 actual
= re
.sub(r
"([0-9]) label ", r
"\1, label ", actual
)
568 # Fix newlines (make them all the same)
569 actual
= ('\n'.join(actual
.splitlines()) + '\n').splitlines(1)
572 diff
= topotest
.get_textdiff(actual
, expected
,
573 title1
="actual IPv4 zebra routing table",
574 title2
="expected IPv4 zebra routing table")
576 # Empty string if it matches, otherwise diff contains unified diff
578 sys
.stderr
.write('r%s failed IPv4 Zebra Routing Table Check:\n%s\n' % (i
, diff
))
583 assert failures
== 0, "IPv4 Zebra Routing Table verification failed for router r%s:\n%s" % (i
, diff
)
585 # Make sure that all daemons are running
586 for i
in range(1, 5):
587 fatal_error
= net
['r%s' % i
].checkRouterRunning()
588 assert fatal_error
== "", fatal_error
590 # For debugging after starting FRR/Quagga daemons, uncomment the next line
594 def test_mpls_table():
599 # Skip if previous fatal error condition is raised
600 if (fatal_error
!= ""):
601 pytest
.skip(fatal_error
)
603 thisDir
= os
.path
.dirname(os
.path
.realpath(__file__
))
605 # Verify OSPFv3 Routing Table
606 print("\n\n** Verifying MPLS table")
607 print("******************************************\n")
609 for i
in range(1, 5):
610 refTableFile
= '%s/r%s/show_mpls_table.ref%s' % (thisDir
, i
, cli_version
)
611 if os
.path
.isfile(refTableFile
):
612 # Read expected result from file
613 expected
= open(refTableFile
).read().rstrip()
614 # Fix newlines (make them all the same)
615 expected
= ('\n'.join(expected
.splitlines()) + '\n').splitlines(1)
617 # Actual output from router
618 actual
= net
['r%s' % i
].cmd('vtysh -c "show mpls table" 2> /dev/null').rstrip()
620 # Fix inconsistent Label numbers at beginning of line
621 actual
= re
.sub(r
"(\s+)[0-9]+(\s+LDP)", r
"\1XX\2", actual
)
622 # Fix inconsistent Label numbers at end of line
623 actual
= re
.sub(r
"(\s+[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+\s+)[0-9][0-9]", r
"\1XX", actual
)
625 # Fix newlines (make them all the same)
626 actual
= ('\n'.join(actual
.splitlines()) + '\n').splitlines(1)
628 # Sort lines which start with " XX LDP"
629 pattern
= r
'^\s+[0-9X]+\s+LDP'
633 for j
in range(1, len(actual
)):
634 if re
.search(pattern
, actual
[j
]) and re
.search(pattern
, actual
[j
-1]):
635 if actual
[j
-1] > actual
[j
]:
637 actual
[j
-1] = actual
[j
]
642 diff
= topotest
.get_textdiff(actual
, expected
,
643 title1
="actual MPLS table output",
644 title2
="expected MPLS table output")
646 # Empty string if it matches, otherwise diff contains unified diff
648 sys
.stderr
.write('r%s failed MPLS table output Check:\n%s\n' % (i
, diff
))
653 assert failures
== 0, "MPLS table output for router r%s:\n%s" % (i
, diff
)
655 # Make sure that all daemons are running
656 for i
in range(1, 5):
657 fatal_error
= net
['r%s' % i
].checkRouterRunning()
658 assert fatal_error
== "", fatal_error
660 # For debugging after starting FRR/Quagga daemons, uncomment the next line
664 def test_linux_mpls_routes():
669 # Skip if previous fatal error condition is raised
670 if (fatal_error
!= ""):
671 pytest
.skip(fatal_error
)
673 thisDir
= os
.path
.dirname(os
.path
.realpath(__file__
))
675 # Verify OSPFv3 Routing Table
676 print("\n\n** Verifying Linux Kernel MPLS routes")
677 print("******************************************\n")
679 for i
in range(1, 5):
680 refTableFile
= '%s/r%s/ip_mpls_route.ref%s' % (thisDir
, i
, cli_version
)
681 if os
.path
.isfile(refTableFile
):
682 # Read expected result from file
683 expected
= open(refTableFile
).read().rstrip()
684 # Fix newlines (make them all the same)
685 expected
= ('\n'.join(expected
.splitlines()) + '\n').splitlines(1)
687 # Actual output from router
688 actual
= net
['r%s' % i
].cmd('ip -family mpls route 2> /dev/null').rstrip()
690 actual
= re
.sub(r
"[0-9][0-9] via inet ", "xx via inet ", actual
)
691 actual
= re
.sub(r
"[0-9][0-9] proto zebra", "xx proto zebra", actual
)
692 actual
= re
.sub(r
"[0-9][0-9] as to ", "xx as to ", actual
)
693 actual
= re
.sub(r
"proto zebra ", "proto zebra", actual
)
695 # Fix newlines (make them all the same)
696 actual
= ('\n'.join(actual
.splitlines()) + '\n').splitlines(1)
698 # Sort lines which start with "xx via inet "
699 pattern
= r
'^xx via inet '
703 for j
in range(1, len(actual
)):
704 if re
.search(pattern
, actual
[j
]) and re
.search(pattern
, actual
[j
-1]):
705 if actual
[j
-1] > actual
[j
]:
707 actual
[j
-1] = actual
[j
]
711 # Sort lines which start with " nexthopvia"
712 pattern
= r
'^\snexthopvia '
716 for j
in range(1, len(actual
)):
717 if re
.search(pattern
, actual
[j
]) and re
.search(pattern
, actual
[j
-1]):
718 if actual
[j
-1] > actual
[j
]:
720 actual
[j
-1] = actual
[j
]
724 # Sort Sections of "xx proto zebra" (with all the indented lines below)
725 pattern
= r
'^xx via inet '
726 # Join paragraphs first
728 temp
= [actual
[0].rstrip()]
729 for k
in range(1, len(actual
)):
730 if re
.search(r
'^\s', actual
[k
]):
732 temp
[j
] += '\n' + actual
[k
].rstrip()
735 temp
.append(actual
[k
].rstrip())
738 # Now write sort array back
740 for k
in range(0, len(temp
)):
741 actual
.extend(temp
[k
].splitlines())
742 # put \n back at line ends
743 actual
= ('\n'.join(actual
) + '\n').splitlines(1)
746 diff
= topotest
.get_textdiff(actual
, expected
,
747 title1
="actual Linux Kernel MPLS route",
748 title2
="expected Linux Kernel MPLS route")
750 # Empty string if it matches, otherwise diff contains unified diff
752 sys
.stderr
.write('r%s failed Linux Kernel MPLS route output Check:\n%s\n' % (i
, diff
))
757 assert failures
== 0, "Linux Kernel MPLS route output for router r%s:\n%s" % (i
, diff
)
759 # Make sure that all daemons are running
760 for i
in range(1, 5):
761 fatal_error
= net
['r%s' % i
].checkRouterRunning()
762 assert fatal_error
== "", fatal_error
764 # For debugging after starting FRR/Quagga daemons, uncomment the next line
768 def test_shutdown_check_stderr():
772 # Skip if previous fatal error condition is raised
773 if (fatal_error
!= ""):
774 pytest
.skip(fatal_error
)
776 if os
.environ
.get('TOPOTESTS_CHECK_STDERR') is None:
777 print("SKIPPED final check on StdErr output: Disabled (TOPOTESTS_CHECK_STDERR undefined)\n")
778 pytest
.skip('Skipping test for Stderr output')
780 thisDir
= os
.path
.dirname(os
.path
.realpath(__file__
))
782 print("\n\n** Verifying unexpected STDERR output from daemons")
783 print("******************************************\n")
785 for i
in range(1, 5):
786 net
['r%s' % i
].stopRouter()
787 log
= net
['r%s' % i
].getStdErr('ldpd')
788 print("\nRouter r%s LDPd StdErr Log:\n%s" % (i
, log
))
789 log
= net
['r%s' % i
].getStdErr('ospfd')
790 print("\nRouter r%s OSPFd StdErr Log:\n%s" % (i
, log
))
791 log
= net
['r%s' % i
].getStdErr('zebra')
792 print("\nRouter r%s Zebra StdErr Log:\n%s" % (i
, log
))
795 def test_shutdown_check_memleak():
799 # Skip if previous fatal error condition is raised
800 if (fatal_error
!= ""):
801 pytest
.skip(fatal_error
)
803 if os
.environ
.get('TOPOTESTS_CHECK_MEMLEAK') is None:
804 print("SKIPPED final check on Memory leaks: Disabled (TOPOTESTS_CHECK_MEMLEAK undefined)\n")
805 pytest
.skip('Skipping test for memory leaks')
807 thisDir
= os
.path
.dirname(os
.path
.realpath(__file__
))
809 for i
in range(1, 5):
810 net
['r%s' % i
].stopRouter()
811 net
['r%s' % i
].report_memory_leaks(os
.environ
.get('TOPOTESTS_CHECK_MEMLEAK'), os
.path
.basename(__file__
))
814 if __name__
== '__main__':
817 # To suppress tracebacks, either use the following pytest call or add "--tb=no" to cli
818 # retval = pytest.main(["-s", "--tb=no"])
819 retval
= pytest
.main(["-s"])