]> git.proxmox.com Git - mirror_frr.git/blob - tests/topotests/isis_lsp_bits_topo1/test_isis_lsp_bits_topo1.py
Merge pull request #9019 from pjdruddy/ospfv3-early-break-list-walk
[mirror_frr.git] / tests / topotests / isis_lsp_bits_topo1 / test_isis_lsp_bits_topo1.py
1 #!/usr/bin/env python
2
3 #
4 # test_isis_lsp_bits_topo1.py
5 # Part of NetDEF Topology Tests
6 #
7 # Copyright (c) 2021 by Volta Networks
8 #
9 # Permission to use, copy, modify, and/or distribute this software
10 # for any purpose with or without fee is hereby granted, provided
11 # that the above copyright notice and this permission notice appear
12 # in all copies.
13 #
14 # THE SOFTWARE IS PROVIDED "AS IS" AND NETDEF DISCLAIMS ALL WARRANTIES
15 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
16 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF BE LIABLE FOR
17 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
18 # DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
19 # WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
20 # ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
21 # OF THIS SOFTWARE.
22 #
23
24 """
25 test_isis_lsp_bits_topo1.py:
26
27 +---------+
28 | |
29 | RT1 |
30 | 1.1.1.1 |
31 | L1 |
32 +---------+
33 |eth-sw1
34 |
35 |
36 |
37 +---------+ | +---------+
38 | | | | |
39 | RT2 |eth-sw1 | eth-sw1| RT3 |
40 | 2.2.2.2 +----------+----------+ 3.3.3.3 |
41 | L1|L2 | 10.0.1.0/24 | L1|L2 |
42 +---------+ +---------+
43 eth-rt4| eth-rt5|
44 | |
45 10.0.2.0/24| |10.0.4.0/24
46 | |
47 eth-rt2| eth-rt3|
48 +---------+ +---------+
49 | | | |
50 | RT4 | 10.0.6.0/24 | RT5 |
51 | 4.4.4.4 +---------------------+ 5.5.5.5 |
52 | L1|L2 |eth-rt5 eth-rt4| L1|L2 |
53 +---------+ +---------+
54 eth-rt6| |eth-rt6
55 | |
56 10.0.7.0/24| |10.0.8.0/24
57 | +---------+ |
58 | | | |
59 | | RT6 | |
60 +----------+ 6.6.6.6 +-----------+
61 eth-rt4| L1 |eth-rt5
62 +---------+
63 """
64
65 import os
66 import sys
67 import pytest
68 import json
69 from functools import partial
70
71 # Save the Current Working Directory to find configuration files.
72 CWD = os.path.dirname(os.path.realpath(__file__))
73 sys.path.append(os.path.join(CWD, "../"))
74
75 # pylint: disable=C0413
76 # Import topogen and topotest helpers
77 from lib import topotest
78 from lib.topogen import Topogen, TopoRouter, get_topogen
79 from lib.topolog import logger
80
81 # Required to instantiate the topology builder class.
82
83 pytestmark = [pytest.mark.isisd]
84
85
86 # Global multi-dimensional dictionary containing all expected outputs
87 outputs = {}
88
89
90 def build_topo(tgen):
91 "Build function"
92
93 #
94 # Define FRR Routers
95 #
96 for router in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]:
97 tgen.add_router(router)
98
99 #
100 # Define connections
101 #
102 switch = tgen.add_switch("s1")
103 switch.add_link(tgen.gears["rt1"], nodeif="eth-sw1")
104 switch.add_link(tgen.gears["rt2"], nodeif="eth-sw1")
105 switch.add_link(tgen.gears["rt3"], nodeif="eth-sw1")
106
107 switch = tgen.add_switch("s2")
108 switch.add_link(tgen.gears["rt2"], nodeif="eth-rt4")
109 switch.add_link(tgen.gears["rt4"], nodeif="eth-rt2")
110
111 switch = tgen.add_switch("s4")
112 switch.add_link(tgen.gears["rt3"], nodeif="eth-rt5")
113 switch.add_link(tgen.gears["rt5"], nodeif="eth-rt3")
114
115 switch = tgen.add_switch("s6")
116 switch.add_link(tgen.gears["rt4"], nodeif="eth-rt5")
117 switch.add_link(tgen.gears["rt5"], nodeif="eth-rt4")
118
119 switch = tgen.add_switch("s7")
120 switch.add_link(tgen.gears["rt4"], nodeif="eth-rt6")
121 switch.add_link(tgen.gears["rt6"], nodeif="eth-rt4")
122
123 switch = tgen.add_switch("s8")
124 switch.add_link(tgen.gears["rt5"], nodeif="eth-rt6")
125 switch.add_link(tgen.gears["rt6"], nodeif="eth-rt5")
126
127
128 def setup_module(mod):
129 "Sets up the pytest environment"
130 tgen = Topogen(build_topo, mod.__name__)
131 tgen.start_topology()
132
133 router_list = tgen.routers()
134
135 # For all registered routers, load the zebra configuration file
136 for rname, router in router_list.items():
137 router.load_config(
138 TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname))
139 )
140 router.load_config(
141 TopoRouter.RD_ISIS, os.path.join(CWD, "{}/isisd.conf".format(rname))
142 )
143
144 tgen.start_router()
145
146
147 def teardown_module(mod):
148 "Teardown the pytest environment"
149 tgen = get_topogen()
150
151 # This function tears down the whole topology.
152 tgen.stop_topology()
153
154
155 def router_compare_json_output(rname, command, reference):
156 "Compare router JSON output"
157
158 logger.info('Comparing router "%s" "%s" output', rname, command)
159
160 tgen = get_topogen()
161 filename = "{}/{}/{}".format(CWD, rname, reference)
162 expected = json.loads(open(filename).read())
163
164 # Run test function until we get an result. Wait at most 60 seconds.
165 test_func = partial(topotest.router_json_cmp, tgen.gears[rname], command, expected)
166 _, diff = topotest.run_and_expect(test_func, None, count=120, wait=0.5)
167 assertmsg = '"{}" JSON output mismatches the expected result'.format(rname)
168 assert diff is None, assertmsg
169
170
171 #
172 # Step 1
173 #
174 # Test initial network convergence
175 # Attach-bit defaults to on, so expect default route pointing to L1|L2 router
176 #
177 def test_isis_adjacencies_step1():
178 logger.info("Test (step 1): check IS-IS adjacencies")
179 tgen = get_topogen()
180
181 # Skip if previous fatal error condition is raised
182 if tgen.routers_have_failure():
183 pytest.skip(tgen.errors)
184
185 for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]:
186 router_compare_json_output(
187 rname,
188 "show yang operational-data /frr-interface:lib isisd",
189 "step1/show_yang_interface_isis_adjacencies.ref",
190 )
191
192
193 def test_rib_ipv4_step1():
194 logger.info("Test (step 1): verify IPv4 RIB")
195 tgen = get_topogen()
196
197 # Skip if previous fatal error condition is raised
198 if tgen.routers_have_failure():
199 pytest.skip(tgen.errors)
200
201 for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]:
202 router_compare_json_output(
203 rname, "show ip route isis json", "step1/show_ip_route.ref"
204 )
205
206
207 def test_rib_ipv6_step1():
208 logger.info("Test (step 1): verify IPv6 RIB")
209 tgen = get_topogen()
210
211 # Skip if previous fatal error condition is raised
212 if tgen.routers_have_failure():
213 pytest.skip(tgen.errors)
214
215 for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]:
216 router_compare_json_output(
217 rname, "show ipv6 route isis json", "step1/show_ipv6_route.ref"
218 )
219
220
221 #
222 # Step 2
223 #
224 # Action(s):
225 # -Disable sending Attach bit on RT2 and RT4
226 #
227 # Expected changes:
228 # -RT1 should remove the default route pointing to RT2
229 # -RT6 should remove the default route pointing to RT4
230 #
231 def test_rib_ipv4_step2():
232 logger.info("Test (step 2): verify IPv4 RIB")
233 tgen = get_topogen()
234
235 # Skip if previous fatal error condition is raised
236 if tgen.routers_have_failure():
237 pytest.skip(tgen.errors)
238
239 logger.info("Disabling setting the attached-bit on RT2 and RT4")
240 tgen.net["rt2"].cmd(
241 'vtysh -c "conf t" -c "router isis 1" -c "no attached-bit send"'
242 )
243 tgen.net["rt4"].cmd(
244 'vtysh -c "conf t" -c "router isis 1" -c "no attached-bit send"'
245 )
246
247 for rname in ["rt1", "rt6"]:
248 router_compare_json_output(
249 rname, "show ip route isis json", "step2/show_ip_route.ref"
250 )
251
252
253 def test_rib_ipv6_step2():
254 logger.info("Test (step 2): verify IPv6 RIB")
255 tgen = get_topogen()
256
257 # Skip if previous fatal error condition is raised
258 if tgen.routers_have_failure():
259 pytest.skip(tgen.errors)
260
261 for rname in ["rt1", "rt6"]:
262 router_compare_json_output(
263 rname, "show ipv6 route isis json", "step2/show_ipv6_route.ref"
264 )
265
266
267 #
268 # Step 3
269 #
270 # Action(s):
271 # -restore attach-bit, enable sending attach-bit
272 # -disble processing a LSP with attach bit set
273 #
274 # Expected changes:
275 # -RT1 and RT6 should not install a default route
276 #
277 def test_rib_ipv4_step3():
278 logger.info("Test (step 3): verify IPv4 RIB")
279 tgen = get_topogen()
280
281 # Skip if previous fatal error condition is raised
282 if tgen.routers_have_failure():
283 pytest.skip(tgen.errors)
284
285 logger.info("Enable setting the attached-bit on RT2 and RT4")
286 tgen.net["rt2"].cmd('vtysh -c "conf t" -c "router isis 1" -c "attached-bit send"')
287 tgen.net["rt4"].cmd('vtysh -c "conf t" -c "router isis 1" -c "attached-bit send"')
288
289 logger.info("Disable processing received attached-bit in LSP on RT1 and RT6")
290 tgen.net["rt1"].cmd(
291 'vtysh -c "conf t" -c "router isis 1" -c "attached-bit receive ignore"'
292 )
293 tgen.net["rt6"].cmd(
294 'vtysh -c "conf t" -c "router isis 1" -c "attached-bit receive ignore"'
295 )
296
297 for rname in ["rt1", "rt6"]:
298 router_compare_json_output(
299 rname, "show ip route isis json", "step3/show_ip_route.ref"
300 )
301
302
303 def test_rib_ipv6_step3():
304 logger.info("Test (step 3): verify IPv6 RIB")
305 tgen = get_topogen()
306
307 # Skip if previous fatal error condition is raised
308 if tgen.routers_have_failure():
309 pytest.skip(tgen.errors)
310
311 for rname in ["rt1", "rt6"]:
312 router_compare_json_output(
313 rname, "show ipv6 route isis json", "step3/show_ipv6_route.ref"
314 )
315
316
317 #
318 # Step 4
319 #
320 # Action(s):
321 # -restore back to default attach-bit config
322 #
323 # Expected changes:
324 # -RT1 and RT6 should add default route
325 # -no changes on other routers
326 #
327 def test_rib_ipv4_step4():
328 logger.info("Test (step 4): verify IPv4 RIB")
329 tgen = get_topogen()
330
331 # Skip if previous fatal error condition is raised
332 if tgen.routers_have_failure():
333 pytest.skip(tgen.errors)
334
335 logger.info(
336 "restore default processing on received attached-bit in LSP on RT1 and RT6"
337 )
338 tgen.net["rt1"].cmd(
339 'vtysh -c "conf t" -c "router isis 1" -c "no attached-bit receive ignore"'
340 )
341 tgen.net["rt6"].cmd(
342 'vtysh -c "conf t" -c "router isis 1" -c "no attached-bit receive ignore"'
343 )
344
345 for rname in ["rt1", "rt6"]:
346 router_compare_json_output(
347 rname, "show ip route isis json", "step4/show_ip_route.ref"
348 )
349
350
351 def test_rib_ipv6_step4():
352 logger.info("Test (step 4): verify IPv6 RIB")
353 tgen = get_topogen()
354
355 # Skip if previous fatal error condition is raised
356 if tgen.routers_have_failure():
357 pytest.skip(tgen.errors)
358
359 for rname in ["rt1", "rt6"]:
360 router_compare_json_output(
361 rname, "show ipv6 route isis json", "step4/show_ipv6_route.ref"
362 )
363
364
365 # Memory leak test template
366 def test_memory_leak():
367 "Run the memory leak test and report results."
368 tgen = get_topogen()
369 if not tgen.is_memleak_enabled():
370 pytest.skip("Memory leak test/report is disabled")
371
372 tgen.report_memory_leaks()
373
374
375 if __name__ == "__main__":
376 args = ["-s"] + sys.argv[1:]
377 sys.exit(pytest.main(args))