]>
git.proxmox.com Git - mirror_frr.git/blob - tests/topotests/isis_snmp/test_isis_snmp.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
27 +---------+ 45.0.0.0/24 +---------+
29 | RT4 +----------------+ RT5 |
31 +---------+ +---------+
34 14.0.0.0/24| |25.0.0.0/24
37 +---------+ +---------+
40 | 1.1.1.1 | | 2.2.2.2 |
42 +---------+ +---------+
46 13.0.0.0/24| +---------+ |23.0.0.0/24
49 +--------+ 3.3.3.3 +-------+
55 ce3-eth0 (172.16.1.3/24)|
67 from functools
import partial
69 # Save the Current Working Directory to find configuration files.
70 CWD
= os
.path
.dirname(os
.path
.realpath(__file__
))
71 sys
.path
.append(os
.path
.join(CWD
, "../"))
73 # pylint: disable=C0413
74 # Import topogen and topotest helpers
75 from lib
import topotest
76 from lib
.topogen
import Topogen
, TopoRouter
, get_topogen
77 from lib
.topolog
import logger
78 from lib
.snmptest
import SnmpTester
80 # Required to instantiate the topology builder class.
82 pytestmark
= [pytest
.mark
.isisd
, pytest
.mark
.ldpd
, pytest
.mark
.snmp
]
91 for router
in ["ce3", "r1", "r2", "r3", "r4", "r5"]:
92 tgen
.add_router(router
)
97 switch
= tgen
.add_switch("s1")
98 switch
.add_link(tgen
.gears
["r1"])
99 switch
.add_link(tgen
.gears
["r4"])
101 switch
= tgen
.add_switch("s2")
102 switch
.add_link(tgen
.gears
["r5"])
103 switch
.add_link(tgen
.gears
["r2"])
105 switch
= tgen
.add_switch("s3")
106 switch
.add_link(tgen
.gears
["ce3"])
107 switch
.add_link(tgen
.gears
["r3"])
109 switch
= tgen
.add_switch("s4")
110 switch
.add_link(tgen
.gears
["r4"])
111 switch
.add_link(tgen
.gears
["r5"])
113 switch
= tgen
.add_switch("s5")
114 switch
.add_link(tgen
.gears
["r1"])
115 switch
.add_link(tgen
.gears
["r3"])
117 switch
= tgen
.add_switch("s6")
118 switch
.add_link(tgen
.gears
["r2"])
119 switch
.add_link(tgen
.gears
["r3"])
122 def setup_module(mod
):
123 "Sets up the pytest environment"
125 # skip tests is SNMP not installed
126 if not os
.path
.isfile("/usr/sbin/snmpd"):
127 error_msg
= "SNMP not installed - skipping"
128 pytest
.skip(error_msg
)
130 # This function initiates the topology build with Topogen...
131 tgen
= Topogen(build_topo
, mod
.__name
__)
132 # ... and here it calls Mininet initialization functions.
133 tgen
.start_topology()
135 router_list
= tgen
.routers()
137 # For all registered routers, load the zebra configuration file
138 for rname
, router
in router_list
.items():
140 TopoRouter
.RD_ZEBRA
, os
.path
.join(CWD
, "{}/zebra.conf".format(rname
))
142 # Don't start the following in the CE nodes
143 if router
.name
[0] == "r":
146 os
.path
.join(CWD
, "{}/isisd.conf".format(rname
)),
151 os
.path
.join(CWD
, "{}/ldpd.conf".format(rname
)),
155 os
.path
.join(CWD
, "{}/snmpd.conf".format(rname
)),
156 "-Le -Ivacm_conf,usmConf,iquery -V -DAgentX,trap",
159 # After loading the configurations, this function loads configured daemons.
163 def teardown_module(mod
):
164 "Teardown the pytest environment"
167 # This function tears down the whole topology.
171 def router_compare_json_output(rname
, command
, reference
):
172 "Compare router JSON output"
174 logger
.info('Comparing router "%s" "%s" output', rname
, command
)
177 filename
= "{}/{}/{}".format(CWD
, rname
, reference
)
178 expected
= json
.loads(open(filename
).read())
180 # Run test function until we get an result. Wait at most 80 seconds.
181 test_func
= partial(topotest
.router_json_cmp
, tgen
.gears
[rname
], command
, expected
)
182 _
, diff
= topotest
.run_and_expect(test_func
, None, count
=160, wait
=0.5)
183 assertmsg
= '"{}" JSON output mismatches the expected result'.format(rname
)
184 assert diff
is None, assertmsg
187 def generate_oid(numoids
, index1
, index2
):
189 oid
= "{}".format(index1
)
191 oid
= "{}.{}".format(index1
, index2
)
195 def test_isis_convergence():
196 logger
.info("Test: check ISIS adjacencies")
199 for rname
in ["r1", "r2", "r3", "r4", "r5"]:
200 router_compare_json_output(
202 "show yang operational-data /frr-interface:lib isisd",
203 "show_yang_interface_isis_adjacencies.ref",
207 def test_r1_scalar_snmp():
208 "Wait for protocol convergence"
211 # Skip if previous fatal error condition is raised
212 if tgen
.routers_have_failure():
213 pytest
.skip(tgen
.errors
)
215 r1
= tgen
.gears
["r1"]
216 r1_snmp
= SnmpTester(r1
, "1.1.1.1", "public", "2c")
218 assert r1_snmp
.test_oid("isisSysVersion", "one(1)")
219 assert r1_snmp
.test_oid("isisSysLevelType", "level1and2(3)")
220 assert r1_snmp
.test_oid("isisSysID", "00 00 00 00 00 01")
221 assert r1_snmp
.test_oid("isisSysMaxPathSplits", "32")
222 assert r1_snmp
.test_oid("isisSysMaxLSPGenInt", "900 seconds")
223 assert r1_snmp
.test_oid("isisSysAdminState", "on(1)")
224 assert r1_snmp
.test_oid("isisSysMaxAge", "1200 seconds")
225 assert r1_snmp
.test_oid("isisSysProtSupported", "07 5 6 7")
227 r2
= tgen
.gears
["r2"]
228 r2_snmp
= SnmpTester(r2
, "2.2.2.2", "public", "2c")
230 assert r2_snmp
.test_oid("isisSysVersion", "one(1)")
231 assert r2_snmp
.test_oid("isisSysLevelType", "level1and2(3)")
232 assert r2_snmp
.test_oid("isisSysID", "00 00 00 00 00 02")
233 assert r2_snmp
.test_oid("isisSysMaxPathSplits", "32")
234 assert r2_snmp
.test_oid("isisSysMaxLSPGenInt", "900 seconds")
235 assert r2_snmp
.test_oid("isisSysAdminState", "on(1)")
236 assert r2_snmp
.test_oid("isisSysMaxAge", "1200 seconds")
237 assert r2_snmp
.test_oid("isisSysProtSupported", "07 5 6 7")
241 "isisCircAdminState": ["on(1)", "on(1)"],
242 "isisCircExistState": ["active(1)", "active(1)"],
243 "isisCircType": ["broadcast(1)", "ptToPt(2)"],
244 "isisCircExtDomain": ["false(2)", "false(2)"],
245 "isisCircLevelType": ["level1(1)", "level1(1)"],
246 "isisCircPassiveCircuit": ["false(2)", "false(2)"],
247 "isisCircMeshGroupEnabled": ["inactive(1)", "inactive(1)"],
248 "isisCircSmallHellos": ["false(2)", "false(2)"],
249 "isisCirc3WayEnabled": ["false(2)", "false(2)"],
253 def test_r1_isisCircTable():
256 r1
= tgen
.gears
["r1"]
257 r1_snmp
= SnmpTester(r1
, "1.1.1.1", "public", "2c")
260 oids
.append(generate_oid(1, 1, 0))
261 oids
.append(generate_oid(1, 2, 0))
264 for item
in circtable_test
.keys():
265 assertmsg
= "{} should be {} oids {} full dict {}:".format(
266 item
, circtable_test
[item
], oids
, r1_snmp
.walk(item
)
268 assert r1_snmp
.test_oid_walk(item
, circtable_test
[item
], oids
), assertmsg
271 circleveltable_test
= {
272 "isisCircLevelMetric": ["10", "10"],
273 "isisCircLevelWideMetric": ["10", "10"],
274 "isisCircLevelISPriority": ["64", "64"],
275 "isisCircLevelHelloMultiplier": ["10", "10"],
276 "isisCircLevelHelloTimer": [
280 "isisCircLevelMinLSPRetransInt": [
287 def test_r1_isislevelCircTable():
290 r1
= tgen
.gears
["r1"]
291 r1_snmp
= SnmpTester(r1
, "1.1.1.1", "public", "2c")
294 oids
.append(generate_oid(2, 1, "area"))
295 oids
.append(generate_oid(2, 2, "area"))
298 for item
in circleveltable_test
.keys():
299 assertmsg
= "{} should be {} oids {} full dict {}:".format(
300 item
, circleveltable_test
[item
], oids
, r1_snmp
.walk(item
)
302 assert r1_snmp
.test_oid_walk(item
, circleveltable_test
[item
], oids
), assertmsg
306 "isisISAdjState": ["up(3)", "up(3)"],
307 "isisISAdj3WayState": ["down(2)", "up(0)"],
308 "isisISAdjNeighSysType": ["l1IntermediateSystem(1)", "l1IntermediateSystem(1)"],
309 "isisISAdjNeighSysID": ["00 00 00 00 00 04", "00 00 00 00 00 03"],
310 "isisISAdjUsage": ["0", "level1(1)"],
311 "isisISAdjNeighPriority": ["64", "0"],
314 adjtable_down_test
= {
315 "isisISAdjState": ["up(3)"],
316 "isisISAdj3WayState": ["down(2)"],
317 "isisISAdjNeighSysType": ["l1IntermediateSystem(1)"],
318 "isisISAdjNeighSysID": ["00 00 00 00 00 04"],
319 "isisISAdjUsage": ["0"],
320 "isisISAdjNeighPriority": ["64"],
324 def test_r1_isisAdjTable():
325 "check ISIS Adjacency Table"
327 r1
= tgen
.gears
["r1"]
328 r1_snmp
= SnmpTester(r1
, "1.1.1.1", "public", "2c")
331 oids
.append(generate_oid(2, 1, 1))
332 oids
.append(generate_oid(2, 2, 1))
335 oids_down
.append(generate_oid(2, 1, 1))
338 for item
in adjtable_test
.keys():
339 assertmsg
= "{} should be {} oids {} full dict {}:".format(
340 item
, adjtable_test
[item
], oids
, r1_snmp
.walk(item
)
342 assert r1_snmp
.test_oid_walk(item
, adjtable_test
[item
], oids
), assertmsg
344 # shutdown interface and one adjacency should be removed
345 "check ISIS adjacency is removed when interface is shutdown"
346 r1
.vtysh_cmd("conf t\ninterface r1-eth1\nshutdown")
347 r1_snmp
= SnmpTester(r1
, "1.1.1.1", "public", "2c")
349 for item
in adjtable_down_test
.keys():
350 assertmsg
= "{} should be {} oids {} full dict {}:".format(
351 item
, adjtable_down_test
[item
], oids_down
, r1_snmp
.walk(item
)
353 assert r1_snmp
.test_oid_walk(
354 item
, adjtable_down_test
[item
], oids_down
357 # no shutdown interface and adjacency should be restored
358 r1
.vtysh_cmd("conf t\ninterface r1-eth1\nno shutdown")
361 # Memory leak test template
362 # disabling memory leak
363 def test_memory_leak():
364 "Run the memory leak test and report results."
366 if not tgen
.is_memleak_enabled():
367 pytest
.skip("Memory leak test/report is disabled")
369 tgen
.report_memory_leaks()
372 if __name__
== "__main__":
373 args
= ["-s"] + sys
.argv
[1:]
374 sys
.exit(pytest
.main(args
))