]> git.proxmox.com Git - mirror_frr.git/blob - tests/topotests/ripng_topo1/test_ripng_topo1.py
Merge pull request #9345 from mjstapp/fix_lib_zmq_free
[mirror_frr.git] / tests / topotests / ripng_topo1 / test_ripng_topo1.py
1 #!/usr/bin/env python
2
3 #
4 # test_ripng_topo1.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 """
26 test_ripng_topo1.py: Test of RIPng Topology
27
28 """
29
30 import os
31 import re
32 import sys
33 import pytest
34 from time import sleep
35
36
37 sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
38 from lib import topotest
39 from lib.topogen import Topogen, get_topogen
40
41 fatal_error = ""
42
43 pytestmark = [pytest.mark.ripd]
44
45 #####################################################
46 ##
47 ## Network Topology Definition
48 ##
49 #####################################################
50
51
52 def build_topo(tgen):
53 # Setup RIPng Routers
54 for i in range(1, 4):
55 tgen.add_router("r%s" % i)
56
57 #
58 # On main router
59 # First switch is for a dummy interface (for local network)
60 switch = tgen.add_switch("sw1")
61 switch.add_link(tgen.gears["r1"])
62 #
63 # Switches for RIPng
64 # switch 2 switch is for connection to RIP router
65 switch = tgen.add_switch("sw2")
66 switch.add_link(tgen.gears["r1"])
67 switch.add_link(tgen.gears["r2"])
68 # switch 3 is between RIP routers
69 switch = tgen.add_switch("sw3")
70 switch.add_link(tgen.gears["r2"])
71 switch.add_link(tgen.gears["r3"], nodeif="r3-eth1")
72 # switch 4 is stub on remote RIP router
73 switch = tgen.add_switch("sw4")
74 switch.add_link(tgen.gears["r3"], nodeif="r3-eth0")
75
76 switch = tgen.add_switch("sw5")
77 switch.add_link(tgen.gears["r1"])
78 switch = tgen.add_switch("sw6")
79 switch.add_link(tgen.gears["r1"])
80
81
82 #####################################################
83 ##
84 ## Tests starting
85 ##
86 #####################################################
87
88
89 def setup_module(module):
90 print("\n\n** %s: Setup Topology" % module.__name__)
91 print("******************************************\n")
92
93 thisDir = os.path.dirname(os.path.realpath(__file__))
94 tgen = Topogen(build_topo, module.__name__)
95 tgen.start_topology()
96
97 net = tgen.net
98
99 # Starting Routers
100 #
101 for i in range(1, 4):
102 net["r%s" % i].loadConf("zebra", "%s/r%s/zebra.conf" % (thisDir, i))
103 net["r%s" % i].loadConf("ripngd", "%s/r%s/ripngd.conf" % (thisDir, i))
104 tgen.gears["r%s" % i].start()
105
106 # For debugging after starting FRR daemons, uncomment the next line
107 # CLI(net)
108
109
110 def teardown_module(module):
111 print("\n\n** %s: Shutdown Topology" % module.__name__)
112 print("******************************************\n")
113 tgen = get_topogen()
114 tgen.stop_topology()
115
116
117 def test_router_running():
118 global fatal_error
119 net = get_topogen().net
120
121 # Skip if previous fatal error condition is raised
122 if fatal_error != "":
123 pytest.skip(fatal_error)
124
125 print("\n\n** Check if FRR is running on each Router node")
126 print("******************************************\n")
127
128 # Starting Routers
129 for i in range(1, 4):
130 fatal_error = net["r%s" % i].checkRouterRunning()
131 assert fatal_error == "", fatal_error
132
133 # For debugging after starting FRR daemons, uncomment the next line
134 # CLI(net)
135
136
137 def test_converge_protocols():
138 global fatal_error
139 net = get_topogen().net
140
141 # Skip if previous fatal error condition is raised
142 if fatal_error != "":
143 pytest.skip(fatal_error)
144
145 thisDir = os.path.dirname(os.path.realpath(__file__))
146
147 print("\n\n** Waiting for protocols convergence")
148 print("******************************************\n")
149
150 # Not really implemented yet - just sleep 11 secs for now
151 sleep(11)
152
153 # Make sure that all daemons are running
154 for i in range(1, 4):
155 fatal_error = net["r%s" % i].checkRouterRunning()
156 assert fatal_error == "", fatal_error
157
158 # For debugging after starting FRR daemons, uncomment the next line
159 # CLI(net)
160
161
162 def test_ripng_status():
163 global fatal_error
164 net = get_topogen().net
165
166 # Skip if previous fatal error condition is raised
167 if fatal_error != "":
168 pytest.skip(fatal_error)
169
170 thisDir = os.path.dirname(os.path.realpath(__file__))
171
172 # Verify RIP Status
173 print("\n\n** Verifying RIPng status")
174 print("******************************************\n")
175 failures = 0
176 for i in range(1, 4):
177 refTableFile = "%s/r%s/ripng_status.ref" % (thisDir, i)
178 if os.path.isfile(refTableFile):
179 # Read expected result from file
180 expected = open(refTableFile).read().rstrip()
181 # Fix newlines (make them all the same)
182 expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1)
183
184 # Actual output from router
185 actual = (
186 net["r%s" % i]
187 .cmd('vtysh -c "show ipv6 ripng status" 2> /dev/null')
188 .rstrip()
189 )
190 # Mask out Link-Local mac address portion. They are random...
191 actual = re.sub(r" fe80::[0-9a-f:]+", " fe80::XXXX:XXXX:XXXX:XXXX", actual)
192 # Drop time in next due
193 actual = re.sub(r"in [0-9]+ seconds", "in XX seconds", actual)
194 # Drop time in last update
195 actual = re.sub(r" [0-2][0-9]:[0-5][0-9]:[0-5][0-9]", " XX:XX:XX", actual)
196 # Fix newlines (make them all the same)
197 actual = ("\n".join(actual.splitlines()) + "\n").splitlines(1)
198
199 # Generate Diff
200 diff = topotest.get_textdiff(
201 actual,
202 expected,
203 title1="actual IPv6 RIPng status",
204 title2="expected IPv6 RIPng status",
205 )
206
207 # Empty string if it matches, otherwise diff contains unified diff
208 if diff:
209 sys.stderr.write(
210 "r%s failed IPv6 RIPng status check:\n%s\n" % (i, diff)
211 )
212 failures += 1
213 else:
214 print("r%s ok" % i)
215
216 assert failures == 0, "IPv6 RIPng status failed for router r%s:\n%s" % (
217 i,
218 diff,
219 )
220
221 # Make sure that all daemons are running
222 for i in range(1, 4):
223 fatal_error = net["r%s" % i].checkRouterRunning()
224 assert fatal_error == "", fatal_error
225
226 # For debugging after starting FRR daemons, uncomment the next line
227 # CLI(net)
228
229
230 def test_ripng_routes():
231 global fatal_error
232 net = get_topogen().net
233
234 # Skip if previous fatal error condition is raised
235 if fatal_error != "":
236 pytest.skip(fatal_error)
237
238 thisDir = os.path.dirname(os.path.realpath(__file__))
239
240 # Verify RIPng Status
241 print("\n\n** Verifying RIPng routes")
242 print("******************************************\n")
243 failures = 0
244 for i in range(1, 4):
245 refTableFile = "%s/r%s/show_ipv6_ripng.ref" % (thisDir, i)
246 if os.path.isfile(refTableFile):
247 # Read expected result from file
248 expected = open(refTableFile).read().rstrip()
249 # Fix newlines (make them all the same)
250 expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1)
251
252 # Actual output from router
253 actual = (
254 net["r%s" % i].cmd('vtysh -c "show ipv6 ripng" 2> /dev/null').rstrip()
255 )
256 # Drop Time
257 actual = re.sub(r" [0-9][0-9]:[0-5][0-9]", " XX:XX", actual)
258 # Mask out Link-Local mac address portion. They are random...
259 actual = re.sub(
260 r" fe80::[0-9a-f: ]+", " fe80::XXXX:XXXX:XXXX:XXXX ", actual
261 )
262 # Remove trailing spaces on all lines
263 actual = "\n".join([line.rstrip() for line in actual.splitlines()])
264
265 # Fix newlines (make them all the same)
266 actual = ("\n".join(actual.splitlines()) + "\n").splitlines(1)
267
268 # Generate Diff
269 diff = topotest.get_textdiff(
270 actual,
271 expected,
272 title1="actual SHOW IPv6 RIPng",
273 title2="expected SHOW IPv6 RIPng",
274 )
275
276 # Empty string if it matches, otherwise diff contains unified diff
277 if diff:
278 sys.stderr.write("r%s failed SHOW IPv6 RIPng check:\n%s\n" % (i, diff))
279 failures += 1
280 else:
281 print("r%s ok" % i)
282
283 assert failures == 0, "SHOW IPv6 RIPng failed for router r%s:\n%s" % (
284 i,
285 diff,
286 )
287
288 # Make sure that all daemons are running
289 for i in range(1, 4):
290 fatal_error = net["r%s" % i].checkRouterRunning()
291 assert fatal_error == "", fatal_error
292
293 # For debugging after starting FRR daemons, uncomment the next line
294 # CLI(net)
295
296
297 def test_zebra_ipv6_routingTable():
298 global fatal_error
299 net = get_topogen().net
300
301 # Skip if previous fatal error condition is raised
302 if fatal_error != "":
303 pytest.skip(fatal_error)
304
305 thisDir = os.path.dirname(os.path.realpath(__file__))
306
307 # Verify OSPFv3 Routing Table
308 print("\n\n** Verifying Zebra IPv6 Routing Table")
309 print("******************************************\n")
310 failures = 0
311 for i in range(1, 4):
312 refTableFile = "%s/r%s/show_ipv6_route.ref" % (thisDir, i)
313 if os.path.isfile(refTableFile):
314 # Read expected result from file
315 expected = open(refTableFile).read().rstrip()
316 # Fix newlines (make them all the same)
317 expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1)
318
319 # Actual output from router
320 actual = (
321 net["r%s" % i]
322 .cmd('vtysh -c "show ipv6 route" 2> /dev/null | grep "^R"')
323 .rstrip()
324 )
325 # Mask out Link-Local mac address portion. They are random...
326 actual = re.sub(r" fe80::[0-9a-f:]+", " fe80::XXXX:XXXX:XXXX:XXXX", actual)
327 # Drop timers on end of line
328 actual = re.sub(r", [0-2][0-9]:[0-5][0-9]:[0-5][0-9]", "", actual)
329 # Fix newlines (make them all the same)
330 actual = ("\n".join(actual.splitlines()) + "\n").splitlines(1)
331
332 # Generate Diff
333 diff = topotest.get_textdiff(
334 actual,
335 expected,
336 title1="actual Zebra IPv6 routing table",
337 title2="expected Zebra IPv6 routing table",
338 )
339
340 # Empty string if it matches, otherwise diff contains unified diff
341 if diff:
342 sys.stderr.write(
343 "r%s failed Zebra IPv6 Routing Table Check:\n%s\n" % (i, diff)
344 )
345 failures += 1
346 else:
347 print("r%s ok" % i)
348
349 assert (
350 failures == 0
351 ), "Zebra IPv6 Routing Table verification failed for router r%s:\n%s" % (
352 i,
353 diff,
354 )
355
356 # Make sure that all daemons are running
357 for i in range(1, 4):
358 fatal_error = net["r%s" % i].checkRouterRunning()
359 assert fatal_error == "", fatal_error
360
361 # For debugging after starting FRR daemons, uncomment the next line
362 # CLI(net)
363
364
365 def test_shutdown_check_stderr():
366 global fatal_error
367 net = get_topogen().net
368
369 # Skip if previous fatal error condition is raised
370 if fatal_error != "":
371 pytest.skip(fatal_error)
372
373 if os.environ.get("TOPOTESTS_CHECK_STDERR") is None:
374 print(
375 "SKIPPED final check on StdErr output: Disabled (TOPOTESTS_CHECK_STDERR undefined)\n"
376 )
377 pytest.skip("Skipping test for Stderr output")
378
379 thisDir = os.path.dirname(os.path.realpath(__file__))
380
381 print("\n\n** Verifying unexpected STDERR output from daemons")
382 print("******************************************\n")
383
384 net["r1"].stopRouter()
385
386 log = net["r1"].getStdErr("ripngd")
387 if log:
388 print("\nRIPngd StdErr Log:\n" + log)
389 log = net["r1"].getStdErr("zebra")
390 if log:
391 print("\nZebra StdErr Log:\n" + log)
392
393
394 def test_shutdown_check_memleak():
395 global fatal_error
396 net = get_topogen().net
397
398 # Skip if previous fatal error condition is raised
399 if fatal_error != "":
400 pytest.skip(fatal_error)
401
402 if os.environ.get("TOPOTESTS_CHECK_MEMLEAK") is None:
403 print(
404 "SKIPPED final check on Memory leaks: Disabled (TOPOTESTS_CHECK_MEMLEAK undefined)\n"
405 )
406 pytest.skip("Skipping test for memory leaks")
407
408 thisDir = os.path.dirname(os.path.realpath(__file__))
409
410 net["r1"].stopRouter()
411 net["r1"].report_memory_leaks(
412 os.environ.get("TOPOTESTS_CHECK_MEMLEAK"), os.path.basename(__file__)
413 )
414
415
416 if __name__ == "__main__":
417
418 # To suppress tracebacks, either use the following pytest call or add "--tb=no" to cli
419 # retval = pytest.main(["-s", "--tb=no"])
420 retval = pytest.main(["-s"])
421 sys.exit(retval)