]> git.proxmox.com Git - mirror_frr.git/blame - tests/topotests/all-protocol-startup/test_all_protocol_startup.py
Merge pull request #7143 from donaldsharp/rip_debugs
[mirror_frr.git] / tests / topotests / all-protocol-startup / test_all_protocol_startup.py
CommitLineData
4501fbca
MW
1#!/usr/bin/env python
2
3#
4# test_all_protocol_startup.py
5# Part of NetDEF Topology Tests
6#
7# Copyright (c) 2017 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"""
26test_all_protocol_startup.py: Test of all protocols at same time
27
28"""
29
30import os
31import re
32import sys
4501fbca 33import pytest
6a57e103 34import glob
4501fbca
MW
35from time import sleep
36
37from mininet.topo import Topo
38from mininet.net import Mininet
39from mininet.node import Node, OVSSwitch, Host
40from mininet.log import setLogLevel, info
41from mininet.cli import CLI
42from mininet.link import Intf
43
44from functools import partial
45
46sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
47from lib import topotest
48
49fatal_error = ""
50
51
52#####################################################
53##
54## Network Topology Definition
55##
56#####################################################
57
58class NetworkTopo(Topo):
59 "All Protocol Startup Test"
60
61 def build(self, **_opts):
62
63 # Setup Routers
64 router = {}
65 #
66 # Setup Main Router
67 router[1] = topotest.addRouter(self, 'r1')
68 #
69
70 # Setup Switches
71 switch = {}
72 #
73 for i in range(0, 10):
74 switch[i] = self.addSwitch('sw%s' % i, cls=topotest.LegacySwitch)
75 self.addLink(switch[i], router[1], intfName2='r1-eth%s' % i )
76
77
78#####################################################
79##
80## Tests starting
81##
82#####################################################
83
84def setup_module(module):
85 global topo, net
86 global fatal_error
87
88 print("\n\n** %s: Setup Topology" % module.__name__)
89 print("******************************************\n")
90
91 print("Cleanup old Mininet runs")
92 os.system('sudo mn -c > /dev/null 2>&1')
93 os.system('sudo rm /tmp/r* > /dev/null 2>&1')
94
95 thisDir = os.path.dirname(os.path.realpath(__file__))
96 topo = NetworkTopo()
97
98 net = Mininet(controller=None, topo=topo)
99 net.start()
100
101 if net['r1'].get_routertype() != 'frr':
102 fatal_error = "Test is only implemented for FRR"
103 sys.stderr.write('\n\nTest is only implemented for FRR - Skipping\n\n')
104 pytest.skip(fatal_error)
105
106 # Starting Routers
107 #
108 # Main router
109 for i in range(1, 2):
110 net['r%s' % i].loadConf('zebra', '%s/r%s/zebra.conf' % (thisDir, i))
111 net['r%s' % i].loadConf('ripd', '%s/r%s/ripd.conf' % (thisDir, i))
112 net['r%s' % i].loadConf('ripngd', '%s/r%s/ripngd.conf' % (thisDir, i))
113 net['r%s' % i].loadConf('ospfd', '%s/r%s/ospfd.conf' % (thisDir, i))
fa2adbc5
MW
114 if net['r1'].checkRouterVersion('<', '4.0'):
115 net['r%s' % i].loadConf('ospf6d', '%s/r%s/ospf6d.conf-pre-v4' % (thisDir, i))
116 else:
117 net['r%s' % i].loadConf('ospf6d', '%s/r%s/ospf6d.conf' % (thisDir, i))
4501fbca
MW
118 net['r%s' % i].loadConf('isisd', '%s/r%s/isisd.conf' % (thisDir, i))
119 net['r%s' % i].loadConf('bgpd', '%s/r%s/bgpd.conf' % (thisDir, i))
120 if net['r%s' % i].daemon_available('ldpd'):
121 # Only test LDPd if it's installed and Kernel >= 4.5
122 net['r%s' % i].loadConf('ldpd', '%s/r%s/ldpd.conf' % (thisDir, i))
8058df22 123 net['r%s' % i].loadConf('sharpd')
a0764a36
DS
124 net['r%s' % i].loadConf('nhrpd', '%s/r%s/nhrpd.conf' % (thisDir, i))
125 net['r%s' % i].loadConf('babeld', '%s/r%s/babeld.conf' % (thisDir, i))
223f87f4 126 net['r%s' % i].loadConf('pbrd', '%s/r%s/pbrd.conf' % (thisDir, i))
4501fbca
MW
127 net['r%s' % i].startRouter()
128
129 # For debugging after starting Quagga/FRR daemons, uncomment the next line
130 # CLI(net)
131
132
133def teardown_module(module):
134 global net
135
136 print("\n\n** %s: Shutdown Topology" % module.__name__)
137 print("******************************************\n")
138
139 # End - Shutdown network
140 net.stop()
141
142
143def test_router_running():
144 global fatal_error
145 global net
146
147 # Skip if previous fatal error condition is raised
148 if (fatal_error != ""):
149 pytest.skip(fatal_error)
150
151 print("\n\n** Check if FRR/Quagga is running on each Router node")
152 print("******************************************\n")
153 sleep(5)
154
155 # Starting Routers
156 for i in range(1, 2):
157 fatal_error = net['r%s' % i].checkRouterRunning()
158 assert fatal_error == "", fatal_error
159
160 # For debugging after starting FRR/Quagga daemons, uncomment the next line
161 # CLI(net)
162
163
164def test_error_messages_vtysh():
165 global fatal_error
166 global net
167
168 # Skip if previous fatal error condition is raised
169 if (fatal_error != ""):
170 pytest.skip(fatal_error)
171
172 print("\n\n** Check for error messages on VTYSH")
173 print("******************************************\n")
174
175 failures = 0
176 for i in range(1, 2):
177 #
178 # First checking Standard Output
179 #
180
181 # VTYSH output from router
182 vtystdout = net['r%s' % i].cmd('vtysh -c "show version" 2> /dev/null').rstrip()
183
184 # Fix newlines (make them all the same)
185 vtystdout = ('\n'.join(vtystdout.splitlines()) + '\n').rstrip()
186 # Drop everything starting with "FRRouting X.xx" message
187 vtystdout = re.sub(r"FRRouting [0-9]+.*", "", vtystdout, flags=re.DOTALL)
188
555451fa 189 if (vtystdout == ''):
4501fbca
MW
190 print("r%s StdOut ok" % i)
191
555451fa 192 assert vtystdout == '', "Vtysh StdOut Output check failed for router r%s" % i
798fb593 193
4501fbca
MW
194 #
195 # Second checking Standard Error
196 #
197
198 # VTYSH StdErr output from router
199 vtystderr = net['r%s' % i].cmd('vtysh -c "show version" > /dev/null').rstrip()
200
201 # Fix newlines (make them all the same)
202 vtystderr = ('\n'.join(vtystderr.splitlines()) + '\n').rstrip()
203 # # Drop everything starting with "FRRouting X.xx" message
204 # vtystderr = re.sub(r"FRRouting [0-9]+.*", "", vtystderr, flags=re.DOTALL)
205
555451fa 206 if (vtystderr == ''):
4501fbca
MW
207 print("r%s StdErr ok" % i)
208
555451fa 209 assert vtystderr == '', "Vtysh StdErr Output check failed for router r%s" % i
4501fbca 210
7e7fc73b
MW
211 # Make sure that all daemons are running
212 for i in range(1, 2):
213 fatal_error = net['r%s' % i].checkRouterRunning()
214 assert fatal_error == "", fatal_error
215
4501fbca
MW
216 # For debugging after starting FRR/Quagga daemons, uncomment the next line
217 # CLI(net)
218
219
220def test_error_messages_daemons():
221 global fatal_error
222 global net
223
224 # Skip if previous fatal error condition is raised
225 if (fatal_error != ""):
226 pytest.skip(fatal_error)
227
228 print("\n\n** Check for error messages in daemons")
229 print("******************************************\n")
230
231 error_logs = ""
232
233 for i in range(1, 2):
234 log = net['r%s' % i].getStdErr('ripd')
235 if log:
236 error_logs += "r%s RIPd StdErr Output:\n" % i
237 error_logs += log
238 log = net['r%s' % i].getStdErr('ripngd')
239 if log:
240 error_logs += "r%s RIPngd StdErr Output:\n" % i
241 error_logs += log
242 log = net['r%s' % i].getStdErr('ospfd')
243 if log:
244 error_logs += "r%s OSPFd StdErr Output:\n" % i
245 error_logs += log
246 log = net['r%s' % i].getStdErr('ospf6d')
247 if log:
248 error_logs += "r%s OSPF6d StdErr Output:\n" % i
249 error_logs += log
250 log = net['r%s' % i].getStdErr('isisd')
251 # ISIS shows debugging enabled status on StdErr
252 # Remove these messages
253 log = re.sub(r"^IS-IS .* debugging is on.*", "", log).rstrip()
254 if log:
255 error_logs += "r%s ISISd StdErr Output:\n" % i
256 error_logs += log
257 log = net['r%s' % i].getStdErr('bgpd')
258 if log:
259 error_logs += "r%s BGPd StdErr Output:\n" % i
260 error_logs += log
261 if (net['r%s' % i].daemon_available('ldpd')):
262 log = net['r%s' % i].getStdErr('ldpd')
263 if log:
264 error_logs += "r%s LDPd StdErr Output:\n" % i
265 error_logs += log
af39fbe7
MS
266
267 log = net['r1'].getStdErr('nhrpd')
268 if log:
269 error_logs += "r%s NHRPd StdErr Output:\n" % i
270 error_logs += log
271
272 log = net['r1'].getStdErr('babeld')
273 if log:
274 error_logs += "r%s BABELd StdErr Output:\n" % i
275 error_logs += log
276
277 log = net['r1'].getStdErr('pbrd')
278 if log:
279 error_logs += "r%s PBRd StdErr Output:\n" % i
280 error_logs += log
281
4501fbca
MW
282 log = net['r%s' % i].getStdErr('zebra')
283 if log:
284 error_logs += "r%s Zebra StdErr Output:\n"
285 error_logs += log
286
287 if error_logs:
288 sys.stderr.write('Failed check for StdErr Output on daemons:\n%s\n' % error_logs)
289
08fa1af7
MW
290 # Ignoring the issue if told to ignore (ie not yet fixed)
291 if (error_logs != ""):
1026c19a 292 if (os.environ.get('bamboo_TOPOTESTS_ISSUE_349') == "IGNORE"):
08fa1af7
MW
293 sys.stderr.write('Known issue - IGNORING. See https://github.com/FRRouting/frr/issues/349\n')
294 pytest.skip('Known issue - IGNORING. See https://github.com/FRRouting/frr/issues/349')
295
4501fbca
MW
296 assert error_logs == "", "Daemons report errors to StdErr"
297
298 # For debugging after starting FRR/Quagga daemons, uncomment the next line
299 # CLI(net)
300
301
302def test_converge_protocols():
303 global fatal_error
304 global net
305
306 # Skip if previous fatal error condition is raised
307 if (fatal_error != ""):
308 pytest.skip(fatal_error)
309
310 thisDir = os.path.dirname(os.path.realpath(__file__))
311
312 print("\n\n** Waiting for protocols convergence")
313 print("******************************************\n")
314
315 # Not really implemented yet - just sleep 60 secs for now
316 sleep(60)
317
7e7fc73b 318 # Make sure that all daemons are running
556f76e1 319 failures = 0
7e7fc73b
MW
320 for i in range(1, 2):
321 fatal_error = net['r%s' % i].checkRouterRunning()
322 assert fatal_error == "", fatal_error
323
556f76e1
DS
324 print("Show that v4 routes are right\n");
325 v4_routesFile = '%s/r%s/ipv4_routes.ref' % (thisDir, i)
326 expected = open(v4_routesFile).read().rstrip()
327 expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1)
328
14c40525 329 actual = net['r%s' %i].cmd('vtysh -c "show ip route" | /usr/bin/tail -n +7 | env LC_ALL=en_US.UTF-8 sort 2> /dev/null').rstrip()
556f76e1
DS
330 # Drop time in last update
331 actual = re.sub(r" [0-2][0-9]:[0-5][0-9]:[0-5][0-9]", " XX:XX:XX", actual)
332 actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
333 diff = topotest.get_textdiff(actual, expected,
334 title1="Actual IP Routing Table",
335 title2="Expected IP RoutingTable")
336 if diff:
337 sys.stderr.write('r%s failed IP Routing table check:\n%s\n' % (i, diff))
338 failures += 1
339 else:
340 print("r%s ok" %i)
341
342 assert failures == 0, "IP Routing table failed for r%s\n%s" % (i, diff)
343
344 failures = 0
345
346 print("Show that v6 routes are right\n")
347 v6_routesFile = '%s/r%s/ipv6_routes.ref' % (thisDir, i)
348 expected = open(v6_routesFile).read().rstrip()
349 expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1)
350
14c40525 351 actual = net['r%s' %i].cmd('vtysh -c "show ipv6 route" | /usr/bin/tail -n +7 | env LC_ALL=en_US.UTF-8 sort 2> /dev/null').rstrip()
556f76e1
DS
352 # Drop time in last update
353 actual = re.sub(r" [0-2][0-9]:[0-5][0-9]:[0-5][0-9]", " XX:XX:XX", actual)
354 actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
355 diff = topotest.get_textdiff(actual, expected,
356 title1="Actual IPv6 Routing Table",
357 title2="Expected IPv6 RoutingTable")
358 if diff:
359 sys.stderr.write('r%s failed IPv6 Routing table check:\n%s\n' % (i, diff))
360 failures += 1
361 else:
362 print("r%s ok" %i)
363
364 assert failures == 0, "IPv6 Routing table failed for r%s\n%s" % (i, diff)
365
4501fbca
MW
366 # For debugging after starting FRR/Quagga daemons, uncomment the next line
367 ## CLI(net)
368
887a232c
SW
369def route_get_nhg_id(route_str):
370 output = net["r1"].cmd('vtysh -c "show ip route %s nexthop-group"' % route_str)
371 match = re.search(r"Nexthop Group ID: (\d+)", output)
372 assert match is not None, "Nexthop Group ID not found for sharpd route %s" % route_str
373
374 nhg_id = int(match.group(1))
375 return nhg_id
376
377def verify_nexthop_group(nhg_id, recursive=False):
378 # Verify NHG is valid/installed
379 output = net["r1"].cmd('vtysh -c "show nexthop-group rib %d"' % nhg_id)
380
381 match = re.search(r"Valid", output)
382 assert match is not None, "Nexthop Group ID=%d not marked Valid" % nhg_id
383
384 # If recursive, we need to look at its resolved group
385 if recursive:
386 match = re.search(r"Depends: \((\d+)\)", output)
387 resolved_id = int(match.group(1))
388 verify_nexthop_group(resolved_id, False)
389 else:
390 match = re.search(r"Installed", output)
391 assert match is not None, "Nexthop Group ID=%d not marked Installed" % nhg_id
392
393def verify_route_nexthop_group(route_str, recursive=False):
394 # Verify route and that zebra created NHGs for and they are valid/installed
395 nhg_id = route_get_nhg_id(route_str)
396 verify_nexthop_group(nhg_id, recursive)
397
8058df22
SW
398def test_nexthop_groups():
399 global fatal_error
400 global net
401
402 # Skip if previous fatal error condition is raised
403 if (fatal_error != ""):
404 pytest.skip(fatal_error)
405
406 print("\n\n** Verifying Nexthop Groups")
407 print("******************************************\n")
408
887a232c
SW
409 ### Nexthop Group Tests
410
411 ## Basic test
412
8058df22 413 # Create a lib nexthop-group
887a232c 414 net["r1"].cmd('vtysh -c "c t" -c "nexthop-group basic" -c "nexthop 1.1.1.1" -c "nexthop 1.1.1.2"')
8058df22
SW
415
416 # Create with sharpd using nexthop-group
887a232c 417 net["r1"].cmd('vtysh -c "sharp install routes 2.2.2.1 nexthop-group basic 1"')
8058df22 418
887a232c 419 verify_route_nexthop_group("2.2.2.1/32")
8058df22 420
887a232c 421 ## Connected
8058df22 422
887a232c 423 net["r1"].cmd('vtysh -c "c t" -c "nexthop-group connected" -c "nexthop r1-eth1" -c "nexthop r1-eth2"')
8058df22 424
887a232c
SW
425 net["r1"].cmd('vtysh -c "sharp install routes 2.2.2.2 nexthop-group connected 1"')
426
427 verify_route_nexthop_group("2.2.2.2/32")
428
429 ## Recursive
430
431 net["r1"].cmd('vtysh -c "c t" -c "nexthop-group basic-recursive" -c "nexthop 2.2.2.1"')
432
433 net["r1"].cmd('vtysh -c "sharp install routes 3.3.3.1 nexthop-group basic-recursive 1"')
434
435 verify_route_nexthop_group("3.3.3.1/32", True)
436
437 ## Duplicate
438
439 net["r1"].cmd('vtysh -c "c t" -c "nexthop-group duplicate" -c "nexthop 2.2.2.1" -c "nexthop 1.1.1.1"')
440
441 net["r1"].cmd('vtysh -c "sharp install routes 3.3.3.2 nexthop-group duplicate 1"')
442
443 verify_route_nexthop_group("3.3.3.2/32")
444
445 ## Two 4-Way ECMP
446
447 net["r1"].cmd('vtysh -c "c t" -c "nexthop-group fourA" -c "nexthop 1.1.1.1" -c "nexthop 1.1.1.2" \
448 -c "nexthop 1.1.1.3" -c "nexthop 1.1.1.4"')
449
450 net["r1"].cmd('vtysh -c "sharp install routes 4.4.4.1 nexthop-group fourA 1"')
451
452 verify_route_nexthop_group("4.4.4.1/32")
453
454 net["r1"].cmd('vtysh -c "c t" -c "nexthop-group fourB" -c "nexthop 1.1.1.5" -c "nexthop 1.1.1.6" \
455 -c "nexthop 1.1.1.7" -c "nexthop 1.1.1.8"')
456
457 net["r1"].cmd('vtysh -c "sharp install routes 4.4.4.2 nexthop-group fourB 1"')
458
459 verify_route_nexthop_group("4.4.4.2/32")
460
461 ## Recursive to 8-Way ECMP
462
463 net["r1"].cmd('vtysh -c "c t" -c "nexthop-group eight-recursive" -c "nexthop 4.4.4.1" -c "nexthop 4.4.4.2"')
464
465 net["r1"].cmd('vtysh -c "sharp install routes 5.5.5.1 nexthop-group eight-recursive 1"')
466
467 verify_route_nexthop_group("5.5.5.1/32")
468
469 ##CLI(net)
470
471 ## Remove all NHG routes
472
473 net["r1"].cmd('vtysh -c "sharp remove routes 2.2.2.1 1"')
474 net["r1"].cmd('vtysh -c "sharp remove routes 2.2.2.2 1"')
475 net["r1"].cmd('vtysh -c "sharp remove routes 3.3.3.1 1"')
476 net["r1"].cmd('vtysh -c "sharp remove routes 3.3.3.2 1"')
477 net["r1"].cmd('vtysh -c "sharp remove routes 4.4.4.1 1"')
478 net["r1"].cmd('vtysh -c "sharp remove routes 4.4.4.2 1"')
479 net["r1"].cmd('vtysh -c "sharp remove routes 5.5.5.1 1"')
4501fbca
MW
480
481def test_rip_status():
482 global fatal_error
483 global net
484
485 # Skip if previous fatal error condition is raised
486 if (fatal_error != ""):
487 pytest.skip(fatal_error)
488
489 thisDir = os.path.dirname(os.path.realpath(__file__))
490
b2764f90 491 print("\n\n** Verifying RIP status")
4501fbca
MW
492 print("******************************************\n")
493 failures = 0
494 for i in range(1, 2):
495 refTableFile = '%s/r%s/rip_status.ref' % (thisDir, i)
496 if os.path.isfile(refTableFile):
497 # Read expected result from file
498 expected = open(refTableFile).read().rstrip()
499 # Fix newlines (make them all the same)
500 expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1)
501
502 # Actual output from router
503 actual = net['r%s' % i].cmd('vtysh -c "show ip rip status" 2> /dev/null').rstrip()
504 # Drop time in next due
505 actual = re.sub(r"in [0-9]+ seconds", "in XX seconds", actual)
506 # Drop time in last update
507 actual = re.sub(r" [0-2][0-9]:[0-5][0-9]:[0-5][0-9]", " XX:XX:XX", actual)
508 # Fix newlines (make them all the same)
509 actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
510
511 # Generate Diff
17070436
MW
512 diff = topotest.get_textdiff(actual, expected,
513 title1="actual IP RIP status",
514 title2="expected IP RIP status")
4501fbca
MW
515
516 # Empty string if it matches, otherwise diff contains unified diff
517 if diff:
518 sys.stderr.write('r%s failed IP RIP status check:\n%s\n' % (i, diff))
519 failures += 1
520 else:
521 print("r%s ok" % i)
522
523 assert failures == 0, "IP RIP status failed for router r%s:\n%s" % (i, diff)
524
7e7fc73b
MW
525 # Make sure that all daemons are running
526 for i in range(1, 2):
527 fatal_error = net['r%s' % i].checkRouterRunning()
528 assert fatal_error == "", fatal_error
529
4501fbca
MW
530 # For debugging after starting FRR/Quagga daemons, uncomment the next line
531 # CLI(net)
532
533
534def test_ripng_status():
535 global fatal_error
536 global net
537
538 # Skip if previous fatal error condition is raised
539 if (fatal_error != ""):
540 pytest.skip(fatal_error)
541
542 thisDir = os.path.dirname(os.path.realpath(__file__))
543
b2764f90 544 print("\n\n** Verifying RIPng status")
4501fbca
MW
545 print("******************************************\n")
546 failures = 0
547 for i in range(1, 2):
548 refTableFile = '%s/r%s/ripng_status.ref' % (thisDir, i)
549 if os.path.isfile(refTableFile):
550 # Read expected result from file
551 expected = open(refTableFile).read().rstrip()
552 # Fix newlines (make them all the same)
553 expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1)
554
555 # Actual output from router
556 actual = net['r%s' % i].cmd('vtysh -c "show ipv6 ripng status" 2> /dev/null').rstrip()
557 # Mask out Link-Local mac address portion. They are random...
558 actual = re.sub(r" fe80::[0-9a-f:]+", " fe80::XXXX:XXXX:XXXX:XXXX", actual)
559 # Drop time in next due
560 actual = re.sub(r"in [0-9]+ seconds", "in XX seconds", actual)
561 # Drop time in last update
562 actual = re.sub(r" [0-2][0-9]:[0-5][0-9]:[0-5][0-9]", " XX:XX:XX", actual)
563 # Fix newlines (make them all the same)
564 actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
565
566 # Generate Diff
17070436
MW
567 diff = topotest.get_textdiff(actual, expected,
568 title1="actual IPv6 RIPng status",
569 title2="expected IPv6 RIPng status")
4501fbca
MW
570
571 # Empty string if it matches, otherwise diff contains unified diff
572 if diff:
573 sys.stderr.write('r%s failed IPv6 RIPng status check:\n%s\n' % (i, diff))
574 failures += 1
575 else:
576 print("r%s ok" % i)
577
578 assert failures == 0, "IPv6 RIPng status failed for router r%s:\n%s" % (i, diff)
579
7e7fc73b
MW
580 # Make sure that all daemons are running
581 for i in range(1, 2):
582 fatal_error = net['r%s' % i].checkRouterRunning()
583 assert fatal_error == "", fatal_error
584
4501fbca
MW
585 # For debugging after starting FRR/Quagga daemons, uncomment the next line
586 # CLI(net)
587
588
589def test_ospfv2_interfaces():
590 global fatal_error
591 global net
592
593 # Skip if previous fatal error condition is raised
594 if (fatal_error != ""):
595 pytest.skip(fatal_error)
596
597 thisDir = os.path.dirname(os.path.realpath(__file__))
598
b2764f90 599 print("\n\n** Verifying OSPFv2 interfaces")
4501fbca
MW
600 print("******************************************\n")
601 failures = 0
602 for i in range(1, 2):
603 refTableFile = '%s/r%s/show_ip_ospf_interface.ref' % (thisDir, i)
604 if os.path.isfile(refTableFile):
605 # Read expected result from file
606 expected = open(refTableFile).read().rstrip()
607 # Fix newlines (make them all the same)
608 expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1)
609
610 # Actual output from router
611 actual = net['r%s' % i].cmd('vtysh -c "show ip ospf interface" 2> /dev/null').rstrip()
612 # Mask out Bandwidth portion. They may change..
613 actual = re.sub(r"BW [0-9]+ Mbit", "BW XX Mbit", actual)
c9d72a0b
DS
614 actual = re.sub(r"ifindex [0-9]", "ifindex X", actual)
615
4501fbca
MW
616 # Drop time in next due
617 actual = re.sub(r"Hello due in [0-9\.]+s", "Hello due in XX.XXXs", actual)
a2ab6fd8 618 actual = re.sub(r"Hello due in [0-9\.]+ usecs", "Hello due in XX.XXXs", actual)
985e6d50
MW
619 # Fix 'MTU mismatch detection: enabled' vs 'MTU mismatch detection:enabled' - accept both
620 actual = re.sub(r"MTU mismatch detection:([a-z]+.*)", r"MTU mismatch detection: \1", actual)
4501fbca
MW
621 # Fix newlines (make them all the same)
622 actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
623
624 # Generate Diff
17070436
MW
625 diff = topotest.get_textdiff(actual, expected,
626 title1="actual SHOW IP OSPF INTERFACE",
627 title2="expected SHOW IP OSPF INTERFACE")
4501fbca
MW
628
629 # Empty string if it matches, otherwise diff contains unified diff
630 if diff:
631 sys.stderr.write('r%s failed SHOW IP OSPF INTERFACE check:\n%s\n' % (i, diff))
632 failures += 1
633 else:
634 print("r%s ok" % i)
635
08fa1af7
MW
636 # Ignoring the issue if told to ignore (ie not yet fixed)
637 if (failures != 0):
1026c19a 638 if (os.environ.get('bamboo_TOPOTESTS_ISSUE_348') == "IGNORE"):
08fa1af7
MW
639 sys.stderr.write('Known issue - IGNORING. See https://github.com/FRRouting/frr/issues/348\n')
640 pytest.skip('Known issue - IGNORING. See https://github.com/FRRouting/frr/issues/348')
641
4501fbca
MW
642 assert failures == 0, "SHOW IP OSPF INTERFACE failed for router r%s:\n%s" % (i, diff)
643
7e7fc73b
MW
644 # Make sure that all daemons are running
645 for i in range(1, 2):
646 fatal_error = net['r%s' % i].checkRouterRunning()
647 assert fatal_error == "", fatal_error
648
4501fbca
MW
649 # For debugging after starting FRR/Quagga daemons, uncomment the next line
650 # CLI(net)
651
652
653def test_isis_interfaces():
654 global fatal_error
655 global net
656
657 # Skip if previous fatal error condition is raised
658 if (fatal_error != ""):
659 pytest.skip(fatal_error)
660
661 thisDir = os.path.dirname(os.path.realpath(__file__))
662
b2764f90 663 print("\n\n** Verifying ISIS interfaces")
4501fbca
MW
664 print("******************************************\n")
665 failures = 0
666 for i in range(1, 2):
667 refTableFile = '%s/r%s/show_isis_interface_detail.ref' % (thisDir, i)
668 if os.path.isfile(refTableFile):
669 # Read expected result from file
670 expected = open(refTableFile).read().rstrip()
671 # Fix newlines (make them all the same)
672 expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1)
673
674 # Actual output from router
675 actual = net['r%s' % i].cmd('vtysh -c "show isis interface detail" 2> /dev/null').rstrip()
676 # Mask out Link-Local mac address portion. They are random...
677 actual = re.sub(r"fe80::[0-9a-f:]+", "fe80::XXXX:XXXX:XXXX:XXXX", actual)
678 # Mask out SNPA mac address portion. They are random...
679 actual = re.sub(r"SNPA: [0-9a-f\.]+", "SNPA: XXXX.XXXX.XXXX", actual)
6ae351e8
MW
680 # Mask out Circuit ID number
681 actual = re.sub(r"Circuit Id: 0x[0-9]+", "Circuit Id: 0xXX", actual)
4501fbca
MW
682 # Fix newlines (make them all the same)
683 actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
684
685 # Generate Diff
17070436
MW
686 diff = topotest.get_textdiff(actual, expected,
687 title1="actual SHOW ISIS INTERFACE DETAIL",
688 title2="expected SHOW ISIS OSPF6 INTERFACE DETAIL")
4501fbca
MW
689
690 # Empty string if it matches, otherwise diff contains unified diff
691 if diff:
692 sys.stderr.write('r%s failed SHOW ISIS INTERFACE DETAIL check:\n%s\n' % (i, diff))
693 failures += 1
694 else:
695 print("r%s ok" % i)
696
697 assert failures == 0, "SHOW ISIS INTERFACE DETAIL failed for router r%s:\n%s" % (i, diff)
698
7e7fc73b
MW
699 # Make sure that all daemons are running
700 for i in range(1, 2):
701 fatal_error = net['r%s' % i].checkRouterRunning()
702 assert fatal_error == "", fatal_error
703
4501fbca
MW
704 # For debugging after starting FRR/Quagga daemons, uncomment the next line
705 # CLI(net)
706
707
708def test_bgp_summary():
709 global fatal_error
710 global net
711
712 # Skip if previous fatal error condition is raised
713 if (fatal_error != ""):
714 pytest.skip(fatal_error)
715
716 thisDir = os.path.dirname(os.path.realpath(__file__))
717
b2764f90 718 print("\n\n** Verifying BGP Summary")
4501fbca
MW
719 print("******************************************\n")
720 failures = 0
721 for i in range(1, 2):
08fa1af7 722 refTableFile = '%s/r%s/show_ip_bgp_summary.ref' % (thisDir, i)
4501fbca
MW
723 if os.path.isfile(refTableFile):
724 # Read expected result from file
725 expected = open(refTableFile).read().rstrip()
726 # Fix newlines (make them all the same)
727 expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1)
728
729 # Actual output from router
08fa1af7 730 actual = net['r%s' % i].cmd('vtysh -c "show ip bgp summary" 2> /dev/null').rstrip()
4501fbca
MW
731 # Mask out "using XXiXX bytes" portion. They are random...
732 actual = re.sub(r"using [0-9]+ bytes", "using XXXX bytes", actual)
733 # Mask out "using XiXXX KiB" portion. They are random...
734 actual = re.sub(r"using [0-9]+ KiB", "using XXXX KiB", actual)
08fa1af7
MW
735 #
736 # Remove extra summaries which exist with newer versions
737 #
738 # Remove summary lines (changed recently)
739 actual = re.sub(r'Total number.*', '', actual)
740 actual = re.sub(r'Displayed.*', '', actual)
741 # Remove IPv4 Unicast Summary (Title only)
742 actual = re.sub(r'IPv4 Unicast Summary:', '', actual)
743 # Remove IPv4 Multicast Summary (all of it)
744 actual = re.sub(r'IPv4 Multicast Summary:', '', actual)
745 actual = re.sub(r'No IPv4 Multicast neighbor is configured', '', actual)
746 # Remove IPv4 VPN Summary (all of it)
747 actual = re.sub(r'IPv4 VPN Summary:', '', actual)
748 actual = re.sub(r'No IPv4 VPN neighbor is configured', '', actual)
749 # Remove IPv4 Encap Summary (all of it)
750 actual = re.sub(r'IPv4 Encap Summary:', '', actual)
751 actual = re.sub(r'No IPv4 Encap neighbor is configured', '', actual)
752 # Remove Unknown Summary (all of it)
753 actual = re.sub(r'Unknown Summary:', '', actual)
754 actual = re.sub(r'No Unknown neighbor is configured', '', actual)
8b2e59e9
DS
755
756 actual = re.sub(r'IPv4 labeled-unicast Summary:', '', actual)
757 actual = re.sub(r'No IPv4 labeled-unicast neighbor is configured', '', actual)
758
08fa1af7
MW
759 # Strip empty lines
760 actual = actual.lstrip()
761 actual = actual.rstrip()
762 #
4501fbca
MW
763 # Fix newlines (make them all the same)
764 actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
765
766 # Generate Diff
17070436
MW
767 diff = topotest.get_textdiff(actual, expected,
768 title1="actual SHOW IP BGP SUMMARY",
769 title2="expected SHOW IP BGP SUMMARY")
4501fbca
MW
770
771 # Empty string if it matches, otherwise diff contains unified diff
772 if diff:
08fa1af7 773 sys.stderr.write('r%s failed SHOW IP BGP SUMMARY check:\n%s\n' % (i, diff))
4501fbca
MW
774 failures += 1
775 else:
776 print("r%s ok" % i)
777
08fa1af7 778 assert failures == 0, "SHOW IP BGP SUMMARY failed for router r%s:\n%s" % (i, diff)
4501fbca 779
7e7fc73b
MW
780 # Make sure that all daemons are running
781 for i in range(1, 2):
782 fatal_error = net['r%s' % i].checkRouterRunning()
783 assert fatal_error == "", fatal_error
784
4501fbca
MW
785 # For debugging after starting FRR/Quagga daemons, uncomment the next line
786 # CLI(net)
787
788
789def test_bgp_ipv6_summary():
790 global fatal_error
791 global net
792
793 # Skip if previous fatal error condition is raised
794 if (fatal_error != ""):
795 pytest.skip(fatal_error)
796
797 thisDir = os.path.dirname(os.path.realpath(__file__))
798
b2764f90 799 print("\n\n** Verifying BGP IPv6 Summary")
4501fbca
MW
800 print("******************************************\n")
801 failures = 0
802 for i in range(1, 2):
803 refTableFile = '%s/r%s/show_bgp_ipv6_summary.ref' % (thisDir, i)
804 if os.path.isfile(refTableFile):
805 # Read expected result from file
806 expected = open(refTableFile).read().rstrip()
807 # Fix newlines (make them all the same)
808 expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1)
809
810 # Actual output from router
811 actual = net['r%s' % i].cmd('vtysh -c "show bgp ipv6 summary" 2> /dev/null').rstrip()
812 # Mask out "using XXiXX bytes" portion. They are random...
813 actual = re.sub(r"using [0-9]+ bytes", "using XXXX bytes", actual)
814 # Mask out "using XiXXX KiB" portion. They are random...
815 actual = re.sub(r"using [0-9]+ KiB", "using XXXX KiB", actual)
08fa1af7
MW
816 #
817 # Remove extra summaries which exist with newer versions
818 #
819 # Remove summary lines (changed recently)
820 actual = re.sub(r'Total number.*', '', actual)
821 actual = re.sub(r'Displayed.*', '', actual)
822 # Remove IPv4 Unicast Summary (Title only)
823 actual = re.sub(r'IPv6 Unicast Summary:', '', actual)
824 # Remove IPv4 Multicast Summary (all of it)
825 actual = re.sub(r'IPv6 Multicast Summary:', '', actual)
826 actual = re.sub(r'No IPv6 Multicast neighbor is configured', '', actual)
827 # Remove IPv4 VPN Summary (all of it)
828 actual = re.sub(r'IPv6 VPN Summary:', '', actual)
829 actual = re.sub(r'No IPv6 VPN neighbor is configured', '', actual)
830 # Remove IPv4 Encap Summary (all of it)
831 actual = re.sub(r'IPv6 Encap Summary:', '', actual)
832 actual = re.sub(r'No IPv6 Encap neighbor is configured', '', actual)
833 # Remove Unknown Summary (all of it)
834 actual = re.sub(r'Unknown Summary:', '', actual)
835 actual = re.sub(r'No Unknown neighbor is configured', '', actual)
8b2e59e9
DS
836
837 # Remove Labeled Unicast Summary (all of it)
838 actual = re.sub(r'IPv6 labeled-unicast Summary:', '', actual)
839 actual = re.sub(r'No IPv6 labeled-unicast neighbor is configured', '', actual)
840
08fa1af7
MW
841 # Strip empty lines
842 actual = actual.lstrip()
843 actual = actual.rstrip()
844 #
4501fbca
MW
845 # Fix newlines (make them all the same)
846 actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
847
848 # Generate Diff
17070436
MW
849 diff = topotest.get_textdiff(actual, expected,
850 title1="actual SHOW BGP IPv6 SUMMARY",
851 title2="expected SHOW BGP IPv6 SUMMARY")
4501fbca
MW
852
853 # Empty string if it matches, otherwise diff contains unified diff
854 if diff:
855 sys.stderr.write('r%s failed SHOW BGP IPv6 SUMMARY check:\n%s\n' % (i, diff))
856 failures += 1
857 else:
858 print("r%s ok" % i)
859
860 assert failures == 0, "SHOW BGP IPv6 SUMMARY failed for router r%s:\n%s" % (i, diff)
861
7e7fc73b
MW
862 # Make sure that all daemons are running
863 for i in range(1, 2):
864 fatal_error = net['r%s' % i].checkRouterRunning()
865 assert fatal_error == "", fatal_error
866
4501fbca
MW
867 # For debugging after starting FRR/Quagga daemons, uncomment the next line
868 # CLI(net)
869
870
871def test_bgp_ipv4():
872 global fatal_error
873 global net
874
875 # Skip if previous fatal error condition is raised
876 if (fatal_error != ""):
877 pytest.skip(fatal_error)
878
879 thisDir = os.path.dirname(os.path.realpath(__file__))
880
b2764f90 881 print("\n\n** Verifying BGP IPv4")
4501fbca 882 print("******************************************\n")
6a57e103 883 diffresult = {}
4501fbca 884 for i in range(1, 2):
6a57e103
PZ
885 success = 0
886 for refTableFile in (glob.glob(
887 '%s/r%s/show_bgp_ipv4*.ref' % (thisDir, i))):
888 if os.path.isfile(refTableFile):
889 # Read expected result from file
890 expected = open(refTableFile).read().rstrip()
891 # Fix newlines (make them all the same)
892 expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1)
893
894 # Actual output from router
895 actual = net['r%s' % i].cmd('vtysh -c "show bgp ipv4" 2> /dev/null').rstrip()
896 # Remove summary line (changed recently)
897 actual = re.sub(r'Total number.*', '', actual)
898 actual = re.sub(r'Displayed.*', '', actual)
899 actual = actual.rstrip()
900 # Fix newlines (make them all the same)
901 actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
902
903 # Generate Diff
904 diff = topotest.get_textdiff(actual, expected,
905 title1="actual SHOW BGP IPv4",
906 title2="expected SHOW BGP IPv4")
907
908 # Empty string if it matches, otherwise diff contains unified diff
909 if diff:
910 diffresult[refTableFile] = diff
911 else:
912 success = 1
913 print("template %s matched: r%s ok" % (refTableFile, i))
914 break
915
916 if not success:
917 resultstr = 'No template matched.\n'
918 for f in diffresult.iterkeys():
919 resultstr += (
920 'template %s: r%s failed SHOW BGP IPv4 check:\n%s\n'
921 % (f, i, diffresult[f]))
922 raise AssertionError(
923 "SHOW BGP IPv4 failed for router r%s:\n%s" % (i, resultstr))
4501fbca 924
7e7fc73b
MW
925 # Make sure that all daemons are running
926 for i in range(1, 2):
927 fatal_error = net['r%s' % i].checkRouterRunning()
928 assert fatal_error == "", fatal_error
929
4501fbca
MW
930 # For debugging after starting FRR/Quagga daemons, uncomment the next line
931 # CLI(net)
932
933
934def test_bgp_ipv6():
935 global fatal_error
936 global net
937
938 # Skip if previous fatal error condition is raised
939 if (fatal_error != ""):
940 pytest.skip(fatal_error)
941
942 thisDir = os.path.dirname(os.path.realpath(__file__))
943
b2764f90 944 print("\n\n** Verifying BGP IPv6")
4501fbca 945 print("******************************************\n")
6a57e103 946 diffresult = {}
4501fbca 947 for i in range(1, 2):
6a57e103
PZ
948 success = 0
949 for refTableFile in (glob.glob(
950 '%s/r%s/show_bgp_ipv6*.ref' % (thisDir, i))):
951 if os.path.isfile(refTableFile):
952 # Read expected result from file
953 expected = open(refTableFile).read().rstrip()
954 # Fix newlines (make them all the same)
955 expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1)
956
957 # Actual output from router
958 actual = net['r%s' % i].cmd('vtysh -c "show bgp ipv6" 2> /dev/null').rstrip()
959 # Remove summary line (changed recently)
960 actual = re.sub(r'Total number.*', '', actual)
961 actual = re.sub(r'Displayed.*', '', actual)
962 actual = actual.rstrip()
963 # Fix newlines (make them all the same)
964 actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
965
966 # Generate Diff
967 diff = topotest.get_textdiff(actual, expected,
968 title1="actual SHOW BGP IPv6",
969 title2="expected SHOW BGP IPv6")
970
971 # Empty string if it matches, otherwise diff contains unified diff
972 if diff:
973 diffresult[refTableFile] = diff
974 else:
975 success = 1
976 print("template %s matched: r%s ok" % (refTableFile, i))
977
978 if not success:
979 resultstr = 'No template matched.\n'
980 for f in diffresult.iterkeys():
981 resultstr += (
982 'template %s: r%s failed SHOW BGP IPv6 check:\n%s\n'
983 % (f, i, diffresult[f]))
984 raise AssertionError(
985 "SHOW BGP IPv6 failed for router r%s:\n%s" % (i, resultstr))
4501fbca 986
7e7fc73b
MW
987 # Make sure that all daemons are running
988 for i in range(1, 2):
989 fatal_error = net['r%s' % i].checkRouterRunning()
990 assert fatal_error == "", fatal_error
991
4501fbca
MW
992 # For debugging after starting FRR/Quagga daemons, uncomment the next line
993 # CLI(net)
994
41fce07c
DS
995def test_route_map():
996 global fatal_error
997 global net
998
999 if (fatal_error != ""):
1000 pytest.skip(fatal_error)
1001
1002 thisDir = os.path.dirname(os.path.realpath(__file__))
1003
1004 print("\n\n** Verifying some basic routemap forward references\n")
1005 print("*******************************************************\n")
1006 failures = 0
1007 for i in range(1, 2):
1008 refroutemap = '%s/r%s/show_route_map.ref' % (thisDir, i)
1009 if os.path.isfile(refroutemap):
1010 expected = open(refroutemap).read().rstrip()
1011 expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1)
1012
1013 actual = net['r%s' %i].cmd('vtysh -c "show route-map" 2> /dev/null').rstrip()
1014 actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
1015
1016 diff = topotest.get_textdiff(actual, expected,
1017 title1="actual show route-map",
1018 title2="expected show route-map")
1019
1020 if diff:
1021 sys.stderr.write('r%s failed show route-map command Check:\n%s\n' % (i, diff))
1022 failures += 1
1023 else:
1024 print("r%s ok" %i)
4501fbca 1025
41fce07c 1026 assert failures == 0, "Show route-map command failed for router r%s:\n%s" % (i, diff)
4501fbca 1027
887a232c
SW
1028def test_nexthop_groups_with_route_maps():
1029 global fatal_error
1030 global net
1031
1032 # Skip if previous fatal error condition is raised
1033 if (fatal_error != ""):
1034 pytest.skip(fatal_error)
1035
1036 print("\n\n** Verifying Nexthop Groups With Route-Maps")
1037 print("******************************************\n")
1038
1039 ### Nexthop Group With Route-Map Tests
1040
1041 # Create a lib nexthop-group
1042 net["r1"].cmd('vtysh -c "c t" -c "nexthop-group test" -c "nexthop 1.1.1.1" -c "nexthop 1.1.1.2"')
1043
1044 ## Route-Map Proto Source
1045
1046 route_str = "2.2.2.1"
1047 src_str = "192.168.0.1"
1048
1049 net["r1"].cmd('vtysh -c "c t" -c "route-map NH-SRC permit 111" -c "set src %s"' % src_str)
1050 net["r1"].cmd('vtysh -c "c t" -c "ip protocol sharp route-map NH-SRC"')
1051
1052 net["r1"].cmd('vtysh -c "sharp install routes %s nexthop-group test 1"' % route_str)
1053
1054 verify_route_nexthop_group("%s/32" % route_str)
1055
1056 # Only a valid test on linux using nexthop objects
1057 if sys.platform.startswith("linux"):
1058 output = net["r1"].cmd('ip route show %s/32' % route_str)
1059 match = re.search(r"src %s" % src_str, output)
1060 assert match is not None, "Route %s/32 not installed with src %s" % (route_str, src_str)
1061
1062 # Remove NHG routes and route-map
1063 net["r1"].cmd('vtysh -c "sharp remove routes %s 1"' % route_str)
1064 net["r1"].cmd('vtysh -c "c t" -c "no ip protocol sharp route-map NH-SRC"')
1065 net["r1"].cmd('vtysh -c "c t" -c "no route-map NH-SRC permit 111" -c "set src %s"' % src_str)
1066 net["r1"].cmd('vtysh -c "c t" -c "no route-map NH-SRC"')
1067
1068 ## Route-Map Deny/Permit with same nexthop group
1069
1070 permit_route_str = "3.3.3.1"
1071 deny_route_str = "3.3.3.2"
1072
1073 net["r1"].cmd('vtysh -c "c t" -c "ip prefix-list NOPE seq 5 permit %s/32"' % permit_route_str)
1074 net["r1"].cmd('vtysh -c "c t" -c "route-map NOPE permit 111" -c "match ip address prefix-list NOPE"')
1075 net["r1"].cmd('vtysh -c "c t" -c "route-map NOPE deny 222"')
1076 net["r1"].cmd('vtysh -c "c t" -c "ip protocol sharp route-map NOPE"')
1077
1078 # This route should be permitted
1079 net["r1"].cmd('vtysh -c "sharp install routes %s nexthop-group test 1"' % permit_route_str)
1080
1081 verify_route_nexthop_group("%s/32" % permit_route_str)
1082
1083 # This route should be denied
1084 net["r1"].cmd('vtysh -c "sharp install routes %s nexthop-group test 1"' % deny_route_str)
1085
1086 nhg_id = route_get_nhg_id(deny_route_str)
1087 output = net["r1"].cmd('vtysh -c "show nexthop-group rib %d"' % nhg_id)
1088
1089 match = re.search(r"Valid", output)
1090 assert match is None, "Nexthop Group ID=%d should not be marked Valid" % nhg_id
1091
1092 match = re.search(r"Installed", output)
1093 assert match is None, "Nexthop Group ID=%d should not be marked Installed" % nhg_id
1094
1095 # Remove NHG routes and route-map
1096 net["r1"].cmd('vtysh -c "sharp remove routes %s 1"' % permit_route_str)
1097 net["r1"].cmd('vtysh -c "sharp remove routes %s 1"' % deny_route_str)
1098 net["r1"].cmd('vtysh -c "c t" -c "no ip protocol sharp route-map NOPE"')
1099 net["r1"].cmd('vtysh -c "c t" -c "no route-map NOPE permit 111"')
1100 net["r1"].cmd('vtysh -c "c t" -c "no route-map NOPE deny 222"')
1101 net["r1"].cmd('vtysh -c "c t" -c "no route-map NOPE"')
1102 net["r1"].cmd('vtysh -c "c t" -c "no ip prefix-list NOPE seq 5 permit %s/32"' % permit_route_str)
1103
4501fbca
MW
1104def test_mpls_interfaces():
1105 global fatal_error
1106 global net
1107
1108 # Skip if previous fatal error condition is raised
1109 if (fatal_error != ""):
1110 pytest.skip(fatal_error)
1111
1112 # Skip if no LDP installed or old kernel
1113 if (net['r1'].daemon_available('ldpd') == False):
1114 pytest.skip("No MPLS or kernel < 4.5")
1115
1116 thisDir = os.path.dirname(os.path.realpath(__file__))
1117
b2764f90 1118 print("\n\n** Verifying MPLS Interfaces")
4501fbca
MW
1119 print("******************************************\n")
1120 failures = 0
1121 for i in range(1, 2):
1122 refTableFile = '%s/r%s/show_mpls_ldp_interface.ref' % (thisDir, i)
1123 if os.path.isfile(refTableFile):
1124 # Read expected result from file
1125 expected = open(refTableFile).read().rstrip()
1126 # Fix newlines (make them all the same)
1127 expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1)
1128
1129 # Actual output from router
1130 actual = net['r%s' % i].cmd('vtysh -c "show mpls ldp interface" 2> /dev/null').rstrip()
1131 # Mask out Timer in Uptime
1132 actual = re.sub(r" [0-9][0-9]:[0-9][0-9]:[0-9][0-9] ", " xx:xx:xx ", actual)
1133 # Fix newlines (make them all the same)
1134 actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
1135
1136 # Generate Diff
17070436
MW
1137 diff = topotest.get_textdiff(actual, expected,
1138 title1="actual MPLS LDP interface status",
1139 title2="expected MPLS LDP interface status")
4501fbca
MW
1140
1141 # Empty string if it matches, otherwise diff contains unified diff
1142 if diff:
1143 sys.stderr.write('r%s failed MPLS LDP Interface status Check:\n%s\n' % (i, diff))
1144 failures += 1
1145 else:
1146 print("r%s ok" % i)
1147
1148 if failures>0:
1149 fatal_error = "MPLS LDP Interface status failed"
1150
1151 assert failures == 0, "MPLS LDP Interface status failed for router r%s:\n%s" % (i, diff)
1152
7e7fc73b
MW
1153 # Make sure that all daemons are running
1154 for i in range(1, 2):
1155 fatal_error = net['r%s' % i].checkRouterRunning()
1156 assert fatal_error == "", fatal_error
1157
4501fbca
MW
1158 # For debugging after starting FRR/Quagga daemons, uncomment the next line
1159 # CLI(net)
1160
1161
1162def test_shutdown_check_stderr():
1163 global fatal_error
1164 global net
1165
1166 # Skip if previous fatal error condition is raised
1167 if (fatal_error != ""):
1168 pytest.skip(fatal_error)
1169
b2764f90 1170 print("\n\n** Verifying unexpected STDERR output from daemons")
4501fbca
MW
1171 print("******************************************\n")
1172
1173 if os.environ.get('TOPOTESTS_CHECK_STDERR') is None:
50c40bde
MW
1174 print("SKIPPED final check on StdErr output: Disabled (TOPOTESTS_CHECK_STDERR undefined)\n")
1175 pytest.skip('Skipping test for Stderr output')
4501fbca
MW
1176
1177 thisDir = os.path.dirname(os.path.realpath(__file__))
1178
50c40bde
MW
1179 print("thisDir=" + thisDir)
1180
4501fbca
MW
1181 net['r1'].stopRouter()
1182
1183 log = net['r1'].getStdErr('ripd')
8e957dbb
MW
1184 if log:
1185 print("\nRIPd StdErr Log:\n" + log)
4501fbca 1186 log = net['r1'].getStdErr('ripngd')
8e957dbb
MW
1187 if log:
1188 print("\nRIPngd StdErr Log:\n" + log)
4501fbca 1189 log = net['r1'].getStdErr('ospfd')
8e957dbb
MW
1190 if log:
1191 print("\nOSPFd StdErr Log:\n" + log)
4501fbca 1192 log = net['r1'].getStdErr('ospf6d')
8e957dbb
MW
1193 if log:
1194 print("\nOSPF6d StdErr Log:\n" + log)
4501fbca 1195 log = net['r1'].getStdErr('isisd')
8e957dbb
MW
1196 if log:
1197 print("\nISISd StdErr Log:\n" + log)
4501fbca 1198 log = net['r1'].getStdErr('bgpd')
8e957dbb
MW
1199 if log:
1200 print("\nBGPd StdErr Log:\n" + log)
af39fbe7
MS
1201
1202 log = net['r1'].getStdErr('nhrpd')
1203 if log:
1204 print("\nNHRPd StdErr Log:\n" + log)
1205
1206 log = net['r1'].getStdErr('pbrd')
1207 if log:
1208 print("\nPBRd StdErr Log:\n" + log)
1209
1210 log = net['r1'].getStdErr('babeld')
1211 if log:
1212 print("\nBABELd StdErr Log:\n" + log)
1213
4501fbca
MW
1214 if (net['r1'].daemon_available('ldpd')):
1215 log = net['r1'].getStdErr('ldpd')
8e957dbb
MW
1216 if log:
1217 print("\nLDPd StdErr Log:\n" + log)
4501fbca 1218 log = net['r1'].getStdErr('zebra')
8e957dbb
MW
1219 if log:
1220 print("\nZebra StdErr Log:\n" + log)
4501fbca
MW
1221
1222
50c40bde
MW
1223def test_shutdown_check_memleak():
1224 global fatal_error
1225 global net
1226
1227 # Skip if previous fatal error condition is raised
1228 if (fatal_error != ""):
1229 pytest.skip(fatal_error)
1230
1231 if os.environ.get('TOPOTESTS_CHECK_MEMLEAK') is None:
1232 print("SKIPPED final check on Memory leaks: Disabled (TOPOTESTS_CHECK_MEMLEAK undefined)\n")
1233 pytest.skip('Skipping test for memory leaks')
1234
1235 thisDir = os.path.dirname(os.path.realpath(__file__))
1236
1237 for i in range(1, 2):
1238 net['r%s' % i].stopRouter()
1239 net['r%s' % i].report_memory_leaks(os.environ.get('TOPOTESTS_CHECK_MEMLEAK'), os.path.basename(__file__))
1240
1241
4501fbca
MW
1242if __name__ == '__main__':
1243
1244 setLogLevel('info')
1245 # To suppress tracebacks, either use the following pytest call or add "--tb=no" to cli
1246 # retval = pytest.main(["-s", "--tb=no"])
1247 retval = pytest.main(["-s"])
1248 sys.exit(retval)