]>
Commit | Line | Data |
---|---|---|
a9179f57 | 1 | #!/usr/bin/env python |
acddc0ed | 2 | # SPDX-License-Identifier: ISC |
a9179f57 PG |
3 | |
4 | # | |
5 | # test_bfd_bgp_cbit_topo3.py | |
6 | # | |
7 | # Copyright (c) 2019 6WIND | |
8 | # | |
a9179f57 PG |
9 | |
10 | """ | |
622c4996 | 11 | test_bfd_bgp_cbit_topo3.py: Test the FRR BFD daemon with multihop and BGP |
a9179f57 PG |
12 | unnumbered. |
13 | """ | |
14 | ||
15 | import os | |
16 | import sys | |
17 | import json | |
18 | from functools import partial | |
19 | import pytest | |
20 | ||
21 | # Save the Current Working Directory to find configuration files. | |
22 | CWD = os.path.dirname(os.path.realpath(__file__)) | |
787e7624 | 23 | sys.path.append(os.path.join(CWD, "../")) |
a9179f57 PG |
24 | |
25 | # pylint: disable=C0413 | |
26 | # Import topogen and topotest helpers | |
27 | from lib import topotest | |
28 | from lib.topogen import Topogen, TopoRouter, get_topogen | |
29 | from lib.topolog import logger | |
30 | ||
5ad1fd54 DS |
31 | pytestmark = [pytest.mark.bgpd, pytest.mark.bfdd] |
32 | ||
787e7624 | 33 | |
a9179f57 PG |
34 | def setup_module(mod): |
35 | "Sets up the pytest environment" | |
8db751b8 CH |
36 | topodef = { |
37 | "s1": ("r1", "r2"), | |
38 | "s2": ("r2", "r3"), | |
39 | } | |
40 | tgen = Topogen(topodef, mod.__name__) | |
a9179f57 PG |
41 | tgen.start_topology() |
42 | ||
43 | router_list = tgen.routers() | |
44 | ||
e5f0ed14 | 45 | for rname, router in router_list.items(): |
a9179f57 | 46 | router.load_config( |
9fa6ec14 | 47 | TopoRouter.RD_ZEBRA, |
48 | os.path.join(CWD, "{}/zebra.conf".format(rname)), | |
a9179f57 PG |
49 | ) |
50 | router.load_config( | |
787e7624 | 51 | TopoRouter.RD_BFD, os.path.join(CWD, "{}/bfdd.conf".format(rname)) |
a9179f57 PG |
52 | ) |
53 | router.load_config( | |
787e7624 | 54 | TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format(rname)) |
a9179f57 PG |
55 | ) |
56 | ||
57 | # Initialize all routers. | |
58 | tgen.start_router() | |
59 | ||
60 | # Verify that we are using the proper version and that the BFD | |
61 | # daemon exists. | |
62 | for router in router_list.values(): | |
63 | # Check for Version | |
787e7624 | 64 | if router.has_version("<", "5.1"): |
65 | tgen.set_error("Unsupported FRR version") | |
a9179f57 PG |
66 | break |
67 | ||
787e7624 | 68 | |
a9179f57 PG |
69 | def teardown_module(_mod): |
70 | "Teardown the pytest environment" | |
71 | tgen = get_topogen() | |
72 | tgen.stop_topology() | |
73 | ||
74 | ||
75 | def test_protocols_convergence(): | |
76 | """ | |
77 | Assert that all protocols have converged before checking for the BFD | |
78 | statuses as they depend on it. | |
79 | """ | |
80 | tgen = get_topogen() | |
81 | if tgen.routers_have_failure(): | |
82 | pytest.skip(tgen.errors) | |
83 | ||
84 | # Check IPv6 routing tables. | |
85 | logger.info("Checking IPv6 routes for convergence") | |
86 | for router in tgen.routers().values(): | |
787e7624 | 87 | if router.name == "r2": |
a9179f57 | 88 | continue |
787e7624 | 89 | json_file = "{}/{}/ipv6_routes.json".format(CWD, router.name) |
a9179f57 | 90 | if not os.path.isfile(json_file): |
787e7624 | 91 | logger.info("skipping file {}".format(json_file)) |
a9179f57 PG |
92 | continue |
93 | expected = json.loads(open(json_file).read()) | |
787e7624 | 94 | test_func = partial( |
95 | topotest.router_json_cmp, router, "show ipv6 route json", expected | |
96 | ) | |
97 | _, result = topotest.run_and_expect(test_func, None, count=40, wait=0.5) | |
a9179f57 PG |
98 | assertmsg = '"{}" JSON output mismatches'.format(router.name) |
99 | assert result is None, assertmsg | |
100 | ||
101 | ||
102 | def test_bfd_connection(): | |
103 | "Assert that the BFD peers can find themselves." | |
104 | tgen = get_topogen() | |
105 | if tgen.routers_have_failure(): | |
106 | pytest.skip(tgen.errors) | |
107 | ||
787e7624 | 108 | logger.info("waiting for bfd peers to go up") |
a9179f57 | 109 | for router in tgen.routers().values(): |
787e7624 | 110 | if router.name == "r2": |
a9179f57 | 111 | continue |
787e7624 | 112 | json_file = "{}/{}/peers.json".format(CWD, router.name) |
a9179f57 PG |
113 | expected = json.loads(open(json_file).read()) |
114 | ||
787e7624 | 115 | test_func = partial( |
116 | topotest.router_json_cmp, router, "show bfd peers json", expected | |
117 | ) | |
d2f589ce | 118 | _, result = topotest.run_and_expect(test_func, None, count=32, wait=0.5) |
a9179f57 PG |
119 | assertmsg = '"{}" JSON output mismatches'.format(router.name) |
120 | assert result is None, assertmsg | |
121 | ||
787e7624 | 122 | |
a9179f57 PG |
123 | def test_bfd_loss_intermediate(): |
124 | """ | |
125 | Assert that BFD notices the bfd link down failure. | |
126 | but BGP entries should still be present | |
127 | """ | |
128 | tgen = get_topogen() | |
129 | if tgen.routers_have_failure(): | |
130 | pytest.skip(tgen.errors) | |
131 | ||
787e7624 | 132 | logger.info("removing IPv6 address from r2 to simulate loss of connectivity") |
a9179f57 | 133 | # Disable r2-eth0 ipv6 address |
787e7624 | 134 | cmd = 'vtysh -c "configure terminal" -c "interface r2-eth1" -c "no ipv6 address 2001:db8:4::2/64"' |
135 | tgen.net["r2"].cmd(cmd) | |
136 | ||
a9179f57 PG |
137 | # Wait the minimum time we can before checking that BGP/BFD |
138 | # converged. | |
787e7624 | 139 | logger.info("waiting for BFD converge down") |
a9179f57 PG |
140 | |
141 | # Check that BGP converged quickly. | |
142 | for router in tgen.routers().values(): | |
787e7624 | 143 | if router.name == "r2": |
a9179f57 | 144 | continue |
787e7624 | 145 | json_file = "{}/{}/peers_down.json".format(CWD, router.name) |
a9179f57 PG |
146 | expected = json.loads(open(json_file).read()) |
147 | ||
787e7624 | 148 | test_func = partial( |
149 | topotest.router_json_cmp, router, "show bfd peers json", expected | |
150 | ) | |
d2f589ce | 151 | _, result = topotest.run_and_expect(test_func, None, count=32, wait=0.5) |
a9179f57 PG |
152 | assertmsg = '"{}" JSON output mismatches'.format(router.name) |
153 | assert result is None, assertmsg | |
154 | ||
787e7624 | 155 | logger.info("waiting for BGP entries to become stale") |
a9179f57 | 156 | for router in tgen.routers().values(): |
787e7624 | 157 | if router.name == "r2": |
a9179f57 | 158 | continue |
787e7624 | 159 | json_file = "{}/{}/bgp_ipv6_routes_down.json".format(CWD, router.name) |
a9179f57 PG |
160 | expected = json.loads(open(json_file).read()) |
161 | ||
787e7624 | 162 | test_func = partial( |
163 | topotest.router_json_cmp, router, "show bgp ipv6 json", expected | |
164 | ) | |
a9179f57 PG |
165 | _, result = topotest.run_and_expect(test_func, None, count=50, wait=1) |
166 | assertmsg = '"{}" JSON output mismatches'.format(router.name) | |
167 | assert result is None, assertmsg | |
168 | ||
169 | logger.info("Checking IPv6 routes on r1 should still be present") | |
170 | for router in tgen.routers().values(): | |
787e7624 | 171 | if router.name == "r2": |
a9179f57 | 172 | continue |
787e7624 | 173 | if router.name == "r3": |
a9179f57 | 174 | continue |
787e7624 | 175 | json_file = "{}/r1/ipv6_routes.json".format(CWD) |
a9179f57 | 176 | expected = json.loads(open(json_file).read()) |
787e7624 | 177 | test_func = partial( |
178 | topotest.router_json_cmp, router, "show ipv6 route json", expected | |
179 | ) | |
180 | _, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) | |
a9179f57 PG |
181 | assertmsg = '"{}" JSON output mismatches'.format(router.name) |
182 | assert result is None, assertmsg | |
183 | ||
787e7624 | 184 | |
a9179f57 PG |
185 | def test_bfd_comes_back_again(): |
186 | """ | |
187 | Assert that BFD notices the bfd link up | |
188 | and that ipv6 entries appear back | |
189 | """ | |
190 | tgen = get_topogen() | |
787e7624 | 191 | logger.info("re-adding IPv6 address from r2 to simulate connectivity is back") |
a9179f57 | 192 | # adds back r2-eth0 ipv6 address |
787e7624 | 193 | cmd = 'vtysh -c "configure terminal" -c "interface r2-eth1" -c "ipv6 address 2001:db8:4::2/64"' |
194 | tgen.net["r2"].cmd(cmd) | |
a9179f57 PG |
195 | |
196 | # Wait the minimum time we can before checking that BGP/BFD | |
197 | # converged. | |
787e7624 | 198 | logger.info("waiting for BFD to converge up") |
a9179f57 PG |
199 | |
200 | # Check that BGP converged quickly. | |
201 | for router in tgen.routers().values(): | |
787e7624 | 202 | if router.name == "r2": |
a9179f57 | 203 | continue |
787e7624 | 204 | json_file = "{}/{}/peers.json".format(CWD, router.name) |
a9179f57 PG |
205 | expected = json.loads(open(json_file).read()) |
206 | ||
787e7624 | 207 | test_func = partial( |
208 | topotest.router_json_cmp, router, "show bfd peers json", expected | |
209 | ) | |
33308371 | 210 | _, result = topotest.run_and_expect(test_func, None, count=16, wait=0.5) |
a9179f57 PG |
211 | assertmsg = '"{}" JSON output mismatches'.format(router.name) |
212 | assert result is None, assertmsg | |
787e7624 | 213 | |
a9179f57 PG |
214 | |
215 | def test_memory_leak(): | |
216 | "Run the memory leak test and report results." | |
217 | tgen = get_topogen() | |
218 | if not tgen.is_memleak_enabled(): | |
787e7624 | 219 | pytest.skip("Memory leak test/report is disabled") |
a9179f57 PG |
220 | |
221 | tgen.report_memory_leaks() | |
222 | ||
223 | ||
787e7624 | 224 | if __name__ == "__main__": |
a9179f57 PG |
225 | args = ["-s"] + sys.argv[1:] |
226 | sys.exit(pytest.main(args)) |