]> git.proxmox.com Git - mirror_frr.git/blob - tests/topotests/pbr_topo1/test_pbr_topo1.py
Merge pull request #12798 from donaldsharp/rib_match_multicast
[mirror_frr.git] / tests / topotests / pbr_topo1 / test_pbr_topo1.py
1 #!/usr/bin/env python
2 # SPDX-License-Identifier: ISC
3
4 #
5 # test_pbr_topo1.py
6 #
7 # Copyright (c) 2020 by
8 # Cumulus Networks, Inc.
9 # Donald Sharp
10 #
11
12 """
13 test_pbr_topo1.py: Testing PBR
14
15 """
16
17 import os
18 import sys
19 import pytest
20 import json
21 import platform
22 from functools import partial
23
24 # Save the Current Working Directory to find configuration files.
25 CWD = os.path.dirname(os.path.realpath(__file__))
26 sys.path.append(os.path.join(CWD, "../"))
27
28 # pylint: disable=C0413
29 # Import topogen and topotest helpers
30 from lib import topotest
31 from lib.topogen import Topogen, TopoRouter, get_topogen
32 from lib.topolog import logger
33 from lib.common_config import shutdown_bringup_interface
34
35 # Required to instantiate the topology builder class.
36
37 pytestmark = [pytest.mark.pbrd]
38
39 #####################################################
40 ##
41 ## Network Topology Definition
42 ##
43 #####################################################
44
45
46 def build_topo(tgen):
47 "Build function"
48
49 # Populate routers
50 for routern in range(1, 2):
51 tgen.add_router("r{}".format(routern))
52
53 # Populate switches
54 for switchn in range(1, 6):
55 switch = tgen.add_switch("sw{}".format(switchn))
56 switch.add_link(tgen.gears["r1"])
57
58
59 #####################################################
60 ##
61 ## Tests starting
62 ##
63 #####################################################
64
65
66 def setup_module(module):
67 "Setup topology"
68 tgen = Topogen(build_topo, module.__name__)
69 tgen.start_topology()
70
71 krel = platform.release()
72 if topotest.version_cmp(krel, "4.10") < 0:
73 tgen.errors = "Newer kernel than 4.9 needed for pbr tests"
74 pytest.skip(tgen.errors)
75
76 router_list = tgen.routers()
77 for rname, router in router_list.items():
78 # Install vrf into the kernel and slave eth3
79 router.run("ip link add vrf-chiyoda type vrf table 1000")
80 router.run("ip link set dev {}-eth3 master vrf-chiyoda".format(rname))
81 router.run("ip link set vrf-chiyoda up")
82
83 router.load_config(
84 TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname))
85 )
86 router.load_config(
87 TopoRouter.RD_PBRD, os.path.join(CWD, "{}/pbrd.conf".format(rname))
88 )
89
90 tgen.start_router()
91
92
93 def teardown_module(_mod):
94 "Teardown the pytest environment"
95 tgen = get_topogen()
96
97 # This function tears down the whole topology.
98 tgen.stop_topology()
99
100
101 def test_converge_protocols():
102 "Wait for protocol convergence"
103
104 tgen = get_topogen()
105 # Don't run this test if we have any failure.
106 if tgen.routers_have_failure():
107 pytest.skip(tgen.errors)
108
109 topotest.sleep(5, "Waiting for PBR convergence")
110
111
112 def test_pbr_data():
113 "Test PBR 'show ip eigrp'"
114
115 tgen = get_topogen()
116 # Don't run this test if we have any failure.
117 if tgen.routers_have_failure():
118 pytest.skip(tgen.errors)
119
120 # Verify PBR Status
121 logger.info("Verifying PBR routes")
122
123 router_list = tgen.routers().values()
124 for router in router_list:
125 intf_file = "{}/{}/pbr-interface.json".format(CWD, router.name)
126 logger.info(intf_file)
127
128 # Read expected result from file
129 expected = json.loads(open(intf_file).read())
130
131 # Actual output from router
132 test_func = partial(
133 topotest.router_json_cmp, router, "show pbr interface json", expected
134 )
135 _, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
136 assertmsg = '"show pbr interface" mismatches on {}'.format(router.name)
137 if result is not None:
138 gather_pbr_data_on_error(router)
139 assert result is None, assertmsg
140
141 map_file = "{}/{}/pbr-map.json".format(CWD, router.name)
142 logger.info(map_file)
143
144 # Read expected result from file
145 expected = json.loads(open(map_file).read())
146
147 # Actual output from router
148 test_func = partial(
149 topotest.router_json_cmp, router, "show pbr map json", expected
150 )
151 _, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
152 assertmsg = '"show pbr map" mismatches on {}'.format(router.name)
153 if result is not None:
154 gather_pbr_data_on_error(router)
155 assert result is None, assertmsg
156
157 nexthop_file = "{}/{}/pbr-nexthop-groups.json".format(CWD, router.name)
158 logger.info(nexthop_file)
159
160 # Read expected result from file
161 expected = json.loads(open(nexthop_file).read())
162
163 # Actual output from router
164 test_func = partial(
165 topotest.router_json_cmp, router, "show pbr nexthop-groups json", expected
166 )
167 _, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
168 assertmsg = '"show pbr nexthop-groups" mismatches on {}'.format(router.name)
169 if result is not None:
170 gather_pbr_data_on_error(router)
171 assert result is None, assertmsg
172
173
174 def test_pbr_flap():
175 "Test PBR interface flapping"
176
177 tgen = get_topogen()
178 # Don't run this test if we have any failure.
179 if tgen.routers_have_failure():
180 pytest.skip(tgen.errors)
181
182 # Verify PBR Status
183 logger.info("Flapping PBR Interfaces")
184
185 router_list = tgen.routers().values()
186 for router in router_list:
187 # Flap interface to see if route-map properties are intact
188 # Shutdown interface
189
190 for i in range(5):
191 intf = "r1-eth{}".format(i)
192
193 # Down and back again
194 shutdown_bringup_interface(tgen, router.name, intf, False)
195 shutdown_bringup_interface(tgen, router.name, intf, True)
196
197 intf_file = "{}/{}/pbr-interface.json".format(CWD, router.name)
198 logger.info(intf_file)
199
200 # Read expected result from file
201 expected = json.loads(open(intf_file).read())
202
203 # Actual output from router
204 test_func = partial(
205 topotest.router_json_cmp, router, "show pbr interface json", expected
206 )
207 _, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
208 assertmsg = '"show pbr interface" mismatches on {}'.format(router.name)
209 if result is not None:
210 gather_pbr_data_on_error(router)
211 assert result is None, assertmsg
212
213
214 def test_rule_linux_installation():
215 "Ensure that rule is installed in the kernel"
216
217 tgen = get_topogen()
218 # Don't run this test if we have any failure.
219 if tgen.routers_have_failure():
220 pytest.skip(tgen.errors)
221
222 logger.info("Checking for installed PBR rules in OS")
223
224 def _get_router_rules(router, expected):
225 actual = topotest.ip_rules(router)
226
227 logger.info(actual)
228 return topotest.json_cmp(actual, expected)
229
230 router_list = tgen.routers().values()
231 for router in router_list:
232 rules_file = "{}/{}/linux-rules.json".format(CWD, router.name)
233
234 expected = json.loads(open(rules_file).read())
235
236 test_func = partial(_get_router_rules, router, expected)
237
238 _, result = topotest.run_and_expect(test_func, None, count=20, wait=1)
239 assertmsg = "Router {} OS rules mismatch".format(router.name)
240 assert result is None, assertmsg
241
242
243 if __name__ == "__main__":
244 args = ["-s"] + sys.argv[1:]
245 sys.exit(pytest.main(args))
246
247 #
248 # EXTRA SAUCE
249 #
250 def gather_pbr_data_on_error(router):
251 logger.info(router.vtysh_cmd("show ip route"))
252 logger.info(router.vtysh_cmd("show ip route vrf vrf-chiyoda"))
253 logger.info(router.vtysh_cmd("show ip nht"))
254 logger.info(router.vtysh_cmd("show pbr interface"))
255 logger.info(router.vtysh_cmd("show pbr map"))
256 logger.info(router.vtysh_cmd("show pbr nexthop-groups"))
257 logger.info(router.vtysh_cmd("show nexthop-group rib singleton ip"))
258 logger.info(router.vtysh_cmd("show nexthop-group rib singleton ipv6"))
259 logger.info(router.vtysh_cmd("show nexthop-group rib"))
260 logger.info(router.run("ip nexthop show"))
261 logger.info(router.run("ip route show"))
262 logger.info(router.run("ip route show table 1000"))
263 logger.info(router.run("ip route show table 10000"))
264 logger.info(router.run("ip -6 route show table 10000"))
265 logger.info(router.run("ip route show table 10001"))
266 logger.info(router.run("ip -6 route show table 10001"))
267 logger.info(router.run("ip route show table 10002"))
268 logger.info(router.run("ip -6 route show table 10002"))
269 logger.info(router.run("ip route show table 10003"))
270 logger.info(router.run("ip -6 route show table 10003"))
271 logger.info(router.run("ip route show table 10004"))
272 logger.info(router.run("ip -6 route show table 10004"))
273 logger.info(router.run("ip route show table 10005"))
274 logger.info(router.run("ip -6 route show table 10005"))
275 logger.info(router.run("ip rule show"))