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