]> git.proxmox.com Git - mirror_frr.git/blob - tests/topotests/rip_topo1/test_rip_topo1.py
doc: Add `show ipv6 rpf X:X::X:X` command to docs
[mirror_frr.git] / tests / topotests / rip_topo1 / test_rip_topo1.py
1 #!/usr/bin/env python
2
3 #
4 # test_rip_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_rip_topo1.py: Testing RIPv2
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 RIP 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 RIP
64
65 # switch 2 switch is for connection to RIP router
66 switch = tgen.add_switch("sw2")
67 switch.add_link(tgen.gears["r1"])
68 switch.add_link(tgen.gears["r2"])
69
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
75 # switch 4 is stub on remote RIP router
76 switch = tgen.add_switch("sw4")
77 switch.add_link(tgen.gears["r3"], nodeif="r3-eth0")
78
79 switch = tgen.add_switch("sw5")
80 switch.add_link(tgen.gears["r1"])
81
82 switch = tgen.add_switch("sw6")
83 switch.add_link(tgen.gears["r1"])
84
85
86 #####################################################
87 ##
88 ## Tests starting
89 ##
90 #####################################################
91
92
93 def setup_module(module):
94 print("\n\n** %s: Setup Topology" % module.__name__)
95 print("******************************************\n")
96
97 thisDir = os.path.dirname(os.path.realpath(__file__))
98 tgen = Topogen(build_topo, module.__name__)
99 tgen.start_topology()
100
101 net = tgen.net
102
103 # Starting Routers
104 #
105 for i in range(1, 4):
106 net["r%s" % i].loadConf("zebra", "%s/r%s/zebra.conf" % (thisDir, i))
107 net["r%s" % i].loadConf("ripd", "%s/r%s/ripd.conf" % (thisDir, i))
108 tgen.gears["r%s" % i].start()
109
110 # For debugging after starting FRR daemons, uncomment the next line
111 # tgen.mininet_cli()
112
113
114 def teardown_module(module):
115 print("\n\n** %s: Shutdown Topology" % module.__name__)
116 print("******************************************\n")
117 tgen = get_topogen()
118 tgen.stop_topology()
119
120
121 def test_router_running():
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 print("\n\n** Check if FRR is running on each Router node")
130 print("******************************************\n")
131
132 # Make sure that all daemons are running
133 for i in range(1, 4):
134 fatal_error = net["r%s" % i].checkRouterRunning()
135 assert fatal_error == "", fatal_error
136
137
138 def test_converge_protocols():
139 global fatal_error
140 net = get_topogen().net
141
142 # Skip if previous fatal error condition is raised
143 if fatal_error != "":
144 pytest.skip(fatal_error)
145
146 thisDir = os.path.dirname(os.path.realpath(__file__))
147
148 print("\n\n** Waiting for protocols convergence")
149 print("******************************************\n")
150
151 # Not really implemented yet - just sleep 11 secs for now
152 sleep(21)
153
154 # Make sure that all daemons are still running
155 for i in range(1, 4):
156 fatal_error = net["r%s" % i].checkRouterRunning()
157 assert fatal_error == "", fatal_error
158
159
160 def test_rip_status():
161 global fatal_error
162 net = get_topogen().net
163
164 # Skip if previous fatal error condition is raised
165 if fatal_error != "":
166 pytest.skip(fatal_error)
167
168 thisDir = os.path.dirname(os.path.realpath(__file__))
169
170 # Verify RIP Status
171 print("\n\n** Verifing RIP status")
172 print("******************************************\n")
173 failures = 0
174 for i in range(1, 4):
175 refTableFile = "%s/r%s/rip_status.ref" % (thisDir, i)
176 if os.path.isfile(refTableFile):
177 # Read expected result from file
178 expected = open(refTableFile).read().rstrip()
179 # Fix newlines (make them all the same)
180 expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1)
181
182 # Actual output from router
183 actual = (
184 net["r%s" % i]
185 .cmd('vtysh -c "show ip rip status" 2> /dev/null')
186 .rstrip()
187 )
188 # Drop time in next due
189 actual = re.sub(r"in [0-9]+ seconds", "in XX seconds", actual)
190 # Drop time in last update
191 actual = re.sub(r" [0-2][0-9]:[0-5][0-9]:[0-5][0-9]", " XX:XX:XX", actual)
192 # Fix newlines (make them all the same)
193 actual = ("\n".join(actual.splitlines()) + "\n").splitlines(1)
194
195 # Generate Diff
196 diff = topotest.get_textdiff(
197 actual,
198 expected,
199 title1="actual IP RIP status",
200 title2="expected IP RIP status",
201 )
202
203 # Empty string if it matches, otherwise diff contains unified diff
204 if diff:
205 sys.stderr.write("r%s failed IP RIP status check:\n%s\n" % (i, diff))
206 failures += 1
207 else:
208 print("r%s ok" % i)
209
210 assert failures == 0, "IP RIP status failed for router r%s:\n%s" % (i, diff)
211
212 # Make sure that all daemons are still running
213 for i in range(1, 4):
214 fatal_error = net["r%s" % i].checkRouterRunning()
215 assert fatal_error == "", fatal_error
216
217
218 def test_rip_routes():
219 global fatal_error
220 net = get_topogen().net
221
222 # Skip if previous fatal error condition is raised
223 if fatal_error != "":
224 pytest.skip(fatal_error)
225
226 thisDir = os.path.dirname(os.path.realpath(__file__))
227
228 # Verify RIP Status
229 print("\n\n** Verifing RIP routes")
230 print("******************************************\n")
231 failures = 0
232 for i in range(1, 4):
233 refTableFile = "%s/r%s/show_ip_rip.ref" % (thisDir, i)
234 if os.path.isfile(refTableFile):
235 # Read expected result from file
236 expected = open(refTableFile).read().rstrip()
237 # Fix newlines (make them all the same)
238 expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1)
239
240 # Actual output from router
241 actual = net["r%s" % i].cmd('vtysh -c "show ip rip" 2> /dev/null').rstrip()
242 # Drop Time
243 actual = re.sub(r"[0-9][0-9]:[0-5][0-9]", "XX:XX", actual)
244 # Fix newlines (make them all the same)
245 actual = ("\n".join(actual.splitlines()) + "\n").splitlines(1)
246
247 # Generate Diff
248 diff = topotest.get_textdiff(
249 actual,
250 expected,
251 title1="actual SHOW IP RIP",
252 title2="expected SHOW IP RIP",
253 )
254
255 # Empty string if it matches, otherwise diff contains unified diff
256 if diff:
257 sys.stderr.write("r%s failed SHOW IP RIP check:\n%s\n" % (i, diff))
258 failures += 1
259 else:
260 print("r%s ok" % i)
261
262 assert failures == 0, "SHOW IP RIP failed for router r%s:\n%s" % (i, diff)
263
264 # Make sure that all daemons are still running
265 for i in range(1, 4):
266 fatal_error = net["r%s" % i].checkRouterRunning()
267 assert fatal_error == "", fatal_error
268
269
270 def test_zebra_ipv4_routingTable():
271 global fatal_error
272 net = get_topogen().net
273
274 # Skip if previous fatal error condition is raised
275 if fatal_error != "":
276 pytest.skip(fatal_error)
277
278 thisDir = os.path.dirname(os.path.realpath(__file__))
279
280 # Verify OSPFv3 Routing Table
281 print("\n\n** Verifing Zebra IPv4 Routing Table")
282 print("******************************************\n")
283 failures = 0
284 for i in range(1, 4):
285 refTableFile = "%s/r%s/show_ip_route.ref" % (thisDir, i)
286 if os.path.isfile(refTableFile):
287 # Read expected result from file
288 expected = open(refTableFile).read().rstrip()
289 # Fix newlines (make them all the same)
290 expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1)
291
292 # Actual output from router
293 actual = (
294 net["r%s" % i]
295 .cmd('vtysh -c "show ip route" 2> /dev/null | grep "^R"')
296 .rstrip()
297 )
298 # Drop timers on end of line
299 actual = re.sub(r", [0-2][0-9]:[0-5][0-9]:[0-5][0-9]", "", actual)
300 # Fix newlines (make them all the same)
301 actual = ("\n".join(actual.splitlines()) + "\n").splitlines(1)
302
303 # Generate Diff
304 diff = topotest.get_textdiff(
305 actual,
306 expected,
307 title1="actual Zebra IPv4 routing table",
308 title2="expected Zebra IPv4 routing table",
309 )
310
311 # Empty string if it matches, otherwise diff contains unified diff
312 if diff:
313 sys.stderr.write(
314 "r%s failed Zebra IPv4 Routing Table Check:\n%s\n" % (i, diff)
315 )
316 failures += 1
317 else:
318 print("r%s ok" % i)
319
320 assert (
321 failures == 0
322 ), "Zebra IPv4 Routing Table verification failed for router r%s:\n%s" % (
323 i,
324 diff,
325 )
326
327 # Make sure that all daemons are still running
328 for i in range(1, 4):
329 fatal_error = net["r%s" % i].checkRouterRunning()
330 assert fatal_error == "", fatal_error
331
332
333 def test_shutdown_check_stderr():
334 global fatal_error
335 net = get_topogen().net
336
337 # Skip if previous fatal error condition is raised
338 if fatal_error != "":
339 pytest.skip(fatal_error)
340
341 if os.environ.get("TOPOTESTS_CHECK_STDERR") is None:
342 pytest.skip("Skipping test for Stderr output and memory leaks")
343
344 thisDir = os.path.dirname(os.path.realpath(__file__))
345
346 print("\n\n** Verifing unexpected STDERR output from daemons")
347 print("******************************************\n")
348
349 net["r1"].stopRouter()
350
351 log = net["r1"].getStdErr("ripd")
352 if log:
353 print("\nRIPd StdErr Log:\n" + log)
354 log = net["r1"].getStdErr("zebra")
355 if log:
356 print("\nZebra StdErr Log:\n" + log)
357
358
359 if __name__ == "__main__":
360
361 # To suppress tracebacks, either use the following pytest call or add "--tb=no" to cli
362 # retval = pytest.main(["-s", "--tb=no"])
363 retval = pytest.main(["-s"])
364 sys.exit(retval)