]>
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)|
68 from time
import sleep
69 from functools
import partial
71 # Save the Current Working Directory to find configuration files.
72 CWD
= os
.path
.dirname(os
.path
.realpath(__file__
))
73 sys
.path
.append(os
.path
.join(CWD
, "../"))
75 # pylint: disable=C0413
76 # Import topogen and topotest helpers
77 from lib
import topotest
78 from lib
.topogen
import Topogen
, TopoRouter
, get_topogen
79 from lib
.topolog
import logger
80 from lib
.snmptest
import SnmpTester
82 # Required to instantiate the topology builder class.
83 from mininet
.topo
import Topo
85 pytestmark
= [pytest
.mark
.isisd
, pytest
.mark
.ldpd
, pytest
.mark
.snmp
]
88 class TemplateTopo(Topo
):
89 "Test topology builder"
91 def build(self
, *_args
, **_opts
):
93 tgen
= get_topogen(self
)
98 for router
in ["ce3", "r1", "r2", "r3", "r4", "r5"]:
99 tgen
.add_router(router
)
104 switch
= tgen
.add_switch("s1")
105 switch
.add_link(tgen
.gears
["r1"])
106 switch
.add_link(tgen
.gears
["r4"])
108 switch
= tgen
.add_switch("s2")
109 switch
.add_link(tgen
.gears
["r5"])
110 switch
.add_link(tgen
.gears
["r2"])
112 switch
= tgen
.add_switch("s3")
113 switch
.add_link(tgen
.gears
["ce3"])
114 switch
.add_link(tgen
.gears
["r3"])
116 switch
= tgen
.add_switch("s4")
117 switch
.add_link(tgen
.gears
["r4"])
118 switch
.add_link(tgen
.gears
["r5"])
120 switch
= tgen
.add_switch("s5")
121 switch
.add_link(tgen
.gears
["r1"])
122 switch
.add_link(tgen
.gears
["r3"])
124 switch
= tgen
.add_switch("s6")
125 switch
.add_link(tgen
.gears
["r2"])
126 switch
.add_link(tgen
.gears
["r3"])
129 def setup_module(mod
):
130 "Sets up the pytest environment"
132 # skip tests is SNMP not installed
133 if not os
.path
.isfile("/usr/sbin/snmpd"):
134 error_msg
= "SNMP not installed - skipping"
135 pytest
.skip(error_msg
)
137 # This function initiates the topology build with Topogen...
138 tgen
= Topogen(TemplateTopo
, mod
.__name
__)
139 # ... and here it calls Mininet initialization functions.
140 tgen
.start_topology()
142 router_list
= tgen
.routers()
144 # For all registered routers, load the zebra configuration file
145 for rname
, router
in router_list
.iteritems():
147 TopoRouter
.RD_ZEBRA
, os
.path
.join(CWD
, "{}/zebra.conf".format(rname
))
149 # Don't start the following in the CE nodes
150 if router
.name
[0] == "r":
153 os
.path
.join(CWD
, "{}/isisd.conf".format(rname
)),
158 os
.path
.join(CWD
, "{}/ldpd.conf".format(rname
)),
162 os
.path
.join(CWD
, "{}/snmpd.conf".format(rname
)),
163 "-Le -Ivacm_conf,usmConf,iquery -V -DAgentX,trap",
166 # After loading the configurations, this function loads configured daemons.
170 def teardown_module(mod
):
171 "Teardown the pytest environment"
174 # This function tears down the whole topology.
178 def router_compare_json_output(rname
, command
, reference
):
179 "Compare router JSON output"
181 logger
.info('Comparing router "%s" "%s" output', rname
, command
)
184 filename
= "{}/{}/{}".format(CWD
, rname
, reference
)
185 expected
= json
.loads(open(filename
).read())
187 # Run test function until we get an result. Wait at most 80 seconds.
188 test_func
= partial(topotest
.router_json_cmp
, tgen
.gears
[rname
], command
, expected
)
189 _
, diff
= topotest
.run_and_expect(test_func
, None, count
=160, wait
=0.5)
190 assertmsg
= '"{}" JSON output mismatches the expected result'.format(rname
)
191 assert diff
is None, assertmsg
194 def generate_oid(numoids
, index1
, index2
):
196 oid
= "{}".format(index1
)
198 oid
= "{}.{}".format(index1
, index2
)
202 def test_isis_convergence():
203 logger
.info("Test: check ISIS adjacencies")
206 for rname
in ["r1", "r2", "r3", "r4", "r5"]:
207 router_compare_json_output(
209 "show yang operational-data /frr-interface:lib isisd",
210 "show_yang_interface_isis_adjacencies.ref",
214 def test_r1_scalar_snmp():
215 "Wait for protocol convergence"
218 # Skip if previous fatal error condition is raised
219 if tgen
.routers_have_failure():
220 pytest
.skip(tgen
.errors
)
222 r1
= tgen
.net
.get("r1")
223 r1_snmp
= SnmpTester(r1
, "1.1.1.1", "public", "2c")
225 assert r1_snmp
.test_oid("isisSysVersion", "one(1)")
226 assert r1_snmp
.test_oid("isisSysLevelType", "level1and2(3)")
227 assert r1_snmp
.test_oid("isisSysID", "00 00 00 00 00 01")
228 assert r1_snmp
.test_oid("isisSysMaxPathSplits", "32")
229 assert r1_snmp
.test_oid("isisSysMaxLSPGenInt", "900 seconds")
230 assert r1_snmp
.test_oid("isisSysAdminState", "on(1)")
231 assert r1_snmp
.test_oid("isisSysMaxAge", "1200 seconds")
232 assert r1_snmp
.test_oid("isisSysProtSupported", "07 5 6 7")
234 r2
= tgen
.net
.get("r2")
235 r2_snmp
= SnmpTester(r2
, "2.2.2.2", "public", "2c")
237 assert r2_snmp
.test_oid("isisSysVersion", "one(1)")
238 assert r2_snmp
.test_oid("isisSysLevelType", "level1and2(3)")
239 assert r2_snmp
.test_oid("isisSysID", "00 00 00 00 00 02")
240 assert r2_snmp
.test_oid("isisSysMaxPathSplits", "32")
241 assert r2_snmp
.test_oid("isisSysMaxLSPGenInt", "900 seconds")
242 assert r2_snmp
.test_oid("isisSysAdminState", "on(1)")
243 assert r2_snmp
.test_oid("isisSysMaxAge", "1200 seconds")
244 assert r2_snmp
.test_oid("isisSysProtSupported", "07 5 6 7")
248 "isisCircAdminState": ["on(1)", "on(1)"],
249 "isisCircExistState": ["active(1)", "active(1)"],
250 "isisCircType": ["broadcast(1)", "ptToPt(2)"],
251 "isisCircExtDomain": ["false(2)", "false(2)"],
252 "isisCircLevelType": ["level1(1)", "level1(1)"],
253 "isisCircPassiveCircuit": ["false(2)", "false(2)"],
254 "isisCircMeshGroupEnabled": ["inactive(1)", "inactive(1)"],
255 "isisCircSmallHellos": ["false(2)", "false(2)"],
256 "isisCirc3WayEnabled": ["false(2)", "false(2)"],
260 def test_r1_isisCircTable():
263 r1
= tgen
.net
.get("r1")
264 r1r
= tgen
.gears
["r1"]
266 r1_snmp
= SnmpTester(r1
, "1.1.1.1", "public", "2c")
269 oids
.append(generate_oid(1, 1, 0))
270 oids
.append(generate_oid(1, 2, 0))
273 for item
in circtable_test
.keys():
274 assertmsg
= "{} should be {} oids {} full dict {}:".format(
275 item
, circtable_test
[item
], oids
, r1_snmp
.walk(item
)
277 assert r1_snmp
.test_oid_walk(item
, circtable_test
[item
], oids
), assertmsg
280 circleveltable_test
= {
281 "isisCircLevelMetric": ["10", "10"],
282 "isisCircLevelWideMetric": ["10", "10"],
283 "isisCircLevelISPriority": ["64", "64"],
284 "isisCircLevelHelloMultiplier": ["10", "10"],
285 "isisCircLevelHelloTimer": [
289 "isisCircLevelMinLSPRetransInt": [
296 def test_r1_isislevelCircTable():
299 r1
= tgen
.net
.get("r1")
300 r1r
= tgen
.gears
["r1"]
302 r1_snmp
= SnmpTester(r1
, "1.1.1.1", "public", "2c")
305 oids
.append(generate_oid(2, 1, "area"))
306 oids
.append(generate_oid(2, 2, "area"))
309 for item
in circleveltable_test
.keys():
310 assertmsg
= "{} should be {} oids {} full dict {}:".format(
311 item
, circleveltable_test
[item
], oids
, r1_snmp
.walk(item
)
313 assert r1_snmp
.test_oid_walk(item
, circleveltable_test
[item
], oids
), assertmsg
317 "isisISAdjState": ["up(3)", "up(3)"],
318 "isisISAdj3WayState": ["down(2)", "up(0)"],
319 "isisISAdjNeighSysType": ["l1IntermediateSystem(1)", "l1IntermediateSystem(1)"],
320 "isisISAdjNeighSysID": ["00 00 00 00 00 04", "00 00 00 00 00 03"],
321 "isisISAdjUsage": ["0", "level1(1)"],
322 "isisISAdjNeighPriority": ["64", "0"],
325 adjtable_down_test
= {
326 "isisISAdjState": ["up(3)"],
327 "isisISAdj3WayState": ["down(2)"],
328 "isisISAdjNeighSysType": ["l1IntermediateSystem(1)"],
329 "isisISAdjNeighSysID": ["00 00 00 00 00 04"],
330 "isisISAdjUsage": ["0"],
331 "isisISAdjNeighPriority": ["64"],
335 def test_r1_isisAdjTable():
336 "check ISIS Adjacency Table"
338 r1
= tgen
.net
.get("r1")
339 r1_cmd
= tgen
.gears
["r1"]
340 r1_snmp
= SnmpTester(r1
, "1.1.1.1", "public", "2c")
343 oids
.append(generate_oid(2, 1, 1))
344 oids
.append(generate_oid(2, 2, 1))
347 oids_down
.append(generate_oid(2, 1, 1))
350 for item
in adjtable_test
.keys():
351 assertmsg
= "{} should be {} oids {} full dict {}:".format(
352 item
, adjtable_test
[item
], oids
, r1_snmp
.walk(item
)
354 assert r1_snmp
.test_oid_walk(item
, adjtable_test
[item
], oids
), assertmsg
356 # shutdown interface and one adjacency should be removed
357 "check ISIS adjacency is removed when interface is shutdown"
358 r1_cmd
.vtysh_cmd("conf t\ninterface r1-eth1\nshutdown")
359 r1_snmp
= SnmpTester(r1
, "1.1.1.1", "public", "2c")
361 for item
in adjtable_down_test
.keys():
362 assertmsg
= "{} should be {} oids {} full dict {}:".format(
363 item
, adjtable_down_test
[item
], oids_down
, r1_snmp
.walk(item
)
365 assert r1_snmp
.test_oid_walk(
366 item
, adjtable_down_test
[item
], oids_down
369 # no shutdown interface and adjacency should be restored
370 r1_cmd
.vtysh_cmd("conf t\ninterface r1-eth1\nno shutdown")
373 # Memory leak test template
374 # disabling memory leak
375 def test_memory_leak():
376 "Run the memory leak test and report results."
378 if not tgen
.is_memleak_enabled():
379 pytest
.skip("Memory leak test/report is disabled")
381 tgen
.report_memory_leaks()
384 if __name__
== "__main__":
385 args
= ["-s"] + sys
.argv
[1:]
386 sys
.exit(pytest
.main(args
))