]>
Commit | Line | Data |
---|---|---|
03e7807b KK |
1 | #!/usr/bin/env python |
2 | ||
3 | # | |
4 | # Copyright (c) 2020 by VMware, Inc. ("VMware") | |
5 | # Used Copyright (c) 2018 by Network Device Education Foundation, | |
6 | # Inc. ("NetDEF") in this file. | |
7 | # | |
8 | # Permission to use, copy, modify, and/or distribute this software | |
9 | # for any purpose with or without fee is hereby granted, provided | |
10 | # that the above copyright notice and this permission notice appear | |
11 | # in all copies. | |
12 | # | |
13 | # THE SOFTWARE IS PROVIDED "AS IS" AND VMWARE DISCLAIMS ALL WARRANTIES | |
14 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
15 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL VMWARE BE LIABLE FOR | |
16 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY | |
17 | # DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, | |
18 | # WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS | |
19 | # ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE | |
20 | # OF THIS SOFTWARE. | |
21 | # | |
22 | ||
23 | """ | |
24 | Following tests are covered to test multicast pim sm: | |
25 | ||
26 | Test steps | |
27 | - Create topology (setup module) | |
28 | - Bring up topology | |
29 | ||
30 | Following tests are covered: | |
31 | 1. TC_1_1: Verify Multicast data traffic with static RP, (*,g) and | |
32 | (s,g) OIL updated correctly | |
33 | 2. TC_1_2: Verify Multicast data traffic with static RP, (*,g) and | |
34 | (s,g) OIL updated correctly | |
35 | 3. TC_4: Verify removing the RP should not impact the multicast | |
36 | data traffic | |
37 | 4. TC_5: Verify (*,G) and (S,G) entry populated again after clear the | |
38 | PIM nbr and mroute from FRR node | |
39 | 5. TC_9: Verify (s,g) timeout from FHR and RP when same receive | |
40 | exist in LHR , FHR and RP | |
41 | 6. TC_19: Verify mroute detail when same receiver joining 5 | |
42 | different sources | |
43 | 7. TC_16: Verify (*,G) and (S,G) populated correctly | |
44 | when FRR is the transit router | |
45 | 8. TC_23: Verify (S,G) should not create if RP is not reachable | |
46 | 9. TC_24: Verify modification of IGMP query timer should get update | |
47 | accordingly | |
48 | 10. TC_25: Verify modification of IGMP max query response timer | |
49 | should get update accordingly | |
50 | """ | |
51 | ||
52 | import os | |
53 | import sys | |
03e7807b | 54 | import time |
03e7807b KK |
55 | from time import sleep |
56 | import pytest | |
57 | ||
58 | pytestmark = pytest.mark.pimd | |
59 | ||
60 | # Save the Current Working Directory to find configuration files. | |
61 | CWD = os.path.dirname(os.path.realpath(__file__)) | |
62 | sys.path.append(os.path.join(CWD, "../")) | |
63 | sys.path.append(os.path.join(CWD, "../lib/")) | |
64 | ||
65 | # Required to instantiate the topology builder class. | |
66 | ||
67 | # pylint: disable=C0413 | |
68 | # Import topogen and topotest helpers | |
69 | from lib.topogen import Topogen, get_topogen | |
03e7807b KK |
70 | |
71 | from lib.common_config import ( | |
72 | start_topology, | |
73 | write_test_header, | |
74 | write_test_footer, | |
75 | step, | |
0a76e764 | 76 | apply_raw_config, |
03e7807b | 77 | reset_config_on_routers, |
03e7807b | 78 | shutdown_bringup_interface, |
03e7807b KK |
79 | required_linux_kernel_version, |
80 | topo_daemons, | |
81 | ) | |
82 | from lib.pim import ( | |
83 | create_pim_config, | |
84 | create_igmp_config, | |
85 | verify_igmp_groups, | |
86 | verify_ip_mroutes, | |
87 | verify_pim_interface_traffic, | |
88 | verify_upstream_iif, | |
03e7807b KK |
89 | verify_ip_pim_join, |
90 | clear_ip_mroute, | |
91 | clear_ip_pim_interface_traffic, | |
92 | verify_igmp_config, | |
5980ad0a | 93 | clear_ip_mroute_verify, |
1973df1d | 94 | McastTesterHelper, |
03e7807b KK |
95 | ) |
96 | from lib.topolog import logger | |
4953ca97 | 97 | from lib.topojson import build_config_from_json |
03e7807b | 98 | |
4be92408 | 99 | |
e82b531d | 100 | pytestmark = [pytest.mark.pimd] |
03e7807b KK |
101 | |
102 | TOPOLOGY = """ | |
103 | ||
104 | ||
105 | i4-----c1-------------c2---i5 | |
106 | | | | |
107 | | | | |
108 | i1-----l1------r2-----f1---i2 | |
109 | | | | | | |
110 | | | | | | |
111 | i7 i6 i3 i8 | |
112 | ||
113 | Description: | |
114 | i1, i2, i3. i4, i5, i6, i7, i8 - FRR running iperf to send IGMP | |
115 | join and traffic | |
8db751b8 CH |
116 | l1 - LHR (last hop router) |
117 | f1 - FHR (first hop router) | |
03e7807b KK |
118 | r2 - FRR router |
119 | c1 - FRR router | |
120 | c2 - FRR router | |
121 | """ | |
122 | ||
123 | # Global variables | |
124 | GROUP_RANGE = "225.0.0.0/8" | |
125 | IGMP_JOIN = "225.1.1.1" | |
126 | GROUP_RANGE_1 = [ | |
127 | "225.1.1.1/32", | |
128 | "225.1.1.2/32", | |
129 | "225.1.1.3/32", | |
130 | "225.1.1.4/32", | |
131 | "225.1.1.5/32", | |
132 | ] | |
133 | IGMP_JOIN_RANGE_1 = ["225.1.1.1", "225.1.1.2", "225.1.1.3", "225.1.1.4", "225.1.1.5"] | |
134 | GROUP_RANGE_2 = [ | |
135 | "226.1.1.1/32", | |
136 | "226.1.1.2/32", | |
137 | "226.1.1.3/32", | |
138 | "226.1.1.4/32", | |
139 | "226.1.1.5/32", | |
140 | ] | |
141 | IGMP_JOIN_RANGE_2 = ["226.1.1.1", "226.1.1.2", "226.1.1.3", "226.1.1.4", "226.1.1.5"] | |
142 | ||
143 | GROUP_RANGE_3 = [ | |
144 | "227.1.1.1/32", | |
145 | "227.1.1.2/32", | |
146 | "227.1.1.3/32", | |
147 | "227.1.1.4/32", | |
148 | "227.1.1.5/32", | |
149 | ] | |
150 | IGMP_JOIN_RANGE_3 = ["227.1.1.1", "227.1.1.2", "227.1.1.3", "227.1.1.4", "227.1.1.5"] | |
151 | ||
152 | ||
03e7807b KK |
153 | def setup_module(mod): |
154 | """ | |
155 | Sets up the pytest environment | |
156 | ||
157 | * `mod`: module name | |
158 | """ | |
159 | ||
160 | # Required linux kernel version for this suite to run. | |
161 | result = required_linux_kernel_version("4.19") | |
162 | if result is not True: | |
163 | pytest.skip("Kernel requirements are not met") | |
164 | ||
165 | testsuite_run_time = time.asctime(time.localtime(time.time())) | |
166 | logger.info("Testsuite start time: {}".format(testsuite_run_time)) | |
167 | logger.info("=" * 40) | |
168 | logger.info("Master Topology: \n {}".format(TOPOLOGY)) | |
169 | ||
170 | logger.info("Running setup_module to create topology") | |
171 | ||
e82b531d CH |
172 | testdir = os.path.dirname(os.path.realpath(__file__)) |
173 | json_file = "{}/multicast_pim_sm_topo1.json".format(testdir) | |
174 | tgen = Topogen(json_file, mod.__name__) | |
175 | global topo | |
176 | topo = tgen.json_topo | |
03e7807b KK |
177 | # ... and here it calls Mininet initialization functions. |
178 | ||
179 | # get list of daemons needs to be started for this suite. | |
e82b531d | 180 | daemons = topo_daemons(tgen, tgen.json_topo) |
03e7807b KK |
181 | |
182 | # Starting topology, create tmp files which are loaded to routers | |
183 | # to start deamons and then start routers | |
184 | start_topology(tgen, daemons) | |
185 | ||
186 | # Don"t run this test if we have any failure. | |
187 | if tgen.routers_have_failure(): | |
188 | pytest.skip(tgen.errors) | |
189 | ||
190 | # Creating configuration from JSON | |
8db751b8 | 191 | build_config_from_json(tgen, tgen.json_topo) |
03e7807b | 192 | |
1973df1d CH |
193 | # XXX Replace this using "with McastTesterHelper()... " in each test if possible. |
194 | global app_helper | |
195 | app_helper = McastTesterHelper(tgen) | |
196 | ||
03e7807b KK |
197 | logger.info("Running setup_module() done") |
198 | ||
199 | ||
200 | def teardown_module(): | |
201 | """Teardown the pytest environment""" | |
202 | ||
203 | logger.info("Running teardown_module to delete topology") | |
204 | ||
205 | tgen = get_topogen() | |
206 | ||
1973df1d | 207 | app_helper.cleanup() |
8db751b8 | 208 | |
03e7807b KK |
209 | # Stop toplogy and Remove tmp files |
210 | tgen.stop_topology() | |
211 | ||
212 | logger.info( | |
213 | "Testsuite end time: {}".format(time.asctime(time.localtime(time.time()))) | |
214 | ) | |
215 | logger.info("=" * 40) | |
216 | ||
217 | ||
218 | ##################################################### | |
219 | # | |
220 | # Testcases | |
221 | # | |
222 | ##################################################### | |
223 | ||
224 | ||
03e7807b KK |
225 | def verify_state_incremented(state_before, state_after): |
226 | """ | |
227 | API to compare interface traffic state incrementing | |
228 | ||
229 | Parameters | |
230 | ---------- | |
231 | * `state_before` : State dictionary for any particular instance | |
232 | * `state_after` : State dictionary for any particular instance | |
233 | """ | |
234 | ||
235 | for router, state_data in state_before.items(): | |
236 | for state, value in state_data.items(): | |
237 | if state_before[router][state] >= state_after[router][state]: | |
238 | errormsg = ( | |
239 | "[DUT: %s]: state %s value has not" | |
240 | " incremented, Initial value: %s, " | |
241 | "Current value: %s [FAILED!!]" | |
242 | % ( | |
243 | router, | |
244 | state, | |
245 | state_before[router][state], | |
246 | state_after[router][state], | |
247 | ) | |
248 | ) | |
249 | return errormsg | |
250 | ||
251 | logger.info( | |
252 | "[DUT: %s]: State %s value is " | |
253 | "incremented, Initial value: %s, Current value: %s" | |
254 | " [PASSED!!]", | |
255 | router, | |
256 | state, | |
257 | state_before[router][state], | |
258 | state_after[router][state], | |
259 | ) | |
260 | ||
261 | return True | |
262 | ||
263 | ||
264 | def test_multicast_data_traffic_static_RP_send_join_then_traffic_p0(request): | |
265 | """ | |
266 | TC_1_1: Verify Multicast data traffic with static RP, (*,g) and | |
267 | (s,g) OIL updated correctly | |
268 | """ | |
269 | ||
270 | tgen = get_topogen() | |
8db751b8 | 271 | topo = tgen.json_topo |
03e7807b KK |
272 | tc_name = request.node.name |
273 | write_test_header(tc_name) | |
274 | ||
275 | # Don"t run this test if we have any failure. | |
276 | if tgen.routers_have_failure(): | |
277 | pytest.skip(tgen.errors) | |
278 | ||
279 | step("Enable IGMP on FRR1 interface and send IGMP join (225.1.1.1)") | |
03e7807b | 280 | |
1973df1d | 281 | step("get joinRx value before join") |
03e7807b KK |
282 | intf_r2_l1 = topo["routers"]["r2"]["links"]["l1"]["interface"] |
283 | state_dict = {"r2": {intf_r2_l1: ["joinRx"]}} | |
284 | state_before = verify_pim_interface_traffic(tgen, state_dict) | |
285 | assert isinstance( | |
286 | state_before, dict | |
d7d21c3a CH |
287 | ), "Testcase {} : Failed \n state_before is not dictionary \n Error: {}".format( |
288 | tc_name, state_before | |
289 | ) | |
03e7807b | 290 | |
1973df1d | 291 | result = app_helper.run_join("i1", IGMP_JOIN, "l1") |
03e7807b KK |
292 | assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result) |
293 | ||
294 | step("Send the IGMP join first and then start the traffic") | |
295 | ||
296 | step("Configure RP on R2 (loopback interface) for the" " group range 225.0.0.0/8") | |
297 | ||
298 | input_dict = { | |
299 | "r2": { | |
300 | "pim": { | |
301 | "rp": [ | |
302 | { | |
303 | "rp_addr": topo["routers"]["r2"]["links"]["lo"]["ipv4"].split( | |
304 | "/" | |
305 | )[0], | |
306 | "group_addr_range": GROUP_RANGE, | |
307 | } | |
308 | ] | |
309 | } | |
310 | } | |
311 | } | |
312 | ||
313 | result = create_pim_config(tgen, topo, input_dict) | |
314 | assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result) | |
315 | ||
316 | step("Send multicast traffic from FRR3 to 225.1.1.1 receiver") | |
1973df1d | 317 | result = app_helper.run_traffic("i2", IGMP_JOIN, "f1") |
03e7807b KK |
318 | assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result) |
319 | ||
320 | step( | |
321 | "Verify 'show ip mroute' showing correct RPF and OIF" | |
322 | " interface for (*,G) and (S,G) entries on all the nodes" | |
323 | ) | |
324 | ||
325 | source = topo["routers"]["i2"]["links"]["f1"]["ipv4"].split("/")[0] | |
326 | intf_l1_r2 = topo["routers"]["l1"]["links"]["r2"]["interface"] | |
327 | intf_l1_i1 = topo["routers"]["l1"]["links"]["i1"]["interface"] | |
328 | intf_r2_l1 = topo["routers"]["r2"]["links"]["l1"]["interface"] | |
329 | intf_r2_f1 = topo["routers"]["r2"]["links"]["f1"]["interface"] | |
330 | intf_f1_i2 = topo["routers"]["f1"]["links"]["i2"]["interface"] | |
331 | intf_f1_r2 = topo["routers"]["f1"]["links"]["r2"]["interface"] | |
332 | input_dict = [ | |
333 | {"dut": "l1", "src_address": "*", "iif": intf_l1_r2, "oil": intf_l1_i1}, | |
334 | {"dut": "l1", "src_address": source, "iif": intf_l1_r2, "oil": intf_l1_i1}, | |
335 | {"dut": "r2", "src_address": "*", "iif": "lo", "oil": intf_r2_l1}, | |
336 | {"dut": "r2", "src_address": source, "iif": intf_r2_f1, "oil": intf_r2_l1}, | |
337 | {"dut": "f1", "src_address": source, "iif": intf_f1_i2, "oil": intf_f1_r2}, | |
338 | ] | |
339 | ||
340 | for data in input_dict: | |
341 | result = verify_ip_mroutes( | |
342 | tgen, data["dut"], data["src_address"], IGMP_JOIN, data["iif"], data["oil"] | |
343 | ) | |
344 | assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result) | |
345 | ||
1973df1d | 346 | |
03e7807b KK |
347 | step( |
348 | "Verify 'show ip pim upstream' showing correct OIL and IIF" " on all the nodes" | |
349 | ) | |
350 | for data in input_dict: | |
351 | result = verify_upstream_iif( | |
352 | tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN | |
353 | ) | |
354 | assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result) | |
355 | ||
1973df1d | 356 | |
03e7807b KK |
357 | step("joinRx value after join sent") |
358 | state_after = verify_pim_interface_traffic(tgen, state_dict) | |
359 | assert isinstance( | |
360 | state_after, dict | |
d7d21c3a CH |
361 | ), "Testcase {} : Failed \n state_before is not dictionary \n Error: {}".format( |
362 | tc_name, result | |
363 | ) | |
03e7807b KK |
364 | |
365 | step( | |
366 | "l1 sent PIM (*,G) join to r2 verify using" | |
367 | "'show ip pim interface traffic' on RP connected interface" | |
368 | ) | |
369 | result = verify_state_incremented(state_before, state_after) | |
370 | assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result) | |
371 | ||
372 | step("l1 sent PIM (S,G) join to f1 , verify using 'show ip pim join'") | |
373 | dut = "f1" | |
374 | interface = intf_f1_r2 | |
375 | result = verify_ip_pim_join(tgen, topo, dut, interface, IGMP_JOIN) | |
376 | assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result) | |
377 | ||
378 | write_test_footer(tc_name) | |
379 | ||
380 | ||
381 | def test_multicast_data_traffic_static_RP_send_traffic_then_join_p0(request): | |
382 | """ | |
383 | TC_1_2: Verify Multicast data traffic with static RP, (*,g) and | |
384 | (s,g) OIL updated correctly | |
385 | """ | |
386 | ||
387 | tgen = get_topogen() | |
8db751b8 | 388 | topo = tgen.json_topo |
03e7807b KK |
389 | tc_name = request.node.name |
390 | write_test_header(tc_name) | |
391 | ||
8db751b8 CH |
392 | # Don"t run this test if we have any failure. |
393 | if tgen.routers_have_failure(): | |
394 | pytest.skip(tgen.errors) | |
395 | ||
03e7807b | 396 | # Creating configuration from JSON |
1973df1d | 397 | app_helper.stop_all_hosts() |
03e7807b KK |
398 | clear_ip_mroute(tgen) |
399 | reset_config_on_routers(tgen) | |
400 | clear_ip_pim_interface_traffic(tgen, topo) | |
401 | ||
03e7807b KK |
402 | step("Configure RP on R2 (loopback interface) for the" " group range 225.0.0.0/8") |
403 | ||
404 | input_dict = { | |
405 | "r2": { | |
406 | "pim": { | |
407 | "rp": [ | |
408 | { | |
409 | "rp_addr": topo["routers"]["r2"]["links"]["lo"]["ipv4"].split( | |
410 | "/" | |
411 | )[0], | |
412 | "group_addr_range": GROUP_RANGE, | |
413 | } | |
414 | ] | |
415 | } | |
416 | } | |
417 | } | |
418 | ||
419 | result = create_pim_config(tgen, topo, input_dict) | |
420 | assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result) | |
421 | ||
422 | step("Start traffic first and then send the IGMP join") | |
423 | ||
424 | step("Send multicast traffic from FRR3 to 225.1.1.1 receiver") | |
1973df1d | 425 | result = app_helper.run_traffic("i2", IGMP_JOIN, "f1") |
03e7807b KK |
426 | assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result) |
427 | ||
428 | step("Enable IGMP on FRR1 interface and send IGMP join (225.1.1.1)") | |
03e7807b KK |
429 | step("joinRx value before join sent") |
430 | state_dict = {"r2": {"r2-l1-eth2": ["joinRx"]}} | |
431 | state_before = verify_pim_interface_traffic(tgen, state_dict) | |
432 | assert isinstance( | |
433 | state_before, dict | |
d7d21c3a CH |
434 | ), "Testcase {} : Failed \n state_before is not dictionary \n Error: {}".format( |
435 | tc_name, result | |
436 | ) | |
03e7807b | 437 | |
1973df1d | 438 | result = app_helper.run_join("i1", IGMP_JOIN, "l1") |
03e7807b KK |
439 | assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result) |
440 | ||
441 | step( | |
442 | "Verify 'show ip mroute' showing correct RPF and OIF" | |
443 | " interface for (*,G) and (S,G) entries on all the nodes" | |
444 | ) | |
445 | ||
446 | source = topo["routers"]["i2"]["links"]["f1"]["ipv4"].split("/")[0] | |
447 | input_dict = [ | |
448 | {"dut": "l1", "src_address": "*", "iif": "l1-r2-eth4", "oil": "l1-i1-eth1"}, | |
449 | {"dut": "l1", "src_address": source, "iif": "l1-r2-eth4", "oil": "l1-i1-eth1"}, | |
450 | {"dut": "r2", "src_address": "*", "iif": "lo", "oil": "r2-l1-eth2"}, | |
451 | {"dut": "r2", "src_address": source, "iif": "r2-f1-eth0", "oil": "r2-l1-eth2"}, | |
452 | {"dut": "f1", "src_address": source, "iif": "f1-i2-eth1", "oil": "f1-r2-eth3"}, | |
453 | ] | |
396b072f CH |
454 | # On timeout change from default of 80 to 120: failures logs indicate times 90+ |
455 | # seconds for success on the 2nd entry in the above table. Using 100s here restores | |
456 | # previous 80 retries with 2s wait if we assume .5s per vtysh/show ip mroute runtime | |
457 | # (41 * (2 + .5)) == 102. | |
03e7807b KK |
458 | for data in input_dict: |
459 | result = verify_ip_mroutes( | |
396b072f CH |
460 | tgen, data["dut"], data["src_address"], IGMP_JOIN, data["iif"], data["oil"], |
461 | retry_timeout=102 | |
03e7807b KK |
462 | ) |
463 | assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result) | |
464 | ||
465 | step( | |
466 | "Verify 'show ip pim upstream' showing correct OIL and IIF" " on all the nodes" | |
467 | ) | |
468 | for data in input_dict: | |
469 | result = verify_upstream_iif( | |
470 | tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN | |
471 | ) | |
472 | assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result) | |
473 | ||
474 | step("joinRx value after join sent") | |
475 | state_after = verify_pim_interface_traffic(tgen, state_dict) | |
476 | assert isinstance( | |
477 | state_after, dict | |
d7d21c3a CH |
478 | ), "Testcase {} : Failed \n state_before is not dictionary \n Error: {}".format( |
479 | tc_name, result | |
480 | ) | |
03e7807b KK |
481 | |
482 | step( | |
483 | "l1 sent PIM (*,G) join to r2 verify using" | |
484 | "'show ip pim interface traffic' on RP connected interface" | |
485 | ) | |
486 | result = verify_state_incremented(state_before, state_after) | |
487 | assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result) | |
488 | ||
489 | step("l1 sent PIM (S,G) join to f1 , verify using 'show ip pim join'") | |
490 | dut = "f1" | |
491 | interface = "f1-r2-eth3" | |
492 | result = verify_ip_pim_join(tgen, topo, dut, interface, IGMP_JOIN) | |
493 | assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result) | |
494 | ||
495 | write_test_footer(tc_name) | |
496 | ||
497 | ||
498 | def test_clear_pim_neighbors_and_mroute_p0(request): | |
499 | """ | |
500 | TC_5: Verify (*,G) and (S,G) entry populated again after clear the | |
501 | PIM nbr and mroute from FRR node | |
502 | """ | |
503 | ||
504 | tgen = get_topogen() | |
8db751b8 | 505 | topo = tgen.json_topo |
03e7807b KK |
506 | tc_name = request.node.name |
507 | write_test_header(tc_name) | |
508 | ||
8db751b8 CH |
509 | # Don"t run this test if we have any failure. |
510 | if tgen.routers_have_failure(): | |
511 | pytest.skip(tgen.errors) | |
512 | ||
03e7807b | 513 | # Creating configuration from JSON |
1973df1d | 514 | app_helper.stop_all_hosts() |
03e7807b KK |
515 | clear_ip_mroute(tgen) |
516 | reset_config_on_routers(tgen) | |
517 | clear_ip_pim_interface_traffic(tgen, topo) | |
518 | ||
03e7807b KK |
519 | step("Configure static RP on c1 for group (225.1.1.1-5)") |
520 | input_dict = { | |
521 | "c1": { | |
522 | "pim": { | |
523 | "rp": [ | |
524 | { | |
525 | "rp_addr": topo["routers"]["c1"]["links"]["lo"]["ipv4"].split( | |
526 | "/" | |
527 | )[0], | |
528 | "group_addr_range": GROUP_RANGE_1, | |
529 | } | |
530 | ] | |
531 | } | |
532 | } | |
533 | } | |
534 | ||
535 | result = create_pim_config(tgen, topo, input_dict) | |
536 | assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result) | |
537 | ||
538 | step( | |
539 | "Enable IGMP on FRR1 interface and send IGMP join 225.1.1.1 " | |
540 | "to 225.1.1.5 from different interfaces" | |
541 | ) | |
1973df1d | 542 | result = app_helper.run_join("i1", IGMP_JOIN_RANGE_1, "l1") |
03e7807b KK |
543 | assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result) |
544 | ||
545 | step("Send multicast traffic from FRR3, wait for SPT switchover") | |
1973df1d | 546 | result = app_helper.run_traffic("i2", IGMP_JOIN_RANGE_1, "f1") |
03e7807b KK |
547 | assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result) |
548 | ||
549 | step("Clear the mroute on l1, wait for 5 sec") | |
550 | result = clear_ip_mroute_verify(tgen, "l1") | |
551 | assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result) | |
552 | ||
553 | step( | |
554 | "After clear ip mroute (*,g) entries are re-populated again" | |
555 | " with same OIL and IIF, verify using 'show ip mroute' and " | |
556 | " 'show ip pim upstream' " | |
557 | ) | |
558 | ||
559 | source = topo["routers"]["i2"]["links"]["f1"]["ipv4"].split("/")[0] | |
560 | input_dict = [ | |
561 | {"dut": "l1", "src_address": "*", "iif": "l1-c1-eth0", "oil": "l1-i1-eth1"} | |
562 | ] | |
563 | ||
564 | for data in input_dict: | |
565 | result = verify_ip_mroutes( | |
566 | tgen, data["dut"], data["src_address"], IGMP_JOIN, data["iif"], data["oil"] | |
567 | ) | |
568 | assert result is True, "Testcase{} : Failed Error: {}".format(tc_name, result) | |
569 | ||
570 | step( | |
571 | "Verify 'show ip pim upstream' showing correct OIL and IIF" " on all the nodes" | |
572 | ) | |
573 | for data in input_dict: | |
574 | result = verify_upstream_iif( | |
575 | tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN | |
576 | ) | |
577 | assert result is True, "Testcase{} : Failed Error: {}".format(tc_name, result) | |
578 | ||
579 | write_test_footer(tc_name) | |
580 | ||
581 | ||
582 | def test_verify_mroute_when_same_receiver_in_FHR_LHR_and_RP_p0(request): | |
583 | """ | |
584 | TC_9: Verify (s,g) timeout from FHR and RP when same receive | |
585 | exist in LHR , FHR and RP | |
586 | """ | |
587 | ||
588 | tgen = get_topogen() | |
8db751b8 | 589 | topo = tgen.json_topo |
03e7807b KK |
590 | tc_name = request.node.name |
591 | write_test_header(tc_name) | |
592 | ||
8db751b8 CH |
593 | # Don"t run this test if we have any failure. |
594 | if tgen.routers_have_failure(): | |
595 | pytest.skip(tgen.errors) | |
596 | ||
03e7807b | 597 | # Creating configuration from JSON |
1973df1d | 598 | app_helper.stop_all_hosts() |
03e7807b KK |
599 | clear_ip_mroute(tgen) |
600 | reset_config_on_routers(tgen) | |
601 | clear_ip_pim_interface_traffic(tgen, topo) | |
602 | ||
03e7807b KK |
603 | step("Configure RP on R2 (loopback interface) for the" " group range 225.0.0.0/8") |
604 | ||
605 | input_dict = { | |
606 | "r2": { | |
607 | "pim": { | |
608 | "rp": [ | |
609 | { | |
610 | "rp_addr": topo["routers"]["r2"]["links"]["lo"]["ipv4"].split( | |
611 | "/" | |
612 | )[0], | |
613 | "group_addr_range": GROUP_RANGE, | |
614 | } | |
615 | ] | |
616 | } | |
617 | } | |
618 | } | |
619 | ||
620 | result = create_pim_config(tgen, topo, input_dict) | |
621 | assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result) | |
622 | ||
623 | step("Enable IGMP on FRR1 interface and send IGMP join " "(225.1.1.1) to R1") | |
624 | ||
625 | input_dict = { | |
1973df1d CH |
626 | "f1": {"igmp": {"interfaces": {"f1-i8-eth2": {"igmp": {"version": "2", "query": {"query-interval": 15} }}}}}, |
627 | "r2": {"igmp": {"interfaces": {"r2-i3-eth1": {"igmp": {"version": "2", "query": {"query-interval": 15} }}}}}, | |
03e7807b KK |
628 | } |
629 | result = create_igmp_config(tgen, topo, input_dict) | |
630 | assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result) | |
631 | ||
632 | input_join = {"i1": "i1-l1-eth0", "i8": "i8-f1-eth0", "i3": "i3-r2-eth0"} | |
633 | ||
634 | for recvr, recvr_intf in input_join.items(): | |
1973df1d | 635 | result = app_helper.run_join(recvr, IGMP_JOIN, join_intf=recvr_intf) |
03e7807b KK |
636 | assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result) |
637 | ||
638 | step("Send multicast traffic from R3 to 225.1.1.1 receiver") | |
1973df1d | 639 | result = app_helper.run_traffic("i2", IGMP_JOIN, "f1") |
03e7807b KK |
640 | assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result) |
641 | ||
642 | step("IGMP is received on FRR1 , FRR2 , FRR3, using " "'show ip igmp groups'") | |
643 | igmp_groups = {"l1": "l1-i1-eth1", "r2": "r2-i3-eth1", "f1": "f1-i8-eth2"} | |
644 | for dut, interface in igmp_groups.items(): | |
8db751b8 | 645 | result = verify_igmp_groups(tgen, dut, interface, IGMP_JOIN, retry_timeout=80) |
03e7807b KK |
646 | assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result) |
647 | ||
648 | step("(*,G) present on all the node with correct OIL" " using 'show ip mroute'") | |
649 | ||
650 | source = topo["routers"]["i2"]["links"]["f1"]["ipv4"].split("/")[0] | |
651 | input_dict = [ | |
652 | {"dut": "l1", "src_address": "*", "iif": "l1-r2-eth4", "oil": "l1-i1-eth1"}, | |
653 | {"dut": "l1", "src_address": source, "iif": "l1-r2-eth4", "oil": "l1-i1-eth1"}, | |
654 | {"dut": "r2", "src_address": "*", "iif": "lo", "oil": "r2-i3-eth1"}, | |
655 | {"dut": "r2", "src_address": source, "iif": "r2-f1-eth0", "oil": "r2-i3-eth1"}, | |
656 | {"dut": "f1", "src_address": "*", "iif": "f1-r2-eth3", "oil": "f1-i8-eth2"}, | |
657 | {"dut": "f1", "src_address": source, "iif": "f1-i2-eth1", "oil": "f1-i8-eth2"}, | |
658 | ] | |
659 | for data in input_dict: | |
660 | result = verify_ip_mroutes( | |
661 | tgen, data["dut"], data["src_address"], IGMP_JOIN, data["iif"], data["oil"] | |
662 | ) | |
663 | assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result) | |
664 | ||
665 | write_test_footer(tc_name) | |
666 | ||
667 | ||
668 | def test_verify_mroute_when_same_receiver_joining_5_diff_sources_p0(request): | |
669 | """ | |
670 | TC_19: Verify mroute detail when same receiver joining 5 | |
671 | different sources | |
672 | """ | |
673 | ||
674 | tgen = get_topogen() | |
8db751b8 | 675 | topo = tgen.json_topo |
03e7807b KK |
676 | tc_name = request.node.name |
677 | write_test_header(tc_name) | |
678 | ||
8db751b8 CH |
679 | # Don"t run this test if we have any failure. |
680 | if tgen.routers_have_failure(): | |
681 | pytest.skip(tgen.errors) | |
682 | ||
03e7807b | 683 | # Creating configuration from JSON |
1973df1d | 684 | app_helper.stop_all_hosts() |
03e7807b KK |
685 | clear_ip_mroute(tgen) |
686 | reset_config_on_routers(tgen) | |
687 | clear_ip_pim_interface_traffic(tgen, topo) | |
688 | ||
03e7807b KK |
689 | step("Configure static RP for (226.1.1.1-5) and (232.1.1.1-5)" " in c1") |
690 | ||
691 | _GROUP_RANGE = GROUP_RANGE_2 + GROUP_RANGE_3 | |
692 | _IGMP_JOIN_RANGE = IGMP_JOIN_RANGE_2 + IGMP_JOIN_RANGE_3 | |
693 | ||
694 | input_dict = { | |
695 | "c1": { | |
696 | "pim": { | |
697 | "rp": [ | |
698 | { | |
699 | "rp_addr": topo["routers"]["c1"]["links"]["lo"]["ipv4"].split( | |
700 | "/" | |
701 | )[0], | |
702 | "group_addr_range": _GROUP_RANGE, | |
703 | } | |
704 | ] | |
705 | } | |
706 | } | |
707 | } | |
708 | ||
709 | result = create_pim_config(tgen, topo, input_dict) | |
710 | assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result) | |
711 | ||
712 | step( | |
713 | "Configure IGMP interface on FRR1 and FRR3 and send IGMP join" | |
714 | "for group (226.1.1.1-5, 232.1.1.1-5)" | |
715 | ) | |
716 | ||
1973df1d | 717 | result = app_helper.run_join("i1", _IGMP_JOIN_RANGE, "l1") |
03e7807b KK |
718 | assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result) |
719 | ||
720 | input_dict = { | |
1973df1d | 721 | "f1": {"igmp": {"interfaces": {"f1-i8-eth2": {"igmp": {"version": "2", "query": {"query-interval": 15} }}}}} |
03e7807b KK |
722 | } |
723 | result = create_igmp_config(tgen, topo, input_dict) | |
724 | assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result) | |
725 | ||
1973df1d | 726 | result = app_helper.run_join("i8", _IGMP_JOIN_RANGE, "f1") |
03e7807b KK |
727 | assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result) |
728 | ||
729 | step( | |
730 | "Send multicast traffic from all the sources to all the " | |
731 | "receivers (226.1.1.1-5, 232.1.1.1-5)" | |
732 | ) | |
733 | ||
734 | input_traffic = { | |
735 | "i6": "i6-l1-eth0", | |
736 | "i7": "i7-l1-eth0", | |
737 | "i3": "i3-r2-eth0", | |
738 | "i4": "i4-c1-eth0", | |
739 | "i5": "i5-c2-eth0", | |
740 | } | |
741 | ||
742 | for src, src_intf in input_traffic.items(): | |
1973df1d | 743 | result = app_helper.run_traffic(src, _IGMP_JOIN_RANGE, bind_intf=src_intf) |
03e7807b KK |
744 | assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result) |
745 | ||
746 | step("Verify (*,G) are created on FRR1 and FRR3 node " " 'show ip mroute' ") | |
747 | ||
748 | source_i7 = topo["routers"]["i7"]["links"]["l1"]["ipv4"].split("/")[0] | |
749 | source_i6 = topo["routers"]["i6"]["links"]["l1"]["ipv4"].split("/")[0] | |
750 | source_i5 = topo["routers"]["i5"]["links"]["c2"]["ipv4"].split("/")[0] | |
751 | source_i3 = topo["routers"]["i3"]["links"]["r2"]["ipv4"].split("/")[0] | |
752 | input_dict = [ | |
753 | {"dut": "l1", "src_address": "*", "iif": "l1-c1-eth0", "oil": "l1-i1-eth1"}, | |
754 | { | |
755 | "dut": "l1", | |
756 | "src_address": source_i5, | |
757 | "iif": "l1-c1-eth0", | |
758 | "oil": "l1-i1-eth1", | |
759 | }, | |
760 | { | |
761 | "dut": "l1", | |
762 | "src_address": source_i3, | |
763 | "iif": "l1-r2-eth4", | |
764 | "oil": "l1-i1-eth1", | |
765 | }, | |
766 | { | |
767 | "dut": "l1", | |
768 | "src_address": source_i6, | |
769 | "iif": "l1-i6-eth2", | |
770 | "oil": "l1-i1-eth1", | |
771 | }, | |
772 | { | |
773 | "dut": "l1", | |
774 | "src_address": source_i7, | |
775 | "iif": "l1-i7-eth3", | |
776 | "oil": "l1-i1-eth1", | |
777 | }, | |
778 | {"dut": "f1", "src_address": "*", "iif": "f1-c2-eth0", "oil": "f1-i8-eth2"}, | |
779 | { | |
780 | "dut": "f1", | |
781 | "src_address": source_i5, | |
782 | "iif": "f1-c2-eth0", | |
783 | "oil": "f1-i8-eth2", | |
784 | }, | |
785 | { | |
786 | "dut": "f1", | |
787 | "src_address": source_i3, | |
788 | "iif": "f1-r2-eth3", | |
789 | "oil": "f1-i8-eth2", | |
790 | }, | |
791 | { | |
792 | "dut": "f1", | |
793 | "src_address": source_i6, | |
794 | "iif": "f1-r2-eth3", | |
795 | "oil": "f1-i8-eth2", | |
796 | }, | |
797 | { | |
798 | "dut": "f1", | |
799 | "src_address": source_i7, | |
800 | "iif": "f1-r2-eth3", | |
801 | "oil": "f1-i8-eth2", | |
802 | }, | |
803 | ] | |
804 | for data in input_dict: | |
805 | result = verify_ip_mroutes( | |
806 | tgen, | |
807 | data["dut"], | |
808 | data["src_address"], | |
809 | IGMP_JOIN_RANGE_2, | |
810 | data["iif"], | |
811 | data["oil"], | |
812 | ) | |
813 | assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result) | |
814 | ||
815 | step("Stop the source one by one on FRR1") | |
816 | input_intf = {"i6": "i6-l1-eth0", "i7": "i7-l1-eth0"} | |
817 | for dut, intf in input_intf.items(): | |
818 | shutdown_bringup_interface(tgen, dut, intf, False) | |
819 | ||
820 | step( | |
821 | "After removing the source verify traffic is stopped" | |
822 | " immediately and (S,G) got timeout in sometime" | |
823 | ) | |
824 | ||
825 | logger.info("After shut, waiting for SG timeout") | |
826 | ||
827 | input_dict = [ | |
828 | { | |
829 | "dut": "l1", | |
830 | "src_address": source_i6, | |
831 | "iif": "l1-i6-eth2", | |
832 | "oil": "l1-i1-eth1", | |
833 | }, | |
834 | { | |
835 | "dut": "l1", | |
836 | "src_address": source_i7, | |
837 | "iif": "l1-i7-eth3", | |
838 | "oil": "l1-i1-eth1", | |
839 | }, | |
840 | ] | |
841 | for data in input_dict: | |
842 | result = verify_ip_mroutes( | |
843 | tgen, | |
844 | data["dut"], | |
845 | data["src_address"], | |
846 | IGMP_JOIN_RANGE_2, | |
847 | data["iif"], | |
848 | data["oil"], | |
849 | expected=False, | |
850 | ) | |
d7d21c3a CH |
851 | assert ( |
852 | result is not True | |
853 | ), "Testcase {} : Failed \n mroutes are still present \n Error: {}".format( | |
854 | tc_name, result | |
855 | ) | |
03e7807b KK |
856 | logger.info("Expected Behavior: {}".format(result)) |
857 | ||
858 | step( | |
859 | "Source which is stopped got removed , other source" | |
860 | " after still present verify using 'show ip mroute' " | |
861 | ) | |
862 | input_dict = [ | |
863 | {"dut": "l1", "src_address": "*", "iif": "l1-c1-eth0", "oil": "l1-i1-eth1"}, | |
864 | { | |
865 | "dut": "l1", | |
866 | "src_address": source_i5, | |
867 | "iif": "l1-c1-eth0", | |
868 | "oil": "l1-i1-eth1", | |
869 | }, | |
870 | { | |
871 | "dut": "l1", | |
872 | "src_address": source_i3, | |
873 | "iif": "l1-r2-eth4", | |
874 | "oil": "l1-i1-eth1", | |
875 | }, | |
876 | {"dut": "f1", "src_address": "*", "iif": "f1-c2-eth0", "oil": "f1-i8-eth2"}, | |
877 | { | |
878 | "dut": "f1", | |
879 | "src_address": source_i5, | |
880 | "iif": "f1-c2-eth0", | |
881 | "oil": "f1-i8-eth2", | |
882 | }, | |
883 | { | |
884 | "dut": "f1", | |
885 | "src_address": source_i3, | |
886 | "iif": "f1-r2-eth3", | |
887 | "oil": "f1-i8-eth2", | |
888 | }, | |
889 | ] | |
890 | for data in input_dict: | |
891 | result = verify_ip_mroutes( | |
892 | tgen, | |
893 | data["dut"], | |
894 | data["src_address"], | |
895 | IGMP_JOIN_RANGE_2, | |
896 | data["iif"], | |
897 | data["oil"], | |
898 | ) | |
899 | assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result) | |
900 | ||
901 | step("Start all the source again for all the receivers") | |
902 | input_intf = {"i6": "i6-l1-eth0", "i7": "i7-l1-eth0"} | |
903 | for dut, intf in input_intf.items(): | |
904 | shutdown_bringup_interface(tgen, dut, intf, True) | |
905 | ||
906 | step( | |
907 | "After starting source all the mroute entries got populated, " | |
908 | "no duplicate entries present in mroute verify 'show ip mroute'" | |
909 | ) | |
910 | ||
911 | input_dict = [ | |
912 | {"dut": "l1", "src_address": "*", "iif": "l1-c1-eth0", "oil": "l1-i1-eth1"}, | |
913 | { | |
914 | "dut": "l1", | |
915 | "src_address": source_i5, | |
916 | "iif": "l1-c1-eth0", | |
917 | "oil": "l1-i1-eth1", | |
918 | }, | |
919 | { | |
920 | "dut": "l1", | |
921 | "src_address": source_i3, | |
922 | "iif": "l1-r2-eth4", | |
923 | "oil": "l1-i1-eth1", | |
924 | }, | |
925 | { | |
926 | "dut": "l1", | |
927 | "src_address": source_i6, | |
928 | "iif": "l1-i6-eth2", | |
929 | "oil": "l1-i1-eth1", | |
930 | }, | |
931 | { | |
932 | "dut": "l1", | |
933 | "src_address": source_i7, | |
934 | "iif": "l1-i7-eth3", | |
935 | "oil": "l1-i1-eth1", | |
936 | }, | |
937 | {"dut": "f1", "src_address": "*", "iif": "f1-c2-eth0", "oil": "f1-i8-eth2"}, | |
938 | { | |
939 | "dut": "f1", | |
940 | "src_address": source_i5, | |
941 | "iif": "f1-c2-eth0", | |
942 | "oil": "f1-i8-eth2", | |
943 | }, | |
944 | { | |
945 | "dut": "f1", | |
946 | "src_address": source_i3, | |
947 | "iif": "f1-r2-eth3", | |
948 | "oil": "f1-i8-eth2", | |
949 | }, | |
950 | { | |
951 | "dut": "f1", | |
952 | "src_address": source_i6, | |
953 | "iif": "f1-r2-eth3", | |
954 | "oil": "f1-i8-eth2", | |
955 | }, | |
956 | { | |
957 | "dut": "f1", | |
958 | "src_address": source_i7, | |
959 | "iif": "f1-r2-eth3", | |
960 | "oil": "f1-i8-eth2", | |
961 | }, | |
962 | ] | |
963 | for data in input_dict: | |
964 | result = verify_ip_mroutes( | |
965 | tgen, | |
966 | data["dut"], | |
967 | data["src_address"], | |
968 | IGMP_JOIN_RANGE_2, | |
969 | data["iif"], | |
970 | data["oil"], | |
971 | ) | |
972 | assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result) | |
973 | ||
974 | write_test_footer(tc_name) | |
975 | ||
976 | ||
977 | def test_verify_mroute_when_frr_is_transit_router_p2(request): | |
978 | """ | |
979 | TC_16: Verify (*,G) and (S,G) populated correctly | |
980 | when FRR is the transit router | |
981 | """ | |
982 | ||
983 | tgen = get_topogen() | |
8db751b8 | 984 | topo = tgen.json_topo |
03e7807b KK |
985 | tc_name = request.node.name |
986 | write_test_header(tc_name) | |
987 | ||
8db751b8 CH |
988 | # Don"t run this test if we have any failure. |
989 | if tgen.routers_have_failure(): | |
990 | pytest.skip(tgen.errors) | |
991 | ||
03e7807b | 992 | # Creating configuration from JSON |
1973df1d | 993 | app_helper.stop_all_hosts() |
03e7807b KK |
994 | clear_ip_mroute(tgen) |
995 | reset_config_on_routers(tgen) | |
996 | clear_ip_pim_interface_traffic(tgen, topo) | |
997 | ||
03e7807b KK |
998 | step("Configure static RP for (226.1.1.1-5) in c2") |
999 | input_dict = { | |
1000 | "c2": { | |
1001 | "pim": { | |
1002 | "rp": [ | |
1003 | { | |
1004 | "rp_addr": topo["routers"]["c2"]["links"]["lo"]["ipv4"].split( | |
1005 | "/" | |
1006 | )[0], | |
1007 | "group_addr_range": GROUP_RANGE_1, | |
1008 | } | |
1009 | ] | |
1010 | } | |
1011 | } | |
1012 | } | |
1013 | ||
1014 | result = create_pim_config(tgen, topo, input_dict) | |
1015 | assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result) | |
1016 | ||
1017 | step("Enable IGMP on FRR1 interface and send IGMP join " "(225.1.1.1-5) to FRR1") | |
1973df1d | 1018 | result = app_helper.run_join("i1", IGMP_JOIN_RANGE_1, "l1") |
03e7807b KK |
1019 | assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result) |
1020 | ||
1021 | step("Send multicast traffic from FRR3 to 225.1.1.1-5 receivers") | |
1973df1d | 1022 | result = app_helper.run_traffic("i2", IGMP_JOIN_RANGE_1, "f1") |
03e7807b KK |
1023 | assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result) |
1024 | ||
1025 | # Stop r2 router to make r2 router disabled from topology | |
1026 | input_intf = {"l1": "l1-r2-eth4", "f1": "f1-r2-eth3"} | |
1027 | for dut, intf in input_intf.items(): | |
1028 | shutdown_bringup_interface(tgen, dut, intf, False) | |
1029 | ||
1030 | step( | |
1031 | "FRR4 has (S,G) and (*,G) ,created where incoming interface" | |
1032 | " toward FRR3 and OIL toward R2, verify using 'show ip mroute'" | |
1033 | " 'show ip pim state' " | |
1034 | ) | |
1035 | ||
1036 | source = topo["routers"]["i2"]["links"]["f1"]["ipv4"].split("/")[0] | |
1037 | input_dict = [ | |
1038 | {"dut": "c2", "src_address": "*", "iif": "lo", "oil": "c2-c1-eth0"}, | |
1039 | {"dut": "c2", "src_address": source, "iif": "c2-f1-eth1", "oil": "c2-c1-eth0"}, | |
1040 | ] | |
1041 | for data in input_dict: | |
1042 | result = verify_ip_mroutes( | |
1043 | tgen, data["dut"], data["src_address"], IGMP_JOIN, data["iif"], data["oil"] | |
1044 | ) | |
1045 | assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result) | |
1046 | ||
1047 | step("Stop multicast traffic from FRR3") | |
1048 | dut = "i2" | |
1049 | intf = "i2-f1-eth0" | |
1050 | shutdown_bringup_interface(tgen, dut, intf, False) | |
1051 | ||
1052 | logger.info("Waiting for 20 sec to get traffic to be stopped..") | |
1053 | sleep(20) | |
1054 | ||
1055 | step("top IGMP receiver from FRR1") | |
1056 | dut = "i1" | |
1057 | intf = "i1-l1-eth0" | |
1058 | shutdown_bringup_interface(tgen, dut, intf, False) | |
1059 | ||
1060 | logger.info("Waiting for 20 sec to get mroutes to be flused out..") | |
1061 | sleep(20) | |
1062 | ||
1063 | step( | |
1064 | "After stopping receiver (*,G) also got timeout from transit" | |
1065 | " router 'show ip mroute'" | |
1066 | ) | |
1067 | ||
1068 | result = verify_ip_mroutes( | |
1069 | tgen, "c1", "*", IGMP_JOIN, "c1-c2-eth1", "c1-l1-eth0", expected=False | |
1070 | ) | |
d7d21c3a CH |
1071 | assert ( |
1072 | result is not True | |
1073 | ), "Testcase {} : Failed \n mroutes are still present \n Error: {}".format( | |
1074 | tc_name, result | |
1075 | ) | |
03e7807b KK |
1076 | logger.info("Expected Behavior: {}".format(result)) |
1077 | ||
1078 | write_test_footer(tc_name) | |
1079 | ||
1080 | ||
1081 | def test_verify_mroute_when_RP_unreachable_p1(request): | |
1082 | """ | |
1083 | TC_23: Verify (S,G) should not create if RP is not reachable | |
1084 | """ | |
1085 | ||
1086 | tgen = get_topogen() | |
8db751b8 | 1087 | topo = tgen.json_topo |
03e7807b KK |
1088 | tc_name = request.node.name |
1089 | write_test_header(tc_name) | |
1090 | ||
8db751b8 CH |
1091 | # Don"t run this test if we have any failure. |
1092 | if tgen.routers_have_failure(): | |
1093 | pytest.skip(tgen.errors) | |
1094 | ||
03e7807b | 1095 | # Creating configuration from JSON |
1973df1d | 1096 | app_helper.stop_all_hosts() |
03e7807b KK |
1097 | clear_ip_mroute(tgen) |
1098 | reset_config_on_routers(tgen) | |
1099 | clear_ip_pim_interface_traffic(tgen, topo) | |
1100 | ||
03e7807b KK |
1101 | step("Configure RP on FRR2 (loopback interface) for " "the group range 225.0.0.0/8") |
1102 | ||
1103 | input_dict = { | |
1104 | "r2": { | |
1105 | "pim": { | |
1106 | "rp": [ | |
1107 | { | |
1108 | "rp_addr": topo["routers"]["r2"]["links"]["lo"]["ipv4"].split( | |
1109 | "/" | |
1110 | )[0], | |
1111 | "group_addr_range": GROUP_RANGE, | |
1112 | } | |
1113 | ] | |
1114 | } | |
1115 | } | |
1116 | } | |
1117 | ||
1118 | result = create_pim_config(tgen, topo, input_dict) | |
1119 | assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result) | |
1120 | ||
1121 | step("Enable IGMP on FRR1 interface and send IGMP join (225.1.1.1)") | |
1122 | ||
1973df1d | 1123 | result = app_helper.run_join("i1", IGMP_JOIN, "l1") |
03e7807b KK |
1124 | assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result) |
1125 | ||
1126 | step("Send multicast traffic from FRR3 to 225.1.1.1 receiver") | |
1973df1d | 1127 | result = app_helper.run_traffic("i2", IGMP_JOIN, "f1") |
03e7807b KK |
1128 | assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result) |
1129 | ||
1130 | step("Configure one IGMP interface on FRR3 node and send IGMP" " join (225.1.1.1)") | |
1131 | input_dict = { | |
1973df1d | 1132 | "f1": {"igmp": {"interfaces": {"f1-i8-eth2": {"igmp": {"version": "2", "query": {"query-interval": 15} }}}}} |
03e7807b KK |
1133 | } |
1134 | result = create_igmp_config(tgen, topo, input_dict) | |
1135 | assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result) | |
1136 | ||
1973df1d | 1137 | result = app_helper.run_join("i8", IGMP_JOIN, "f1") |
03e7807b KK |
1138 | assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result) |
1139 | ||
1140 | # Verify mroutes are present in FRR3(f1) | |
1141 | source = topo["routers"]["i2"]["links"]["f1"]["ipv4"].split("/")[0] | |
1142 | input_dict = [ | |
1143 | {"dut": "f1", "src_address": "*", "iif": "f1-r2-eth3", "oil": "f1-i8-eth2"}, | |
1144 | {"dut": "f1", "src_address": source, "iif": "f1-i2-eth1", "oil": "f1-i8-eth2"}, | |
1145 | ] | |
1146 | for data in input_dict: | |
1147 | result = verify_ip_mroutes( | |
1148 | tgen, data["dut"], data["src_address"], IGMP_JOIN, data["iif"], data["oil"] | |
1149 | ) | |
1150 | assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result) | |
1151 | ||
1152 | step("Shut the RP connected interface from f1 ( r2 to f1) link") | |
1153 | dut = "f1" | |
1154 | intf = "f1-r2-eth3" | |
1155 | shutdown_bringup_interface(tgen, dut, intf, False) | |
1156 | ||
1157 | logger.info("Waiting for 20 sec to get mroutes to be flushed out..") | |
1158 | sleep(20) | |
1159 | ||
1160 | step("Clear the mroute on f1") | |
1161 | clear_ip_mroute(tgen, "f1") | |
1162 | ||
1163 | step( | |
1164 | "After Shut the RP interface and clear the mroute verify all " | |
1165 | "(*,G) and (S,G) got timeout from FRR3 node , verify using " | |
1166 | " 'show ip mroute' " | |
1167 | ) | |
1168 | ||
1169 | result = verify_ip_mroutes( | |
1170 | tgen, "f1", "*", IGMP_JOIN, "f1-r2-eth3", "f1-i8-eth2", expected=False | |
1171 | ) | |
d7d21c3a CH |
1172 | assert ( |
1173 | result is not True | |
1174 | ), "Testcase {} : Failed \n mroutes are still present \n Error: {}".format( | |
1175 | tc_name, result | |
1176 | ) | |
03e7807b KK |
1177 | logger.info("Expected Behavior: {}".format(result)) |
1178 | ||
1179 | step("IGMP groups are present verify using 'show ip igmp group'") | |
1180 | dut = "l1" | |
1181 | interface = "l1-i1-eth1" | |
1182 | result = verify_igmp_groups(tgen, dut, interface, IGMP_JOIN) | |
1183 | assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result) | |
1184 | ||
1185 | write_test_footer(tc_name) | |
1186 | ||
1187 | ||
1188 | def test_modify_igmp_query_timer_p0(request): | |
1189 | """ | |
1190 | TC_24: | |
1191 | Verify modification of IGMP query timer should get update | |
1192 | accordingly | |
1193 | """ | |
1194 | ||
1195 | tgen = get_topogen() | |
8db751b8 | 1196 | topo = tgen.json_topo |
03e7807b KK |
1197 | tc_name = request.node.name |
1198 | write_test_header(tc_name) | |
1199 | ||
8db751b8 CH |
1200 | # Don"t run this test if we have any failure. |
1201 | if tgen.routers_have_failure(): | |
1202 | pytest.skip(tgen.errors) | |
1203 | ||
03e7807b | 1204 | # Creating configuration from JSON |
1973df1d | 1205 | app_helper.stop_all_hosts() |
03e7807b KK |
1206 | clear_ip_mroute(tgen) |
1207 | reset_config_on_routers(tgen) | |
1208 | clear_ip_pim_interface_traffic(tgen, topo) | |
1209 | ||
03e7807b | 1210 | step("Enable IGMP on FRR1 interface and send IGMP join (225.1.1.1)") |
1973df1d | 1211 | result = app_helper.run_join("i1", IGMP_JOIN, "l1") |
03e7807b KK |
1212 | assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result) |
1213 | ||
1214 | step("Configure RP on R2 (loopback interface) for the" " group range 225.0.0.0/8") | |
1215 | ||
1216 | input_dict = { | |
1217 | "r2": { | |
1218 | "pim": { | |
1219 | "rp": [ | |
1220 | { | |
1221 | "rp_addr": topo["routers"]["r2"]["links"]["lo"]["ipv4"].split( | |
1222 | "/" | |
1223 | )[0], | |
1224 | "group_addr_range": GROUP_RANGE, | |
1225 | } | |
1226 | ] | |
1227 | } | |
1228 | } | |
1229 | } | |
1230 | ||
1231 | result = create_pim_config(tgen, topo, input_dict) | |
1232 | assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result) | |
1233 | ||
1234 | step("Send multicast traffic from FRR3 to 225.1.1.1 receiver") | |
1973df1d | 1235 | result = app_helper.run_traffic("i2", IGMP_JOIN, "f1") |
03e7807b KK |
1236 | assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result) |
1237 | ||
1238 | step( | |
1239 | "Verify 'show ip mroute' showing correct RPF and OIF" | |
1240 | " interface for (*,G) and (S,G) entries on all the nodes" | |
1241 | ) | |
1242 | ||
1243 | source = topo["routers"]["i2"]["links"]["f1"]["ipv4"].split("/")[0] | |
1244 | input_dict_4 = [ | |
1245 | {"dut": "l1", "src_address": "*", "iif": "l1-r2-eth4", "oil": "l1-i1-eth1"}, | |
1246 | {"dut": "l1", "src_address": source, "iif": "l1-r2-eth4", "oil": "l1-i1-eth1"}, | |
1247 | {"dut": "f1", "src_address": source, "iif": "f1-i2-eth1", "oil": "f1-r2-eth3"}, | |
1248 | ] | |
1249 | for data in input_dict_4: | |
1250 | result = verify_ip_mroutes( | |
1251 | tgen, data["dut"], data["src_address"], IGMP_JOIN, data["iif"], data["oil"] | |
1252 | ) | |
1253 | assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result) | |
1254 | ||
1255 | step( | |
1256 | "Verify 'show ip pim upstream' showing correct OIL and IIF" " on all the nodes" | |
1257 | ) | |
1258 | for data in input_dict_4: | |
1259 | result = verify_upstream_iif( | |
1260 | tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN | |
1261 | ) | |
1262 | assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result) | |
1263 | ||
1264 | step("Modify IGMP query interval default to other timer on FRR1" "3 times") | |
1265 | input_dict_1 = { | |
1266 | "l1": { | |
1267 | "igmp": { | |
1268 | "interfaces": { | |
1973df1d | 1269 | "l1-i1-eth1": {"igmp": {"query": {"query-interval": 20}}} |
03e7807b KK |
1270 | } |
1271 | } | |
1272 | } | |
1273 | } | |
1274 | result = create_igmp_config(tgen, topo, input_dict_1) | |
1275 | assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result) | |
1276 | ||
1277 | result = verify_igmp_config(tgen, input_dict_1) | |
1278 | assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result) | |
1279 | ||
1280 | input_dict_2 = { | |
1281 | "l1": { | |
1282 | "igmp": { | |
1283 | "interfaces": { | |
1973df1d | 1284 | "l1-i1-eth1": {"igmp": {"query": {"query-interval": 25}}} |
03e7807b KK |
1285 | } |
1286 | } | |
1287 | } | |
1288 | } | |
1289 | result = create_igmp_config(tgen, topo, input_dict_2) | |
1290 | assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result) | |
1291 | ||
1292 | result = verify_igmp_config(tgen, input_dict_2) | |
1293 | assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result) | |
1294 | ||
1295 | input_dict_3 = { | |
1296 | "l1": { | |
1297 | "igmp": { | |
1298 | "interfaces": { | |
1973df1d | 1299 | "l1-i1-eth1": {"igmp": {"query": {"query-interval": 30}}} |
03e7807b KK |
1300 | } |
1301 | } | |
1302 | } | |
1303 | } | |
1304 | result = create_igmp_config(tgen, topo, input_dict_3) | |
1305 | assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result) | |
1306 | ||
1307 | result = verify_igmp_config(tgen, input_dict_3) | |
1308 | assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result) | |
1309 | ||
1310 | step("Verify that no core is observed") | |
1311 | if tgen.routers_have_failure(): | |
1312 | assert False, "Testcase {}: Failed Error: {}".format(tc_name, result) | |
1313 | ||
1314 | write_test_footer(tc_name) | |
1315 | ||
1316 | ||
1317 | def test_modify_igmp_max_query_response_timer_p0(request): | |
1318 | """ | |
1319 | TC_25: | |
1320 | Verify modification of IGMP max query response timer | |
1321 | should get update accordingly | |
1322 | """ | |
1323 | ||
1324 | tgen = get_topogen() | |
8db751b8 | 1325 | topo = tgen.json_topo |
03e7807b KK |
1326 | tc_name = request.node.name |
1327 | write_test_header(tc_name) | |
1328 | ||
8db751b8 CH |
1329 | # Don"t run this test if we have any failure. |
1330 | if tgen.routers_have_failure(): | |
1331 | pytest.skip(tgen.errors) | |
1332 | ||
03e7807b | 1333 | # Creating configuration from JSON |
1973df1d | 1334 | app_helper.stop_all_hosts() |
03e7807b KK |
1335 | clear_ip_mroute(tgen) |
1336 | reset_config_on_routers(tgen) | |
1337 | clear_ip_pim_interface_traffic(tgen, topo) | |
1338 | ||
03e7807b | 1339 | step("Enable IGMP on FRR1 interface and send IGMP join (225.1.1.1)") |
1973df1d | 1340 | result = app_helper.run_join("i1", IGMP_JOIN, "l1") |
03e7807b KK |
1341 | assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result) |
1342 | ||
8db751b8 | 1343 | step("Configure IGMP query response time to 10 deci-sec on FRR1") |
03e7807b KK |
1344 | input_dict_1 = { |
1345 | "l1": { | |
1346 | "igmp": { | |
1347 | "interfaces": { | |
1348 | "l1-i1-eth1": { | |
1349 | "igmp": { | |
1350 | "version": "2", | |
1351 | "query": {"query-max-response-time": 10}, | |
1352 | } | |
1353 | } | |
1354 | } | |
1355 | } | |
1356 | } | |
1357 | } | |
1358 | result = create_igmp_config(tgen, topo, input_dict_1) | |
1359 | assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result) | |
1360 | ||
1361 | result = verify_igmp_config(tgen, input_dict_1) | |
1362 | assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result) | |
1363 | ||
1364 | step("Configure RP on R2 (loopback interface) for the" " group range 225.0.0.0/8") | |
1365 | ||
1366 | input_dict = { | |
1367 | "r2": { | |
1368 | "pim": { | |
1369 | "rp": [ | |
1370 | { | |
1371 | "rp_addr": topo["routers"]["r2"]["links"]["lo"]["ipv4"].split( | |
1372 | "/" | |
1373 | )[0], | |
1374 | "group_addr_range": GROUP_RANGE, | |
1375 | } | |
1376 | ] | |
1377 | } | |
1378 | } | |
1379 | } | |
1380 | ||
1381 | result = create_pim_config(tgen, topo, input_dict) | |
1382 | assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result) | |
1383 | ||
1384 | step("Send multicast traffic from FRR3 to 225.1.1.1 receiver") | |
1973df1d | 1385 | result = app_helper.run_traffic("i2", IGMP_JOIN, "f1") |
03e7807b KK |
1386 | assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result) |
1387 | ||
1388 | step( | |
1389 | "Verify 'show ip mroute' showing correct RPF and OIF" | |
1390 | " interface for (*,G) and (S,G) entries on all the nodes" | |
1391 | ) | |
1392 | ||
1393 | source = topo["routers"]["i2"]["links"]["f1"]["ipv4"].split("/")[0] | |
1394 | input_dict_5 = [ | |
1395 | {"dut": "l1", "src_address": "*", "iif": "l1-r2-eth4", "oil": "l1-i1-eth1"}, | |
1396 | {"dut": "l1", "src_address": source, "iif": "l1-r2-eth4", "oil": "l1-i1-eth1"}, | |
1397 | {"dut": "f1", "src_address": source, "iif": "f1-i2-eth1", "oil": "f1-r2-eth3"}, | |
1398 | ] | |
1399 | for data in input_dict_5: | |
1400 | result = verify_ip_mroutes( | |
1401 | tgen, data["dut"], data["src_address"], IGMP_JOIN, data["iif"], data["oil"] | |
1402 | ) | |
1403 | assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result) | |
1404 | ||
1973df1d | 1405 | |
03e7807b KK |
1406 | step( |
1407 | "Verify 'show ip pim upstream' showing correct OIL and IIF" " on all the nodes" | |
1408 | ) | |
1409 | for data in input_dict_5: | |
1410 | result = verify_upstream_iif( | |
1411 | tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN | |
1412 | ) | |
1413 | assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result) | |
1414 | ||
1415 | step("Delete the PIM and IGMP on FRR1") | |
0a76e764 CH |
1416 | raw_config = { |
1417 | "l1": {"raw_config": ["interface l1-i1-eth1", "no ip pim"]} | |
1418 | } | |
1419 | result = apply_raw_config(tgen, raw_config) | |
03e7807b KK |
1420 | assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result) |
1421 | ||
1422 | input_dict_2 = { | |
1423 | "l1": { | |
1424 | "igmp": { | |
1425 | "interfaces": { | |
1426 | "l1-i1-eth1": { | |
1427 | "igmp": { | |
1428 | "version": "2", | |
1429 | "delete": True, | |
1430 | "query": {"query-max-response-time": 10, "delete": True}, | |
1431 | } | |
1432 | } | |
1433 | } | |
1434 | } | |
1435 | } | |
1436 | } | |
1437 | result = create_igmp_config(tgen, topo, input_dict_2) | |
1438 | assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result) | |
1439 | ||
1440 | step("Configure PIM on FRR") | |
1441 | result = create_pim_config(tgen, topo["routers"]) | |
1442 | assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result) | |
1443 | ||
1973df1d | 1444 | step("Configure max query response timer 100 decisec on FRR1") |
03e7807b KK |
1445 | input_dict_3 = { |
1446 | "l1": { | |
1447 | "igmp": { | |
1448 | "interfaces": { | |
1449 | "l1-i1-eth1": { | |
1450 | "igmp": { | |
1451 | "version": "2", | |
1452 | "query": {"query-max-response-time": 100}, | |
1453 | } | |
1454 | } | |
1455 | } | |
1456 | } | |
1457 | } | |
1458 | } | |
1459 | result = create_igmp_config(tgen, topo, input_dict_3) | |
1460 | assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result) | |
1461 | ||
1462 | result = verify_igmp_config(tgen, input_dict_3) | |
1463 | assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result) | |
1464 | ||
1465 | step( | |
1466 | "Remove and add max query response timer cli with different" | |
1467 | "timer 5 times on FRR1 Enable IGMP and IGMP version 2 on FRR1" | |
1468 | " on FRR1" | |
1469 | ) | |
1470 | ||
1471 | input_dict_3 = { | |
1472 | "l1": { | |
1473 | "igmp": { | |
1474 | "interfaces": { | |
1475 | "l1-i1-eth1": { | |
1476 | "igmp": { | |
1477 | "version": "2", | |
1973df1d | 1478 | "query": {"query-max-response-time": 105}, |
03e7807b KK |
1479 | } |
1480 | } | |
1481 | } | |
1482 | } | |
1483 | } | |
1484 | } | |
1485 | result = create_igmp_config(tgen, topo, input_dict_3) | |
1486 | assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result) | |
1487 | ||
1488 | result = verify_igmp_config(tgen, input_dict_3) | |
1489 | assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result) | |
1490 | ||
1491 | input_dict_3 = { | |
1492 | "l1": { | |
1493 | "igmp": { | |
1494 | "interfaces": { | |
1495 | "l1-i1-eth1": { | |
1496 | "igmp": { | |
1497 | "version": "2", | |
1973df1d | 1498 | "query": {"query-max-response-time": 110}, |
03e7807b KK |
1499 | } |
1500 | } | |
1501 | } | |
1502 | } | |
1503 | } | |
1504 | } | |
1505 | result = create_igmp_config(tgen, topo, input_dict_3) | |
1506 | assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result) | |
1507 | ||
1508 | result = verify_igmp_config(tgen, input_dict_3) | |
1509 | assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result) | |
1510 | ||
1511 | input_dict_3 = { | |
1512 | "l1": { | |
1513 | "igmp": { | |
1514 | "interfaces": { | |
1515 | "l1-i1-eth1": { | |
1516 | "igmp": { | |
1517 | "version": "2", | |
1973df1d | 1518 | "query": {"query-max-response-time": 115}, |
03e7807b KK |
1519 | } |
1520 | } | |
1521 | } | |
1522 | } | |
1523 | } | |
1524 | } | |
1525 | result = create_igmp_config(tgen, topo, input_dict_3) | |
1526 | assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result) | |
1527 | ||
1528 | result = verify_igmp_config(tgen, input_dict_3) | |
1529 | assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result) | |
1530 | ||
1531 | input_dict_3 = { | |
1532 | "l1": { | |
1533 | "igmp": { | |
1534 | "interfaces": { | |
1535 | "l1-i1-eth1": { | |
1536 | "igmp": { | |
1537 | "version": "2", | |
1973df1d | 1538 | "query": {"query-max-response-time": 120}, |
03e7807b KK |
1539 | } |
1540 | } | |
1541 | } | |
1542 | } | |
1543 | } | |
1544 | } | |
1545 | result = create_igmp_config(tgen, topo, input_dict_3) | |
1546 | assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result) | |
1547 | ||
1548 | result = verify_igmp_config(tgen, input_dict_3) | |
1549 | assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result) | |
1550 | ||
1551 | step("Enable IGMP and IGMP version 2 on FRR1 on FRR1") | |
1552 | ||
1553 | input_dict_4 = { | |
1554 | "l1": {"igmp": {"interfaces": {"l1-i1-eth1": {"igmp": {"version": "2"}}}}} | |
1555 | } | |
1556 | result = create_igmp_config(tgen, topo, input_dict_4) | |
1557 | assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result) | |
1558 | ||
1559 | step("Verify that no core is observed") | |
1560 | if tgen.routers_have_failure(): | |
1561 | assert False, "Testcase {}: Failed Error: {}".format(tc_name, result) | |
1562 | ||
1563 | write_test_footer(tc_name) | |
1564 | ||
1565 | ||
1566 | if __name__ == "__main__": | |
1567 | args = ["-s"] + sys.argv[1:] | |
1568 | sys.exit(pytest.main(args)) |