]> git.proxmox.com Git - mirror_frr.git/blame - tests/topotests/cspf_topo1/test_cspf_topo1.py
*: auto-convert to SPDX License IDs
[mirror_frr.git] / tests / topotests / cspf_topo1 / test_cspf_topo1.py
CommitLineData
62f79ac1 1#!/usr/bin/env python
acddc0ed 2# SPDX-License-Identifier: ISC
62f79ac1
OD
3
4#
5# test_cspf_topo1.py
6# Part of NetDEF Topology Tests
7#
8# Copyright (c) 2022 by Orange
9# Author: Olivier Dugeon <olivier.dugeon@orange.com>
10#
62f79ac1
OD
11
12"""
13test_cspf_topo1.py: Test the FRR Constraint Shortest Path First algorithm.
14
15 +------------+
16 | |
17 | R1 |
18 | 10.0.225.1 |
19 | |
20 +------------+
21 r1-eth0| |r1-eth1
22 | |
23 10.0.0.0/24| |10.0.1.0/24
24 | |2001:db8:1:/64
25 | |
26 r2-eth0| |r2-eth1
27 +------------+ +------------+
28 | | | |
29 | R2 |r2-eth2 r3-eth0| R3 |
30 | 10.0.255.2 +------------------+ 10.0.255.3 |
31 | | 10.0.3.0/24 | |
32 +------------+ 2001:db8:3:/64 +------+-----+
33 r2-eth3| r3-eth1|
34 | |
35 10.0.4.0/24| |
36 | |
37 | |
38 r4-eth0| 2001:db8:5:/64|
39 +------------+ |
40 | | |
41 | R4 |r4-eth1 |
42 | 10.0.255.4 +-------------------------+
43 | |
44 +------------+
45
46"""
47
48import os
49import sys
50import json
51from functools import partial
52
53# Save the Current Working Directory to find configuration files.
54CWD = os.path.dirname(os.path.realpath(__file__))
55sys.path.append(os.path.join(CWD, "../"))
56
57# pylint: disable=C0413
58
59# Import topogen and topotest helpers
60from lib import topotest
61from lib.topogen import Topogen, TopoRouter, get_topogen
62from lib.topolog import logger
63
64# and Finally pytest
65import pytest
66
67pytestmark = [pytest.mark.isisd]
68
69
70def build_topo(tgen):
71 "Build function"
72
73 # Create 4 routers
74 for routern in range(1, 5):
75 tgen.add_router("r{}".format(routern))
76
77 # Interconect router 1 and 2 with 2 links
78 switch = tgen.add_switch("s1")
79 switch.add_link(tgen.gears["r1"])
80 switch.add_link(tgen.gears["r2"])
81 switch = tgen.add_switch("s2")
82 switch.add_link(tgen.gears["r1"])
83 switch.add_link(tgen.gears["r2"])
84
85 # Interconect router 3 and 2
86 switch = tgen.add_switch("s3")
87 switch.add_link(tgen.gears["r3"])
88 switch.add_link(tgen.gears["r2"])
89
90 # Interconect router 4 and 2
91 switch = tgen.add_switch("s4")
92 switch.add_link(tgen.gears["r4"])
93 switch.add_link(tgen.gears["r2"])
94
95 # Interconnect router 3 and 4
96 switch = tgen.add_switch("s5")
97 switch.add_link(tgen.gears["r3"])
98 switch.add_link(tgen.gears["r4"])
99
100
101def setup_module(mod):
102 "Sets up the pytest environment"
103
104 logger.info("\n\n---- Starting CSPF tests ----\n")
105
106 tgen = Topogen(build_topo, mod.__name__)
107 tgen.start_topology()
108
109 router_list = tgen.routers()
110
111 for rname, router in router_list.items():
112 router.load_config(
113 TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname))
114 )
115 router.load_config(
116 TopoRouter.RD_ISIS, os.path.join(CWD, "{}/isisd.conf".format(rname))
117 )
118 if rname == "r1":
119 router.load_config(
120 TopoRouter.RD_SHARP, os.path.join(CWD, "{}/sharpd.conf".format("r1"))
121 )
122
123 # Initialize all routers.
124 tgen.start_router()
125
126
127def teardown_module():
128 "Teardown the pytest environment"
129
130 tgen = get_topogen()
131 tgen.stop_topology()
132
133 logger.info("\n\n---- CSPF tests End ----\n")
134
135
136def compare_ted_json_output(tgen, rname, fileref):
137 "Compare TED JSON output"
138
139 logger.info('Comparing router "%s" TED output', rname)
140
141 filename = "{}/reference/{}".format(CWD, fileref)
142 expected = json.loads(open(filename).read())
143 command = "show sharp ted json"
144
145 # Run test function until we get an result. Wait at most 60 seconds.
146 test_func = partial(topotest.router_json_cmp, tgen.gears[rname], command, expected)
147 _, diff = topotest.run_and_expect(test_func, None, count=60, wait=2)
148 assertmsg = '"{}" TED JSON output mismatches the expected result'.format(rname)
149 assert diff is None, assertmsg
150
151
152def compare_cspf_output(tgen, rname, fileref, src, dst, cost, bw=""):
153 "Compare CSPF output"
154
155 logger.info('Comparing router "%s" CSPF output', rname)
156
157 filename = "{}/reference/{}".format(CWD, fileref)
158 expected = open(filename).read()
4b8daf6b
LS
159 command = "show sharp cspf source {} destination {} {} {}".format(
160 src, dst, cost, bw
161 )
62f79ac1
OD
162
163 # Run test function until we get an result. Wait at most 60 seconds.
4b8daf6b
LS
164 test_func = partial(
165 topotest.router_output_cmp, tgen.gears[rname], command, expected
166 )
c6653ab2 167 result, diff = topotest.run_and_expect(test_func, "", count=5, wait=2)
4b8daf6b
LS
168 assert result, "CSPF output mismatches the expected result on {}:\n{}".format(
169 rname, diff
170 )
171
62f79ac1
OD
172
173def setup_testcase(msg):
174 "Setup test case"
175
176 logger.info(msg)
177 tgen = get_topogen()
178
179 # Skip if previous fatal error condition is raised
180 if tgen.routers_have_failure():
181 pytest.skip(tgen.errors)
182
183 return tgen
184
185
186# Note that all routers must discover the same Network Topology, so the same TED.
187
188
189def test_step1():
190 "Step1: Check initial topology"
191
192 tgen = setup_testcase("Step1: test initial IS-IS TE Data Base import")
193 tgen.net["r1"].cmd('vtysh -c "sharp import-te"')
194
195 compare_ted_json_output(tgen, "r1", "sharp-ted.json")
196
197
198def test_step2():
199 "Step2: Test CSPF from r1 to r4 for IPv4 with various metric"
200
201 tgen = setup_testcase("Step2: CSPF(r1, r4, IPv4)")
202
4b8daf6b
LS
203 compare_cspf_output(
204 tgen, "r1", "cspf-ipv4-metric.txt", "10.0.0.1", "10.0.255.4", "metric 50"
205 )
206 compare_cspf_output(
207 tgen, "r1", "cspf-ipv4-te-metric.txt", "10.0.255.1", "10.0.4.4", "te-metric 50"
208 )
209 compare_cspf_output(
210 tgen, "r1", "cspf-ipv4-delay.txt", "10.0.255.1", "10.0.255.4", "delay 50000"
211 )
212 compare_cspf_output(
213 tgen,
214 "r1",
215 "cspf-ipv4-delay.txt",
216 "10.0.255.1",
217 "10.0.255.4",
218 "delay 50000",
219 "rsv 7 1000000",
220 )
62f79ac1
OD
221
222
223def test_step3():
224 "Step3: Test CSPF from r1 to r4 for IPv6 with various metric"
225
226 tgen = setup_testcase("Step2: CSPF(r1, r4, IPv6)")
227
4b8daf6b
LS
228 compare_cspf_output(
229 tgen,
230 "r1",
231 "cspf-ipv6-metric.txt",
232 "2001:db8:1::1:1",
233 "2001:db8::4",
234 "metric 50",
235 )
236 compare_cspf_output(
237 tgen,
238 "r1",
239 "cspf-ipv6-te-metric.txt",
240 "2001:db8::1",
241 "2001:db8:5::3:4",
242 "te-metric 80",
243 )
244 compare_cspf_output(
245 tgen, "r1", "cspf-ipv6-delay.txt", "2001:db8::1", "2001:db8::4", "delay 80000"
246 )
247 compare_cspf_output(
248 tgen,
249 "r1",
250 "cspf-ipv6-delay.txt",
251 "2001:db8::1",
252 "2001:db8::4",
253 "delay 80000",
254 "rsv 7 1000000",
255 )
62f79ac1
OD
256
257
258def test_step4():
259 "Step4: Test CSPF from r1 to r4 with no possible path"
260
261 tgen = setup_testcase("Step2: CSPF(r1, r4, failure)")
262
4b8daf6b
LS
263 compare_cspf_output(
264 tgen, "r1", "cspf-failed.txt", "10.0.255.1", "10.0.255.4", "metric 10"
265 )
266 compare_cspf_output(
267 tgen, "r1", "cspf-failed.txt", "2001:db8::1", "2001:db8::4", "te-metric 50"
268 )
269 compare_cspf_output(
270 tgen, "r1", "cspf-failed.txt", "10.0.255.1", "10.0.255.4", "delay 5000"
271 )
272 compare_cspf_output(
273 tgen,
274 "r1",
275 "cspf-failed.txt",
276 "2001:db8::1",
277 "2001:db8::4",
278 "delay 80000",
279 "rsv 7 10000000",
280 )
281 compare_cspf_output(
282 tgen, "r1", "cspf-failed-src.txt", "10.0.0.3", "10.0.255.4", "metric 10"
283 )
284 compare_cspf_output(
285 tgen, "r1", "cspf-failed-dst.txt", "10.0.0.1", "10.0.4.40", "metric 10"
286 )
287 compare_cspf_output(
288 tgen, "r1", "cspf-failed-same.txt", "10.0.0.1", "10.0.0.1", "metric 10"
289 )
62f79ac1
OD
290
291
292def test_memory_leak():
293 "Run the memory leak test and report results."
294
295 tgen = get_topogen()
296 if not tgen.is_memleak_enabled():
297 pytest.skip("Memory leak test/report is disabled")
298
299 tgen.report_memory_leaks()
300
301
302if __name__ == "__main__":
303 args = ["-s"] + sys.argv[1:]
304 sys.exit(pytest.main(args))