]> git.proxmox.com Git - mirror_frr.git/blame - 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
CommitLineData
f03e38f3
MW
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"""
622c4996 26test_ldp_topo1.py: Simple FRR LDP Test
f03e38f3
MW
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 \ / \
55r3-eth1 .3 | | .3 r3-eth0 | .4 r4-eth0
56 +----+--+---+ +----+----+
57 | r3 | | r4 |
58 | 3.3.3.3 | | 4.4.4.4 |
59 +-----------+ +---------+
787e7624 60"""
f03e38f3
MW
61
62import os
63import re
64import sys
594b1259
MW
65import pytest
66from time import sleep
f03e38f3
MW
67
68from mininet.topo import Topo
69from mininet.net import Mininet
70from mininet.node import Node, OVSSwitch, Host
71from mininet.log import setLogLevel, info
72from mininet.cli import CLI
73from mininet.link import Intf
74
594b1259
MW
75sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
76from lib import topotest
f03e38f3
MW
77
78fatal_error = ""
79
6907ac7e
DS
80pytestmark = [pytest.mark.ldpd]
81
f03e38f3
MW
82#####################################################
83##
84## Network Topology Definition
85##
86#####################################################
87
787e7624 88
f03e38f3 89class NetworkTopo(Topo):
594b1259 90 "LDP Test Topology 1"
f03e38f3
MW
91
92 def build(self, **_opts):
93
f03e38f3
MW
94 # Setup Routers
95 router = {}
96 for i in range(1, 5):
787e7624 97 router[i] = topotest.addRouter(self, "r%s" % i)
f03e38f3 98
594b1259 99 # Setup Switches, add Interfaces and Connections
f03e38f3
MW
100 switch = {}
101 # First switch
787e7624 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 )
f03e38f3 117 # Second switch
787e7624 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 )
f03e38f3 140 # Third switch
787e7624 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 )
f03e38f3 156
594b1259 157
f03e38f3
MW
158#####################################################
159##
160## Tests starting
161##
162#####################################################
163
6907ac7e 164
f03e38f3
MW
165def setup_module(module):
166 global topo, net
594b1259 167 global fatal_error
f03e38f3
MW
168
169 print("\n\n** %s: Setup Topology" % module.__name__)
170 print("******************************************\n")
171
172 print("Cleanup old Mininet runs")
787e7624 173 os.system("sudo mn -c > /dev/null 2>&1")
f03e38f3
MW
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):
787e7624 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()
594b1259
MW
187
188 if fatal_error != "":
189 break
f03e38f3 190
622c4996 191 # For debugging after starting FRR daemons, uncomment the next line
f03e38f3
MW
192 # CLI(net)
193
787e7624 194
f03e38f3
MW
195def 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
594b1259 205def test_router_running():
f03e38f3
MW
206 global fatal_error
207 global net
208
209 # Skip if previous fatal error condition is raised
787e7624 210 if fatal_error != "":
f03e38f3
MW
211 pytest.skip(fatal_error)
212
622c4996 213 print("\n\n** Check if FRR is running on each Router node")
f03e38f3
MW
214 print("******************************************\n")
215 sleep(5)
216
217 # Starting Routers
218 for i in range(1, 5):
787e7624 219 fatal_error = net["r%s" % i].checkRouterRunning()
594b1259 220 assert fatal_error == "", fatal_error
f03e38f3 221
622c4996 222 # For debugging after starting FRR daemons, uncomment the next line
594b1259 223 # CLI(net)
f03e38f3 224
787e7624 225
f03e38f3
MW
226def test_mpls_interfaces():
227 global fatal_error
228 global net
229
230 # Skip if previous fatal error condition is raised
787e7624 231 if fatal_error != "":
f03e38f3
MW
232 pytest.skip(fatal_error)
233
234 thisDir = os.path.dirname(os.path.realpath(__file__))
235
b290da1d 236 # Verify MPLS Interfaces
b2764f90 237 print("\n\n** Verifying MPLS Interfaces")
f03e38f3
MW
238 print("******************************************\n")
239 failures = 0
240 for i in range(1, 5):
787e7624 241 refTableFile = "%s/r%s/show_mpls_ldp_interface.ref"
f03e38f3
MW
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)
787e7624 246 expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1)
f03e38f3
MW
247
248 # Actual output from router
787e7624 249 actual = (
250 net["r%s" % i]
251 .cmd('vtysh -c "show mpls ldp interface" 2> /dev/null')
252 .rstrip()
253 )
f03e38f3
MW
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)
787e7624 257 actual = ("\n".join(actual.splitlines()) + "\n").splitlines(1)
f03e38f3
MW
258
259 # Generate Diff
787e7624 260 diff = topotest.get_textdiff(
261 actual,
262 expected,
17070436 263 title1="actual MPLS LDP interface status",
787e7624 264 title2="expected MPLS LDP interface status",
265 )
f03e38f3
MW
266
267 # Empty string if it matches, otherwise diff contains unified diff
268 if diff:
787e7624 269 sys.stderr.write(
270 "r%s failed MPLS LDP Interface status Check:\n%s\n" % (i, diff)
271 )
f03e38f3
MW
272 failures += 1
273 else:
274 print("r%s ok" % i)
275
787e7624 276 if failures > 0:
594b1259
MW
277 fatal_error = "MPLS LDP Interface status failed"
278
787e7624 279 assert (
280 failures == 0
281 ), "MPLS LDP Interface status failed for router r%s:\n%s" % (i, diff)
f03e38f3 282
7e7fc73b
MW
283 # Make sure that all daemons are running
284 for i in range(1, 5):
787e7624 285 fatal_error = net["r%s" % i].checkRouterRunning()
7e7fc73b
MW
286 assert fatal_error == "", fatal_error
287
622c4996 288 # For debugging after starting FRR daemons, uncomment the next line
f03e38f3
MW
289 # CLI(net)
290
291
292def test_mpls_ldp_neighbor_establish():
293 global fatal_error
294 global net
295
296 # Skip if previous fatal error condition is raised
787e7624 297 if fatal_error != "":
f03e38f3
MW
298 pytest.skip(fatal_error)
299
b290da1d 300 # Wait for MPLS LDP neighbors to establish.
f03e38f3
MW
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):
787e7624 309 established = (
310 net["r%s" % i]
311 .cmd('vtysh -c "show mpls ldp neighbor" 2> /dev/null')
312 .rstrip()
313 )
e29f8d0d
RW
314
315 # On current version, we need to make sure they all turn to OPERATIONAL on all lines
316 #
787e7624 317 lines = ("\n".join(established.splitlines()) + "\n").splitlines(1)
e29f8d0d 318 # Check all lines to be either table header (starting with ^AF or show OPERATIONAL)
787e7624 319 header = r"^AF.*"
320 operational = r"^ip.*OPERATIONAL.*"
e29f8d0d
RW
321 found_operational = 0
322 for j in range(1, len(lines)):
787e7624 323 if (not re.search(header, lines[j])) and (
324 not re.search(operational, lines[j])
325 ):
3eaafbd9 326 established = "" # Empty string shows NOT established
e29f8d0d
RW
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
f03e38f3 332 if not established:
787e7624 333 print("Waiting for r%s" % i)
f03e38f3
MW
334 sys.stdout.flush()
335 break
336 if not established:
337 sleep(5)
338 timeout -= 5
339 else:
787e7624 340 print("Done")
f03e38f3
MW
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)
787e7624 353
7e7fc73b
MW
354 # Make sure that all daemons are running
355 for i in range(1, 5):
787e7624 356 fatal_error = net["r%s" % i].checkRouterRunning()
7e7fc73b
MW
357 assert fatal_error == "", fatal_error
358
f03e38f3
MW
359
360def test_mpls_ldp_discovery():
361 global fatal_error
362 global net
363
364 # Skip if previous fatal error condition is raised
787e7624 365 if fatal_error != "":
f03e38f3
MW
366 pytest.skip(fatal_error)
367
368 thisDir = os.path.dirname(os.path.realpath(__file__))
369
b290da1d 370 # Verify MPLS LDP discovery
b2764f90 371 print("\n\n** Verifying MPLS LDP discovery")
f03e38f3
MW
372 print("******************************************\n")
373 failures = 0
374 for i in range(1, 5):
787e7624 375 refTableFile = "%s/r%s/show_mpls_ldp_discovery.ref" % (thisDir, i)
f03e38f3 376 if os.path.isfile(refTableFile):
3eaafbd9 377 # Actual output from router
787e7624 378 actual = (
379 net["r%s" % i]
380 .cmd('vtysh -c "show mpls ldp discovery" 2> /dev/null')
381 .rstrip()
382 )
3eaafbd9 383
f03e38f3
MW
384 # Read expected result from file
385 expected = open(refTableFile).read().rstrip()
386 # Fix newlines (make them all the same)
787e7624 387 expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1)
f03e38f3
MW
388
389 # Actual output from router
787e7624 390 actual = (
391 net["r%s" % i]
392 .cmd('vtysh -c "show mpls ldp discovery" 2> /dev/null')
393 .rstrip()
394 )
f03e38f3
MW
395
396 # Fix newlines (make them all the same)
787e7624 397 actual = ("\n".join(actual.splitlines()) + "\n").splitlines(1)
f03e38f3
MW
398
399 # Generate Diff
787e7624 400 diff = topotest.get_textdiff(
401 actual,
402 expected,
17070436 403 title1="actual MPLS LDP discovery output",
787e7624 404 title2="expected MPLS LDP discovery output",
405 )
f03e38f3
MW
406
407 # Empty string if it matches, otherwise diff contains unified diff
408 if diff:
787e7624 409 sys.stderr.write(
410 "r%s failed MPLS LDP discovery output Check:\n%s\n" % (i, diff)
411 )
f03e38f3
MW
412 failures += 1
413 else:
414 print("r%s ok" % i)
415
787e7624 416 assert (
417 failures == 0
418 ), "MPLS LDP Interface discovery output for router r%s:\n%s" % (i, diff)
f03e38f3 419
7e7fc73b
MW
420 # Make sure that all daemons are running
421 for i in range(1, 5):
787e7624 422 fatal_error = net["r%s" % i].checkRouterRunning()
7e7fc73b
MW
423 assert fatal_error == "", fatal_error
424
622c4996 425 # For debugging after starting FRR daemons, uncomment the next line
f03e38f3
MW
426 # CLI(net)
427
428
429def test_mpls_ldp_neighbor():
430 global fatal_error
431 global net
432
433 # Skip if previous fatal error condition is raised
787e7624 434 if fatal_error != "":
f03e38f3
MW
435 pytest.skip(fatal_error)
436
437 thisDir = os.path.dirname(os.path.realpath(__file__))
438
b290da1d 439 # Verify MPLS LDP neighbor
b2764f90 440 print("\n\n** Verifying MPLS LDP neighbor")
f03e38f3
MW
441 print("******************************************\n")
442 failures = 0
443 for i in range(1, 5):
787e7624 444 refTableFile = "%s/r%s/show_mpls_ldp_neighbor.ref" % (thisDir, i)
f03e38f3
MW
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)
787e7624 449 expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1)
f03e38f3
MW
450
451 # Actual output from router
787e7624 452 actual = (
453 net["r%s" % i]
454 .cmd('vtysh -c "show mpls ldp neighbor" 2> /dev/null')
455 .rstrip()
456 )
3eaafbd9
MW
457
458 # Mask out changing parts in output
e29f8d0d 459 # Mask out Timer in Uptime
787e7624 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 )
f03e38f3
MW
465
466 # Fix newlines (make them all the same)
787e7624 467 actual = ("\n".join(actual.splitlines()) + "\n").splitlines(1)
f03e38f3
MW
468
469 # Generate Diff
787e7624 470 diff = topotest.get_textdiff(
471 actual,
472 expected,
17070436 473 title1="actual MPLS LDP neighbor output",
787e7624 474 title2="expected MPLS LDP neighbor output",
475 )
f03e38f3
MW
476
477 # Empty string if it matches, otherwise diff contains unified diff
478 if diff:
787e7624 479 sys.stderr.write(
480 "r%s failed MPLS LDP neighbor output Check:\n%s\n" % (i, diff)
481 )
f03e38f3
MW
482 failures += 1
483 else:
484 print("r%s ok" % i)
485
787e7624 486 assert (
487 failures == 0
488 ), "MPLS LDP Interface neighbor output for router r%s:\n%s" % (i, diff)
f03e38f3 489
7e7fc73b
MW
490 # Make sure that all daemons are running
491 for i in range(1, 5):
787e7624 492 fatal_error = net["r%s" % i].checkRouterRunning()
7e7fc73b
MW
493 assert fatal_error == "", fatal_error
494
622c4996 495 # For debugging after starting FRR daemons, uncomment the next line
787e7624 496 # CLI(net)
f03e38f3
MW
497
498
499def 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
787e7624 508 if fatal_error != "":
f03e38f3
MW
509 pytest.skip(fatal_error)
510
511 thisDir = os.path.dirname(os.path.realpath(__file__))
512
b290da1d 513 # Verify MPLS LDP binding
b2764f90 514 print("\n\n** Verifying MPLS LDP binding")
f03e38f3
MW
515 print("******************************************\n")
516 failures = 0
517 for i in range(1, 5):
787e7624 518 refTableFile = "%s/r%s/show_mpls_ldp_binding.ref" % (thisDir, i)
f03e38f3
MW
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)
787e7624 523 expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1)
f03e38f3
MW
524
525 # Actual output from router
787e7624 526 actual = (
527 net["r%s" % i]
528 .cmd('vtysh -c "show mpls ldp binding" 2> /dev/null')
529 .rstrip()
530 )
3eaafbd9
MW
531
532 # Mask out changing parts in output
e29f8d0d 533 # Mask out label
787e7624 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 )
3eaafbd9 542
f03e38f3 543 # Fix newlines (make them all the same)
787e7624 544 actual = ("\n".join(actual.splitlines()) + "\n").splitlines(1)
f03e38f3
MW
545
546 # Sort lines which start with "xx via inet "
787e7624 547 pattern = r"^\s+[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+\s+"
f03e38f3
MW
548 swapped = True
549 while swapped:
550 swapped = False
551 for j in range(1, len(actual)):
787e7624 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]
f03e38f3
MW
558 actual[j] = temp
559 swapped = True
560
561 # Generate Diff
787e7624 562 diff = topotest.get_textdiff(
563 actual,
564 expected,
17070436 565 title1="actual MPLS LDP binding output",
787e7624 566 title2="expected MPLS LDP binding output",
567 )
f03e38f3
MW
568
569 # Empty string if it matches, otherwise diff contains unified diff
570 if diff:
787e7624 571 sys.stderr.write(
572 "r%s failed MPLS LDP binding output Check:\n%s\n" % (i, diff)
573 )
f03e38f3
MW
574 failures += 1
575 else:
576 print("r%s ok" % i)
577
787e7624 578 assert (
579 failures == 0
580 ), "MPLS LDP Interface binding output for router r%s:\n%s" % (i, diff)
f03e38f3 581
7e7fc73b
MW
582 # Make sure that all daemons are running
583 for i in range(1, 5):
787e7624 584 fatal_error = net["r%s" % i].checkRouterRunning()
7e7fc73b
MW
585 assert fatal_error == "", fatal_error
586
622c4996 587 # For debugging after starting FRR daemons, uncomment the next line
787e7624 588 # CLI(net)
f03e38f3
MW
589
590
591def test_zebra_ipv4_routingTable():
592 global fatal_error
593 global net
594
595 # Skip if previous fatal error condition is raised
787e7624 596 if fatal_error != "":
f03e38f3
MW
597 pytest.skip(fatal_error)
598
599 thisDir = os.path.dirname(os.path.realpath(__file__))
600
b290da1d 601 # Verify Zebra IPv4 Routing Table
b2764f90 602 print("\n\n** Verifying Zebra IPv4 Routing Table")
f03e38f3
MW
603 print("******************************************\n")
604 failures = 0
605 for i in range(1, 5):
787e7624 606 refTableFile = "%s/r%s/show_ipv4_route.ref" % (thisDir, i)
f03e38f3
MW
607 if os.path.isfile(refTableFile):
608 # Read expected result from file
609 expected = open(refTableFile).read().rstrip()
f03e38f3
MW
610
611 # Actual output from router
787e7624 612 actual = (
613 net["r%s" % i]
614 .cmd('vtysh -c "show ip route" 2> /dev/null | grep "^O"')
615 .rstrip()
616 )
622c4996 617 # Drop timers on end of line
f03e38f3 618 actual = re.sub(r", [0-2][0-9]:[0-5][0-9]:[0-5][0-9]", "", actual)
6c97c0cb
MW
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)
be7286cc
MW
623 # and translating remaining implicit (single-digit) labels to label implicit-null
624 actual = re.sub(r" label [0-9]+", " label implicit-null", actual)
6c97c0cb 625 # Check if we have implicit labels - if not, then remove them from reference
787e7624 626 if not re.search(r" label implicit-null", actual):
be7286cc 627 expected = re.sub(r", label implicit-null", "", expected)
6c97c0cb
MW
628
629 # now fix newlines of expected (make them all the same)
787e7624 630 expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1)
6c97c0cb 631
f03e38f3 632 # Fix newlines (make them all the same)
787e7624 633 actual = ("\n".join(actual.splitlines()) + "\n").splitlines(1)
f03e38f3
MW
634
635 # Generate Diff
787e7624 636 diff = topotest.get_textdiff(
637 actual,
638 expected,
17070436 639 title1="actual IPv4 zebra routing table",
787e7624 640 title2="expected IPv4 zebra routing table",
641 )
f03e38f3
MW
642
643 # Empty string if it matches, otherwise diff contains unified diff
644 if diff:
787e7624 645 sys.stderr.write(
646 "r%s failed IPv4 Zebra Routing Table Check:\n%s\n" % (i, diff)
647 )
f03e38f3
MW
648 failures += 1
649 else:
650 print("r%s ok" % i)
651
9fa6ec14 652 assert (
653 failures == 0
654 ), "IPv4 Zebra Routing Table verification failed for router r%s:\n%s" % (
655 i,
656 diff,
787e7624 657 )
f03e38f3 658
7e7fc73b
MW
659 # Make sure that all daemons are running
660 for i in range(1, 5):
787e7624 661 fatal_error = net["r%s" % i].checkRouterRunning()
7e7fc73b
MW
662 assert fatal_error == "", fatal_error
663
622c4996 664 # For debugging after starting FRR daemons, uncomment the next line
f03e38f3
MW
665 # CLI(net)
666
667
668def test_mpls_table():
669 global fatal_error
670 global net
671
672 # Skip if previous fatal error condition is raised
787e7624 673 if fatal_error != "":
f03e38f3
MW
674 pytest.skip(fatal_error)
675
676 thisDir = os.path.dirname(os.path.realpath(__file__))
677
b290da1d 678 # Verify MPLS table
b2764f90 679 print("\n\n** Verifying MPLS table")
f03e38f3
MW
680 print("******************************************\n")
681 failures = 0
d01e89f1 682
f03e38f3 683 for i in range(1, 5):
787e7624 684 refTableFile = "%s/r%s/show_mpls_table.ref" % (thisDir, i)
f03e38f3
MW
685 if os.path.isfile(refTableFile):
686 # Read expected result from file
a971aeb6 687 expected = open(refTableFile).read()
f03e38f3 688 # Fix newlines (make them all the same)
787e7624 689 expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1)
f03e38f3
MW
690
691 # Actual output from router
787e7624 692 actual = net["r%s" % i].cmd('vtysh -c "show mpls table" 2> /dev/null')
b290da1d 693
f03e38f3
MW
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
787e7624 697 actual = re.sub(
698 r"(\s+[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+\s+)[0-9][0-9]", r"\1XX", actual
699 )
f03e38f3
MW
700
701 # Fix newlines (make them all the same)
787e7624 702 actual = ("\n".join(actual.splitlines()) + "\n").splitlines(1)
f03e38f3
MW
703
704 # Sort lines which start with " XX LDP"
787e7624 705 pattern = r"^\s+[0-9X]+\s+LDP"
f03e38f3
MW
706 swapped = True
707 while swapped:
708 swapped = False
709 for j in range(1, len(actual)):
787e7624 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]
f03e38f3
MW
716 actual[j] = temp
717 swapped = True
718
719 # Generate Diff
787e7624 720 diff = topotest.get_textdiff(
721 actual,
722 expected,
17070436 723 title1="actual MPLS table output",
787e7624 724 title2="expected MPLS table output",
725 )
f03e38f3
MW
726
727 # Empty string if it matches, otherwise diff contains unified diff
728 if diff:
787e7624 729 sys.stderr.write(
730 "r%s failed MPLS table output Check:\n%s\n" % (i, diff)
731 )
f03e38f3
MW
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
7e7fc73b
MW
738 # Make sure that all daemons are running
739 for i in range(1, 5):
787e7624 740 fatal_error = net["r%s" % i].checkRouterRunning()
7e7fc73b
MW
741 assert fatal_error == "", fatal_error
742
622c4996 743 # For debugging after starting FRR daemons, uncomment the next line
f03e38f3
MW
744 # CLI(net)
745
746
747def test_linux_mpls_routes():
748 global fatal_error
749 global net
750
787e7624 751 # Skip if previous fatal error condition is raised
752 if fatal_error != "":
f03e38f3
MW
753 pytest.skip(fatal_error)
754
755 thisDir = os.path.dirname(os.path.realpath(__file__))
756
b290da1d 757 # Verify Linux Kernel MPLS routes
b2764f90 758 print("\n\n** Verifying Linux Kernel MPLS routes")
f03e38f3
MW
759 print("******************************************\n")
760 failures = 0
761 for i in range(1, 5):
787e7624 762 refTableFile = "%s/r%s/ip_mpls_route.ref" % (thisDir, i)
f03e38f3
MW
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)
787e7624 767 expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1)
f03e38f3
MW
768
769 # Actual output from router
787e7624 770 actual = (
771 net["r%s" % i].cmd("ip -o -family mpls route 2> /dev/null").rstrip()
772 )
3a103f9a
CF
773
774 # Mask out label and protocol
f03e38f3 775 actual = re.sub(r"[0-9][0-9] via inet ", "xx via inet ", actual)
3a103f9a 776 actual = re.sub(r"[0-9][0-9] +proto", "xx proto", actual)
f03e38f3 777 actual = re.sub(r"[0-9][0-9] as to ", "xx as to ", actual)
dd3ddc06 778 actual = re.sub(r"[ ]+proto \w+", " proto xx", actual)
f03e38f3 779
3a103f9a
CF
780 # Sort nexthops
781 nexthop_sorted = []
782 for line in actual.splitlines():
787e7624 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 )
3a103f9a
CF
790
791 # Sort lines and fixup differences between old and new iproute
787e7624 792 actual = "\n".join(sorted(nexthop_sorted))
3a103f9a
CF
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)
f03e38f3 797
f03e38f3 798 # put \n back at line ends
787e7624 799 actual = ("\n".join(actual.splitlines()) + "\n").splitlines(1)
f03e38f3
MW
800
801 # Generate Diff
787e7624 802 diff = topotest.get_textdiff(
803 actual,
804 expected,
17070436 805 title1="actual Linux Kernel MPLS route",
787e7624 806 title2="expected Linux Kernel MPLS route",
807 )
f03e38f3
MW
808
809 # Empty string if it matches, otherwise diff contains unified diff
810 if diff:
787e7624 811 sys.stderr.write(
812 "r%s failed Linux Kernel MPLS route output Check:\n%s\n" % (i, diff)
813 )
f03e38f3
MW
814 failures += 1
815 else:
816 print("r%s ok" % i)
817
787e7624 818 assert (
819 failures == 0
820 ), "Linux Kernel MPLS route output for router r%s:\n%s" % (i, diff)
f03e38f3 821
7e7fc73b
MW
822 # Make sure that all daemons are running
823 for i in range(1, 5):
787e7624 824 fatal_error = net["r%s" % i].checkRouterRunning()
7e7fc73b
MW
825 assert fatal_error == "", fatal_error
826
622c4996 827 # For debugging after starting FRR daemons, uncomment the next line
f03e38f3
MW
828 # CLI(net)
829
830
99561211
MW
831def test_shutdown_check_stderr():
832 global fatal_error
833 global net
834
835 # Skip if previous fatal error condition is raised
787e7624 836 if fatal_error != "":
99561211
MW
837 pytest.skip(fatal_error)
838
787e7624 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")
99561211
MW
844
845 thisDir = os.path.dirname(os.path.realpath(__file__))
846
b2764f90 847 print("\n\n** Verifying unexpected STDERR output from daemons")
99561211
MW
848 print("******************************************\n")
849
850 for i in range(1, 5):
787e7624 851 net["r%s" % i].stopRouter()
852 log = net["r%s" % i].getStdErr("ldpd")
8e957dbb
MW
853 if log:
854 print("\nRouter r%s LDPd StdErr Log:\n%s" % (i, log))
787e7624 855 log = net["r%s" % i].getStdErr("ospfd")
8e957dbb
MW
856 if log:
857 print("\nRouter r%s OSPFd StdErr Log:\n%s" % (i, log))
787e7624 858 log = net["r%s" % i].getStdErr("zebra")
8e957dbb
MW
859 if log:
860 print("\nRouter r%s Zebra StdErr Log:\n%s" % (i, log))
99561211
MW
861
862
50c40bde
MW
863def test_shutdown_check_memleak():
864 global fatal_error
865 global net
866
867 # Skip if previous fatal error condition is raised
787e7624 868 if fatal_error != "":
50c40bde
MW
869 pytest.skip(fatal_error)
870
787e7624 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
50c40bde
MW
877 thisDir = os.path.dirname(os.path.realpath(__file__))
878
879 for i in range(1, 5):
787e7624 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 )
50c40bde 884
99561211 885
787e7624 886if __name__ == "__main__":
f03e38f3 887
787e7624 888 setLogLevel("info")
f03e38f3
MW
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)