]> git.proxmox.com Git - mirror_frr.git/blame - tests/topotests/all-protocol-startup/test_all_protocol_startup.py
bgp: tolerate route-table-show header changes of PR 2045
[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))
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
555451fa 182 if (vtystdout == ''):
4501fbca
MW
183 print("r%s StdOut ok" % i)
184
555451fa 185 assert vtystdout == '', "Vtysh StdOut Output check failed for router r%s" % i
798fb593 186
4501fbca
MW
187 #
188 # Second checking Standard Error
189 #
190
191 # VTYSH StdErr output from router
192 vtystderr = net['r%s' % i].cmd('vtysh -c "show version" > /dev/null').rstrip()
193
194 # Fix newlines (make them all the same)
195 vtystderr = ('\n'.join(vtystderr.splitlines()) + '\n').rstrip()
196 # # Drop everything starting with "FRRouting X.xx" message
197 # vtystderr = re.sub(r"FRRouting [0-9]+.*", "", vtystderr, flags=re.DOTALL)
198
555451fa 199 if (vtystderr == ''):
4501fbca
MW
200 print("r%s StdErr ok" % i)
201
555451fa 202 assert vtystderr == '', "Vtysh StdErr Output check failed for router r%s" % i
4501fbca 203
7e7fc73b
MW
204 # Make sure that all daemons are running
205 for i in range(1, 2):
206 fatal_error = net['r%s' % i].checkRouterRunning()
207 assert fatal_error == "", fatal_error
208
4501fbca
MW
209 # For debugging after starting FRR/Quagga daemons, uncomment the next line
210 # CLI(net)
211
212
213def test_error_messages_daemons():
214 global fatal_error
215 global net
216
217 # Skip if previous fatal error condition is raised
218 if (fatal_error != ""):
219 pytest.skip(fatal_error)
220
221 print("\n\n** Check for error messages in daemons")
222 print("******************************************\n")
223
224 error_logs = ""
225
226 for i in range(1, 2):
227 log = net['r%s' % i].getStdErr('ripd')
228 if log:
229 error_logs += "r%s RIPd StdErr Output:\n" % i
230 error_logs += log
231 log = net['r%s' % i].getStdErr('ripngd')
232 if log:
233 error_logs += "r%s RIPngd StdErr Output:\n" % i
234 error_logs += log
235 log = net['r%s' % i].getStdErr('ospfd')
236 if log:
237 error_logs += "r%s OSPFd StdErr Output:\n" % i
238 error_logs += log
239 log = net['r%s' % i].getStdErr('ospf6d')
240 if log:
241 error_logs += "r%s OSPF6d StdErr Output:\n" % i
242 error_logs += log
243 log = net['r%s' % i].getStdErr('isisd')
244 # ISIS shows debugging enabled status on StdErr
245 # Remove these messages
246 log = re.sub(r"^IS-IS .* debugging is on.*", "", log).rstrip()
247 if log:
248 error_logs += "r%s ISISd StdErr Output:\n" % i
249 error_logs += log
250 log = net['r%s' % i].getStdErr('bgpd')
251 if log:
252 error_logs += "r%s BGPd StdErr Output:\n" % i
253 error_logs += log
254 if (net['r%s' % i].daemon_available('ldpd')):
255 log = net['r%s' % i].getStdErr('ldpd')
256 if log:
257 error_logs += "r%s LDPd StdErr Output:\n" % i
258 error_logs += log
259 log = net['r%s' % i].getStdErr('zebra')
260 if log:
261 error_logs += "r%s Zebra StdErr Output:\n"
262 error_logs += log
263
264 if error_logs:
265 sys.stderr.write('Failed check for StdErr Output on daemons:\n%s\n' % error_logs)
266
08fa1af7
MW
267 # Ignoring the issue if told to ignore (ie not yet fixed)
268 if (error_logs != ""):
1026c19a 269 if (os.environ.get('bamboo_TOPOTESTS_ISSUE_349') == "IGNORE"):
08fa1af7
MW
270 sys.stderr.write('Known issue - IGNORING. See https://github.com/FRRouting/frr/issues/349\n')
271 pytest.skip('Known issue - IGNORING. See https://github.com/FRRouting/frr/issues/349')
272
4501fbca
MW
273 assert error_logs == "", "Daemons report errors to StdErr"
274
275 # For debugging after starting FRR/Quagga daemons, uncomment the next line
276 # CLI(net)
277
278
279def test_converge_protocols():
280 global fatal_error
281 global net
282
283 # Skip if previous fatal error condition is raised
284 if (fatal_error != ""):
285 pytest.skip(fatal_error)
286
287 thisDir = os.path.dirname(os.path.realpath(__file__))
288
289 print("\n\n** Waiting for protocols convergence")
290 print("******************************************\n")
291
292 # Not really implemented yet - just sleep 60 secs for now
293 sleep(60)
294
7e7fc73b
MW
295 # Make sure that all daemons are running
296 for i in range(1, 2):
297 fatal_error = net['r%s' % i].checkRouterRunning()
298 assert fatal_error == "", fatal_error
299
4501fbca
MW
300 # For debugging after starting FRR/Quagga daemons, uncomment the next line
301 ## CLI(net)
302
303
304def test_rip_status():
305 global fatal_error
306 global net
307
308 # Skip if previous fatal error condition is raised
309 if (fatal_error != ""):
310 pytest.skip(fatal_error)
311
312 thisDir = os.path.dirname(os.path.realpath(__file__))
313
b2764f90 314 print("\n\n** Verifying RIP status")
4501fbca
MW
315 print("******************************************\n")
316 failures = 0
317 for i in range(1, 2):
318 refTableFile = '%s/r%s/rip_status.ref' % (thisDir, i)
319 if os.path.isfile(refTableFile):
320 # Read expected result from file
321 expected = open(refTableFile).read().rstrip()
322 # Fix newlines (make them all the same)
323 expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1)
324
325 # Actual output from router
326 actual = net['r%s' % i].cmd('vtysh -c "show ip rip status" 2> /dev/null').rstrip()
327 # Drop time in next due
328 actual = re.sub(r"in [0-9]+ seconds", "in XX seconds", actual)
329 # Drop time in last update
330 actual = re.sub(r" [0-2][0-9]:[0-5][0-9]:[0-5][0-9]", " XX:XX:XX", actual)
331 # Fix newlines (make them all the same)
332 actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
333
334 # Generate Diff
17070436
MW
335 diff = topotest.get_textdiff(actual, expected,
336 title1="actual IP RIP status",
337 title2="expected IP RIP status")
4501fbca
MW
338
339 # Empty string if it matches, otherwise diff contains unified diff
340 if diff:
341 sys.stderr.write('r%s failed IP RIP status check:\n%s\n' % (i, diff))
342 failures += 1
343 else:
344 print("r%s ok" % i)
345
346 assert failures == 0, "IP RIP status failed for router r%s:\n%s" % (i, diff)
347
7e7fc73b
MW
348 # Make sure that all daemons are running
349 for i in range(1, 2):
350 fatal_error = net['r%s' % i].checkRouterRunning()
351 assert fatal_error == "", fatal_error
352
4501fbca
MW
353 # For debugging after starting FRR/Quagga daemons, uncomment the next line
354 # CLI(net)
355
356
357def test_ripng_status():
358 global fatal_error
359 global net
360
361 # Skip if previous fatal error condition is raised
362 if (fatal_error != ""):
363 pytest.skip(fatal_error)
364
365 thisDir = os.path.dirname(os.path.realpath(__file__))
366
b2764f90 367 print("\n\n** Verifying RIPng status")
4501fbca
MW
368 print("******************************************\n")
369 failures = 0
370 for i in range(1, 2):
371 refTableFile = '%s/r%s/ripng_status.ref' % (thisDir, i)
372 if os.path.isfile(refTableFile):
373 # Read expected result from file
374 expected = open(refTableFile).read().rstrip()
375 # Fix newlines (make them all the same)
376 expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1)
377
378 # Actual output from router
379 actual = net['r%s' % i].cmd('vtysh -c "show ipv6 ripng status" 2> /dev/null').rstrip()
380 # Mask out Link-Local mac address portion. They are random...
381 actual = re.sub(r" fe80::[0-9a-f:]+", " fe80::XXXX:XXXX:XXXX:XXXX", actual)
382 # Drop time in next due
383 actual = re.sub(r"in [0-9]+ seconds", "in XX seconds", actual)
384 # Drop time in last update
385 actual = re.sub(r" [0-2][0-9]:[0-5][0-9]:[0-5][0-9]", " XX:XX:XX", actual)
386 # Fix newlines (make them all the same)
387 actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
388
389 # Generate Diff
17070436
MW
390 diff = topotest.get_textdiff(actual, expected,
391 title1="actual IPv6 RIPng status",
392 title2="expected IPv6 RIPng status")
4501fbca
MW
393
394 # Empty string if it matches, otherwise diff contains unified diff
395 if diff:
396 sys.stderr.write('r%s failed IPv6 RIPng status check:\n%s\n' % (i, diff))
397 failures += 1
398 else:
399 print("r%s ok" % i)
400
401 assert failures == 0, "IPv6 RIPng status failed for router r%s:\n%s" % (i, diff)
402
7e7fc73b
MW
403 # Make sure that all daemons are running
404 for i in range(1, 2):
405 fatal_error = net['r%s' % i].checkRouterRunning()
406 assert fatal_error == "", fatal_error
407
4501fbca
MW
408 # For debugging after starting FRR/Quagga daemons, uncomment the next line
409 # CLI(net)
410
411
412def test_ospfv2_interfaces():
413 global fatal_error
414 global net
415
416 # Skip if previous fatal error condition is raised
417 if (fatal_error != ""):
418 pytest.skip(fatal_error)
419
420 thisDir = os.path.dirname(os.path.realpath(__file__))
421
b2764f90 422 print("\n\n** Verifying OSPFv2 interfaces")
4501fbca
MW
423 print("******************************************\n")
424 failures = 0
425 for i in range(1, 2):
426 refTableFile = '%s/r%s/show_ip_ospf_interface.ref' % (thisDir, i)
427 if os.path.isfile(refTableFile):
428 # Read expected result from file
429 expected = open(refTableFile).read().rstrip()
430 # Fix newlines (make them all the same)
431 expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1)
432
433 # Actual output from router
434 actual = net['r%s' % i].cmd('vtysh -c "show ip ospf interface" 2> /dev/null').rstrip()
435 # Mask out Bandwidth portion. They may change..
436 actual = re.sub(r"BW [0-9]+ Mbit", "BW XX Mbit", actual)
437 # Drop time in next due
438 actual = re.sub(r"Hello due in [0-9\.]+s", "Hello due in XX.XXXs", actual)
985e6d50
MW
439 # Fix 'MTU mismatch detection: enabled' vs 'MTU mismatch detection:enabled' - accept both
440 actual = re.sub(r"MTU mismatch detection:([a-z]+.*)", r"MTU mismatch detection: \1", actual)
4501fbca
MW
441 # Fix newlines (make them all the same)
442 actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
443
444 # Generate Diff
17070436
MW
445 diff = topotest.get_textdiff(actual, expected,
446 title1="actual SHOW IP OSPF INTERFACE",
447 title2="expected SHOW IP OSPF INTERFACE")
4501fbca
MW
448
449 # Empty string if it matches, otherwise diff contains unified diff
450 if diff:
451 sys.stderr.write('r%s failed SHOW IP OSPF INTERFACE check:\n%s\n' % (i, diff))
452 failures += 1
453 else:
454 print("r%s ok" % i)
455
08fa1af7
MW
456 # Ignoring the issue if told to ignore (ie not yet fixed)
457 if (failures != 0):
1026c19a 458 if (os.environ.get('bamboo_TOPOTESTS_ISSUE_348') == "IGNORE"):
08fa1af7
MW
459 sys.stderr.write('Known issue - IGNORING. See https://github.com/FRRouting/frr/issues/348\n')
460 pytest.skip('Known issue - IGNORING. See https://github.com/FRRouting/frr/issues/348')
461
4501fbca
MW
462 assert failures == 0, "SHOW IP OSPF INTERFACE failed for router r%s:\n%s" % (i, diff)
463
7e7fc73b
MW
464 # Make sure that all daemons are running
465 for i in range(1, 2):
466 fatal_error = net['r%s' % i].checkRouterRunning()
467 assert fatal_error == "", fatal_error
468
4501fbca
MW
469 # For debugging after starting FRR/Quagga daemons, uncomment the next line
470 # CLI(net)
471
472
473def test_isis_interfaces():
474 global fatal_error
475 global net
476
477 # Skip if previous fatal error condition is raised
478 if (fatal_error != ""):
479 pytest.skip(fatal_error)
480
481 thisDir = os.path.dirname(os.path.realpath(__file__))
482
b2764f90 483 print("\n\n** Verifying ISIS interfaces")
4501fbca
MW
484 print("******************************************\n")
485 failures = 0
486 for i in range(1, 2):
487 refTableFile = '%s/r%s/show_isis_interface_detail.ref' % (thisDir, i)
488 if os.path.isfile(refTableFile):
489 # Read expected result from file
490 expected = open(refTableFile).read().rstrip()
491 # Fix newlines (make them all the same)
492 expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1)
493
494 # Actual output from router
495 actual = net['r%s' % i].cmd('vtysh -c "show isis interface detail" 2> /dev/null').rstrip()
496 # Mask out Link-Local mac address portion. They are random...
497 actual = re.sub(r"fe80::[0-9a-f:]+", "fe80::XXXX:XXXX:XXXX:XXXX", actual)
498 # Mask out SNPA mac address portion. They are random...
499 actual = re.sub(r"SNPA: [0-9a-f\.]+", "SNPA: XXXX.XXXX.XXXX", actual)
6ae351e8
MW
500 # Mask out Circuit ID number
501 actual = re.sub(r"Circuit Id: 0x[0-9]+", "Circuit Id: 0xXX", actual)
4501fbca
MW
502 # Fix newlines (make them all the same)
503 actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
504
505 # Generate Diff
17070436
MW
506 diff = topotest.get_textdiff(actual, expected,
507 title1="actual SHOW ISIS INTERFACE DETAIL",
508 title2="expected SHOW ISIS OSPF6 INTERFACE DETAIL")
4501fbca
MW
509
510 # Empty string if it matches, otherwise diff contains unified diff
511 if diff:
512 sys.stderr.write('r%s failed SHOW ISIS INTERFACE DETAIL check:\n%s\n' % (i, diff))
513 failures += 1
514 else:
515 print("r%s ok" % i)
516
517 assert failures == 0, "SHOW ISIS INTERFACE DETAIL failed for router r%s:\n%s" % (i, diff)
518
7e7fc73b
MW
519 # Make sure that all daemons are running
520 for i in range(1, 2):
521 fatal_error = net['r%s' % i].checkRouterRunning()
522 assert fatal_error == "", fatal_error
523
4501fbca
MW
524 # For debugging after starting FRR/Quagga daemons, uncomment the next line
525 # CLI(net)
526
527
528def test_bgp_summary():
529 global fatal_error
530 global net
531
532 # Skip if previous fatal error condition is raised
533 if (fatal_error != ""):
534 pytest.skip(fatal_error)
535
536 thisDir = os.path.dirname(os.path.realpath(__file__))
537
b2764f90 538 print("\n\n** Verifying BGP Summary")
4501fbca
MW
539 print("******************************************\n")
540 failures = 0
541 for i in range(1, 2):
08fa1af7 542 refTableFile = '%s/r%s/show_ip_bgp_summary.ref' % (thisDir, i)
4501fbca
MW
543 if os.path.isfile(refTableFile):
544 # Read expected result from file
545 expected = open(refTableFile).read().rstrip()
546 # Fix newlines (make them all the same)
547 expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1)
548
549 # Actual output from router
08fa1af7 550 actual = net['r%s' % i].cmd('vtysh -c "show ip bgp summary" 2> /dev/null').rstrip()
4501fbca
MW
551 # Mask out "using XXiXX bytes" portion. They are random...
552 actual = re.sub(r"using [0-9]+ bytes", "using XXXX bytes", actual)
553 # Mask out "using XiXXX KiB" portion. They are random...
554 actual = re.sub(r"using [0-9]+ KiB", "using XXXX KiB", actual)
08fa1af7
MW
555 #
556 # Remove extra summaries which exist with newer versions
557 #
558 # Remove summary lines (changed recently)
559 actual = re.sub(r'Total number.*', '', actual)
560 actual = re.sub(r'Displayed.*', '', actual)
561 # Remove IPv4 Unicast Summary (Title only)
562 actual = re.sub(r'IPv4 Unicast Summary:', '', actual)
563 # Remove IPv4 Multicast Summary (all of it)
564 actual = re.sub(r'IPv4 Multicast Summary:', '', actual)
565 actual = re.sub(r'No IPv4 Multicast neighbor is configured', '', actual)
566 # Remove IPv4 VPN Summary (all of it)
567 actual = re.sub(r'IPv4 VPN Summary:', '', actual)
568 actual = re.sub(r'No IPv4 VPN neighbor is configured', '', actual)
569 # Remove IPv4 Encap Summary (all of it)
570 actual = re.sub(r'IPv4 Encap Summary:', '', actual)
571 actual = re.sub(r'No IPv4 Encap neighbor is configured', '', actual)
572 # Remove Unknown Summary (all of it)
573 actual = re.sub(r'Unknown Summary:', '', actual)
574 actual = re.sub(r'No Unknown neighbor is configured', '', actual)
8b2e59e9
DS
575
576 actual = re.sub(r'IPv4 labeled-unicast Summary:', '', actual)
577 actual = re.sub(r'No IPv4 labeled-unicast neighbor is configured', '', actual)
578
08fa1af7
MW
579 # Strip empty lines
580 actual = actual.lstrip()
581 actual = actual.rstrip()
582 #
4501fbca
MW
583 # Fix newlines (make them all the same)
584 actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
585
586 # Generate Diff
17070436
MW
587 diff = topotest.get_textdiff(actual, expected,
588 title1="actual SHOW IP BGP SUMMARY",
589 title2="expected SHOW IP BGP SUMMARY")
4501fbca
MW
590
591 # Empty string if it matches, otherwise diff contains unified diff
592 if diff:
08fa1af7 593 sys.stderr.write('r%s failed SHOW IP BGP SUMMARY check:\n%s\n' % (i, diff))
4501fbca
MW
594 failures += 1
595 else:
596 print("r%s ok" % i)
597
08fa1af7 598 assert failures == 0, "SHOW IP BGP SUMMARY failed for router r%s:\n%s" % (i, diff)
4501fbca 599
7e7fc73b
MW
600 # Make sure that all daemons are running
601 for i in range(1, 2):
602 fatal_error = net['r%s' % i].checkRouterRunning()
603 assert fatal_error == "", fatal_error
604
4501fbca
MW
605 # For debugging after starting FRR/Quagga daemons, uncomment the next line
606 # CLI(net)
607
608
609def test_bgp_ipv6_summary():
610 global fatal_error
611 global net
612
613 # Skip if previous fatal error condition is raised
614 if (fatal_error != ""):
615 pytest.skip(fatal_error)
616
617 thisDir = os.path.dirname(os.path.realpath(__file__))
618
b2764f90 619 print("\n\n** Verifying BGP IPv6 Summary")
4501fbca
MW
620 print("******************************************\n")
621 failures = 0
622 for i in range(1, 2):
623 refTableFile = '%s/r%s/show_bgp_ipv6_summary.ref' % (thisDir, i)
624 if os.path.isfile(refTableFile):
625 # Read expected result from file
626 expected = open(refTableFile).read().rstrip()
627 # Fix newlines (make them all the same)
628 expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1)
629
630 # Actual output from router
631 actual = net['r%s' % i].cmd('vtysh -c "show bgp ipv6 summary" 2> /dev/null').rstrip()
632 # Mask out "using XXiXX bytes" portion. They are random...
633 actual = re.sub(r"using [0-9]+ bytes", "using XXXX bytes", actual)
634 # Mask out "using XiXXX KiB" portion. They are random...
635 actual = re.sub(r"using [0-9]+ KiB", "using XXXX KiB", actual)
08fa1af7
MW
636 #
637 # Remove extra summaries which exist with newer versions
638 #
639 # Remove summary lines (changed recently)
640 actual = re.sub(r'Total number.*', '', actual)
641 actual = re.sub(r'Displayed.*', '', actual)
642 # Remove IPv4 Unicast Summary (Title only)
643 actual = re.sub(r'IPv6 Unicast Summary:', '', actual)
644 # Remove IPv4 Multicast Summary (all of it)
645 actual = re.sub(r'IPv6 Multicast Summary:', '', actual)
646 actual = re.sub(r'No IPv6 Multicast neighbor is configured', '', actual)
647 # Remove IPv4 VPN Summary (all of it)
648 actual = re.sub(r'IPv6 VPN Summary:', '', actual)
649 actual = re.sub(r'No IPv6 VPN neighbor is configured', '', actual)
650 # Remove IPv4 Encap Summary (all of it)
651 actual = re.sub(r'IPv6 Encap Summary:', '', actual)
652 actual = re.sub(r'No IPv6 Encap neighbor is configured', '', actual)
653 # Remove Unknown Summary (all of it)
654 actual = re.sub(r'Unknown Summary:', '', actual)
655 actual = re.sub(r'No Unknown neighbor is configured', '', actual)
8b2e59e9
DS
656
657 # Remove Labeled Unicast Summary (all of it)
658 actual = re.sub(r'IPv6 labeled-unicast Summary:', '', actual)
659 actual = re.sub(r'No IPv6 labeled-unicast neighbor is configured', '', actual)
660
08fa1af7
MW
661 # Strip empty lines
662 actual = actual.lstrip()
663 actual = actual.rstrip()
664 #
4501fbca
MW
665 # Fix newlines (make them all the same)
666 actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
667
668 # Generate Diff
17070436
MW
669 diff = topotest.get_textdiff(actual, expected,
670 title1="actual SHOW BGP IPv6 SUMMARY",
671 title2="expected SHOW BGP IPv6 SUMMARY")
4501fbca
MW
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 SUMMARY 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 SUMMARY failed for router r%s:\n%s" % (i, diff)
681
7e7fc73b
MW
682 # Make sure that all daemons are running
683 for i in range(1, 2):
684 fatal_error = net['r%s' % i].checkRouterRunning()
685 assert fatal_error == "", fatal_error
686
4501fbca
MW
687 # For debugging after starting FRR/Quagga daemons, uncomment the next line
688 # CLI(net)
689
690
691def test_bgp_ipv4():
692 global fatal_error
693 global net
694
695 # Skip if previous fatal error condition is raised
696 if (fatal_error != ""):
697 pytest.skip(fatal_error)
698
699 thisDir = os.path.dirname(os.path.realpath(__file__))
700
b2764f90 701 print("\n\n** Verifying BGP IPv4")
4501fbca 702 print("******************************************\n")
6a57e103 703 diffresult = {}
4501fbca 704 for i in range(1, 2):
6a57e103
PZ
705 success = 0
706 for refTableFile in (glob.glob(
707 '%s/r%s/show_bgp_ipv4*.ref' % (thisDir, i))):
708 if os.path.isfile(refTableFile):
709 # Read expected result from file
710 expected = open(refTableFile).read().rstrip()
711 # Fix newlines (make them all the same)
712 expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1)
713
714 # Actual output from router
715 actual = net['r%s' % i].cmd('vtysh -c "show bgp ipv4" 2> /dev/null').rstrip()
716 # Remove summary line (changed recently)
717 actual = re.sub(r'Total number.*', '', actual)
718 actual = re.sub(r'Displayed.*', '', actual)
719 actual = actual.rstrip()
720 # Fix newlines (make them all the same)
721 actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
722
723 # Generate Diff
724 diff = topotest.get_textdiff(actual, expected,
725 title1="actual SHOW BGP IPv4",
726 title2="expected SHOW BGP IPv4")
727
728 # Empty string if it matches, otherwise diff contains unified diff
729 if diff:
730 diffresult[refTableFile] = diff
731 else:
732 success = 1
733 print("template %s matched: r%s ok" % (refTableFile, i))
734 break
735
736 if not success:
737 resultstr = 'No template matched.\n'
738 for f in diffresult.iterkeys():
739 resultstr += (
740 'template %s: r%s failed SHOW BGP IPv4 check:\n%s\n'
741 % (f, i, diffresult[f]))
742 raise AssertionError(
743 "SHOW BGP IPv4 failed for router r%s:\n%s" % (i, resultstr))
4501fbca 744
7e7fc73b
MW
745 # Make sure that all daemons are running
746 for i in range(1, 2):
747 fatal_error = net['r%s' % i].checkRouterRunning()
748 assert fatal_error == "", fatal_error
749
4501fbca
MW
750 # For debugging after starting FRR/Quagga daemons, uncomment the next line
751 # CLI(net)
752
753
754def test_bgp_ipv6():
755 global fatal_error
756 global net
757
758 # Skip if previous fatal error condition is raised
759 if (fatal_error != ""):
760 pytest.skip(fatal_error)
761
762 thisDir = os.path.dirname(os.path.realpath(__file__))
763
b2764f90 764 print("\n\n** Verifying BGP IPv6")
4501fbca 765 print("******************************************\n")
6a57e103 766 diffresult = {}
4501fbca 767 for i in range(1, 2):
6a57e103
PZ
768 success = 0
769 for refTableFile in (glob.glob(
770 '%s/r%s/show_bgp_ipv6*.ref' % (thisDir, i))):
771 if os.path.isfile(refTableFile):
772 # Read expected result from file
773 expected = open(refTableFile).read().rstrip()
774 # Fix newlines (make them all the same)
775 expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1)
776
777 # Actual output from router
778 actual = net['r%s' % i].cmd('vtysh -c "show bgp ipv6" 2> /dev/null').rstrip()
779 # Remove summary line (changed recently)
780 actual = re.sub(r'Total number.*', '', actual)
781 actual = re.sub(r'Displayed.*', '', actual)
782 actual = actual.rstrip()
783 # Fix newlines (make them all the same)
784 actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
785
786 # Generate Diff
787 diff = topotest.get_textdiff(actual, expected,
788 title1="actual SHOW BGP IPv6",
789 title2="expected SHOW BGP IPv6")
790
791 # Empty string if it matches, otherwise diff contains unified diff
792 if diff:
793 diffresult[refTableFile] = diff
794 else:
795 success = 1
796 print("template %s matched: r%s ok" % (refTableFile, i))
797
798 if not success:
799 resultstr = 'No template matched.\n'
800 for f in diffresult.iterkeys():
801 resultstr += (
802 'template %s: r%s failed SHOW BGP IPv6 check:\n%s\n'
803 % (f, i, diffresult[f]))
804 raise AssertionError(
805 "SHOW BGP IPv6 failed for router r%s:\n%s" % (i, resultstr))
4501fbca 806
7e7fc73b
MW
807 # Make sure that all daemons are running
808 for i in range(1, 2):
809 fatal_error = net['r%s' % i].checkRouterRunning()
810 assert fatal_error == "", fatal_error
811
4501fbca
MW
812 # For debugging after starting FRR/Quagga daemons, uncomment the next line
813 # CLI(net)
814
815
816
817def test_mpls_interfaces():
818 global fatal_error
819 global net
820
821 # Skip if previous fatal error condition is raised
822 if (fatal_error != ""):
823 pytest.skip(fatal_error)
824
825 # Skip if no LDP installed or old kernel
826 if (net['r1'].daemon_available('ldpd') == False):
827 pytest.skip("No MPLS or kernel < 4.5")
828
829 thisDir = os.path.dirname(os.path.realpath(__file__))
830
b2764f90 831 print("\n\n** Verifying MPLS Interfaces")
4501fbca
MW
832 print("******************************************\n")
833 failures = 0
834 for i in range(1, 2):
835 refTableFile = '%s/r%s/show_mpls_ldp_interface.ref' % (thisDir, i)
836 if os.path.isfile(refTableFile):
837 # Read expected result from file
838 expected = open(refTableFile).read().rstrip()
839 # Fix newlines (make them all the same)
840 expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1)
841
842 # Actual output from router
843 actual = net['r%s' % i].cmd('vtysh -c "show mpls ldp interface" 2> /dev/null').rstrip()
844 # Mask out Timer in Uptime
845 actual = re.sub(r" [0-9][0-9]:[0-9][0-9]:[0-9][0-9] ", " xx:xx:xx ", actual)
846 # Fix newlines (make them all the same)
847 actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
848
849 # Generate Diff
17070436
MW
850 diff = topotest.get_textdiff(actual, expected,
851 title1="actual MPLS LDP interface status",
852 title2="expected MPLS LDP interface status")
4501fbca
MW
853
854 # Empty string if it matches, otherwise diff contains unified diff
855 if diff:
856 sys.stderr.write('r%s failed MPLS LDP Interface status Check:\n%s\n' % (i, diff))
857 failures += 1
858 else:
859 print("r%s ok" % i)
860
861 if failures>0:
862 fatal_error = "MPLS LDP Interface status failed"
863
864 assert failures == 0, "MPLS LDP Interface status failed for router r%s:\n%s" % (i, diff)
865
7e7fc73b
MW
866 # Make sure that all daemons are running
867 for i in range(1, 2):
868 fatal_error = net['r%s' % i].checkRouterRunning()
869 assert fatal_error == "", fatal_error
870
4501fbca
MW
871 # For debugging after starting FRR/Quagga daemons, uncomment the next line
872 # CLI(net)
873
874
875def test_shutdown_check_stderr():
876 global fatal_error
877 global net
878
879 # Skip if previous fatal error condition is raised
880 if (fatal_error != ""):
881 pytest.skip(fatal_error)
882
b2764f90 883 print("\n\n** Verifying unexpected STDERR output from daemons")
4501fbca
MW
884 print("******************************************\n")
885
886 if os.environ.get('TOPOTESTS_CHECK_STDERR') is None:
50c40bde
MW
887 print("SKIPPED final check on StdErr output: Disabled (TOPOTESTS_CHECK_STDERR undefined)\n")
888 pytest.skip('Skipping test for Stderr output')
4501fbca
MW
889
890 thisDir = os.path.dirname(os.path.realpath(__file__))
891
50c40bde
MW
892 print("thisDir=" + thisDir)
893
4501fbca
MW
894 net['r1'].stopRouter()
895
896 log = net['r1'].getStdErr('ripd')
8e957dbb
MW
897 if log:
898 print("\nRIPd StdErr Log:\n" + log)
4501fbca 899 log = net['r1'].getStdErr('ripngd')
8e957dbb
MW
900 if log:
901 print("\nRIPngd StdErr Log:\n" + log)
4501fbca 902 log = net['r1'].getStdErr('ospfd')
8e957dbb
MW
903 if log:
904 print("\nOSPFd StdErr Log:\n" + log)
4501fbca 905 log = net['r1'].getStdErr('ospf6d')
8e957dbb
MW
906 if log:
907 print("\nOSPF6d StdErr Log:\n" + log)
4501fbca 908 log = net['r1'].getStdErr('isisd')
8e957dbb
MW
909 if log:
910 print("\nISISd StdErr Log:\n" + log)
4501fbca 911 log = net['r1'].getStdErr('bgpd')
8e957dbb
MW
912 if log:
913 print("\nBGPd StdErr Log:\n" + log)
4501fbca
MW
914 if (net['r1'].daemon_available('ldpd')):
915 log = net['r1'].getStdErr('ldpd')
8e957dbb
MW
916 if log:
917 print("\nLDPd StdErr Log:\n" + log)
4501fbca 918 log = net['r1'].getStdErr('zebra')
8e957dbb
MW
919 if log:
920 print("\nZebra StdErr Log:\n" + log)
4501fbca
MW
921
922
50c40bde
MW
923def test_shutdown_check_memleak():
924 global fatal_error
925 global net
926
927 # Skip if previous fatal error condition is raised
928 if (fatal_error != ""):
929 pytest.skip(fatal_error)
930
931 if os.environ.get('TOPOTESTS_CHECK_MEMLEAK') is None:
932 print("SKIPPED final check on Memory leaks: Disabled (TOPOTESTS_CHECK_MEMLEAK undefined)\n")
933 pytest.skip('Skipping test for memory leaks')
934
935 thisDir = os.path.dirname(os.path.realpath(__file__))
936
937 for i in range(1, 2):
938 net['r%s' % i].stopRouter()
939 net['r%s' % i].report_memory_leaks(os.environ.get('TOPOTESTS_CHECK_MEMLEAK'), os.path.basename(__file__))
940
941
4501fbca
MW
942if __name__ == '__main__':
943
944 setLogLevel('info')
945 # To suppress tracebacks, either use the following pytest call or add "--tb=no" to cli
946 # retval = pytest.main(["-s", "--tb=no"])
947 retval = pytest.main(["-s"])
948 sys.exit(retval)