]> git.proxmox.com Git - mirror_frr.git/blob - tests/topotests/isis_sr_flex_algo_topo1/test_isis_sr_flex_algo_topo1.py
Merge pull request #13020 from SaiGomathiN/2462808-3
[mirror_frr.git] / tests / topotests / isis_sr_flex_algo_topo1 / test_isis_sr_flex_algo_topo1.py
1 #!/usr/bin/env python
2 # SPDX-License-Identifier: ISC
3
4 #
5 # Part of NetDEF Topology Tests
6 #
7 # Copyright 2021 by LINE Corporation, Hiroki Shirokura <hiroki.shirokura@linecorp.com>
8 # Copyright 2023 6WIND S.A.
9
10 """
11 test_isis_sr_flex_algo_topo1.py:
12
13 [+] Flex-Algos 201 exclude red
14 [+] Flex-Algos 202 exclude blue
15 [+] Flex-Algos 203 exclude green
16 [+] Flex-Algos 204 include-any blue green
17 [+] Flex-Algos 205 include-any red green
18 [+] Flex-Algos 206 include-any red blue
19 [+] Flex-Algos 207 include-all yellow orange
20
21 +--------+ 10.12.0.0/24 +--------+
22 | | red | |
23 | RT1 |----------------| RT2 |
24 | | | |
25 +--------+ +--------+
26 10.13.0.0/24 \\ / 10.23.0.0/24
27 green \\ / blue
28 yellow \\ / yellow
29 orange +--------+ orange
30 | |
31 | RT3 |
32 | |
33 +--------+
34 """
35
36 import os
37 import sys
38 import pytest
39 import json
40 import tempfile
41 from functools import partial
42
43 # Save the Current Working Directory to find configuration files.
44 CWD = os.path.dirname(os.path.realpath(__file__))
45 sys.path.append(os.path.join(CWD, "../"))
46
47 # pylint: disable=C0413
48 # Import topogen and topotest helpers
49 from lib import topotest
50 from lib.topogen import Topogen, TopoRouter, get_topogen
51 from lib.topolog import logger
52
53
54 pytestmark = [pytest.mark.isisd]
55
56 # Global multi-dimensional dictionary containing all expected outputs
57 outputs = {}
58
59
60 def build_topo(tgen):
61 "Build function"
62
63 def connect_routers(tgen, left_idx, right_idx):
64 left = "rt{}".format(left_idx)
65 right = "rt{}".format(right_idx)
66 switch = tgen.add_switch("s-{}-{}".format(left, right))
67 switch.add_link(tgen.gears[left], nodeif="eth-{}".format(right))
68 switch.add_link(tgen.gears[right], nodeif="eth-{}".format(left))
69 l_addr = "52:54:00:{}:{}:{}".format(left_idx, right_idx, left_idx)
70 tgen.gears[left].run("ip link set eth-{} down".format(right))
71 tgen.gears[left].run("ip link set eth-{} address {}".format(right, l_addr))
72 tgen.gears[left].run("ip link set eth-{} up".format(right))
73 r_addr = "52:54:00:{}:{}:{}".format(left_idx, right_idx, right_idx)
74 tgen.gears[right].run("ip link set eth-{} down".format(left))
75 tgen.gears[right].run("ip link set eth-{} address {}".format(left, r_addr))
76 tgen.gears[right].run("ip link set eth-{} up".format(left))
77
78 tgen.add_router("rt1")
79 tgen.add_router("rt2")
80 tgen.add_router("rt3")
81 connect_routers(tgen, 1, 2)
82 connect_routers(tgen, 2, 3)
83 connect_routers(tgen, 3, 1)
84
85 #
86 # Populate multi-dimensional dictionary containing all expected outputs
87 #
88 number_of_steps = 11
89 filenames = [
90 "show_mpls_table.ref",
91 "show_isis_flex_algo.ref",
92 ]
93 for rname in ["rt1", "rt2", "rt3"]:
94 outputs[rname] = {}
95 for step in range(1, number_of_steps + 1):
96 outputs[rname][step] = {}
97 for filename in filenames:
98 # Get snapshots relative to the expected network convergence
99 filename_pullpath = "{}/{}/step{}/{}".format(CWD, rname, step, filename)
100 outputs[rname][step][filename] = open(filename_pullpath).read()
101
102
103 def setup_module(mod):
104 "Sets up the pytest environment"
105 tgen = Topogen(build_topo, mod.__name__)
106 frrdir = tgen.config.get(tgen.CONFIG_SECTION, "frrdir")
107 if not os.path.isfile(os.path.join(frrdir, "pathd")):
108 pytest.skip("pathd daemon wasn't built")
109 tgen.start_topology()
110 router_list = tgen.routers()
111
112 # For all registered routers, load the zebra configuration file
113 for rname, router in router_list.items():
114 router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)))
115 router.load_config( TopoRouter.RD_ISIS, os.path.join(CWD, "{}/isisd.conf".format(rname)))
116 tgen.start_router()
117
118
119 def teardown_module(mod):
120 "Teardown the pytest environment"
121 tgen = get_topogen()
122 tgen.stop_topology()
123
124
125 def setup_testcase(msg):
126 logger.info(msg)
127 tgen = get_topogen()
128 if tgen.routers_have_failure():
129 pytest.skip(tgen.errors)
130 return tgen
131
132
133 def router_compare_json_output(rname, command, reference):
134 "Compare router JSON output"
135
136 logger.info('Comparing router "%s" "%s" output', rname, command)
137
138 tgen = get_topogen()
139 expected = json.loads(reference)
140
141 # Run test function until we get an result. Wait at most 60 seconds.
142 test_func = partial(topotest.router_json_cmp, tgen.gears[rname], command, expected)
143 _, diff = topotest.run_and_expect(test_func, None, count=120, wait=0.5)
144 assertmsg = '"{}" JSON output mismatches the expected result'.format(rname)
145 assert diff is None, assertmsg
146
147
148 def router_compare_output(rname, command, reference):
149 "Compare router output"
150
151 logger.info('Comparing router "%s" "%s" output', rname, command)
152
153 tgen = get_topogen()
154
155 # Run test function until we get an result. Wait at most 60 seconds.
156 test_func = partial(topotest.router_output_cmp, tgen.gears[rname], command, reference)
157 result, diff = topotest.run_and_expect(test_func, "", count=120, wait=0.5)
158 assertmsg = '{} command "{}" output mismatches the expected result:\n{}'.format(rname, command, diff)
159 assert result, assertmsg
160
161
162 #
163 # Step 1
164 #
165 # Test initial network convergenece
166 #
167 # All flex-algo are defined and its fib entries are installed
168 #
169 def test_step1_mpls_lfib():
170 logger.info("Test (step 1)")
171 tgen = get_topogen()
172 if tgen.routers_have_failure():
173 pytest.skip(tgen.errors)
174
175 # For Developers
176 # tgen.mininet_cli()
177 for rname in ["rt1", "rt2", "rt3"]:
178 router_compare_output(
179 rname, "show isis flex-algo",
180 outputs[rname][1]["show_isis_flex_algo.ref"])
181 router_compare_json_output(
182 rname, "show mpls table json",
183 outputs[rname][1]["show_mpls_table.ref"])
184
185
186 #
187 # Step 2
188 #
189 # Action(s):
190 # - Disable flex-algo-203 definition advertisement on rt1
191 #
192 # Expected change(s):
193 # - Nothing
194 #
195 # Description:
196 # No change occurs because it refers to the FAD set in rt2.
197 #
198 def test_step2_mpls_lfib():
199 logger.info("Test (step 2)")
200 tgen = get_topogen()
201 if tgen.routers_have_failure():
202 pytest.skip(tgen.errors)
203
204 tgen.gears["rt1"].vtysh_cmd(
205 """
206 configure terminal
207 router isis 1
208 flex-algo 203
209 no advertise-definition
210 """)
211
212 # For Developers
213 # tgen.mininet_cli()
214 for rname in ["rt1", "rt2", "rt3"]:
215 router_compare_output(
216 rname, "show isis flex-algo",
217 outputs[rname][2]["show_isis_flex_algo.ref"])
218 router_compare_json_output(
219 rname, "show mpls table json",
220 outputs[rname][2]["show_mpls_table.ref"])
221
222
223 #
224 # Step 3
225 #
226 # Action(s):
227 # - Disable flex-algo-203 definition advertisement on rt2
228 #
229 # Expected change(s):
230 # - rt1,rt2,rt3 should uninstall all Prefix-SIDs of flex-algo-203
231 #
232 # Description:
233 # When all FADs are disappeared, all their prefix sid routes are withdrawn.
234 #
235 def test_step3_mpls_lfib():
236 logger.info("Test (step 3)")
237 tgen = get_topogen()
238 if tgen.routers_have_failure():
239 pytest.skip(tgen.errors)
240
241 tgen.gears["rt2"].vtysh_cmd(
242 """
243 configure terminal
244 router isis 1
245 flex-algo 203
246 no advertise-definition
247 """)
248
249 # For Developers
250 # tgen.mininet_cli()
251 for rname in ["rt1", "rt2", "rt3"]:
252 router_compare_output(
253 rname, "show isis flex-algo",
254 outputs[rname][3]["show_isis_flex_algo.ref"])
255 router_compare_json_output(
256 rname, "show mpls table json",
257 outputs[rname][3]["show_mpls_table.ref"])
258
259
260 #
261 # Step 4
262 #
263 # Action(s):
264 # - Enable flex-algo-203 definition advertisement on rt2
265 #
266 # Expected change(s):
267 # - rt1,rt2,rt3 should install all Prefix-SIDs of flex-algo-203
268 #
269 # Description:
270 # Since the FAD is restored, the reachability to the Prefix-SID is restored.
271 #
272 def test_step4_mpls_lfib():
273 logger.info("Test (step 4)")
274 tgen = get_topogen()
275 if tgen.routers_have_failure():
276 pytest.skip(tgen.errors)
277
278 tgen.gears["rt2"].vtysh_cmd(
279 """
280 configure terminal
281 router isis 1
282 flex-algo 203
283 advertise-definition
284 """)
285
286 # For Developers
287 # tgen.mininet_cli()
288 for rname in ["rt1", "rt2", "rt3"]:
289 router_compare_output(
290 rname, "show isis flex-algo",
291 outputs[rname][4]["show_isis_flex_algo.ref"])
292 router_compare_json_output(
293 rname, "show mpls table json",
294 outputs[rname][4]["show_mpls_table.ref"])
295
296
297 #
298 # Step 5
299 #
300 # Action(s):
301 # - Enable flex-algo-203 definition advertisement on rt1
302 #
303 # Expected change(s):
304 # - Nothing
305 #
306 # Description:
307 # This does not affect the FIB, since there is already a FAD for rt2.
308 # However, the FAD owner will be changed from rt2 to rt1.
309 #
310 def test_step5_mpls_lfib():
311 logger.info("Test (step 5)")
312 tgen = get_topogen()
313 if tgen.routers_have_failure():
314 pytest.skip(tgen.errors)
315
316 tgen.gears["rt1"].vtysh_cmd(
317 """
318 configure terminal
319 router isis 1
320 flex-algo 203
321 advertise-definition
322 """)
323
324 # For Developers
325 # tgen.mininet_cli()
326 for rname in ["rt1", "rt2", "rt3"]:
327 router_compare_output(
328 rname, "show isis flex-algo",
329 outputs[rname][5]["show_isis_flex_algo.ref"])
330 router_compare_json_output(
331 rname, "show mpls table json",
332 outputs[rname][5]["show_mpls_table.ref"])
333
334
335 #
336 # Step 6
337 #
338 # Action(s):
339 # - Disable flex-algo-203 SR-MPLS dataplane on rt1
340 # - Disable flex-algo-203 SR-MPLS dataplane on rt2
341 # - Disable flex-algo-203 SR-MPLS dataplane on rt3
342 #
343 # Expected change(s):
344 # - rt1,rt2,rt3 should uninstall all Prefix-SIDs of flex-algo-203
345 #
346 # Description:
347 # Clear the Flex-Algo 203 whole settings on each routers. All routes related
348 # to it will be withdrawn.
349 #
350 def test_step6_mpls_lfib():
351 logger.info("Test (step 6)")
352 tgen = get_topogen()
353 if tgen.routers_have_failure():
354 pytest.skip(tgen.errors)
355
356 for rname in ["rt1", "rt2", "rt3"]:
357 tgen.gears[rname].vtysh_cmd(
358 """
359 configure terminal
360 router isis 1
361 flex-algo 203
362 no dataplane sr-mpls
363 """)
364
365 # For Developers
366 # tgen.mininet_cli()
367 for rname in ["rt1", "rt2", "rt3"]:
368 router_compare_output(
369 rname, "show isis flex-algo",
370 outputs[rname][6]["show_isis_flex_algo.ref"])
371 router_compare_json_output(
372 rname, "show mpls table json",
373 outputs[rname][6]["show_mpls_table.ref"])
374
375
376 #
377 # Step 7
378 #
379 # Action(s):
380 # - Disable flex-algo-203 all configuration on rt1
381 # - Disable flex-algo-203 all configuration on rt2
382 # - Disable flex-algo-203 all configuration on rt3
383 #
384 # Expected change(s):
385 # - rt1,rt2,rt3 should uninstall all Prefix-SIDs of flex-algo-203
386 #
387 # Description:
388 # Clear the Flex-Algo 203 whole settings on each routers. All routes related
389 # to it will be withdrawn.
390 #
391 def test_step7_mpls_lfib():
392 logger.info("Test (step 7)")
393 tgen = get_topogen()
394 if tgen.routers_have_failure():
395 pytest.skip(tgen.errors)
396
397 for rname in ["rt1", "rt2", "rt3"]:
398 tgen.gears[rname].vtysh_cmd(
399 """
400 configure terminal
401 router isis 1
402 no flex-algo 203
403 """)
404
405 # For Developers
406 # tgen.mininet_cli()
407 for rname in ["rt1", "rt2", "rt3"]:
408 router_compare_output(
409 rname, "show isis flex-algo",
410 outputs[rname][7]["show_isis_flex_algo.ref"])
411 router_compare_json_output(
412 rname, "show mpls table json",
413 outputs[rname][7]["show_mpls_table.ref"])
414
415 #
416 # Step 8
417 #
418 # Action(s):
419 # - Enable flex-algo-203 all configuration on rt1
420 # - Enable flex-algo-203 all configuration on rt2
421 # - Enable flex-algo-203 all configuration on rt3
422 #
423 # Expected change(s):
424 # - rt1,rt2,rt3 should install all Prefix-SIDs of flex-algo-203
425 #
426 # Description:
427 # All configurations were backed.
428 #
429 def test_step8_mpls_lfib():
430 logger.info("Test (step 8)")
431 tgen = get_topogen()
432 if tgen.routers_have_failure():
433 pytest.skip(tgen.errors)
434
435 tgen.gears["rt1"].vtysh_cmd(
436 """
437 configure terminal
438 router isis 1
439 flex-algo 203
440 advertise-definition
441 affinity exclude-any green
442 dataplane sr-mpls
443 """)
444
445 tgen.gears["rt2"].vtysh_cmd(
446 """
447 configure terminal
448 router isis 1
449 flex-algo 203
450 advertise-definition
451 affinity exclude-any green
452 dataplane sr-mpls
453 """)
454
455 tgen.gears["rt3"].vtysh_cmd(
456 """
457 configure terminal
458 router isis 1
459 flex-algo 203
460 dataplane sr-mpls
461 """)
462
463 # For Developers
464 # tgen.mininet_cli()
465 for rname in ["rt1", "rt2", "rt3"]:
466 router_compare_output(
467 rname, "show isis flex-algo",
468 outputs[rname][8]["show_isis_flex_algo.ref"])
469 router_compare_json_output(
470 rname, "show mpls table json",
471 outputs[rname][8]["show_mpls_table.ref"])
472
473
474 #
475 # Step 9
476 #
477 # Action(s):
478 # - Disable algorithm prefix-sid of algo-203 on rt1
479 #
480 # Expected change(s):
481 # - rt1 should uninstall all Prefix-SIDs of flex-algo-203
482 # - rt2 should uninstall Prefix-SIDs of rt1's flex-algo-203
483 # - rt3 should uninstall Prefix-SIDs of rt1's flex-algo-203
484 #
485 def test_step9_mpls_lfib():
486 logger.info("Test (step 9)")
487 tgen = get_topogen()
488 if tgen.routers_have_failure():
489 pytest.skip(tgen.errors)
490
491 tgen.gears["rt1"].vtysh_cmd(
492 """
493 configure terminal
494 router isis 1
495 no segment-routing prefix 1.1.1.1/32 algorithm 203 index 301
496 no segment-routing prefix 2001:db8:1000::1/128 algorithm 203 index 1301
497 """)
498
499 # For Developers
500 # tgen.mininet_cli()
501 for rname in ["rt1", "rt2", "rt3"]:
502 router_compare_output(
503 rname, "show isis flex-algo",
504 outputs[rname][9]["show_isis_flex_algo.ref"])
505 router_compare_json_output(
506 rname, "show mpls table json",
507 outputs[rname][9]["show_mpls_table.ref"])
508
509
510 #
511 # Step 10
512 #
513 # Action(s):
514 # - Enable algorithm prefix-sid of algo-203 on rt1
515 #
516 # Expected change(s):
517 # - rt1 should install all Prefix-SIDs of flex-algo-203
518 # - rt2 should install Prefix-SIDs of rt1's flex-algo-203
519 # - rt3 should install Prefix-SIDs of rt1's flex-algo-203
520 #
521 def test_step10_mpls_lfib():
522 logger.info("Test (step 10)")
523 tgen = get_topogen()
524 if tgen.routers_have_failure():
525 pytest.skip(tgen.errors)
526
527 tgen.gears["rt1"].vtysh_cmd(
528 """
529 configure terminal
530 router isis 1
531 segment-routing prefix 1.1.1.1/32 algorithm 203 index 301
532 segment-routing prefix 2001:db8:1000::1/128 algorithm 203 index 1301
533 """)
534
535 # For Developers
536 # tgen.mininet_cli()
537 for rname in ["rt1", "rt2", "rt3"]:
538 router_compare_output(
539 rname, "show isis flex-algo",
540 outputs[rname][10]["show_isis_flex_algo.ref"])
541 router_compare_json_output(
542 rname, "show mpls table json",
543 outputs[rname][10]["show_mpls_table.ref"])
544
545
546 #
547 # Step 11
548 #
549 # Action(s):
550 # - Update algorithm prefix-sid of algo-203 on rt1 from 301 to 311
551 #
552 # Expected change(s):
553 # - rt2 should update Prefix-SIDs of rt1's flex-algo-203 from 301 to 311
554 # - rt3 should update Prefix-SIDs of rt1's flex-algo-203 from 301 to 311
555 #
556 def test_step11_mpls_lfib():
557 logger.info("Test (step 11)")
558 tgen = get_topogen()
559 if tgen.routers_have_failure():
560 pytest.skip(tgen.errors)
561
562 tgen.gears["rt1"].vtysh_cmd(
563 """
564 configure terminal
565 router isis 1
566 segment-routing prefix 1.1.1.1/32 algorithm 203 index 311
567 segment-routing prefix 2001:db8:1000::1/128 algorithm 203 index 1311
568 """)
569
570 # For Developers
571 # tgen.mininet_cli()
572 for rname in ["rt1", "rt2", "rt3"]:
573 router_compare_output(
574 rname, "show isis flex-algo",
575 outputs[rname][11]["show_isis_flex_algo.ref"])
576 router_compare_json_output(
577 rname, "show mpls table json",
578 outputs[rname][11]["show_mpls_table.ref"])
579
580
581 if __name__ == "__main__":
582 args = ["-s"] + sys.argv[1:]
583 sys.exit(pytest.main(args))