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