]>
Commit | Line | Data |
---|---|---|
418b2885 KS |
1 | #!/usr/bin/env python |
2 | ||
3 | # | |
4 | # test_ldp_oc_acl_topo1.py | |
5 | # Part of NetDEF Topology Tests | |
6 | # | |
7 | # Copyright (c) 2020 by Volta Networks | |
8 | # | |
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 | |
12 | # in all copies. | |
13 | # | |
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 | |
21 | # OF THIS SOFTWARE. | |
22 | # | |
23 | ||
24 | """ | |
25 | test_ldp_oc_acl_topo1.py: Simple FRR/Quagga LDP Test | |
26 | ||
27 | +---------+ | |
28 | | r1 | | |
29 | | 1.1.1.1 | | |
30 | +----+----+ | |
31 | | .1 r1-eth0 | |
32 | | | |
33 | ~~~~~~~~~~~~~ | |
34 | ~~ sw0 ~~ | |
35 | ~~ 10.0.1.0/24 ~~ | |
36 | ~~~~~~~~~~~~~ | |
37 | |10.0.1.0/24 | |
38 | | | |
39 | | .2 r2-eth0 | |
40 | +----+----+ | |
41 | | r2 | | |
42 | | 2.2.2.2 | | |
43 | +--+---+--+ | |
44 | r2-eth2 .2 | | .2 r2-eth1 | |
45 | ______/ \______ | |
46 | / \ | |
47 | ~~~~~~~~~~~~~ ~~~~~~~~~~~~~ | |
48 | ~~ sw2 ~~ ~~ sw1 ~~ | |
49 | ~~ 10.0.3.0/24 ~~ ~~ 10.0.2.0/24 ~~ | |
50 | ~~~~~~~~~~~~~ ~~~~~~~~~~~~~ | |
51 | | / | | |
52 | \ _________/ | | |
53 | \ / \ | |
54 | r3-eth1 .3 | | .3 r3-eth0 | .4 r4-eth0 | |
55 | +----+--+---+ +----+----+ | |
56 | | r3 | | r4 | | |
57 | | 3.3.3.3 | | 4.4.4.4 | | |
58 | +-----------+ +---------+ | |
59 | """ | |
60 | ||
61 | import os | |
62 | import sys | |
63 | import pytest | |
64 | import json | |
65 | from time import sleep | |
66 | from functools import partial | |
67 | ||
68 | # Save the Current Working Directory to find configuration files. | |
69 | CWD = os.path.dirname(os.path.realpath(__file__)) | |
787e7624 | 70 | sys.path.append(os.path.join(CWD, "../")) |
418b2885 KS |
71 | |
72 | # pylint: disable=C0413 | |
73 | # Import topogen and topotest helpers | |
74 | from lib import topotest | |
75 | from lib.topogen import Topogen, TopoRouter, get_topogen | |
76 | from lib.topolog import logger | |
77 | ||
78 | # Required to instantiate the topology builder class. | |
79 | from mininet.topo import Topo | |
80 | ||
787e7624 | 81 | |
418b2885 KS |
82 | class TemplateTopo(Topo): |
83 | "Test topology builder" | |
787e7624 | 84 | |
418b2885 KS |
85 | def build(self, *_args, **_opts): |
86 | "Build function" | |
87 | tgen = get_topogen(self) | |
88 | ||
89 | # | |
90 | # Define FRR Routers | |
91 | # | |
787e7624 | 92 | for router in ["r1", "r2", "r3", "r4"]: |
418b2885 KS |
93 | tgen.add_router(router) |
94 | ||
95 | # | |
96 | # Define connections | |
97 | # | |
787e7624 | 98 | switch = tgen.add_switch("s0") |
99 | switch.add_link(tgen.gears["r1"]) | |
100 | switch.add_link(tgen.gears["r2"]) | |
101 | ||
102 | switch = tgen.add_switch("s1") | |
103 | switch.add_link(tgen.gears["r2"]) | |
104 | switch.add_link(tgen.gears["r3"]) | |
105 | switch.add_link(tgen.gears["r4"]) | |
418b2885 | 106 | |
787e7624 | 107 | switch = tgen.add_switch("s2") |
108 | switch.add_link(tgen.gears["r2"]) | |
109 | switch.add_link(tgen.gears["r3"]) | |
418b2885 | 110 | |
418b2885 KS |
111 | |
112 | def setup_module(mod): | |
113 | "Sets up the pytest environment" | |
114 | tgen = Topogen(TemplateTopo, mod.__name__) | |
115 | tgen.start_topology() | |
116 | ||
117 | router_list = tgen.routers() | |
118 | ||
119 | # For all registered routers, load the zebra configuration file | |
120 | for rname, router in router_list.iteritems(): | |
121 | router.load_config( | |
787e7624 | 122 | TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) |
418b2885 KS |
123 | ) |
124 | # Don't start ospfd and ldpd in the CE nodes | |
787e7624 | 125 | if router.name[0] == "r": |
418b2885 | 126 | router.load_config( |
787e7624 | 127 | TopoRouter.RD_OSPF, os.path.join(CWD, "{}/ospfd.conf".format(rname)) |
418b2885 KS |
128 | ) |
129 | router.load_config( | |
787e7624 | 130 | TopoRouter.RD_LDP, os.path.join(CWD, "{}/ldpd.conf".format(rname)) |
418b2885 KS |
131 | ) |
132 | ||
133 | tgen.start_router() | |
134 | ||
787e7624 | 135 | |
418b2885 KS |
136 | def teardown_module(mod): |
137 | "Teardown the pytest environment" | |
138 | tgen = get_topogen() | |
139 | ||
140 | # This function tears down the whole topology. | |
141 | tgen.stop_topology() | |
142 | ||
143 | ||
144 | def router_compare_json_output(rname, command, reference): | |
145 | "Compare router JSON output" | |
146 | ||
147 | logger.info('Comparing router "%s" "%s" output', rname, command) | |
148 | ||
149 | tgen = get_topogen() | |
787e7624 | 150 | filename = "{}/{}/{}".format(CWD, rname, reference) |
418b2885 KS |
151 | expected = json.loads(open(filename).read()) |
152 | ||
153 | # Run test function until we get an result. Wait at most 80 seconds. | |
787e7624 | 154 | test_func = partial(topotest.router_json_cmp, tgen.gears[rname], command, expected) |
418b2885 KS |
155 | _, diff = topotest.run_and_expect(test_func, None, count=160, wait=0.5) |
156 | ||
157 | assertmsg = '"{}" JSON output mismatches the expected result'.format(rname) | |
158 | assert diff is None, assertmsg | |
159 | ||
787e7624 | 160 | |
418b2885 KS |
161 | def test_ospf_convergence(): |
162 | logger.info("Test: check OSPF adjacencies") | |
163 | ||
164 | tgen = get_topogen() | |
165 | ||
166 | # Skip if previous fatal error condition is raised | |
167 | if tgen.routers_have_failure(): | |
168 | pytest.skip(tgen.errors) | |
169 | ||
787e7624 | 170 | for rname in ["r1", "r2", "r3", "r4"]: |
171 | router_compare_json_output( | |
172 | rname, "show ip ospf neighbor json", "show_ip_ospf_neighbor.json" | |
173 | ) | |
174 | ||
418b2885 KS |
175 | |
176 | def test_rib(): | |
177 | logger.info("Test: verify RIB") | |
178 | tgen = get_topogen() | |
179 | ||
180 | # Skip if previous fatal error condition is raised | |
181 | if tgen.routers_have_failure(): | |
182 | pytest.skip(tgen.errors) | |
183 | ||
787e7624 | 184 | for rname in ["r1", "r2", "r3", "r4"]: |
418b2885 KS |
185 | router_compare_json_output(rname, "show ip route json", "show_ip_route.ref") |
186 | ||
787e7624 | 187 | |
418b2885 KS |
188 | def test_ldp_adjacencies(): |
189 | logger.info("Test: verify LDP adjacencies") | |
190 | tgen = get_topogen() | |
191 | ||
192 | # Skip if previous fatal error condition is raised | |
193 | if tgen.routers_have_failure(): | |
194 | pytest.skip(tgen.errors) | |
195 | ||
787e7624 | 196 | for rname in ["r1", "r2", "r3", "r4"]: |
197 | router_compare_json_output( | |
198 | rname, "show mpls ldp discovery json", "show_ldp_discovery.ref" | |
199 | ) | |
200 | ||
418b2885 KS |
201 | |
202 | def test_ldp_neighbors(): | |
203 | logger.info("Test: verify LDP neighbors") | |
204 | tgen = get_topogen() | |
205 | ||
206 | # Skip if previous fatal error condition is raised | |
207 | if tgen.routers_have_failure(): | |
208 | pytest.skip(tgen.errors) | |
209 | ||
787e7624 | 210 | for rname in ["r1", "r2", "r3", "r4"]: |
211 | router_compare_json_output( | |
212 | rname, "show mpls ldp neighbor json", "show_ldp_neighbor.ref" | |
213 | ) | |
214 | ||
418b2885 KS |
215 | |
216 | def test_ldp_bindings(): | |
217 | logger.info("Test: verify LDP bindings") | |
218 | tgen = get_topogen() | |
219 | ||
220 | # Skip if previous fatal error condition is raised | |
221 | if tgen.routers_have_failure(): | |
222 | pytest.skip(tgen.errors) | |
223 | ||
787e7624 | 224 | for rname in ["r1", "r2", "r3", "r4"]: |
225 | router_compare_json_output( | |
226 | rname, "show mpls ldp binding json", "show_ldp_binding.ref" | |
227 | ) | |
228 | ||
418b2885 | 229 | |
6b4830dc | 230 | def test_ldp_bindings_all_routes(): |
231 | logger.info("Test: verify LDP bindings after host filter removed") | |
232 | tgen = get_topogen() | |
233 | ||
234 | # Skip if previous fatal error condition is raised | |
235 | if tgen.routers_have_failure(): | |
236 | pytest.skip(tgen.errors) | |
237 | ||
238 | # remove ACL that blocks advertising everything but host routes */ | |
787e7624 | 239 | cmd = 'vtysh -c "configure terminal" -c "mpls ldp" -c "address-family ipv4" -c "no label local allocate host-routes"' |
240 | tgen.net["r1"].cmd(cmd) | |
6b4830dc | 241 | sleep(2) |
242 | ||
787e7624 | 243 | for rname in ["r1", "r2", "r3", "r4"]: |
244 | router_compare_json_output( | |
245 | rname, "show mpls ldp binding json", "show_ldp_all_binding.ref" | |
246 | ) | |
247 | ||
6b4830dc | 248 | |
418b2885 KS |
249 | # Memory leak test template |
250 | def test_memory_leak(): | |
251 | "Run the memory leak test and report results." | |
252 | tgen = get_topogen() | |
253 | if not tgen.is_memleak_enabled(): | |
787e7624 | 254 | pytest.skip("Memory leak test/report is disabled") |
418b2885 KS |
255 | |
256 | tgen.report_memory_leaks() | |
257 | ||
787e7624 | 258 | |
259 | if __name__ == "__main__": | |
418b2885 KS |
260 | args = ["-s"] + sys.argv[1:] |
261 | sys.exit(pytest.main(args)) |