]>
git.proxmox.com Git - mirror_frr.git/blob - tests/topotests/isis_advertise_high_metrics/test_isis_advertise_high_metrics.py
4 # test_isis_advertise_high_metrics.py
5 # Part of NetDEF Topology Tests
7 # Copyright (c) 2020 by Volta Networks
9 # Permission to use, copy, modify, and/or distribute this software
10 # for any purpose with or without fee is hereby granted, provided
11 # that the above copyright notice and this permission notice appear
14 # THE SOFTWARE IS PROVIDED "AS IS" AND NETDEF DISCLAIMS ALL WARRANTIES
15 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
16 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF BE LIABLE FOR
17 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
18 # DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
19 # WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
20 # ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
25 test_isis_advertise_high_metrics.py: Advertise High Metrics FRR ISIS Test
33 from time
import sleep
34 from functools
import partial
36 # Save the Current Working Directory to find configuration files.
37 CWD
= os
.path
.dirname(os
.path
.realpath(__file__
))
38 sys
.path
.append(os
.path
.join(CWD
, "../"))
40 # pylint: disable=C0413
41 # Import topogen and topotest helpers
42 from lib
import topotest
43 from lib
.common_config
import (
48 from lib
.topogen
import Topogen
, TopoRouter
, get_topogen
49 from lib
.topolog
import logger
51 # Required to instantiate the topology builder class.
53 pytestmark
= [pytest
.mark
.isisd
]
69 for router
in ["r1", "r2", "r3", "r4"]:
70 tgen
.add_router(router
)
74 switch
= tgen
.add_switch("s0")
75 switch
.add_link(tgen
.gears
["r1"], nodeif
="eth-r2")
76 switch
.add_link(tgen
.gears
["r2"], nodeif
="eth-r1")
78 switch
= tgen
.add_switch("s1")
79 switch
.add_link(tgen
.gears
["r1"], nodeif
="eth-r3")
80 switch
.add_link(tgen
.gears
["r3"], nodeif
="eth-r1")
82 switch
= tgen
.add_switch("s2")
83 switch
.add_link(tgen
.gears
["r2"], nodeif
="eth-r4")
84 switch
.add_link(tgen
.gears
["r4"], nodeif
="eth-r2")
86 switch
= tgen
.add_switch("s3")
87 switch
.add_link(tgen
.gears
["r3"], nodeif
="eth-r4")
88 switch
.add_link(tgen
.gears
["r4"], nodeif
="eth-r3")
91 def setup_module(mod
):
92 "Sets up the pytest environment"
93 tgen
= Topogen(build_topo
, mod
.__name
__)
96 # For all registered routers, load the zebra configuration file
97 for rname
, router
in tgen
.routers().items():
99 TopoRouter
.RD_ZEBRA
, os
.path
.join(CWD
, "{}/zebra.conf".format(rname
))
102 TopoRouter
.RD_ISIS
, os
.path
.join(CWD
, "{}/isisd.conf".format(rname
))
105 # After loading the configurations, this function loads configured daemons.
109 def teardown_module(mod
):
110 "Teardown the pytest environment"
113 # This function tears down the whole topology.
117 @retry(retry_timeout
=60)
118 def _check_interface_metrics(router
, expected_metrics
):
119 "Verfiy metrics on router's isis interfaces"
122 router
= tgen
.gears
[router
]
123 logger
.info(f
"check_interface_metrics {router}")
124 isis_interface_output
= router
.vtysh_cmd(
125 "show isis interface detail json"
128 intf_json
= json
.loads(isis_interface_output
)
129 for i
in range(len(expected_metrics
)):
130 metric
= intf_json
["areas"][0]["circuits"][i
]["interface"]["levels"][0]["metric"]
131 if (metric
!= expected_metrics
[i
]):
132 intf_name
= intf_json
["areas"][0]["circuits"][i
]["interface"]["name"]
133 return "{} with expected metric {} on {} got {}".format(
134 router
.name
, expected_metrics
[i
], intf_name
, metric
139 def check_interface_metrics(router
, expected_metrics
):
140 "Verfiy metrics on router's isis interfaces"
142 assertmsg
= _check_interface_metrics(
143 router
, expected_metrics
145 assert assertmsg
is True, assertmsg
148 @retry(retry_timeout
=60)
149 def _check_lsp_metrics(router
, lsp
, expected_metrics
):
150 "Verfiy metrics on router's lsp"
152 router
= tgen
.gears
[router
]
153 logger
.info(f
"check_lsp_metrics {router}")
154 isis_lsp_output
= router
.vtysh_cmd(
155 "show isis database detail {}".format(lsp
)
158 metrics_list
= [int(i
) for i
in re
.findall(r
"Metric: (\d+)", isis_lsp_output
)]
159 if len(metrics_list
) == 0:
161 for metric
in metrics_list
:
162 if metric
not in expected_metrics
:
163 return "{} with expected metrics {} got {}".format(
164 router
.name
, expected_metrics
, metrics_list
170 def check_lsp_metrics(router
, lsp
, expected_metrics
):
171 "Verfiy metrics on router's lsp"
173 assertmsg
= _check_lsp_metrics(
174 router
, lsp
, expected_metrics
176 assert assertmsg
is True, assertmsg
179 @retry(retry_timeout
=60)
180 def _check_ip_route(router
, destination
, expected_interface
):
184 router
= tgen
.gears
[router
]
185 logger
.info(f
"check_ip_route {router}")
186 route_output
= router
.vtysh_cmd(
187 "show ip route {} json".format(destination
)
189 route_json
= json
.loads(route_output
)
191 interface
= route_json
[destination
][0]["nexthops"][0]["interfaceName"]
193 if (interface
!= expected_interface
):
194 return "{} with expected route to {} got {} expected {}".format(
195 router
.name
, destination
, interface
, expected_interface
201 def check_ip_route(router
, destination
, expected_interface
):
204 assertmsg
= _check_ip_route(
205 router
, destination
, expected_interface
207 assert assertmsg
is True, assertmsg
210 def test_isis_daemon_up():
211 "Check isis daemon up before starting test"
213 # Don't run this test if we have any failure.
214 if tgen
.routers_have_failure():
215 pytest
.skip(tgen
.errors
)
217 for router
in ["r1", "r2", "r3", "r4"]:
218 r
= tgen
.gears
[router
]
219 daemons
= r
.vtysh_cmd(
222 assert "isisd" in daemons
224 # Verify initial metric values.
225 check_lsp_metrics("r1", "r1.00-00", [10, 20])
226 check_lsp_metrics("r2", "r2.00-00", [10, 10])
227 check_lsp_metrics("r3", "r3.00-00", [20, 20])
228 check_lsp_metrics("r4", "r4.00-00", [10, 20])
231 def test_isis_advertise_high_metrics():
232 "Check that advertise high metrics behaves as expected"
235 net
= get_topogen().net
237 # Don't run this test if we have any failure.
238 if tgen
.routers_have_failure():
239 pytest
.skip(tgen
.errors
)
241 logger
.info("Testing advertise high metrics basic behavior")
243 # Confirm low metrics values on each isis interface on r1
244 r1
= tgen
.gears
["r1"]
245 check_interface_metrics("r1", [10, 20])
247 # Confirm low metrics values within isis database on r1
248 check_lsp_metrics("r1", "r1.00-00", [10, 20])
250 # Configure advertise high metrics
255 advertise-high-metrics
259 # Confirm high wide metrics values on each isis interface on r1
260 check_interface_metrics("r1", [16777215])
262 # Confirm high wide metrics values within isis database on r1
263 check_lsp_metrics("r1", "r1.00-00", [16777215])
265 # Remove advertise high metrics
270 no advertise-high-metrics
274 # Confirm low metrics values on each isis interface on r1
275 check_interface_metrics("r1", [10, 20])
277 # Confirm low metrics values within isis database on r1
278 check_lsp_metrics("r1", "r1.00-00", [10, 20])
281 def test_isis_advertise_high_metrics_narrow():
282 "Check that advertise high metrics behaves as expected with narrow metrics"
285 net
= get_topogen().net
287 # Don't run this test if we have any failure.
288 if tgen
.routers_have_failure():
289 pytest
.skip(tgen
.errors
)
291 logger
.info("Testing advertise high metrics with narrow metric style")
293 r1
= tgen
.gears
["r1"]
295 # Configure narrow metric-style
304 # Confirm low metrics values on each isis interface on r1
305 check_interface_metrics("r1", [10, 20])
307 # Confirm low metrics values within isis database on r1
308 check_lsp_metrics("r1", "r1.00-00", [10, 20])
310 # Configure advertise high metrics
315 advertise-high-metrics
319 # Confirm high narrow metrics values on each isis interface on r1
320 check_interface_metrics("r1", [63])
322 # Confirm high narrow metrics values within isis database on r1
323 check_lsp_metrics("r1", "r1.00-00", [63])
325 # Remove advertise high metrics
330 no advertise-high-metrics
334 # Confirm low metrics values on each isis interface on r1
335 check_interface_metrics("r1", [10, 20])
337 # Confirm low metrics values within isis database on r1
338 check_lsp_metrics("r1", "r1.00-00", [10, 20])
340 # Remove narrow metric-style
345 no metric-style narrow
350 def test_isis_advertise_high_metrics_transition():
351 "Check that advertise high metrics behaves as expected with transition metrics"
353 net
= get_topogen().net
355 # Don't run this test if we have any failure.
356 if tgen
.routers_have_failure():
357 pytest
.skip(tgen
.errors
)
359 logger
.info("Testing advertise high metrics with transition metric style")
361 r1
= tgen
.gears
["r1"]
363 # Configure transition metric-style
368 metric-style transition
372 # Confirm low metrics values on each isis interface on r1
373 check_interface_metrics("r1", [10, 20])
375 # Confirm low metrics values within isis database on r1
376 check_lsp_metrics("r1", "r1.00-00", [10, 20])
378 # Configure advertise high metrics
383 advertise-high-metrics
387 # Confirm high transition metrics values on each isis interface on r1
388 check_interface_metrics("r1", [62])
390 # Confirm high transition metrics values within isis database on r1
391 check_lsp_metrics("r1", "r1.00-00", [62])
393 # Remove advertise high metrics
398 no advertise-high-metrics
402 # Confirm low metrics values on each isis interface on r1
403 check_interface_metrics("r1", [10, 20])
405 # Confirm low metrics values within isis database on r1
406 check_lsp_metrics("r1", "r1.00-00", [10, 20])
408 # Remove narrow metric-style
413 no metric-style transition
418 def test_isis_advertise_high_metrics_route():
428 Devices are configured with preferred route between r1 and r4:
430 Configure "advertise-high-metrics" on r2 and check that preferred route is:
432 Shut r3 and check that preferred route is:
436 net
= get_topogen().net
438 # Don't run this test if we have any failure.
439 if tgen
.routers_have_failure():
440 pytest
.skip(tgen
.errors
)
442 logger
.info("Testing advertise high metrics route behavior")
444 r1
= tgen
.gears
["r1"]
445 r2
= tgen
.gears
["r2"]
447 # Verify the preferred path from r1 to r4 (192.168.1.6) is currently via 192.168.1.1, eth-r2
448 check_ip_route("r1", "192.168.1.6/31", "eth-r2")
450 # Configure advertise high metrics on r2
455 advertise-high-metrics
459 # Verify the preferred path from r1 to r4 (192.168.1.6) is now via 192.168.1.3, eth-r3
460 check_ip_route("r1", "192.168.1.6/31", "eth-r3")
463 logger
.info("Stop router r3")
464 stop_router(tgen
, "r3")
466 # Verify the preferred path from r1 to r4 (192.168.1.6) is now via 192.168.1.1, eth-r2
467 check_ip_route("r1", "192.168.1.6/31", "eth-r2")
470 logger
.info("Start router r3")
471 start_router(tgen
, "r3")
474 def test_memory_leak():
475 "Run the memory leak test and report results."
477 if not tgen
.is_memleak_enabled():
478 pytest
.skip("Memory leak test/report is disabled")
480 tgen
.report_memory_leaks()
483 if __name__
== "__main__":
484 args
= ["-s"] + sys
.argv
[1:]
485 sys
.exit(pytest
.main(args
))