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