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