]>
Commit | Line | Data |
---|---|---|
57ea1920 | 1 | #!/usr/bin/env python |
acddc0ed | 2 | # SPDX-License-Identifier: ISC |
57ea1920 PG |
3 | |
4 | # | |
5 | # Copyright (c) 2019 by VMware, Inc. ("VMware") | |
6 | # Used Copyright (c) 2018 by Network Device Education Foundation, Inc. | |
7 | # ("NetDEF") in this file. | |
8 | # | |
57ea1920 PG |
9 | |
10 | ||
11 | """ | |
12 | Following tests are covered to test ecmp functionality on iBGP. | |
13 | 1. Verify bgp fast-convergence functionality | |
14 | """ | |
15 | import os | |
16 | import sys | |
17 | import time | |
57ea1920 | 18 | import pytest |
1430ea83 | 19 | import re |
57ea1920 PG |
20 | from time import sleep |
21 | ||
22 | # Save the Current Working Directory to find configuration files. | |
23 | CWD = os.path.dirname(os.path.realpath(__file__)) | |
24 | sys.path.append(os.path.join(CWD, "../")) | |
25 | sys.path.append(os.path.join(CWD, "../../")) | |
26 | ||
27 | # pylint: disable=C0413 | |
28 | # Import topogen and topotest helpers | |
991a971f | 29 | from lib.topogen import Topogen, get_topogen |
57ea1920 PG |
30 | |
31 | from lib.common_config import ( | |
57ea1920 PG |
32 | write_test_header, |
33 | write_test_footer, | |
34 | verify_rib, | |
35 | create_static_routes, | |
36 | check_address_types, | |
57ea1920 | 37 | reset_config_on_routers, |
57ea1920 PG |
38 | shutdown_bringup_interface, |
39 | apply_raw_config, | |
991a971f | 40 | start_topology, |
57ea1920 PG |
41 | ) |
42 | from lib.topolog import logger | |
991a971f | 43 | from lib.topojson import build_config_from_json |
4953ca97 | 44 | from lib.bgp import create_router_bgp, verify_bgp_convergence |
57ea1920 | 45 | |
57ea1920 PG |
46 | pytestmark = [pytest.mark.bgpd, pytest.mark.staticd] |
47 | ||
48 | ||
57ea1920 PG |
49 | # Global variables |
50 | NEXT_HOPS = {"ipv4": [], "ipv6": []} | |
51 | NETWORK = {"ipv4": "192.168.1.10/32", "ipv6": "fd00:0:0:1::10/128"} | |
52 | NEXT_HOP_IP = {"ipv4": "10.0.0.1", "ipv6": "fd00::1"} | |
53 | BGP_CONVERGENCE = False | |
54 | ||
55 | ||
57ea1920 PG |
56 | def setup_module(mod): |
57 | """ | |
58 | Sets up the pytest environment. | |
59 | ||
60 | * `mod`: module name | |
61 | """ | |
57ea1920 PG |
62 | global ADDR_TYPES |
63 | ||
64 | testsuite_run_time = time.asctime(time.localtime(time.time())) | |
65 | logger.info("Testsuite start time: {}".format(testsuite_run_time)) | |
66 | logger.info("=" * 40) | |
67 | ||
991a971f KK |
68 | # This function initiates the topology build with Topogen... |
69 | json_file = "{}/ibgp_ecmp_topo3.json".format(CWD) | |
70 | tgen = Topogen(json_file, mod.__name__) | |
71 | global topo | |
e82b531d | 72 | topo = tgen.json_topo |
57ea1920 | 73 | |
991a971f KK |
74 | # Starting topology, create tmp files which are loaded to routers |
75 | # to start daemons and then start routers | |
76 | start_topology(tgen) | |
77 | ||
78 | # Creating configuration from JSON | |
79 | build_config_from_json(tgen, topo) | |
80 | ||
57ea1920 PG |
81 | # Don't run this test if we have any failure. |
82 | if tgen.routers_have_failure(): | |
83 | pytest.skip(tgen.errors) | |
84 | ||
85 | # Api call verify whether BGP is converged | |
86 | ADDR_TYPES = check_address_types() | |
87 | ||
88 | BGP_CONVERGENCE = verify_bgp_convergence(tgen, topo) | |
89 | assert BGP_CONVERGENCE is True, "setup_module :Failed \n Error:" " {}".format( | |
90 | BGP_CONVERGENCE | |
91 | ) | |
92 | ||
93 | # STATIC_ROUTE = True | |
94 | logger.info("Running setup_module() done") | |
95 | ||
96 | ||
97 | def teardown_module(): | |
e82b531d | 98 | get_topogen().stop_topology() |
57ea1920 PG |
99 | |
100 | ||
101 | def static_or_nw(tgen, topo, tc_name, test_type, dut): | |
102 | ||
103 | if test_type == "redist_static": | |
104 | input_dict_static = { | |
105 | dut: { | |
106 | "static_routes": [ | |
107 | {"network": NETWORK["ipv4"], "next_hop": NEXT_HOP_IP["ipv4"]}, | |
108 | {"network": NETWORK["ipv6"], "next_hop": NEXT_HOP_IP["ipv6"]}, | |
109 | ] | |
110 | } | |
111 | } | |
112 | logger.info("Configuring static route on router %s", dut) | |
113 | result = create_static_routes(tgen, input_dict_static) | |
114 | assert result is True, "Testcase {} : Failed \n Error: {}".format( | |
115 | tc_name, result | |
116 | ) | |
117 | ||
118 | input_dict_2 = { | |
119 | dut: { | |
120 | "bgp": { | |
121 | "address_family": { | |
122 | "ipv4": { | |
123 | "unicast": {"redistribute": [{"redist_type": "static"}]} | |
124 | }, | |
125 | "ipv6": { | |
126 | "unicast": {"redistribute": [{"redist_type": "static"}]} | |
127 | }, | |
128 | } | |
129 | } | |
130 | } | |
131 | } | |
132 | ||
133 | logger.info("Configuring redistribute static route on router %s", dut) | |
134 | result = create_router_bgp(tgen, topo, input_dict_2) | |
135 | assert result is True, "Testcase {} : Failed \n Error: {}".format( | |
136 | tc_name, result | |
137 | ) | |
138 | ||
139 | elif test_type == "advertise_nw": | |
140 | input_dict_nw = { | |
141 | dut: { | |
142 | "bgp": { | |
143 | "address_family": { | |
144 | "ipv4": { | |
145 | "unicast": { | |
146 | "advertise_networks": [{"network": NETWORK["ipv4"]}] | |
147 | } | |
148 | }, | |
149 | "ipv6": { | |
150 | "unicast": { | |
151 | "advertise_networks": [{"network": NETWORK["ipv6"]}] | |
152 | } | |
153 | }, | |
154 | } | |
155 | } | |
156 | } | |
157 | } | |
158 | ||
159 | logger.info( | |
160 | "Advertising networks %s %s from router %s", | |
161 | NETWORK["ipv4"], | |
162 | NETWORK["ipv6"], | |
163 | dut, | |
164 | ) | |
165 | result = create_router_bgp(tgen, topo, input_dict_nw) | |
166 | assert result is True, "Testcase {} : Failed \n Error: {}".format( | |
167 | tc_name, result | |
168 | ) | |
169 | ||
170 | ||
171 | @pytest.mark.parametrize("test_type", ["redist_static"]) | |
e82b531d | 172 | def test_ecmp_fast_convergence(request, test_type, tgen, topo): |
57ea1920 PG |
173 | """This test is to verify bgp fast-convergence cli functionality""" |
174 | ||
175 | tc_name = request.node.name | |
176 | write_test_header(tc_name) | |
57ea1920 PG |
177 | |
178 | # Verifying RIB routes | |
179 | dut = "r3" | |
180 | protocol = "bgp" | |
181 | ||
182 | reset_config_on_routers(tgen) | |
183 | static_or_nw(tgen, topo, tc_name, test_type, "r2") | |
184 | ||
185 | for addr_type in ADDR_TYPES: | |
186 | input_dict = {"r3": {"static_routes": [{"network": NETWORK[addr_type]}]}} | |
187 | ||
188 | logger.info("Verifying %s routes on r3", addr_type) | |
189 | result = verify_rib( | |
190 | tgen, | |
191 | addr_type, | |
192 | dut, | |
193 | input_dict, | |
194 | protocol=protocol, | |
195 | ) | |
196 | assert result is True, "Testcase {} : Failed \n Error: {}".format( | |
197 | tc_name, result | |
198 | ) | |
199 | ||
200 | intf1 = topo["routers"]["r2"]["links"]["r3-link1"]["interface"] | |
201 | intf2 = topo["routers"]["r2"]["links"]["r3-link2"]["interface"] | |
202 | ||
203 | logger.info("Shutdown one of the link b/w r2 and r3") | |
204 | shutdown_bringup_interface(tgen, "r2", intf1, False) | |
205 | ||
206 | logger.info("Verify bgp neighbors are still up") | |
207 | result = verify_bgp_convergence(tgen, topo) | |
208 | assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) | |
209 | ||
210 | logger.info("Shutdown another link b/w r2 and r3") | |
211 | shutdown_bringup_interface(tgen, "r2", intf2, False) | |
212 | ||
213 | logger.info("Wait for 10 sec and make sure bgp neighbors are still up") | |
214 | sleep(10) | |
215 | result = verify_bgp_convergence(tgen, topo) | |
216 | assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) | |
217 | ||
218 | logger.info("No shut links b/w r2 and r3") | |
219 | shutdown_bringup_interface(tgen, "r2", intf1, True) | |
220 | shutdown_bringup_interface(tgen, "r2", intf2, True) | |
221 | ||
1430ea83 DS |
222 | logger.info("Ensure that the links are still up") |
223 | result = verify_bgp_convergence(tgen, topo) | |
224 | ||
57ea1920 PG |
225 | logger.info("Enable bgp fast-convergence cli") |
226 | raw_config = { | |
a53c08bc CH |
227 | "r2": { |
228 | "raw_config": [ | |
229 | "router bgp {}".format(topo["routers"]["r2"]["bgp"]["local_as"]), | |
230 | "bgp fast-convergence", | |
231 | ] | |
232 | } | |
57ea1920 PG |
233 | } |
234 | result = apply_raw_config(tgen, raw_config) | |
235 | assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result) | |
236 | ||
1430ea83 DS |
237 | logger.info("Ensure BGP has processed the cli") |
238 | r2 = tgen.gears["r2"] | |
239 | output = r2.vtysh_cmd("show run") | |
d63c7094 KK |
240 | verify = re.search(r"fast-convergence", output) |
241 | assert verify is not None, "r2 does not have the fast convergence command yet" | |
1430ea83 | 242 | |
57ea1920 PG |
243 | logger.info("Shutdown one link b/w r2 and r3") |
244 | shutdown_bringup_interface(tgen, "r2", intf1, False) | |
245 | ||
246 | logger.info("Verify bgp neighbors goes down immediately") | |
247 | result = verify_bgp_convergence(tgen, topo, dut="r2", expected=False) | |
d63c7094 KK |
248 | assert result is not True, ( |
249 | "Testcase {} : Failed \n " | |
250 | "Expected: BGP should not be converged for {} \n " | |
251 | "Found: {}".format(tc_name, "r2", result) | |
57ea1920 PG |
252 | ) |
253 | ||
254 | logger.info("Shutdown second link b/w r2 and r3") | |
255 | shutdown_bringup_interface(tgen, "r2", intf2, False) | |
256 | ||
257 | logger.info("Verify bgp neighbors goes down immediately") | |
258 | result = verify_bgp_convergence(tgen, topo, dut="r2", expected=False) | |
d63c7094 KK |
259 | assert result is not True, ( |
260 | "Testcase {} : Failed \n " | |
261 | "Expected: BGP should not be converged for {} \n " | |
262 | "Found: {}".format(tc_name, "r2", result) | |
57ea1920 PG |
263 | ) |
264 | ||
265 | write_test_footer(tc_name) | |
266 | ||
267 | ||
268 | if __name__ == "__main__": | |
269 | args = ["-s"] + sys.argv[1:] | |
270 | sys.exit(pytest.main(args)) |