]>
git.proxmox.com Git - mirror_frr.git/blob - tests/topotests/isis_lfa_topo1/test_isis_lfa_topo1.py
2 # SPDX-License-Identifier: ISC
5 # test_isis_tilfa_topo1.py
6 # Part of NetDEF Topology Tests
8 # Copyright (c) 2020 by
9 # Network Device Education Foundation, Inc. ("NetDEF")
13 test_isis_lfa_topo1.py:
17 +--------------------------------+ RT1 +-------------------------------+
18 | +-------------+ +-------------+ |
24 +----+----+ +----+----+ +----+----+ +----+----+ +----+----+
26 | RT2 | 5 | RT3 | | RT4 | | RT5 | | RT6 |
27 | +--------+ | | | | | | |
29 +----+----+ +----+----+ +----+----+ +----+----+ +----+----+
35 | +-------------+ RT7 +-------------+ |
36 +--------------------------------+ +-------------------------------+
47 from functools
import partial
49 # Save the Current Working Directory to find configuration files.
50 CWD
= os
.path
.dirname(os
.path
.realpath(__file__
))
51 sys
.path
.append(os
.path
.join(CWD
, "../"))
53 # pylint: disable=C0413
54 # Import topogen and topotest helpers
55 from lib
import topotest
56 from lib
.topogen
import Topogen
, TopoRouter
, get_topogen
57 from lib
.topolog
import logger
59 # Required to instantiate the topology builder class.
61 pytestmark
= [pytest
.mark
.isisd
]
63 # Global multi-dimensional dictionary containing all expected outputs
73 for router
in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6", "rt7"]:
74 tgen
.add_router(router
)
79 switch
= tgen
.add_switch("s1")
80 switch
.add_link(tgen
.gears
["rt1"], nodeif
="eth-rt2")
81 switch
.add_link(tgen
.gears
["rt2"], nodeif
="eth-rt1")
82 switch
= tgen
.add_switch("s2")
83 switch
.add_link(tgen
.gears
["rt2"], nodeif
="eth-rt3")
84 switch
.add_link(tgen
.gears
["rt3"], nodeif
="eth-rt2")
85 switch
= tgen
.add_switch("s3")
86 switch
.add_link(tgen
.gears
["rt1"], nodeif
="eth-rt3")
87 switch
.add_link(tgen
.gears
["rt3"], nodeif
="eth-rt1")
88 switch
= tgen
.add_switch("s4")
89 switch
.add_link(tgen
.gears
["rt1"], nodeif
="eth-rt4")
90 switch
.add_link(tgen
.gears
["rt4"], nodeif
="eth-rt1")
91 switch
= tgen
.add_switch("s5")
92 switch
.add_link(tgen
.gears
["rt1"], nodeif
="eth-rt5")
93 switch
.add_link(tgen
.gears
["rt5"], nodeif
="eth-rt1")
94 switch
= tgen
.add_switch("s6")
95 switch
.add_link(tgen
.gears
["rt1"], nodeif
="eth-rt6")
96 switch
.add_link(tgen
.gears
["rt6"], nodeif
="eth-rt1")
97 switch
= tgen
.add_switch("s7")
98 switch
.add_link(tgen
.gears
["rt2"], nodeif
="eth-rt7")
99 switch
.add_link(tgen
.gears
["rt7"], nodeif
="eth-rt2")
100 switch
= tgen
.add_switch("s8")
101 switch
.add_link(tgen
.gears
["rt3"], nodeif
="eth-rt7")
102 switch
.add_link(tgen
.gears
["rt7"], nodeif
="eth-rt3")
103 switch
= tgen
.add_switch("s9")
104 switch
.add_link(tgen
.gears
["rt4"], nodeif
="eth-rt7")
105 switch
.add_link(tgen
.gears
["rt7"], nodeif
="eth-rt4")
106 switch
= tgen
.add_switch("s10")
107 switch
.add_link(tgen
.gears
["rt5"], nodeif
="eth-rt7")
108 switch
.add_link(tgen
.gears
["rt7"], nodeif
="eth-rt5")
109 switch
= tgen
.add_switch("s11")
110 switch
.add_link(tgen
.gears
["rt6"], nodeif
="eth-rt7")
111 switch
.add_link(tgen
.gears
["rt7"], nodeif
="eth-rt6")
114 # Populate multi-dimensional dictionary containing all expected outputs
116 files
= ["show_ipv6_route.ref", "show_yang_interface_isis_adjacencies.ref"]
117 for rname
in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6", "rt7"]:
119 for step
in range(1, 16 + 1):
120 outputs
[rname
][step
] = {}
123 # Get snapshots relative to the expected initial network convergence
124 filename
= "{}/{}/step{}/{}".format(CWD
, rname
, step
, file)
125 outputs
[rname
][step
][file] = open(filename
).read()
129 if file == "show_yang_interface_isis_adjacencies.ref":
132 # Get diff relative to the previous step
133 filename
= "{}/{}/step{}/{}.diff".format(CWD
, rname
, step
, file)
135 # Create temporary files in order to apply the diff
136 f_in
= tempfile
.NamedTemporaryFile(mode
="w")
137 f_in
.write(outputs
[rname
][step
- 1][file])
139 f_out
= tempfile
.NamedTemporaryFile(mode
="r")
141 "patch -s -o %s %s %s" % (f_out
.name
, f_in
.name
, filename
)
144 # Store the updated snapshot and remove the temporary files
145 outputs
[rname
][step
][file] = open(f_out
.name
).read()
150 def setup_module(mod
):
151 "Sets up the pytest environment"
152 tgen
= Topogen(build_topo
, mod
.__name
__)
153 tgen
.start_topology()
155 router_list
= tgen
.routers()
157 # For all registered routers, load the zebra configuration file
158 for rname
, router
in router_list
.items():
160 TopoRouter
.RD_ZEBRA
, os
.path
.join(CWD
, "{}/zebra.conf".format(rname
))
163 TopoRouter
.RD_ISIS
, os
.path
.join(CWD
, "{}/isisd.conf".format(rname
))
166 TopoRouter
.RD_BFD
, os
.path
.join(CWD
, "/dev/null".format(rname
))
172 def teardown_module(mod
):
173 "Teardown the pytest environment"
176 # This function tears down the whole topology.
180 def router_compare_json_output(rname
, command
, reference
, wait
=0.5, count
=120):
181 "Compare router JSON output"
183 logger
.info('Comparing router "%s" "%s" output', rname
, command
)
186 expected
= json
.loads(reference
)
188 # Run test function until we get an result. Wait at most 60 seconds.
189 test_func
= partial(topotest
.router_json_cmp
, tgen
.gears
[rname
], command
, expected
)
190 _
, diff
= topotest
.run_and_expect(test_func
, None, count
=count
, wait
=wait
)
191 assertmsg
= '"{}" JSON output mismatches the expected result'.format(rname
)
192 assert diff
is None, assertmsg
198 # Test initial network convergence
200 def test_isis_adjacencies_step1():
201 logger
.info("Test (step 1): check IS-IS adjacencies")
204 # Skip if previous fatal error condition is raised
205 if tgen
.routers_have_failure():
206 pytest
.skip(tgen
.errors
)
208 for rname
in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6", "rt7"]:
209 router_compare_json_output(
211 "show yang operational-data /frr-interface:lib isisd",
212 outputs
[rname
][1]["show_yang_interface_isis_adjacencies.ref"],
216 def test_rib_ipv6_step1():
217 logger
.info("Test (step 1): verify IPv6 RIB")
220 # Skip if previous fatal error condition is raised
221 if tgen
.routers_have_failure():
222 pytest
.skip(tgen
.errors
)
224 for rname
in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6", "rt7"]:
225 router_compare_json_output(
226 rname
, "show ipv6 route isis json", outputs
[rname
][1]["show_ipv6_route.ref"]
234 # -Disable LFA protection on all interfaces
237 # -rt1 should uninstall all backup nexthops from all routes
239 def test_rib_ipv6_step2():
240 logger
.info("Test (step 2): verify IPv6 RIB")
243 # Skip if previous fatal error condition is raised
244 if tgen
.routers_have_failure():
245 pytest
.skip(tgen
.errors
)
247 logger
.info("Disabling LFA protection on all rt1 interfaces")
249 'vtysh -c "conf t" -c "interface eth-rt2" -c "no isis fast-reroute lfa"'
252 'vtysh -c "conf t" -c "interface eth-rt3" -c "no isis fast-reroute lfa"'
255 'vtysh -c "conf t" -c "interface eth-rt4" -c "no isis fast-reroute lfa"'
258 'vtysh -c "conf t" -c "interface eth-rt5" -c "no isis fast-reroute lfa"'
261 'vtysh -c "conf t" -c "interface eth-rt6" -c "no isis fast-reroute lfa"'
264 for rname
in ["rt1"]:
265 router_compare_json_output(
266 rname
, "show ipv6 route isis json", outputs
[rname
][2]["show_ipv6_route.ref"]
274 # -Re-enable LFA protection on all interfaces
277 # -Revert changes from the previous step
279 def test_rib_ipv6_step3():
280 logger
.info("Test (step 3): verify IPv6 RIB")
283 # Skip if previous fatal error condition is raised
284 if tgen
.routers_have_failure():
285 pytest
.skip(tgen
.errors
)
287 logger
.info("Re-enabling LFA protection on all rt1 interfaces")
289 'vtysh -c "conf t" -c "interface eth-rt2" -c "isis fast-reroute lfa"'
292 'vtysh -c "conf t" -c "interface eth-rt3" -c "isis fast-reroute lfa"'
295 'vtysh -c "conf t" -c "interface eth-rt4" -c "isis fast-reroute lfa"'
298 'vtysh -c "conf t" -c "interface eth-rt5" -c "isis fast-reroute lfa"'
301 'vtysh -c "conf t" -c "interface eth-rt6" -c "isis fast-reroute lfa"'
304 for rname
in ["rt1"]:
305 router_compare_json_output(
306 rname
, "show ipv6 route isis json", outputs
[rname
][3]["show_ipv6_route.ref"]
314 # -Disable LFA load-sharing
317 # -rt1 should use at most one backup nexthop for each route
319 def test_rib_ipv6_step4():
320 logger
.info("Test (step 4): verify IPv6 RIB")
323 # Skip if previous fatal error condition is raised
324 if tgen
.routers_have_failure():
325 pytest
.skip(tgen
.errors
)
327 logger
.info("Disabling LFA load-sharing on rt1")
329 'vtysh -c "conf t" -c "router isis 1" -c "fast-reroute load-sharing disable"'
332 for rname
in ["rt1"]:
333 router_compare_json_output(
334 rname
, "show ipv6 route isis json", outputs
[rname
][4]["show_ipv6_route.ref"]
342 # -Re-enable LFA load-sharing
345 # -Revert changes from the previous step
347 def test_rib_ipv6_step5():
348 logger
.info("Test (step 5): verify IPv6 RIB")
351 # Skip if previous fatal error condition is raised
352 if tgen
.routers_have_failure():
353 pytest
.skip(tgen
.errors
)
355 logger
.info("Re-enabling LFA load-sharing on rt1")
357 'vtysh -c "conf t" -c "router isis 1" -c "no fast-reroute load-sharing disable"'
360 for rname
in ["rt1"]:
361 router_compare_json_output(
362 rname
, "show ipv6 route isis json", outputs
[rname
][5]["show_ipv6_route.ref"]
370 # -Limit backup computation to critical priority prefixes only
373 # -rt1 should uninstall all backup nexthops from all routes
375 def test_rib_ipv6_step6():
376 logger
.info("Test (step 6): verify IPv6 RIB")
379 # Skip if previous fatal error condition is raised
380 if tgen
.routers_have_failure():
381 pytest
.skip(tgen
.errors
)
383 logger
.info("Limiting backup computation to critical priority prefixes only")
385 'vtysh -c "conf t" -c "router isis 1" -c "fast-reroute priority-limit critical"'
388 for rname
in ["rt1"]:
389 router_compare_json_output(
390 rname
, "show ipv6 route isis json", outputs
[rname
][6]["show_ipv6_route.ref"]
398 # -Configure a prefix priority list to classify rt7's loopback as a
399 # critical-priority prefix
402 # -rt1 should install backup nexthops for rt7's loopback route.
404 def test_rib_ipv6_step7():
405 logger
.info("Test (step 7): verify IPv6 RIB")
408 # Skip if previous fatal error condition is raised
409 if tgen
.routers_have_failure():
410 pytest
.skip(tgen
.errors
)
412 logger
.info("Configuring a prefix priority list")
414 'vtysh -c "conf t" -c "router isis 1" -c "spf prefix-priority critical CRITICAL_DESTINATIONS"'
417 'vtysh -c "conf t" -c "ipv6 access-list CRITICAL_DESTINATIONS seq 5 permit 2001:db8:1000::7/128"'
420 for rname
in ["rt1"]:
421 router_compare_json_output(
422 rname
, "show ipv6 route isis json", outputs
[rname
][7]["show_ipv6_route.ref"]
430 # -Revert previous changes related to prefix priorities
433 # -Revert changes from the previous two steps
435 def test_rib_ipv6_step8():
436 logger
.info("Test (step 8): verify IPv6 RIB")
439 # Skip if previous fatal error condition is raised
440 if tgen
.routers_have_failure():
441 pytest
.skip(tgen
.errors
)
443 logger
.info("Reverting previous changes related to prefix priorities")
445 'vtysh -c "conf t" -c "no ipv6 access-list CRITICAL_DESTINATIONS seq 5 permit 2001:db8:1000::7/128"'
448 'vtysh -c "conf t" -c "router isis 1" -c "no fast-reroute priority-limit critical"'
451 'vtysh -c "conf t" -c "router isis 1" -c "no spf prefix-priority critical CRITICAL_DESTINATIONS"'
454 for rname
in ["rt1"]:
455 router_compare_json_output(
456 rname
, "show ipv6 route isis json", outputs
[rname
][8]["show_ipv6_route.ref"]
464 # -Exclude eth-rt6 from LFA computation for eth-rt2's failure
467 # -Uninstall the eth-rt2 protecting backup nexthops that go through eth-rt6
469 def test_rib_ipv6_step9():
470 logger
.info("Test (step 9): verify IPv6 RIB")
473 # Skip if previous fatal error condition is raised
474 if tgen
.routers_have_failure():
475 pytest
.skip(tgen
.errors
)
477 logger
.info("Excluding eth-rt6 from LFA computation for eth-rt2's failure")
479 'vtysh -c "conf t" -c "interface eth-rt2" -c "isis fast-reroute lfa exclude interface eth-rt6"'
482 for rname
in ["rt1"]:
483 router_compare_json_output(
484 rname
, "show ipv6 route isis json", outputs
[rname
][9]["show_ipv6_route.ref"]
492 # -Remove exclusion of eth-rt6 from LFA computation for eth-rt2's failure
495 # -Revert changes from the previous step
497 def test_rib_ipv6_step10():
498 logger
.info("Test (step 10): verify IPv6 RIB")
501 # Skip if previous fatal error condition is raised
502 if tgen
.routers_have_failure():
503 pytest
.skip(tgen
.errors
)
506 "Removing exclusion of eth-rt6 from LFA computation for eth-rt2's failure"
509 'vtysh -c "conf t" -c "interface eth-rt2" -c "no isis fast-reroute lfa exclude interface eth-rt6"'
512 for rname
in ["rt1"]:
513 router_compare_json_output(
515 "show ipv6 route isis json",
516 outputs
[rname
][10]["show_ipv6_route.ref"],
524 # -Add LFA tiebreaker: prefer node protecting backup path
527 # -rt1 should prefer backup nexthops that provide node protection
529 def test_rib_ipv6_step11():
530 logger
.info("Test (step 11): verify IPv6 RIB")
533 # Skip if previous fatal error condition is raised
534 if tgen
.routers_have_failure():
535 pytest
.skip(tgen
.errors
)
537 logger
.info("Adding LFA tiebreaker: prefer node protecting backup path")
539 'vtysh -c "conf t" -c "router isis 1" -c "fast-reroute lfa tiebreaker node-protecting index 10"'
542 for rname
in ["rt1"]:
543 router_compare_json_output(
545 "show ipv6 route isis json",
546 outputs
[rname
][11]["show_ipv6_route.ref"],
554 # -Add LFA tiebreaker: prefer backup path via downstream node
557 # -rt1 should prefer backup nexthops that satisfy the downstream condition
559 def test_rib_ipv6_step12():
560 logger
.info("Test (step 12): verify IPv6 RIB")
563 # Skip if previous fatal error condition is raised
564 if tgen
.routers_have_failure():
565 pytest
.skip(tgen
.errors
)
567 logger
.info("Adding LFA tiebreaker: prefer backup path via downstream node")
569 'vtysh -c "conf t" -c "router isis 1" -c "fast-reroute lfa tiebreaker downstream index 20"'
572 for rname
in ["rt1"]:
573 router_compare_json_output(
575 "show ipv6 route isis json",
576 outputs
[rname
][12]["show_ipv6_route.ref"],
584 # -Add LFA tiebreaker: prefer backup path with lowest total metric
587 # -rt1 should prefer backup nexthops that have the best metric
589 def test_rib_ipv6_step13():
590 logger
.info("Test (step 13): verify IPv6 RIB")
593 # Skip if previous fatal error condition is raised
594 if tgen
.routers_have_failure():
595 pytest
.skip(tgen
.errors
)
597 logger
.info("Adding LFA tiebreaker: prefer backup path with lowest total metric")
599 'vtysh -c "conf t" -c "router isis 1" -c "fast-reroute lfa tiebreaker lowest-backup-metric index 30"'
602 for rname
in ["rt1"]:
603 router_compare_json_output(
605 "show ipv6 route isis json",
606 outputs
[rname
][13]["show_ipv6_route.ref"],
614 # - Setting spf-delay-ietf init-delay of 15s
617 # - No routing table change
618 # - At the end of test, SPF reacts to a failure in 15s
620 def test_rib_ipv6_step14():
621 logger
.info("Test (step 14): verify IPv6 RIB")
624 # Skip if previous fatal error condition is raised
625 if tgen
.routers_have_failure():
626 pytest
.skip(tgen
.errors
)
628 logger
.info("Setting spf-delay-ietf init-delay of 15s")
630 'vtysh -c "conf t" -c "router isis 1" -c "spf-delay-ietf init-delay 15000 short-delay 0 long-delay 0 holddown 0 time-to-learn 0"'
633 for rname
in ["rt1"]:
634 router_compare_json_output(
636 "show ipv6 route isis json",
637 outputs
[rname
][14]["show_ipv6_route.ref"],
645 # - shut the eth-rt2 interface on rt1
648 # - Route switchover of routes via eth-rt2
650 def test_rib_ipv6_step15():
651 logger
.info("Test (step 15): verify IPv6 RIB")
654 # Skip if previous fatal error condition is raised
655 if tgen
.routers_have_failure():
656 pytest
.skip(tgen
.errors
)
658 logger
.info("Shut the interface to rt2 from the switch side and check fast-reroute")
659 tgen
.net
.cmd_raises("ip link set %s down" % tgen
.net
["s1"].intfs
[0])
661 for rname
in ["rt1"]:
662 router_compare_json_output(
664 "show ipv6 route isis json",
665 outputs
[rname
][15]["show_ipv6_route.ref"],
674 # Action(s): wait for the convergence and SPF computation on rt1
677 # - convergence of IPv6 RIB
679 def test_rib_ipv6_step16():
680 logger
.info("Test (step 16): verify IPv6 RIB")
683 # Skip if previous fatal error condition is raised
684 if tgen
.routers_have_failure():
685 pytest
.skip(tgen
.errors
)
687 logger
.info("Check SPF convergence")
689 for rname
in ["rt1"]:
690 router_compare_json_output(
692 "show ipv6 route isis json",
693 outputs
[rname
][16]["show_ipv6_route.ref"],
701 # - Unshut the interface to rt2 from the switch sid
704 # - The routing table converges
706 def test_rib_ipv6_step17():
707 logger
.info("Test (step 17): verify IPv6 RIB")
710 # Skip if previous fatal error condition is raised
711 if tgen
.routers_have_failure():
712 pytest
.skip(tgen
.errors
)
716 logger
.info("Unsetting spf-delay-ietf init-delay of 15s")
717 tgen
.net
[rname
].cmd('vtysh -c "conf t" -c "router isis 1" -c "no spf-delay-ietf"')
720 "Unshut the interface to rt2 from the switch side and check fast-reroute"
722 tgen
.net
.cmd_raises("ip link set %s up" % tgen
.net
["s1"].intfs
[0])
724 logger
.info("Setting spf-delay-ietf init-delay of 15s")
726 'vtysh -c "conf t" -c "router isis 1" -c "spf-delay-ietf init-delay 15000 short-delay 0 long-delay 0 holddown 0 time-to-learn 0"'
729 router_compare_json_output(
731 "show ipv6 route isis json",
732 outputs
[rname
][14]["show_ipv6_route.ref"],
740 # - drop traffic between rt1 and rt2 by shutting down the bridge between
741 # the routers. Interfaces on rt1 and rt2 stay up.
745 # - Route switchover of routes via eth-rt2
747 def test_rib_ipv6_step18():
748 def _rt2_neigh_down(router
):
749 output
= json
.loads(router
.vtysh_cmd("show isis neighbor rt2 json"))
769 "topo-0":"ipv6-unicast"
771 "snpa":"2020.2020.2020",
776 "ipv6":"fe80::ac19:a8ff:fee5:f48f"
820 return topotest
.json_cmp(output
, expected
, exact
=True)
822 logger
.info("Test (step 18): verify IPv6 RIB")
825 # Skip if previous fatal error condition is raised
826 if tgen
.routers_have_failure():
827 pytest
.skip(tgen
.errors
)
829 logger
.info("Drop traffic between rt1 and rt2")
830 tgen
.net
.cmd_raises("ip link set s1 down")
833 router
= tgen
.gears
[rname
]
834 test_func
= partial(_rt2_neigh_down
, router
)
835 success
, result
= topotest
.run_and_expect(test_func
, None, count
=200, wait
=0.05)
836 assert result
is None, 'rt2 neighbor is still present on "{}"'.format(router
)
838 router_compare_json_output(
840 "show ipv6 route isis json",
841 outputs
[rname
][15]["show_ipv6_route.ref"],
850 # Action(s): wait for the convergence and SPF computation on rt1
853 # - convergence of IPv6 RIB
855 def test_rib_ipv6_step19():
856 logger
.info("Test (step 19): verify IPv6 RIB")
859 # Skip if previous fatal error condition is raised
860 if tgen
.routers_have_failure():
861 pytest
.skip(tgen
.errors
)
863 logger
.info("Check SPF convergence")
865 for rname
in ["rt1"]:
866 router_compare_json_output(
868 "show ipv6 route isis json",
869 outputs
[rname
][16]["show_ipv6_route.ref"],
877 # - Unshut the switch from rt1 to rt2
880 # - The routing table goes back to the nominal state
882 def test_rib_ipv6_step20():
883 logger
.info("Test (step 20): verify IPv6 RIB")
886 # Skip if previous fatal error condition is raised
887 if tgen
.routers_have_failure():
888 pytest
.skip(tgen
.errors
)
892 logger
.info("Unsetting spf-delay-ietf init-delay of 15s")
893 tgen
.net
[rname
].cmd('vtysh -c "conf t" -c "router isis 1" -c "no spf-delay-ietf"')
896 "Unshut the interface to rt2 from the switch side and check fast-reroute"
898 tgen
.net
.cmd_raises("ip link set s1 up")
900 logger
.info("Setting spf-delay-ietf init-delay of 15s")
902 'vtysh -c "conf t" -c "router isis 1" -c "spf-delay-ietf init-delay 15000 short-delay 0 long-delay 0 holddown 0 time-to-learn 0"'
905 router_compare_json_output(
907 "show ipv6 route isis json",
908 outputs
[rname
][14]["show_ipv6_route.ref"],
916 # - clear the rt2 ISIS neighbor on rt1
919 # - Route switchover of routes via eth-rt2
921 def test_rib_ipv6_step21():
922 logger
.info("Test (step 21): verify IPv6 RIB")
925 # Skip if previous fatal error condition is raised
926 if tgen
.routers_have_failure():
927 pytest
.skip(tgen
.errors
)
931 logger
.info("Clear the rt2 ISIS neighbor on rt1 and check fast-reroute")
932 tgen
.gears
[rname
].vtysh_cmd("clear isis neighbor rt2")
934 router_compare_json_output(
936 "show ipv6 route isis json",
937 outputs
[rname
][15]["show_ipv6_route.ref"],
946 # Action(s): wait for the convergence and SPF computation on rt1
949 # - convergence of IPv6 RIB
951 def test_rib_ipv6_step22():
952 logger
.info("Test (step 22): verify IPv6 RIB")
955 # Skip if previous fatal error condition is raised
956 if tgen
.routers_have_failure():
957 pytest
.skip(tgen
.errors
)
959 logger
.info("Check SPF convergence")
961 for rname
in ["rt1"]:
962 router_compare_json_output(
964 "show ipv6 route isis json",
965 outputs
[rname
][16]["show_ipv6_route.ref"],
976 # - No routing table change
979 def test_rib_ipv6_step23():
980 logger
.info("Test (step 23): verify IPv6 RIB")
983 # Skip if previous fatal error condition is raised
984 if tgen
.routers_have_failure():
985 pytest
.skip(tgen
.errors
)
987 logger
.info("Setup BFD on rt1 and rt2")
988 for rname
in ["rt1", "rt2"]:
989 conf_file
= os
.path
.join(CWD
, "{}/bfdd.conf".format(rname
))
990 tgen
.net
[rname
].cmd("vtysh -f {}".format(conf_file
))
992 logger
.info("Set ISIS BFD")
993 tgen
.net
["rt1"].cmd('vtysh -c "conf t" -c "int eth-rt2" -c "isis bfd"')
994 tgen
.net
["rt2"].cmd('vtysh -c "conf t" -c "int eth-rt1" -c "isis bfd"')
997 expect
= '[{"multihop":false,"interface":"eth-rt2","status":"up"}]'
998 router_compare_json_output(rname
, "show bfd peers json", expect
)
1000 router_compare_json_output(
1002 "show ipv6 route isis json",
1003 outputs
[rname
][14]["show_ipv6_route.ref"],
1011 # - drop traffic between rt1 and rt2 by shutting down the bridge between
1012 # the routers. Interfaces on rt1 and rt2 stay up.
1015 # - BFD comes down before IS-IS
1016 # - Route switchover of routes via eth-rt2
1018 def test_rib_ipv6_step24():
1019 def _bfd_down(router
):
1020 output
= json
.loads(router
.vtysh_cmd("show bfd peers json"))
1022 return topotest
.json_cmp(output
, expected
, exact
=True)
1024 logger
.info("Test (step 24): verify IPv6 RIB")
1025 tgen
= get_topogen()
1027 # Skip if previous fatal error condition is raised
1028 if tgen
.routers_have_failure():
1029 pytest
.skip(tgen
.errors
)
1031 logger
.info("Shut the interface to rt2 from the switch side and check fast-reroute")
1032 tgen
.net
.cmd_raises("ip link set s1 down")
1035 router
= tgen
.gears
[rname
]
1036 test_func
= partial(_bfd_down
, router
)
1037 success
, result
= topotest
.run_and_expect(test_func
, None, count
=30, wait
=0.3)
1038 assert result
is None, 'BFD session is still up on "{}"'.format(router
)
1040 router_compare_json_output(
1042 "show ipv6 route isis json",
1043 outputs
[rname
][15]["show_ipv6_route.ref"],
1051 # Action(s): wait for the convergence and SPF computation on rt1
1054 # - convergence of IPv6 RIB
1056 def test_rib_ipv6_step25():
1057 logger
.info("Test (step 25): verify IPv6 RIB")
1058 tgen
= get_topogen()
1060 # Skip if previous fatal error condition is raised
1061 if tgen
.routers_have_failure():
1062 pytest
.skip(tgen
.errors
)
1064 logger
.info("Check SPF convergence")
1066 for rname
in ["rt1"]:
1067 router_compare_json_output(
1069 "show ipv6 route isis json",
1070 outputs
[rname
][16]["show_ipv6_route.ref"],
1074 # Memory leak test template
1075 def test_memory_leak():
1076 "Run the memory leak test and report results."
1077 tgen
= get_topogen()
1078 if not tgen
.is_memleak_enabled():
1079 pytest
.skip("Memory leak test/report is disabled")
1081 tgen
.report_memory_leaks()
1084 if __name__
== "__main__":
1085 args
= ["-s"] + sys
.argv
[1:]
1086 sys
.exit(pytest
.main(args
))