]>
git.proxmox.com Git - mirror_frr.git/blob - tests/topotests/bfd_ospf_topo1/test_bfd_ospf_topo1.py
2 # SPDX-License-Identifier: ISC
5 # test_bfd_ospf_topo1.py
6 # Part of NetDEF Topology Tests
8 # Copyright (c) 2020 by
9 # Network Device Education Foundation, Inc. ("NetDEF")
13 test_bfd_ospf_topo1.py:
17 eth-rt2 (.1) | RT1 | eth-rt3 (.1)
18 +----------+ 1.1.1.1 +----------+
25 | 10.0.1.0/24 +----+----+
30 (.2) | eth-rt1 +----+----+
31 +----+----+ eth-rt4 | (.1)
34 | 2.2.2.2 | 10.0.4.0/24 |
37 (.1) | eth-rt5 eth-rt3 | (.2)
44 | 10.0.3.0/24 eth-rt5 | (.1)
51 +----------+ RT5 +----------+
52 eth-rt2 (.2) | 5.5.5.5 | eth-rt4 (.2)
62 from time
import sleep
63 from functools
import partial
65 # Save the Current Working Directory to find configuration files.
66 CWD
= os
.path
.dirname(os
.path
.realpath(__file__
))
67 sys
.path
.append(os
.path
.join(CWD
, "../"))
69 # pylint: disable=C0413
70 # Import topogen and topotest helpers
71 from lib
import topotest
72 from lib
.topogen
import Topogen
, TopoRouter
, get_topogen
73 from lib
.topolog
import logger
75 pytestmark
= [pytest
.mark
.bfdd
, pytest
.mark
.ospfd
]
78 def setup_module(mod
):
79 "Sets up the pytest environment"
81 "s1": ("rt1:eth-rt2", "rt2:eth-rt1"),
82 "s2": ("rt1:eth-rt3", "rt3:eth-rt1"),
83 "s3": ("rt2:eth-rt5", "rt5:eth-rt2"),
84 "s4": ("rt3:eth-rt4", "rt4:eth-rt3"),
85 "s5": ("rt4:eth-rt5", "rt5:eth-rt4"),
87 tgen
= Topogen(topodef
, mod
.__name
__)
90 router_list
= tgen
.routers()
92 # For all registered routers, load the zebra configuration file
93 for rname
, router
in router_list
.items():
95 TopoRouter
.RD_ZEBRA
, os
.path
.join(CWD
, "{}/zebra.conf".format(rname
))
98 TopoRouter
.RD_BFD
, os
.path
.join(CWD
, "{}/bfdd.conf".format(rname
))
101 TopoRouter
.RD_OSPF
, os
.path
.join(CWD
, "{}/ospfd.conf".format(rname
))
104 TopoRouter
.RD_OSPF6
, os
.path
.join(CWD
, "{}/ospf6d.conf".format(rname
))
110 def teardown_module(mod
):
111 "Teardown the pytest environment"
114 # This function tears down the whole topology.
118 def print_cmd_result(rname
, command
):
119 print(get_topogen().gears
[rname
].vtysh_cmd(command
, isjson
=False))
122 def router_compare_json_output(rname
, command
, reference
, count
=40, wait
=2):
123 "Compare router JSON output"
125 logger
.info('Comparing router "%s" "%s" output', rname
, command
)
128 filename
= "{}/{}/{}".format(CWD
, rname
, reference
)
129 expected
= json
.loads(open(filename
).read())
131 # Run test function until we get an result. Wait at most 80 seconds.
132 test_func
= partial(topotest
.router_json_cmp
, tgen
.gears
[rname
], command
, expected
)
133 _
, diff
= topotest
.run_and_expect(test_func
, None, count
=count
, wait
=wait
)
134 assertmsg
= '"{}" JSON output mismatches the expected result'.format(rname
)
135 assert diff
is None, assertmsg
141 def test_rib_ospf_step1():
142 logger
.info("Test (step 1): verify RIB for OSPF")
145 # Skip if previous fatal error condition is raised
146 if tgen
.routers_have_failure():
147 pytest
.skip(tgen
.errors
)
149 router_compare_json_output(
150 "rt1", "show ip route ospf json", "step1/show_ip_route.ref"
152 router_compare_json_output(
153 "rt1", "show ipv6 route ospf json", "step1/show_ipv6_route.ref"
157 def test_bfd_ospf_sessions_step2():
158 logger
.info("Test (step 2): verify BFD peers for OSPF")
161 # Skip if previous fatal error condition is raised
162 if tgen
.routers_have_failure():
163 pytest
.skip(tgen
.errors
)
165 # BFD is just used on three routers
166 for rt
in ["rt1", "rt2", "rt3"]:
167 router_compare_json_output(
168 rt
, "show bfd peers json", "step2/show_bfd_peers.ref"
172 def test_bfd_ospf_interface_failure_rt2_step3():
173 logger
.info("Test (step 3): Check failover handling with RT2 down")
176 # Skip if previous fatal error condition is raised
177 if tgen
.routers_have_failure():
178 pytest
.skip(tgen
.errors
)
180 # Let's kill the interface on rt2 and see what happens with the RIB and BFD on rt1
181 tgen
.gears
["rt2"].link_enable("eth-rt1", enabled
=False)
183 # By default BFD provides a recovery time of 900ms plus jitter, so let's wait
184 # initial 2 seconds to let the CI not suffer.
185 topotest
.sleep(2, "Wait for BFD down notification")
187 router_compare_json_output(
188 "rt1", "show ip route ospf json", "step3/show_ip_route_rt2_down.ref", 10, 2
190 router_compare_json_output(
191 "rt1", "show ipv6 route ospf json", "step3/show_ipv6_route_rt2_down.ref", 10, 2
193 router_compare_json_output(
194 "rt1", "show bfd peers json", "step3/show_bfd_peers_rt2_down.ref", 10, 2
197 # Check recovery, this can take some time
198 tgen
.gears
["rt2"].link_enable("eth-rt1", enabled
=True)
200 router_compare_json_output(
201 "rt1", "show ip route ospf json", "step3/show_ip_route_healthy.ref"
203 router_compare_json_output(
204 "rt1", "show ipv6 route ospf json", "step3/show_ipv6_route_healthy.ref"
206 router_compare_json_output(
207 "rt1", "show bfd peers json", "step3/show_bfd_peers_healthy.ref"
211 def test_bfd_ospf_interface_failure_rt3_step3():
212 logger
.info("Test (step 3): Check failover handling with RT3 down")
215 # Skip if previous fatal error condition is raised
216 if tgen
.routers_have_failure():
217 pytest
.skip(tgen
.errors
)
219 # Let's kill the interface on rt3 and see what happens with the RIB and BFD on rt1
220 tgen
.gears
["rt3"].link_enable("eth-rt1", enabled
=False)
222 # By default BFD provides a recovery time of 900ms plus jitter, so let's wait
223 # initial 2 seconds to let the CI not suffer.
224 topotest
.sleep(2, "Wait for BFD down notification")
225 router_compare_json_output(
226 "rt1", "show ip route ospf json", "step3/show_ip_route_rt3_down.ref", 10, 2
228 router_compare_json_output(
229 "rt1", "show ipv6 route ospf json", "step3/show_ipv6_route_rt3_down.ref", 10, 2
231 router_compare_json_output(
232 "rt1", "show bfd peers json", "step3/show_bfd_peers_rt3_down.ref", 10, 2
235 # Check recovery, this can take some time
236 tgen
.gears
["rt3"].link_enable("eth-rt1", enabled
=True)
238 router_compare_json_output(
239 "rt1", "show ip route ospf json", "step3/show_ip_route_healthy.ref"
241 router_compare_json_output(
242 "rt1", "show ipv6 route ospf json", "step3/show_ipv6_route_healthy.ref"
244 router_compare_json_output(
245 "rt1", "show bfd peers json", "step3/show_bfd_peers_healthy.ref"
249 def test_memory_leak():
250 "Run the memory leak test and report results."
252 if not tgen
.is_memleak_enabled():
253 pytest
.skip("Memory leak test/report is disabled")
255 tgen
.report_memory_leaks()
258 if __name__
== "__main__":
259 args
= ["-s"] + sys
.argv
[1:]
260 sys
.exit(pytest
.main(args
))