]> git.proxmox.com Git - mirror_frr.git/blame - tests/topotests/ospf_basic_functionality/test_ospf_ecmp_lan.py
tests: [topojson] Update assert/error messages
[mirror_frr.git] / tests / topotests / ospf_basic_functionality / test_ospf_ecmp_lan.py
CommitLineData
4256a209 1#!/usr/bin/python
2
3#
4# Copyright (c) 2020 by VMware, Inc. ("VMware")
5# Used Copyright (c) 2018 by Network Device Education Foundation, Inc.
6# ("NetDEF") in this file.
7#
8# Permission to use, copy, modify, and/or distribute this software
9# for any purpose with or without fee is hereby granted, provided
10# that the above copyright notice and this permission notice appear
11# in all copies.
12#
13# THE SOFTWARE IS PROVIDED "AS IS" AND VMWARE DISCLAIMS ALL WARRANTIES
14# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL VMWARE BE LIABLE FOR
16# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
17# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
18# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
19# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
20# OF THIS SOFTWARE.
21#
22
23
24"""OSPF Basic Functionality Automation."""
25import os
26import sys
27import time
28import pytest
4256a209 29
30# Save the Current Working Directory to find configuration files.
31CWD = os.path.dirname(os.path.realpath(__file__))
32sys.path.append(os.path.join(CWD, "../"))
33sys.path.append(os.path.join(CWD, "../lib/"))
34
35# pylint: disable=C0413
36# Import topogen and topotest helpers
4256a209 37from lib.topogen import Topogen, get_topogen
38
39# Import topoJson from lib, to create topology and initial configuration
40from lib.common_config import (
41 start_topology,
42 write_test_header,
4256a209 43 write_test_footer,
44 reset_config_on_routers,
45 verify_rib,
46 create_static_routes,
4256a209 47 step,
4256a209 48)
4256a209 49from lib.topolog import logger
4953ca97 50from lib.topojson import build_config_from_json
4256a209 51
52from lib.ospf import (
53 verify_ospf_neighbor,
4256a209 54 clear_ospf,
55 verify_ospf_rib,
88b7d3e7 56 redistribute_ospf,
4256a209 57)
4256a209 58
6ff492b1
DS
59pytestmark = [pytest.mark.ospfd, pytest.mark.staticd]
60
61
4256a209 62# Global variables
63topo = None
64# Reading the data from JSON File for topology creation
4256a209 65NETWORK = {
66 "ipv4": [
67 "11.0.20.1/32",
68 "11.0.20.2/32",
69 "11.0.20.3/32",
70 "11.0.20.4/32",
71 "11.0.20.5/32",
72 ],
73 "ipv6": ["1::1/128", "1::2/128", "1::3/128", "1::4/128", "1::5/128"],
74}
75MASK = {"ipv4": "32", "ipv6": "128"}
76NEXT_HOP = {
77 "ipv4": ["10.0.0.1", "10.0.1.1", "10.0.2.1", "10.0.3.1", "10.0.4.1"],
78 "ipv6": ["Null0", "Null0", "Null0", "Null0", "Null0"],
79}
80"""
81TOPOOLOGY =
82 Please view in a fixed-width font such as Courier.
83 Topo : Broadcast Networks
84 +---+ +---+ +---+ +---+
85 |R0 + +R1 + +R2 + +R3 |
86 +-+-+ +-+-+ +-+-+ +-+-+
87 | | | |
88 | | | |
89 --+-----------+--------------+---------------+-----
90 Ethernet Segment
91
92TESTCASES =
931. Verify OSPF ECMP with max path configured as 8
94 (Edge having 1 uplink port as broadcast network,
95 connect to 8 TORs - LAN case)
96
97 """
98
99
4256a209 100def setup_module(mod):
101 """
102 Sets up the pytest environment
103
104 * `mod`: module name
105 """
4256a209 106 testsuite_run_time = time.asctime(time.localtime(time.time()))
107 logger.info("Testsuite start time: {}".format(testsuite_run_time))
108 logger.info("=" * 40)
109
110 logger.info("Running setup_module to create topology")
111
112 # This function initiates the topology build with Topogen...
e82b531d
CH
113 json_file = "{}/ospf_ecmp_lan.json".format(CWD)
114 tgen = Topogen(json_file, mod.__name__)
115 global topo
116 topo = tgen.json_topo
4256a209 117 # ... and here it calls Mininet initialization functions.
118
119 # Starting topology, create tmp files which are loaded to routers
d60a3f0e 120 # to start daemons and then start routers
991a971f 121 start_topology(tgen)
035267a3 122
4256a209 123 # Creating configuration from JSON
124 build_config_from_json(tgen, topo)
125
126 # Don't run this test if we have any failure.
127 if tgen.routers_have_failure():
128 pytest.skip(tgen.errors)
129 # Api call verify whether OSPF is converged
130 ospf_covergence = verify_ospf_neighbor(tgen, topo, lan=True)
74dd0c84 131 assert ospf_covergence is True, "setup_module :Failed \n Error {}".format(
4256a209 132 ospf_covergence
133 )
134
135 logger.info("Running setup_module() done")
136
137
138def teardown_module():
139 """Teardown the pytest environment"""
140
141 logger.info("Running teardown_module to delete topology")
142
143 tgen = get_topogen()
144
145 try:
146 # Stop toplogy and Remove tmp files
147 tgen.stop_topology()
148
149 except OSError:
150 # OSError exception is raised when mininet tries to stop switch
151 # though switch is stopped once but mininet tries to stop same
152 # switch again, where it ended up with exception
153 pass
154
155
4256a209 156# ##################################
157# Test cases start here.
158# ##################################
159
160
161def test_ospf_lan_ecmp_tc18_p0(request):
162 """
163 OSPF ECMP.
164
165 Verify OSPF ECMP with max path configured as 8
166 (Edge having 1 uplink port as broadcast network,
167 connect to 8 TORs - LAN case)
168
169 """
170 tc_name = request.node.name
171 write_test_header(tc_name)
172 tgen = get_topogen()
173
174 # Don't run this test if we have any failure.
175 if tgen.routers_have_failure():
176 pytest.skip(tgen.errors)
177
178 global topo
179 step("Bring up the base config as per the topology")
180 step(". Configure ospf in all the routers on LAN interface.")
181 reset_config_on_routers(tgen)
182 step("Verify that OSPF is up with 8 neighborship sessions.")
183
184 ospf_covergence = verify_ospf_neighbor(tgen, topo, lan=True)
74dd0c84 185 assert ospf_covergence is True, "Testcase Failed \n Error {}".format(
4256a209 186 ospf_covergence
187 )
188
189 step(
190 "Configure a static route in all the routes and "
191 "redistribute static/connected in OSPF."
192 )
193
194 for rtr in topo["routers"]:
195 input_dict = {
196 rtr: {
197 "static_routes": [
198 {"network": NETWORK["ipv4"][0], "no_of_ip": 5, "next_hop": "Null0"}
199 ]
200 }
201 }
202 result = create_static_routes(tgen, input_dict)
203 assert result is True, "Testcase {} : Failed \n Error: {}".format(
204 tc_name, result
205 )
206
207 dut = rtr
88b7d3e7 208 redistribute_ospf(tgen, topo, dut, "static")
4256a209 209
210 step(
211 "Verify that route in R0 in stalled with 8 hops. "
212 "Verify ospf route table and ip route table."
213 )
214
215 nh = []
216 for rtr in topo["routers"]:
217 nh.append(topo["routers"][rtr]["links"]["s1"]["ipv4"].split("/")[0])
218 nh.remove(topo["routers"]["r1"]["links"]["s1"]["ipv4"].split("/")[0])
219 dut = "r1"
220 result = verify_ospf_rib(tgen, dut, input_dict, next_hop=nh)
221 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
222
223 protocol = "ospf"
224 result = verify_rib(tgen, "ipv4", dut, input_dict, protocol=protocol, next_hop=nh)
225 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
226
227 step(" clear ip ospf interface on DUT(r0)")
228 clear_ospf(tgen, "r0")
229
230 step(
231 "Verify that after clearing the ospf interface all the "
232 "neighbours are up and routes are installed with 8 next hop "
233 "in ospf and ip route tables on R0"
234 )
235
236 dut = "r0"
237 ospf_covergence = verify_ospf_neighbor(tgen, topo, dut=dut, lan=True)
74dd0c84 238 assert ospf_covergence is True, "Testcase Failed \n Error {}".format(
4256a209 239 ospf_covergence
240 )
241
242 step(" clear ip ospf interface on R2")
243 clear_ospf(tgen, "r2")
244
245 dut = "r2"
246 ospf_covergence = verify_ospf_neighbor(tgen, topo, dut=dut, lan=True)
74dd0c84 247 assert ospf_covergence is True, "Testcase Failed \n Error {}".format(
4256a209 248 ospf_covergence
249 )
250
251 step("Delete static/connected cmd in ospf in all the routes one by one.")
252 for rtr in topo["routers"]:
253 input_dict = {
254 rtr: {
255 "static_routes": [
256 {
257 "network": NETWORK["ipv4"][0],
258 "no_of_ip": 5,
259 "next_hop": "Null0",
260 "delete": True,
261 }
262 ]
263 }
264 }
265 result = create_static_routes(tgen, input_dict)
266 assert result is True, "Testcase {} : Failed \n Error: {}".format(
267 tc_name, result
268 )
269
270 step("Verify that all the routes are withdrawn from R0")
271 dut = "r1"
a81774ec 272 result = verify_ospf_rib(
ed776e38 273 tgen, dut, input_dict, next_hop=nh, retry_timeout=10, expected=False
a81774ec 274 )
0b25370e
DS
275 assert (
276 result is not True
74dd0c84 277 ), "Testcase {} : Failed \n r1: OSPF routes are present \n Error: {}".format(
4256a209 278 tc_name, result
0b25370e 279 )
4256a209 280
281 protocol = "ospf"
a81774ec 282 result = verify_rib(
283 tgen,
284 "ipv4",
285 dut,
286 input_dict,
287 protocol=protocol,
288 next_hop=nh,
ed776e38 289 retry_timeout=10,
a81774ec 290 expected=False,
291 )
0b25370e
DS
292 assert (
293 result is not True
74dd0c84 294 ), "Testcase {} : Failed \n r1: routes are still present \n Error: {}".format(
4256a209 295 tc_name, result
0b25370e 296 )
4256a209 297
298 write_test_footer(tc_name)
299
300
301if __name__ == "__main__":
302 args = ["-s"] + sys.argv[1:]
303 sys.exit(pytest.main(args))