]> git.proxmox.com Git - mirror_frr.git/blame - tests/topotests/all-protocol-startup/test_all_protocol_startup.py
all-protocol-startup: Add test suite which runs all protocols at once and verifies...
[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
33import difflib
34import pytest
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))
114 net['r%s' % i].loadConf('ospf6d', '%s/r%s/ospf6d.conf' % (thisDir, i))
115 net['r%s' % i].loadConf('isisd', '%s/r%s/isisd.conf' % (thisDir, i))
116 net['r%s' % i].loadConf('bgpd', '%s/r%s/bgpd.conf' % (thisDir, i))
117 if net['r%s' % i].daemon_available('ldpd'):
118 # Only test LDPd if it's installed and Kernel >= 4.5
119 net['r%s' % i].loadConf('ldpd', '%s/r%s/ldpd.conf' % (thisDir, i))
120 net['r%s' % i].startRouter()
121
122 # For debugging after starting Quagga/FRR daemons, uncomment the next line
123 # CLI(net)
124
125
126def teardown_module(module):
127 global net
128
129 print("\n\n** %s: Shutdown Topology" % module.__name__)
130 print("******************************************\n")
131
132 # End - Shutdown network
133 net.stop()
134
135
136def test_router_running():
137 global fatal_error
138 global net
139
140 # Skip if previous fatal error condition is raised
141 if (fatal_error != ""):
142 pytest.skip(fatal_error)
143
144 print("\n\n** Check if FRR/Quagga is running on each Router node")
145 print("******************************************\n")
146 sleep(5)
147
148 # Starting Routers
149 for i in range(1, 2):
150 fatal_error = net['r%s' % i].checkRouterRunning()
151 assert fatal_error == "", fatal_error
152
153 # For debugging after starting FRR/Quagga daemons, uncomment the next line
154 # CLI(net)
155
156
157def test_error_messages_vtysh():
158 global fatal_error
159 global net
160
161 # Skip if previous fatal error condition is raised
162 if (fatal_error != ""):
163 pytest.skip(fatal_error)
164
165 print("\n\n** Check for error messages on VTYSH")
166 print("******************************************\n")
167
168 failures = 0
169 for i in range(1, 2):
170 #
171 # First checking Standard Output
172 #
173
174 # VTYSH output from router
175 vtystdout = net['r%s' % i].cmd('vtysh -c "show version" 2> /dev/null').rstrip()
176
177 # Fix newlines (make them all the same)
178 vtystdout = ('\n'.join(vtystdout.splitlines()) + '\n').rstrip()
179 # Drop everything starting with "FRRouting X.xx" message
180 vtystdout = re.sub(r"FRRouting [0-9]+.*", "", vtystdout, flags=re.DOTALL)
181
182 if (vtystdout != ''):
183 sys.stderr.write('\nr%s created some spurious VTYSH start StdOut messages:\n%s\n' % (i, vtystdout))
184 failures += 1
185 else:
186 print("r%s StdOut ok" % i)
187
188 #
189 # Second checking Standard Error
190 #
191
192 # VTYSH StdErr output from router
193 vtystderr = net['r%s' % i].cmd('vtysh -c "show version" > /dev/null').rstrip()
194
195 # Fix newlines (make them all the same)
196 vtystderr = ('\n'.join(vtystderr.splitlines()) + '\n').rstrip()
197 # # Drop everything starting with "FRRouting X.xx" message
198 # vtystderr = re.sub(r"FRRouting [0-9]+.*", "", vtystderr, flags=re.DOTALL)
199
200 if (vtystderr != ''):
201 sys.stderr.write('\nr%s created some spurious VTYSH start StdErr messages:\n<%s>\n' % (i, vtystderr))
202 failures += 1
203 else:
204 print("r%s StdErr ok" % i)
205
206 assert failures == 0, "IP RIP status failed for router r%s:\n%s" % (i, diff)
207
208 # For debugging after starting FRR/Quagga daemons, uncomment the next line
209 # CLI(net)
210
211
212def test_error_messages_daemons():
213 global fatal_error
214 global net
215
216 # Skip if previous fatal error condition is raised
217 if (fatal_error != ""):
218 pytest.skip(fatal_error)
219
220 print("\n\n** Check for error messages in daemons")
221 print("******************************************\n")
222
223 error_logs = ""
224
225 for i in range(1, 2):
226 log = net['r%s' % i].getStdErr('ripd')
227 if log:
228 error_logs += "r%s RIPd StdErr Output:\n" % i
229 error_logs += log
230 log = net['r%s' % i].getStdErr('ripngd')
231 if log:
232 error_logs += "r%s RIPngd StdErr Output:\n" % i
233 error_logs += log
234 log = net['r%s' % i].getStdErr('ospfd')
235 if log:
236 error_logs += "r%s OSPFd StdErr Output:\n" % i
237 error_logs += log
238 log = net['r%s' % i].getStdErr('ospf6d')
239 if log:
240 error_logs += "r%s OSPF6d StdErr Output:\n" % i
241 error_logs += log
242 log = net['r%s' % i].getStdErr('isisd')
243 # ISIS shows debugging enabled status on StdErr
244 # Remove these messages
245 log = re.sub(r"^IS-IS .* debugging is on.*", "", log).rstrip()
246 if log:
247 error_logs += "r%s ISISd StdErr Output:\n" % i
248 error_logs += log
249 log = net['r%s' % i].getStdErr('bgpd')
250 if log:
251 error_logs += "r%s BGPd StdErr Output:\n" % i
252 error_logs += log
253 if (net['r%s' % i].daemon_available('ldpd')):
254 log = net['r%s' % i].getStdErr('ldpd')
255 if log:
256 error_logs += "r%s LDPd StdErr Output:\n" % i
257 error_logs += log
258 log = net['r%s' % i].getStdErr('zebra')
259 if log:
260 error_logs += "r%s Zebra StdErr Output:\n"
261 error_logs += log
262
263 if error_logs:
264 sys.stderr.write('Failed check for StdErr Output on daemons:\n%s\n' % error_logs)
265
266 assert error_logs == "", "Daemons report errors to StdErr"
267
268 # For debugging after starting FRR/Quagga daemons, uncomment the next line
269 # CLI(net)
270
271
272def test_converge_protocols():
273 global fatal_error
274 global net
275
276 # Skip if previous fatal error condition is raised
277 if (fatal_error != ""):
278 pytest.skip(fatal_error)
279
280 thisDir = os.path.dirname(os.path.realpath(__file__))
281
282 print("\n\n** Waiting for protocols convergence")
283 print("******************************************\n")
284
285 # Not really implemented yet - just sleep 60 secs for now
286 sleep(60)
287
288 # For debugging after starting FRR/Quagga daemons, uncomment the next line
289 ## CLI(net)
290
291
292def test_rip_status():
293 global fatal_error
294 global net
295
296 # Skip if previous fatal error condition is raised
297 if (fatal_error != ""):
298 pytest.skip(fatal_error)
299
300 thisDir = os.path.dirname(os.path.realpath(__file__))
301
302 # Verify RIP Status
303 print("\n\n** Verifing RIP status")
304 print("******************************************\n")
305 failures = 0
306 for i in range(1, 2):
307 refTableFile = '%s/r%s/rip_status.ref' % (thisDir, i)
308 if os.path.isfile(refTableFile):
309 # Read expected result from file
310 expected = open(refTableFile).read().rstrip()
311 # Fix newlines (make them all the same)
312 expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1)
313
314 # Actual output from router
315 actual = net['r%s' % i].cmd('vtysh -c "show ip rip status" 2> /dev/null').rstrip()
316 # Drop time in next due
317 actual = re.sub(r"in [0-9]+ seconds", "in XX seconds", actual)
318 # Drop time in last update
319 actual = re.sub(r" [0-2][0-9]:[0-5][0-9]:[0-5][0-9]", " XX:XX:XX", actual)
320 # Fix newlines (make them all the same)
321 actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
322
323 # Generate Diff
324 diff = ''.join(difflib.context_diff(actual, expected,
325 fromfile="actual IP RIP status",
326 tofile="expected IP RIP status"))
327
328 # Empty string if it matches, otherwise diff contains unified diff
329 if diff:
330 sys.stderr.write('r%s failed IP RIP status check:\n%s\n' % (i, diff))
331 failures += 1
332 else:
333 print("r%s ok" % i)
334
335 assert failures == 0, "IP RIP status failed for router r%s:\n%s" % (i, diff)
336
337 # For debugging after starting FRR/Quagga daemons, uncomment the next line
338 # CLI(net)
339
340
341def test_ripng_status():
342 global fatal_error
343 global net
344
345 # Skip if previous fatal error condition is raised
346 if (fatal_error != ""):
347 pytest.skip(fatal_error)
348
349 thisDir = os.path.dirname(os.path.realpath(__file__))
350
351 # Verify RIP Status
352 print("\n\n** Verifing RIPng status")
353 print("******************************************\n")
354 failures = 0
355 for i in range(1, 2):
356 refTableFile = '%s/r%s/ripng_status.ref' % (thisDir, i)
357 if os.path.isfile(refTableFile):
358 # Read expected result from file
359 expected = open(refTableFile).read().rstrip()
360 # Fix newlines (make them all the same)
361 expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1)
362
363 # Actual output from router
364 actual = net['r%s' % i].cmd('vtysh -c "show ipv6 ripng status" 2> /dev/null').rstrip()
365 # Mask out Link-Local mac address portion. They are random...
366 actual = re.sub(r" fe80::[0-9a-f:]+", " fe80::XXXX:XXXX:XXXX:XXXX", actual)
367 # Drop time in next due
368 actual = re.sub(r"in [0-9]+ seconds", "in XX seconds", actual)
369 # Drop time in last update
370 actual = re.sub(r" [0-2][0-9]:[0-5][0-9]:[0-5][0-9]", " XX:XX:XX", actual)
371 # Fix newlines (make them all the same)
372 actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
373
374 # Generate Diff
375 diff = ''.join(difflib.context_diff(actual, expected,
376 fromfile="actual IPv6 RIPng status",
377 tofile="expected IPv6 RIPng status"))
378
379 # Empty string if it matches, otherwise diff contains unified diff
380 if diff:
381 sys.stderr.write('r%s failed IPv6 RIPng status check:\n%s\n' % (i, diff))
382 failures += 1
383 else:
384 print("r%s ok" % i)
385
386 assert failures == 0, "IPv6 RIPng status failed for router r%s:\n%s" % (i, diff)
387
388 # For debugging after starting FRR/Quagga daemons, uncomment the next line
389 # CLI(net)
390
391
392def test_ospfv2_interfaces():
393 global fatal_error
394 global net
395
396 # Skip if previous fatal error condition is raised
397 if (fatal_error != ""):
398 pytest.skip(fatal_error)
399
400 thisDir = os.path.dirname(os.path.realpath(__file__))
401
402 # Verify RIP Status
403 print("\n\n** Verifing OSPFv2 interfaces")
404 print("******************************************\n")
405 failures = 0
406 for i in range(1, 2):
407 refTableFile = '%s/r%s/show_ip_ospf_interface.ref' % (thisDir, i)
408 if os.path.isfile(refTableFile):
409 # Read expected result from file
410 expected = open(refTableFile).read().rstrip()
411 # Fix newlines (make them all the same)
412 expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1)
413
414 # Actual output from router
415 actual = net['r%s' % i].cmd('vtysh -c "show ip ospf interface" 2> /dev/null').rstrip()
416 # Mask out Bandwidth portion. They may change..
417 actual = re.sub(r"BW [0-9]+ Mbit", "BW XX Mbit", actual)
418 # Drop time in next due
419 actual = re.sub(r"Hello due in [0-9\.]+s", "Hello due in XX.XXXs", actual)
420 # Fix newlines (make them all the same)
421 actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
422
423 # Generate Diff
424 diff = ''.join(difflib.context_diff(actual, expected,
425 fromfile="actual SHOW IP OSPF INTERFACE",
426 tofile="expected SHOW IP OSPF INTERFACE"))
427
428 # Empty string if it matches, otherwise diff contains unified diff
429 if diff:
430 sys.stderr.write('r%s failed SHOW IP OSPF INTERFACE check:\n%s\n' % (i, diff))
431 failures += 1
432 else:
433 print("r%s ok" % i)
434
435 assert failures == 0, "SHOW IP OSPF INTERFACE failed for router r%s:\n%s" % (i, diff)
436
437 # For debugging after starting FRR/Quagga daemons, uncomment the next line
438 # CLI(net)
439
440
441def test_isis_interfaces():
442 global fatal_error
443 global net
444
445 # Skip if previous fatal error condition is raised
446 if (fatal_error != ""):
447 pytest.skip(fatal_error)
448
449 thisDir = os.path.dirname(os.path.realpath(__file__))
450
451 # Verify RIP Status
452 print("\n\n** Verifing ISIS interfaces")
453 print("******************************************\n")
454 failures = 0
455 for i in range(1, 2):
456 refTableFile = '%s/r%s/show_isis_interface_detail.ref' % (thisDir, i)
457 if os.path.isfile(refTableFile):
458 # Read expected result from file
459 expected = open(refTableFile).read().rstrip()
460 # Fix newlines (make them all the same)
461 expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1)
462
463 # Actual output from router
464 actual = net['r%s' % i].cmd('vtysh -c "show isis interface detail" 2> /dev/null').rstrip()
465 # Mask out Link-Local mac address portion. They are random...
466 actual = re.sub(r"fe80::[0-9a-f:]+", "fe80::XXXX:XXXX:XXXX:XXXX", actual)
467 # Mask out SNPA mac address portion. They are random...
468 actual = re.sub(r"SNPA: [0-9a-f\.]+", "SNPA: XXXX.XXXX.XXXX", actual)
469 # Fix newlines (make them all the same)
470 actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
471
472 # Generate Diff
473 diff = ''.join(difflib.context_diff(actual, expected,
474 fromfile="actual SHOW ISIS INTERFACE DETAIL",
475 tofile="expected SHOW ISIS OSPF6 INTERFACE DETAIL"))
476
477 # Empty string if it matches, otherwise diff contains unified diff
478 if diff:
479 sys.stderr.write('r%s failed SHOW ISIS INTERFACE DETAIL check:\n%s\n' % (i, diff))
480 failures += 1
481 else:
482 print("r%s ok" % i)
483
484 assert failures == 0, "SHOW ISIS INTERFACE DETAIL failed for router r%s:\n%s" % (i, diff)
485
486 # For debugging after starting FRR/Quagga daemons, uncomment the next line
487 # CLI(net)
488
489
490def test_bgp_summary():
491 global fatal_error
492 global net
493
494 # Skip if previous fatal error condition is raised
495 if (fatal_error != ""):
496 pytest.skip(fatal_error)
497
498 thisDir = os.path.dirname(os.path.realpath(__file__))
499
500 # Verify RIP Status
501 print("\n\n** Verifing BGP Summary")
502 print("******************************************\n")
503 failures = 0
504 for i in range(1, 2):
505 refTableFile = '%s/r%s/show_bgp_summary.ref' % (thisDir, i)
506 if os.path.isfile(refTableFile):
507 # Read expected result from file
508 expected = open(refTableFile).read().rstrip()
509 # Fix newlines (make them all the same)
510 expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1)
511
512 # Actual output from router
513 actual = net['r%s' % i].cmd('vtysh -c "show bgp summary" 2> /dev/null').rstrip()
514 # Mask out "using XXiXX bytes" portion. They are random...
515 actual = re.sub(r"using [0-9]+ bytes", "using XXXX bytes", actual)
516 # Mask out "using XiXXX KiB" portion. They are random...
517 actual = re.sub(r"using [0-9]+ KiB", "using XXXX KiB", actual)
518 # Fix newlines (make them all the same)
519 actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
520
521 # Generate Diff
522 diff = ''.join(difflib.context_diff(actual, expected,
523 fromfile="actual SHOW BGP SUMMARY",
524 tofile="expected SHOW BGP SUMMARY"))
525
526 # Empty string if it matches, otherwise diff contains unified diff
527 if diff:
528 sys.stderr.write('r%s failed SHOW BGP SUMMARY check:\n%s\n' % (i, diff))
529 failures += 1
530 else:
531 print("r%s ok" % i)
532
533 assert failures == 0, "SHOW SHOW BGP SUMMARY failed for router r%s:\n%s" % (i, diff)
534
535 # For debugging after starting FRR/Quagga daemons, uncomment the next line
536 # CLI(net)
537
538
539def test_bgp_ipv6_summary():
540 global fatal_error
541 global net
542
543 # Skip if previous fatal error condition is raised
544 if (fatal_error != ""):
545 pytest.skip(fatal_error)
546
547 thisDir = os.path.dirname(os.path.realpath(__file__))
548
549 # Verify RIP Status
550 print("\n\n** Verifing BGP IPv6 Summary")
551 print("******************************************\n")
552 failures = 0
553 for i in range(1, 2):
554 refTableFile = '%s/r%s/show_bgp_ipv6_summary.ref' % (thisDir, i)
555 if os.path.isfile(refTableFile):
556 # Read expected result from file
557 expected = open(refTableFile).read().rstrip()
558 # Fix newlines (make them all the same)
559 expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1)
560
561 # Actual output from router
562 actual = net['r%s' % i].cmd('vtysh -c "show bgp ipv6 summary" 2> /dev/null').rstrip()
563 # Mask out "using XXiXX bytes" portion. They are random...
564 actual = re.sub(r"using [0-9]+ bytes", "using XXXX bytes", actual)
565 # Mask out "using XiXXX KiB" portion. They are random...
566 actual = re.sub(r"using [0-9]+ KiB", "using XXXX KiB", actual)
567 # Fix newlines (make them all the same)
568 actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
569
570 # Generate Diff
571 diff = ''.join(difflib.context_diff(actual, expected,
572 fromfile="actual SHOW BGP IPv6 SUMMARY",
573 tofile="expected SHOW BGP IPv6 SUMMARY"))
574
575 # Empty string if it matches, otherwise diff contains unified diff
576 if diff:
577 sys.stderr.write('r%s failed SHOW BGP IPv6 SUMMARY check:\n%s\n' % (i, diff))
578 failures += 1
579 else:
580 print("r%s ok" % i)
581
582 assert failures == 0, "SHOW BGP IPv6 SUMMARY failed for router r%s:\n%s" % (i, diff)
583
584 # For debugging after starting FRR/Quagga daemons, uncomment the next line
585 # CLI(net)
586
587
588def test_bgp_ipv4():
589 global fatal_error
590 global net
591
592 # Skip if previous fatal error condition is raised
593 if (fatal_error != ""):
594 pytest.skip(fatal_error)
595
596 thisDir = os.path.dirname(os.path.realpath(__file__))
597
598 # Verify RIP Status
599 print("\n\n** Verifing BGP IPv4")
600 print("******************************************\n")
601 failures = 0
602 for i in range(1, 2):
603 refTableFile = '%s/r%s/show_bgp_ipv4.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 bgp ipv4" 2> /dev/null').rstrip()
612 # Remove summary line (changed recently)
613 actual = re.sub(r'Total number.*', '', actual)
614 actual = re.sub(r'Displayed.*', '', actual)
615 actual = actual.rstrip()
616 # Fix newlines (make them all the same)
617 actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
618
619 # Generate Diff
620 diff = ''.join(difflib.context_diff(actual, expected,
621 fromfile="actual SHOW BGP IPv4",
622 tofile="expected SHOW BGP IPv4"))
623
624 # Empty string if it matches, otherwise diff contains unified diff
625 if diff:
626 sys.stderr.write('r%s failed SHOW BGP IPv4 check:\n%s\n' % (i, diff))
627 failures += 1
628 else:
629 print("r%s ok" % i)
630
631 assert failures == 0, "SHOW BGP IPv4 failed for router r%s:\n%s" % (i, diff)
632
633 # For debugging after starting FRR/Quagga daemons, uncomment the next line
634 # CLI(net)
635
636
637def test_bgp_ipv6():
638 global fatal_error
639 global net
640
641 # Skip if previous fatal error condition is raised
642 if (fatal_error != ""):
643 pytest.skip(fatal_error)
644
645 thisDir = os.path.dirname(os.path.realpath(__file__))
646
647 # Verify RIP Status
648 print("\n\n** Verifing BGP IPv6")
649 print("******************************************\n")
650 failures = 0
651 for i in range(1, 2):
652 refTableFile = '%s/r%s/show_bgp_ipv6.ref' % (thisDir, i)
653 if os.path.isfile(refTableFile):
654 # Read expected result from file
655 expected = open(refTableFile).read().rstrip()
656 # Fix newlines (make them all the same)
657 expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1)
658
659 # Actual output from router
660 actual = net['r%s' % i].cmd('vtysh -c "show bgp ipv6" 2> /dev/null').rstrip()
661 # Remove summary line (changed recently)
662 actual = re.sub(r'Total number.*', '', actual)
663 actual = re.sub(r'Displayed.*', '', actual)
664 actual = actual.rstrip()
665 # Fix newlines (make them all the same)
666 actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
667
668 # Generate Diff
669 diff = ''.join(difflib.context_diff(actual, expected,
670 fromfile="actual SHOW BGP IPv6",
671 tofile="expected SHOW BGP IPv6"))
672
673 # Empty string if it matches, otherwise diff contains unified diff
674 if diff:
675 sys.stderr.write('r%s failed SHOW BGP IPv6 check:\n%s\n' % (i, diff))
676 failures += 1
677 else:
678 print("r%s ok" % i)
679
680 assert failures == 0, "SHOW BGP IPv6 failed for router r%s:\n%s" % (i, diff)
681
682 # For debugging after starting FRR/Quagga daemons, uncomment the next line
683 # CLI(net)
684
685
686
687def test_mpls_interfaces():
688 global fatal_error
689 global net
690
691 # Skip if previous fatal error condition is raised
692 if (fatal_error != ""):
693 pytest.skip(fatal_error)
694
695 # Skip if no LDP installed or old kernel
696 if (net['r1'].daemon_available('ldpd') == False):
697 pytest.skip("No MPLS or kernel < 4.5")
698
699 thisDir = os.path.dirname(os.path.realpath(__file__))
700
701 # Verify OSPFv3 Routing Table
702 print("\n\n** Verifing MPLS Interfaces")
703 print("******************************************\n")
704 failures = 0
705 for i in range(1, 2):
706 refTableFile = '%s/r%s/show_mpls_ldp_interface.ref' % (thisDir, i)
707 if os.path.isfile(refTableFile):
708 # Read expected result from file
709 expected = open(refTableFile).read().rstrip()
710 # Fix newlines (make them all the same)
711 expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1)
712
713 # Actual output from router
714 actual = net['r%s' % i].cmd('vtysh -c "show mpls ldp interface" 2> /dev/null').rstrip()
715 # Mask out Timer in Uptime
716 actual = re.sub(r" [0-9][0-9]:[0-9][0-9]:[0-9][0-9] ", " xx:xx:xx ", actual)
717 # Fix newlines (make them all the same)
718 actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
719
720 # Generate Diff
721 diff = ''.join(difflib.context_diff(actual, expected,
722 fromfile="actual MPLS LDP interface status",
723 tofile="expected MPLS LDP interface status"))
724
725 # Empty string if it matches, otherwise diff contains unified diff
726 if diff:
727 sys.stderr.write('r%s failed MPLS LDP Interface status Check:\n%s\n' % (i, diff))
728 failures += 1
729 else:
730 print("r%s ok" % i)
731
732 if failures>0:
733 fatal_error = "MPLS LDP Interface status failed"
734
735 assert failures == 0, "MPLS LDP Interface status failed for router r%s:\n%s" % (i, diff)
736
737 # For debugging after starting FRR/Quagga daemons, uncomment the next line
738 # CLI(net)
739
740
741def test_shutdown_check_stderr():
742 global fatal_error
743 global net
744
745 # Skip if previous fatal error condition is raised
746 if (fatal_error != ""):
747 pytest.skip(fatal_error)
748
749 print("\n\n** Verifing unexpected STDERR output from daemons")
750 print("******************************************\n")
751
752 if os.environ.get('TOPOTESTS_CHECK_STDERR') is None:
753 print("SKIPPED (Disabled) - TOPOTESTS_CHECK_STDERR undefined\n")
754 pytest.skip('Skipping test for Stderr output and memory leaks')
755
756 thisDir = os.path.dirname(os.path.realpath(__file__))
757
758 net['r1'].stopRouter()
759
760 log = net['r1'].getStdErr('ripd')
761 print("\nRIPd StdErr Log:\n" + log)
762 log = net['r1'].getStdErr('ripngd')
763 print("\nRIPngd StdErr Log:\n" + log)
764 log = net['r1'].getStdErr('ospfd')
765 print("\nOSPFd StdErr Log:\n" + log)
766 log = net['r1'].getStdErr('ospf6d')
767 print("\nOSPF6d StdErr Log:\n" + log)
768 log = net['r1'].getStdErr('isisd')
769 print("\nISISd StdErr Log:\n" + log)
770 log = net['r1'].getStdErr('bgpd')
771 print("\nBGPd StdErr Log:\n" + log)
772 if (net['r1'].daemon_available('ldpd')):
773 log = net['r1'].getStdErr('ldpd')
774 print("\nLDPd StdErr Log:\n" + log)
775 log = net['r1'].getStdErr('zebra')
776 print("\nZebra StdErr Log:\n" + log)
777
778
779if __name__ == '__main__':
780
781 setLogLevel('info')
782 # To suppress tracebacks, either use the following pytest call or add "--tb=no" to cli
783 # retval = pytest.main(["-s", "--tb=no"])
784 retval = pytest.main(["-s"])
785 sys.exit(retval)