]> git.proxmox.com Git - mirror_frr.git/blob - tests/topotests/multicast_pim_static_rp_topo1/test_multicast_pim_static_rp.py
doc: Add `show ipv6 rpf X:X::X:X` command to docs
[mirror_frr.git] / tests / topotests / multicast_pim_static_rp_topo1 / test_multicast_pim_static_rp.py
1 #!/usr/bin/env python
2
3 #
4 # Copyright (c) 2019 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 basic functionality:
25
26 Topology:
27
28 _______r2_____
29 | |
30 iperf | | iperf
31 r0-----r1-------------r3-----r5
32 | |
33 |_____________|
34 r4
35
36 Test steps
37 - Create topology (setup module)
38 - Bring up topology
39
40 TC_1 : Verify upstream interfaces(IIF) and join state are updated properly
41 after adding and deleting the static RP
42 TC_2 : Verify IIF and OIL in "show ip pim state" updated properly after
43 adding and deleting the static RP
44 TC_3: (*, G) Mroute entry are cleared when static RP gets deleted
45 TC_4: Verify (*,G) prune is send towards the RP after deleting the static RP
46 TC_5: Verify OIF entry for RP is cleared when RP becomes unreachable
47 TC_6: Verify IIF and OIL in "show ip pim state" updated properly when RP
48 becomes unreachable
49 TC_7 : Verify upstream interfaces(IIF) and join state are updated properly
50 after adding and deleting the static RP
51 TC_8: Verify (*,G) prune is send towards the RP when RP becomes unreachable
52 TC_9 : Verify RP configured after IGMP join received, PIM join towards RP is
53 sent immediately
54 TC_10 : Verify RP becomes reachable after IGMP join received, PIM join
55 towards RP is sent immediately
56 TC_11 : Verify PIM join send towards the higher preferred RP
57 TC_12 : Verify PIM prune send towards the lower preferred RP
58 TC_13 : Verify RPF interface is updated in mroute (kernel) when higher
59 preferred overlapping RP configured
60 TC_14 : Verify IIF and OIL in "show ip pim state" updated properly when higher
61 preferred overlapping RP configured
62 TC_15 : Verify upstream interfaces(IIF) and join state are updated when higher
63 preferred overlapping RP is configured
64 TC_16 : Verify join is send to lower preferred RP, when higher preferred RP
65 gets deleted
66 TC_17 : Verify prune is send to higher preferred RP when higher preferred RP
67 gets deleted
68 TC_18 : Verify RPF interface updated in mroute when higher preferred RP gets
69 deleted
70 TC_19 : Verify IIF and OIL in "show ip pim state" updated when higher
71 preferred overlapping RP is deleted
72 TC_20 : Verify PIM upstream IIF updated when higher preferred overlapping RP
73 deleted
74 TC_21_1 : Verify OIF and RFP for (*,G) and (S,G) when static RP configure in
75 LHR router
76 TC_21_2 : Verify OIF and RFP for (*,G) and (S,G) when static RP configure in
77 LHR router
78 TC_22_1 : Verify OIF and RPF for (*,G) and (S,G) when static RP configure in
79 FHR router
80 TC_22_2 : Verify OIF and RPF for (*,G) and (S,G) when static RP configure in
81 FHR router
82 TC_23 : Verify (*,G) and (S,G) populated correctly when RPT and SPT path are
83 different
84 TC_24 : Verify (*,G) and (S,G) populated correctly when SPT and RPT share the
85 same path
86 TC_25 : Verify (*,G) and (S,G) populated correctly after clearing the PIM ,
87 IGMP and mroutes joins
88 TC_26 : Restart the PIMd process and verify PIM joins , and mroutes entries
89 TC_27 : Configure multiple groups (10 grps) with same RP address
90 TC_28 : Configure multiple groups (10 grps) with different RP address
91 TC_29 : Verify IIF and OIL in updated in mroute when upstream interface
92 configure as RP
93 TC_30 : Verify IIF and OIL change to other path after shut the primary path
94 TC_31 : Verify RP info and (*,G) mroute after deleting the RP and shut / no
95 shut the RPF interface.
96 TC_32 : Verify RP info and (*,G) mroute after deleting the RP and shut / no
97 shut the RPF interface
98 """
99
100 import os
101 import sys
102 import time
103 from time import sleep
104 import datetime
105 import pytest
106
107 # Save the Current Working Directory to find configuration files.
108 CWD = os.path.dirname(os.path.realpath(__file__))
109 sys.path.append(os.path.join(CWD, "../"))
110 sys.path.append(os.path.join(CWD, "../lib/"))
111
112 # Required to instantiate the topology builder class.
113
114 # pylint: disable=C0413
115 # Import topogen and topotest helpers
116
117 from lib.topogen import Topogen, get_topogen
118 from lib.topolog import logger
119 from lib.topojson import build_topo_from_json, build_config_from_json
120
121 from lib.common_config import (
122 start_topology,
123 write_test_header,
124 write_test_footer,
125 reset_config_on_routers,
126 step,
127 shutdown_bringup_interface,
128 kill_router_daemons,
129 start_router_daemons,
130 create_static_routes,
131 topo_daemons,
132 )
133 from lib.pim import (
134 create_pim_config,
135 verify_igmp_groups,
136 verify_upstream_iif,
137 verify_join_state_and_timer,
138 verify_mroutes,
139 verify_pim_neighbors,
140 get_pim_interface_traffic,
141 verify_pim_rp_info,
142 verify_pim_state,
143 clear_pim_interface_traffic,
144 clear_igmp_interfaces,
145 clear_pim_interfaces,
146 clear_mroute,
147 clear_mroute_verify,
148 McastTesterHelper,
149 )
150
151 pytestmark = [pytest.mark.pimd, pytest.mark.staticd]
152
153
154 # Global variables
155 GROUP_RANGE_ALL = "224.0.0.0/4"
156 GROUP_RANGE = "225.1.1.1/32"
157 GROUP_RANGE_LIST_1 = [
158 "225.1.1.1/32",
159 "225.1.1.2/32",
160 "225.1.1.3/32",
161 "225.1.1.4/32",
162 "225.1.1.5/32",
163 ]
164 GROUP_RANGE_LIST_2 = [
165 "225.1.1.6/32",
166 "225.1.1.7/32",
167 "225.1.1.8/32",
168 "225.1.1.9/32",
169 "225.1.1.10/32",
170 ]
171 GROUP_ADDRESS = "225.1.1.1"
172 GROUP_ADDRESS_LIST_1 = ["225.1.1.1", "225.1.1.2", "225.1.1.3", "225.1.1.4", "225.1.1.5"]
173 GROUP_ADDRESS_LIST_2 = [
174 "225.1.1.6",
175 "225.1.1.7",
176 "225.1.1.8",
177 "225.1.1.9",
178 "225.1.1.10",
179 ]
180 STAR = "*"
181 SOURCE_ADDRESS = "10.0.6.2"
182 SOURCE = "Static"
183
184
185 def build_topo(tgen):
186 """Build function"""
187
188 # Building topology from json file
189 build_topo_from_json(tgen, TOPO)
190
191
192 def setup_module(mod):
193 """
194 Sets up the pytest environment
195
196 * `mod`: module name
197 """
198
199 testsuite_run_time = time.asctime(time.localtime(time.time()))
200 logger.info("Testsuite start time: %s", testsuite_run_time)
201 logger.info("=" * 40)
202
203 topology = """
204
205 _______r2_____
206 | |
207 iperf | | iperf
208 r0-----r1-------------r3-----r5
209 | |
210 |_____________|
211 r4
212
213 """
214 logger.info("Master Topology: \n %s", topology)
215
216 logger.info("Running setup_module to create topology")
217
218 # This function initiates the topology build with Topogen...
219 json_file = "{}/multicast_pim_static_rp.json".format(CWD)
220 tgen = Topogen(json_file, mod.__name__)
221 global TOPO
222 TOPO = tgen.json_topo
223
224 # ... and here it calls Mininet initialization functions.
225
226 # Starting topology, create tmp files which are loaded to routers
227 # to start daemons and then start routers
228 start_topology(tgen)
229
230 # Don"t run this test if we have any failure.
231 if tgen.routers_have_failure():
232 pytest.skip(tgen.errors)
233
234 # Creating configuration from JSON
235 build_config_from_json(tgen, TOPO)
236
237 # Verify PIM neighbors
238 result = verify_pim_neighbors(tgen, TOPO)
239 assert result is True, "setup_module :Failed \n Error:" " {}".format(result)
240
241 # XXX Replace this using "with McastTesterHelper()... " in each test if possible.
242 global app_helper
243 app_helper = McastTesterHelper(tgen)
244
245 logger.info("Running setup_module() done")
246
247
248 def teardown_module():
249 """Teardown the pytest environment"""
250
251 logger.info("Running teardown_module to delete topology")
252
253 tgen = get_topogen()
254
255 app_helper.cleanup()
256
257 # Stop toplogy and Remove tmp files
258 tgen.stop_topology()
259
260 logger.info("Testsuite end time: %s", time.asctime(time.localtime(time.time())))
261 logger.info("=" * 40)
262
263
264 #####################################################
265 #
266 # Testcases
267 #
268 #####################################################
269
270
271 def verify_mroute_repopulated(uptime_before, uptime_after):
272 """
273 API to compare uptime for mroutes
274
275 Parameters
276 ----------
277 * `uptime_before` : Uptime dictionary for any particular instance
278 * `uptime_after` : Uptime dictionary for any particular instance
279 """
280
281 for group in uptime_before.keys():
282 for source in uptime_before[group].keys():
283 if set(uptime_before[group]) != set(uptime_after[group]):
284 errormsg = (
285 "mroute (%s, %s) has not come"
286 " up after mroute clear [FAILED!!]" % (source, group)
287 )
288 return errormsg
289
290 d_1 = datetime.datetime.strptime(uptime_before[group][source], "%H:%M:%S")
291 d_2 = datetime.datetime.strptime(uptime_after[group][source], "%H:%M:%S")
292 if d_2 >= d_1:
293 errormsg = "mroute (%s, %s) is not " "repopulated [FAILED!!]" % (
294 source,
295 group,
296 )
297 return errormsg
298
299 logger.info("mroute (%s, %s) is " "repopulated [PASSED!!]", source, group)
300
301 return True
302
303
304 def verify_state_incremented(state_before, state_after):
305 """
306 API to compare interface traffic state incrementing
307
308 Parameters
309 ----------
310 * `state_before` : State dictionary for any particular instance
311 * `state_after` : State dictionary for any particular instance
312 """
313
314 for router, state_data in state_before.items():
315 for state, _ in state_data.items():
316 if state_before[router][state] >= state_after[router][state]:
317 errormsg = (
318 "[DUT: %s]: state %s value has not"
319 " incremented, Initial value: %s, "
320 "Current value: %s [FAILED!!]"
321 % (
322 router,
323 state,
324 state_before[router][state],
325 state_after[router][state],
326 )
327 )
328 return errormsg
329
330 logger.info(
331 "[DUT: %s]: State %s value is "
332 "incremented, Initial value: %s, Current value: %s"
333 " [PASSED!!]",
334 router,
335 state,
336 state_before[router][state],
337 state_after[router][state],
338 )
339
340 return True
341
342
343 def test_add_delete_static_RP_p0(request):
344 """
345 TC_1_P0 : Verify upstream interfaces(IIF) and join state are updated
346 properly after adding and deleting the static RP
347 TC_2_P0 : Verify IIF and OIL in "show ip pim state" updated properly
348 after adding and deleting the static RP
349 TC_3_P0: (*, G) Mroute entry are cleared when static RP gets deleted
350 TC_4_P0: Verify (*,G) prune is send towards the RP after deleting the
351 static RP
352
353 Topology used:
354 r0------r1-----r2
355 iperf DUT RP
356 """
357
358 tgen = get_topogen()
359 tc_name = request.node.name
360 write_test_header(tc_name)
361
362 # Don"t run this test if we have any failure.
363 if tgen.routers_have_failure():
364 pytest.skip(tgen.errors)
365
366 step("pre-configuration to send IGMP join and multicast traffic")
367
368 step("Enable IGMP on r1 interface and send IGMP " "join (225.1.1.1) to r1")
369 step("Configure r2 loopback interface as RP")
370 step("Enable PIM between r1 and r3")
371
372 step("r1: Verify show ip igmp group without any IGMP join")
373 dut = "r1"
374 interface = "r1-r0-eth0"
375 result = verify_igmp_groups(tgen, dut, interface, GROUP_ADDRESS, expected=False)
376 assert result is not True, (
377 "Testcase {} : Failed \n "
378 "Expected: [{}]: IGMP groups should not be present without any IGMP join\n "
379 "Found: {}".format(tc_name, dut, result)
380 )
381
382 step("r1: Verify show ip pim interface traffic without any IGMP join")
383 state_dict = {"r1": {"r1-r2-eth1": ["pruneTx"]}}
384
385 state_before = get_pim_interface_traffic(tgen, state_dict)
386 assert isinstance(
387 state_before, dict
388 ), "Testcase {} : Failed \n state_before is not dictionary\n Error: {}".format(
389 tc_name, result
390 )
391
392 step("r0 : Send IGMP join")
393 result = app_helper.run_join("r0", GROUP_ADDRESS, "r1")
394 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
395
396 step("r1: Verify IGMP groups")
397 oif = "r1-r0-eth0"
398 result = verify_igmp_groups(tgen, dut, oif, GROUP_ADDRESS)
399 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
400
401 step("r1: Verify RP info")
402 dut = "r1"
403 iif = "r1-r2-eth1"
404 rp_address = "1.0.2.17"
405 result = verify_pim_rp_info(
406 tgen, TOPO, dut, GROUP_RANGE_ALL, iif, rp_address, SOURCE
407 )
408 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
409
410 step("r1: Verify upstream IIF interface")
411 result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS)
412 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
413
414 step("r1: Verify upstream join state and join timer")
415 result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS)
416 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
417 step("r1: Verify ip mroutes")
418 result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif)
419 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
420
421 step("r1: Verify ip pim join")
422 result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS)
423 step("r1: Delete RP configuration")
424
425 # Delete RP configuration
426 input_dict = {
427 "r1": {
428 "pim": {
429 "rp": [
430 {
431 "rp_addr": "1.0.2.17",
432 "group_addr_range": GROUP_RANGE_ALL,
433 "delete": True,
434 }
435 ]
436 }
437 }
438 }
439
440 result = create_pim_config(tgen, TOPO, input_dict)
441 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
442
443 step("r1: Verify RP info")
444 result = verify_pim_rp_info(
445 tgen, TOPO, dut, GROUP_RANGE_ALL, iif, rp_address, SOURCE, expected=False
446 )
447 assert result is not True, (
448 "Testcase {} : Failed \n "
449 "Expected: [{}]: RP info should not be present \n "
450 "Found: {}".format(tc_name, dut, result)
451 )
452
453 step("r1: Verify upstream IIF interface")
454 result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS, expected=False)
455 assert result is not True, (
456 "Testcase {} : Failed \n "
457 "Expected: [{}]: Upstream IIF interface {} should not be present\n "
458 "Found: {}".format(tc_name, dut, iif, result)
459 )
460
461 step("r1: Verify upstream join state and join timer")
462 result = verify_join_state_and_timer(
463 tgen, dut, iif, STAR, GROUP_ADDRESS, expected=False
464 )
465 assert result is not True, (
466 "Testcase {} : Failed \n "
467 "Expected: [{}]: Upstream Join State timer should not run\n "
468 "Found: {}".format(tc_name, dut, result)
469 )
470
471 # 20
472 step("r1: Verify PIM state")
473 result = verify_pim_state(tgen, dut, iif, oif, GROUP_ADDRESS, expected=False)
474 assert result is not True, (
475 "Testcase {} : Failed \n "
476 "Expected: [{}]: PIM state should not be up \n "
477 "Found: {}".format(tc_name, dut, result)
478 )
479
480 step("r1: Verify ip mroutes")
481 result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif, expected=False)
482 assert result is not True, (
483 "Testcase {} : Failed \n "
484 "Expected: [{}]: mroute (*, G) should not be present \n "
485 "Found: {}".format(tc_name, dut, result)
486 )
487
488 step("r1: Verify show ip pim interface traffic without any IGMP join")
489 state_after = get_pim_interface_traffic(tgen, state_dict)
490 assert isinstance(
491 state_after, dict
492 ), "Testcase {} : Failed \n state_before is not dictionary \n Error: {}".format(
493 tc_name, result
494 )
495
496 result = verify_state_incremented(state_before, state_after)
497 assert result is True, "Testcase{} : Failed Error: {}".format(tc_name, result)
498
499 # Uncomment next line for debugging
500 # tgen.mininet_cli()
501
502 write_test_footer(tc_name)
503
504
505 def test_SPT_RPT_path_same_p1(request):
506 """
507 TC_24_P1 : Verify (*,G) and (S,G) populated correctly when SPT and RPT
508 share the same path
509
510 Topology used:
511 ________r2_____
512 | |
513 iperf | | iperf
514 r0-----r1 r3-----r5
515
516 r1 : LHR
517 r2 : RP
518 r3 : FHR
519 """
520
521 tgen = get_topogen()
522 tc_name = request.node.name
523 write_test_header(tc_name)
524
525 # Don"t run this test if we have any failure.
526 if tgen.routers_have_failure():
527 pytest.skip(tgen.errors)
528
529 step("Creating configuration from JSON")
530 reset_config_on_routers(tgen)
531 app_helper.stop_all_hosts()
532 clear_mroute(tgen)
533 clear_pim_interface_traffic(tgen, TOPO)
534
535 dut = "r1"
536 intf = "r1-r3-eth2"
537 shutdown_bringup_interface(tgen, dut, intf, False)
538 intf = "r1-r4-eth3"
539 shutdown_bringup_interface(tgen, dut, intf, False)
540
541 dut = "r3"
542 intf = "r3-r1-eth0"
543 shutdown_bringup_interface(tgen, dut, intf, False)
544 intf = "r3-r4-eth2"
545 shutdown_bringup_interface(tgen, dut, intf, False)
546
547 step("Enable IGMP on r1 interface and send IGMP join (225.1.1.1) to R1")
548 step("Configure RP on r2 (loopback interface) for the group range" " 224.0.0.0/4")
549 step("Enable the PIM on all the interfaces of r1, r2, r3 and r4 routers")
550 step("Send multicast traffic from R3")
551
552 step("r2: Verify RP info")
553 dut = "r2"
554 rp_address = "1.0.2.17"
555 iif = "lo"
556 result = verify_pim_rp_info(
557 tgen, TOPO, dut, GROUP_RANGE_ALL, iif, rp_address, SOURCE
558 )
559 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
560
561 step("r0: Send IGMP join")
562 result = app_helper.run_join("r0", GROUP_ADDRESS, "r1")
563 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
564
565 step("r1: Verify IGMP groups")
566 dut = "r1"
567 oif = "r1-r0-eth0"
568 result = verify_igmp_groups(tgen, dut, oif, GROUP_ADDRESS)
569 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
570
571 step("r5: Send multicast traffic for group 225.1.1.1")
572 result = app_helper.run_traffic("r5", GROUP_ADDRESS, "r3")
573 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
574
575 step("r1: Verify (*, G) upstream IIF interface")
576 dut = "r1"
577 iif = "r1-r2-eth1"
578 result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS)
579 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
580
581 step("r1: Verify (*, G) upstream join state and join timer")
582 result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS)
583 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
584
585 step("r1: Verify (*, G) ip mroutes")
586 result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif)
587 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
588
589 step("r1: Verify (S, G) upstream IIF interface")
590 iif = "r1-r2-eth1"
591 result = verify_upstream_iif(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS)
592 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
593
594 step("r1: Verify (S, G) upstream join state and join timer")
595 result = verify_join_state_and_timer(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS)
596 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
597
598 step("r1: Verify (S, G) ip mroutes")
599 result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, GROUP_ADDRESS, iif, oif)
600 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
601
602 step("r2: Verify (*, G) upstream IIF interface")
603 dut = "r2"
604 iif = "lo"
605 result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS)
606 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
607
608 step("r2: Verify (*, G) upstream join state and join timer")
609 result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS)
610 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
611
612 step("r2: Verify (*, G) ip mroutes")
613 oif = "r2-r1-eth0"
614 result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif)
615 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
616
617 step("r2: Verify (S, G) upstream IIF interface")
618 iif = "r2-r3-eth1"
619 result = verify_upstream_iif(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS)
620 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
621
622 step("r2: Verify (S, G) upstream join state and join timer")
623 result = verify_join_state_and_timer(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS)
624 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
625
626 step("r2: Verify (S, G) ip mroutes")
627 result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, GROUP_ADDRESS, iif, oif)
628 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
629
630 step("r3: Verify (S, G) upstream IIF interface")
631 dut = "r3"
632 iif = "r3-r5-eth3"
633 result = verify_upstream_iif(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS)
634 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
635
636 step("r3: Verify (S, G) upstream join state and join timer")
637 result = verify_join_state_and_timer(
638 tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS, expected=False
639 )
640 assert result is not True, (
641 "Testcase {} : Failed \n "
642 "Expected: [{}]: Upstream Join State timer should not run\n "
643 "Found: {}".format(tc_name, dut, result)
644 )
645
646 step("r3: Verify (S, G) ip mroutes")
647 oif = "r3-r2-eth1"
648 result = verify_mroutes(tgen, dut, SOURCE_ADDRESS, GROUP_ADDRESS, iif, oif)
649 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
650
651 # Uncomment next line for debugging
652 # tgen.mininet_cli()
653
654 write_test_footer(tc_name)
655
656
657 def test_not_reachable_static_RP_p0(request):
658 """
659 TC_5_P0: Verify OIF entry for RP is cleared when RP becomes unreachable
660 TC_6_P0: Verify IIF and OIL in "show ip pim state" updated properly when
661 RP becomes unreachable
662 TC_7_P0 : Verify upstream interfaces(IIF) and join state are updated
663 properly after adding and deleting the static RP
664 TC_8_P0: Verify (*,G) prune is send towards the RP when RP becomes
665 unreachable
666
667 Topology used:
668 r0------r1-----r2
669 iperf DUT RP
670 """
671
672 tgen = get_topogen()
673 tc_name = request.node.name
674 write_test_header(tc_name)
675
676 # Don"t run this test if we have any failure.
677 if tgen.routers_have_failure():
678 pytest.skip(tgen.errors)
679
680 step("Creating configuration from JSON")
681 reset_config_on_routers(tgen)
682 app_helper.stop_all_hosts()
683 clear_mroute(tgen)
684 clear_pim_interface_traffic(tgen, TOPO)
685
686 dut = "r1"
687 intf = "r1-r3-eth2"
688 shutdown_bringup_interface(tgen, dut, intf, False)
689
690 dut = "r1"
691 intf = "r1-r4-eth3"
692 shutdown_bringup_interface(tgen, dut, intf, False)
693
694 step(
695 "r1: (*,G) prune is not sent towards the RP interface, verify using"
696 "show ip pim interface traffic"
697 )
698 state_dict = {"r1": {"r1-r2-eth1": ["pruneTx"]}}
699 state_before = get_pim_interface_traffic(tgen, state_dict)
700 assert isinstance(
701 state_before, dict
702 ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
703 tc_name, state_before
704 )
705
706 step("Enable IGMP on r1 interface and send IGMP " "join (225.1.1.1) to r1")
707 step("Configure r2 loopback interface as RP")
708 step("Enable PIM between r1 and r2")
709
710 step("r0 : Send IGMP join")
711 result = app_helper.run_join("r0", GROUP_ADDRESS, "r1")
712 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
713
714 step("r1 : Verify rp info")
715 dut = "r1"
716 iif = "r1-r2-eth1"
717 rp_address = "1.0.2.17"
718 result = verify_pim_rp_info(
719 tgen, TOPO, dut, GROUP_RANGE_ALL, iif, rp_address, SOURCE
720 )
721 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
722
723 step("r1: Verify IGMP groups")
724 oif = "r1-r0-eth0"
725 result = verify_igmp_groups(tgen, dut, oif, GROUP_ADDRESS)
726 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
727
728 step("r1: Verify PIM state")
729 result = verify_pim_state(tgen, dut, iif, oif, GROUP_ADDRESS)
730 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
731
732 step("r1: Verify upstream IIF interface")
733 result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS)
734 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
735
736 step("r1: Verify upstream join state and join timer")
737 result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS)
738 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
739
740 step("r1 :Verify ip mroutes")
741 result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif)
742 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
743
744 step("r1: Make RP un-reachable")
745 dut = "r1"
746 input_dict = {
747 dut: {
748 "static_routes": [
749 {"network": "1.0.2.17/32", "next_hop": "10.0.1.2", "delete": True}
750 ]
751 }
752 }
753
754 result = create_static_routes(tgen, input_dict)
755 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
756
757 step("r1: Check RP detail using show ip pim rp-info OIF should be unknown")
758 result = verify_pim_rp_info(
759 tgen, TOPO, dut, GROUP_RANGE_ALL, "Unknown", rp_address, SOURCE
760 )
761 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
762
763 step(
764 "r1 : OIL should be same and IIF should be cleared on R1 verify"
765 "using show ip pim state"
766 )
767 result = verify_pim_state(tgen, dut, iif, oif, GROUP_ADDRESS, expected=False)
768 assert result is not True, (
769 "Testcase {} : Failed \n "
770 "Expected: [{}]: OIL should be same and IIF should be cleared\n "
771 "Found: {}".format(tc_name, dut, result)
772 )
773
774 step("r1: upstream IIF should be unknown , verify using show ip pim" "upstream")
775 result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS, expected=False)
776 assert result is not True, (
777 "Testcase {} : Failed \n "
778 "Expected: [{}]: Upstream IIF interface {} should be unknown \n "
779 "Found: {}".format(tc_name, dut, iif, result)
780 )
781
782 step(
783 "r1: join state should not be joined and join timer should stop,"
784 "verify using show ip pim upstream"
785 )
786 result = verify_join_state_and_timer(
787 tgen, dut, iif, STAR, GROUP_ADDRESS, expected=False
788 )
789 assert result is not True, (
790 "Testcase {} : Failed \n "
791 "Expected: [{}]: Upstream Join State timer should not run\n "
792 "Found: {}".format(tc_name, dut, result)
793 )
794
795 step(
796 "r1: (*,G) prune is sent towards the RP interface, verify using"
797 "show ip pim interface traffic"
798 )
799 state_after = get_pim_interface_traffic(tgen, state_dict)
800 assert isinstance(
801 state_after, dict
802 ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
803 tc_name, result
804 )
805
806 result = verify_state_incremented(state_before, state_after)
807 assert result is True, "Testcase{} : Failed Error: {}".format(tc_name, result)
808
809 step("r1: (*, G) cleared from mroute table using show ip mroute")
810 result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif, expected=False)
811 assert result is not True, (
812 "Testcase {} : Failed \n "
813 "Expected: [{}]: mroute (*, G) should be cleared from mroute table\n "
814 "Found: {}".format(tc_name, dut, result)
815 )
816
817 # Uncomment next line for debugging
818 # tgen.mininet_cli()
819
820 write_test_footer(tc_name)
821
822
823 def test_add_RP_after_join_received_p1(request):
824 """
825 TC_9_P1 : Verify RP configured after IGMP join received, PIM join towards
826 RP is sent immediately
827
828 Topology used:
829 r0------r1-----r2
830 iperf DUT RP
831 """
832
833 tgen = get_topogen()
834 tc_name = request.node.name
835 write_test_header(tc_name)
836
837 # Don"t run this test if we have any failure.
838 if tgen.routers_have_failure():
839 pytest.skip(tgen.errors)
840
841 step("Creating configuration from JSON")
842 reset_config_on_routers(tgen)
843 app_helper.stop_all_hosts()
844 clear_mroute(tgen)
845 clear_pim_interface_traffic(tgen, TOPO)
846
847 step("Enable IGMP on R1 interface")
848 step("Configure r2 loopback interface as RP")
849 step("Enable PIM between r1 and r2")
850 step("Delete RP configuration from r1")
851
852 step("r1: Delete RP configuration")
853 input_dict = {
854 "r1": {
855 "pim": {
856 "rp": [
857 {
858 "rp_addr": "1.0.2.17",
859 "group_addr_range": GROUP_RANGE_ALL,
860 "delete": True,
861 }
862 ]
863 }
864 }
865 }
866
867 result = create_pim_config(tgen, TOPO, input_dict)
868 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
869
870 step("r1: Verify rp-info")
871 dut = "r1"
872 rp_address = "1.0.2.17"
873 iif = "r1-r2-eth1"
874 result = verify_pim_rp_info(
875 tgen, TOPO, dut, GROUP_RANGE_ALL, iif, rp_address, SOURCE, expected=False
876 )
877 assert result is not True, (
878 "Testcase {} : Failed \n "
879 "Expected: [{}]: RP-info should not be present \n "
880 "Found: {}".format(tc_name, dut, result)
881 )
882
883 step("joinTx value before join sent")
884 state_dict = {"r1": {"r1-r2-eth1": ["joinTx"]}}
885 state_before = get_pim_interface_traffic(tgen, state_dict)
886 assert isinstance(
887 state_before, dict
888 ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
889 tc_name, result
890 )
891
892 step("r0 : Send IGMP join (225.1.1.1) to r1, when rp is not configured" "in r1")
893 result = app_helper.run_join("r0", GROUP_ADDRESS, "r1")
894 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
895
896 step("r1: IGMP group is received on R1 verify using show ip igmp groups")
897 oif = "r1-r0-eth0"
898 result = verify_igmp_groups(tgen, dut, oif, GROUP_ADDRESS)
899 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
900
901 step("r1: Verify upstream IIF interface")
902 result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS, expected=False)
903 assert result is not True, (
904 "Testcase {} : Failed \n "
905 "Expected: [{}]: Upstream IIF interface {} should not be present \n "
906 "Found: {}".format(tc_name, dut, iif, result)
907 )
908
909 step("r1: Verify upstream join state and join timer")
910
911 result = verify_join_state_and_timer(
912 tgen, dut, iif, STAR, GROUP_ADDRESS, expected=False
913 )
914 assert result is not True, (
915 "Testcase {} : Failed \n "
916 "Expected: [{}]: Upstream Join State timer should not run\n "
917 "Found: {}".format(tc_name, dut, result)
918 )
919
920 step("r1: Verify PIM state")
921 result = verify_pim_state(tgen, dut, iif, oif, GROUP_ADDRESS, expected=False)
922 assert result is not True, (
923 "Testcase {} : Failed \n "
924 "Expected: [{}]: PIM state should not be up\n "
925 "Found: {}".format(tc_name, dut, result)
926 )
927
928 step("r1: Verify ip mroutes")
929 result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif, expected=False)
930 assert result is not True, (
931 "Testcase {} : Failed \n "
932 "Expected: [{}]: mroute (*, G) should not be present in mroute table \n "
933 "Found: {}".format(tc_name, dut, result)
934 )
935
936 step("r1: Configure static RP")
937 input_dict = {
938 "r1": {
939 "pim": {
940 "rp": [
941 {
942 "rp_addr": "1.0.2.17",
943 "group_addr_range": GROUP_RANGE_ALL,
944 }
945 ]
946 }
947 }
948 }
949
950 result = create_pim_config(tgen, TOPO, input_dict)
951 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
952
953 step("r1: Verify rp-info")
954 result = verify_pim_rp_info(
955 tgen, TOPO, dut, GROUP_RANGE_ALL, iif, rp_address, SOURCE
956 )
957 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
958
959 step("r1: Verify upstream IIF interface")
960 result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS)
961 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
962
963 step("r1 : Verify upstream join state and join timer")
964 result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS)
965 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
966
967 step("r1: Verify PIM state")
968 result = verify_pim_state(tgen, dut, iif, oif, GROUP_ADDRESS)
969 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
970
971 step("r1 : Verify ip mroutes")
972 result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif)
973 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
974 logger.info("Expected behavior: %s", result)
975
976 state_after = get_pim_interface_traffic(tgen, state_dict)
977 assert isinstance(
978 state_after, dict
979 ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
980 tc_name, result
981 )
982
983 result = verify_state_incremented(state_before, state_after)
984 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
985
986 # Uncomment next line for debugging
987 # tgen.mininet_cli()
988
989 write_test_footer(tc_name)
990
991
992 def test_reachable_static_RP_after_join_p0(request):
993 """
994 TC_10_P0 : Verify RP becomes reachable after IGMP join received, PIM join
995 towards RP is sent immediately
996
997 Topology used:
998 r0------r1-----r3
999 iperf DUT RP
1000 """
1001 tgen = get_topogen()
1002 tc_name = request.node.name
1003 write_test_header(tc_name)
1004
1005 # Don"t run this test if we have any failure.
1006 if tgen.routers_have_failure():
1007 pytest.skip(tgen.errors)
1008
1009 step("Creating configuration from JSON")
1010 reset_config_on_routers(tgen)
1011 app_helper.stop_all_hosts()
1012 clear_mroute(tgen)
1013 clear_pim_interface_traffic(tgen, TOPO)
1014
1015 step("Enable IGMP on r1 interface and send IGMP " "join (225.1.1.1) to r1")
1016 step("Configure r2 loopback interface as RP")
1017 step("Enable PIM between r1 and r2")
1018
1019 step("r1 : Verify pim interface traffic")
1020 state_dict = {"r1": {"r1-r2-eth1": ["joinTx"]}}
1021 state_before = get_pim_interface_traffic(tgen, state_dict)
1022 assert isinstance(
1023 state_before, dict
1024 ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
1025 tc_name, state_before
1026 )
1027
1028 step("r1: Make RP un-reachable")
1029 dut = "r1"
1030 intf = "r1-r2-eth1"
1031 shutdown_bringup_interface(tgen, dut, intf, False)
1032 intf = "r1-r3-eth2"
1033 shutdown_bringup_interface(tgen, dut, intf, False)
1034 intf = "r1-r4-eth3"
1035 shutdown_bringup_interface(tgen, dut, intf, False)
1036
1037 step("r1: Verify rp-info")
1038 rp_address = "1.0.2.17"
1039 result = verify_pim_rp_info(
1040 tgen, TOPO, dut, GROUP_ADDRESS, "Unknown", rp_address, SOURCE
1041 )
1042 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1043
1044 step("r1 : Send IGMP join for 225.1.1.1")
1045 result = app_helper.run_join("r0", GROUP_ADDRESS, "r1")
1046 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1047
1048 step("r1 : Verify IGMP groups")
1049 oif = "r1-r0-eth0"
1050 result = verify_igmp_groups(tgen, dut, oif, GROUP_ADDRESS)
1051 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1052
1053 step("r1 : Verify upstream IIF interface")
1054 iif = "r1-r2-eth1"
1055 result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS, expected=False)
1056 assert result is not True, (
1057 "Testcase {} : Failed \n "
1058 "Expected: [{}]: Upstream IIF interface {} should not be present \n "
1059 "Found: {}".format(tc_name, dut, iif, result)
1060 )
1061
1062 step("r1 : Verify upstream join state and join timer")
1063 result = verify_join_state_and_timer(
1064 tgen, dut, iif, STAR, GROUP_ADDRESS, expected=False
1065 )
1066 assert result is not True, (
1067 "Testcase {} : Failed \n "
1068 "Expected: [{}]: Upstream Join State timer should not run\n "
1069 "Found: {}".format(tc_name, dut, result)
1070 )
1071
1072 step("r1 : Verify PIM state")
1073 result = verify_pim_state(tgen, dut, iif, oif, GROUP_ADDRESS, expected=False)
1074 assert result is not True, (
1075 "Testcase {} : Failed \n "
1076 "Expected: [{}]: PIM state should not be up \n "
1077 "Found: {}".format(tc_name, dut, result)
1078 )
1079
1080 step("r1 : Verify ip mroutes")
1081 result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif, expected=False)
1082 assert result is not True, (
1083 "Testcase {} : Failed \n "
1084 "Expected: [{}]: mroute (*, G) should not be present \n "
1085 "Found: {}".format(tc_name, dut, result)
1086 )
1087
1088 step("r1: Make RP reachable")
1089 intf = "r1-r2-eth1"
1090 shutdown_bringup_interface(tgen, dut, intf, True)
1091 intf = "r1-r3-eth2"
1092 shutdown_bringup_interface(tgen, dut, intf, True)
1093 intf = "r1-r4-eth3"
1094 shutdown_bringup_interface(tgen, dut, intf, True)
1095
1096 step("r1 : Verify rp-info")
1097 result = verify_pim_rp_info(
1098 tgen, TOPO, dut, GROUP_RANGE_ALL, iif, rp_address, SOURCE
1099 )
1100 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1101
1102 step("r1: Verify upstream IIF interface")
1103 result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS)
1104 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1105
1106 step("r1 : Verify upstream join state and join timer")
1107 result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS)
1108 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1109
1110 step("r1 : Verify PIM state")
1111 result = verify_pim_state(tgen, dut, iif, oif, GROUP_ADDRESS)
1112 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1113
1114 step("r1 : Verify ip mroutes")
1115 result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif)
1116 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1117 logger.info("Expected behavior: %s", result)
1118
1119 step("r1 : Verify pim interface traffic")
1120 state_after = get_pim_interface_traffic(tgen, state_dict)
1121 assert isinstance(
1122 state_after, dict
1123 ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
1124 tc_name, result
1125 )
1126
1127 result = verify_state_incremented(state_before, state_after)
1128 assert result is True, "Testcase{} : Failed Error: {}".format(tc_name, result)
1129
1130 # Uncomment next line for debugging
1131 # tgen.mininet_cli()
1132
1133 write_test_footer(tc_name)
1134
1135
1136 def test_send_join_on_higher_preffered_rp_p1(request):
1137 """
1138 TC_11_P1 : Verify PIM join send towards the higher preferred RP
1139 TC_12_P1 : Verify PIM prune send towards the lower preferred RP
1140 TC_13_P1 : Verify RPF interface is updated in mroute (kernel) when higher
1141 preferred overlapping RP configured
1142 TC_14_P1 : Verify IIF and OIL in "show ip pim state" updated properly when
1143 higher preferred overlapping RP configured
1144 TC_15_P1 : Verify upstream interfaces(IIF) and join state are updated when
1145 higher preferred overlapping RP is configured
1146 TC_16_P1 : Verify join is send to lower preferred RP, when higher
1147 preferred RP gets deleted
1148 TC_17_P1 : Verify prune is send to higher preferred RP when higher
1149 preferred RP gets deleted
1150 TC_18_P1 : Verify RPF interface updated in mroute when higher preferred RP
1151 gets deleted
1152 TC_19_P1 : Verify IIF and OIL in "show ip pim state" updated when higher
1153 preferred overlapping RP is deleted
1154 TC_20_P1 : Verify PIM upstream IIF updated when higher preferred
1155 overlapping RP deleted
1156
1157 Topology used:
1158 _______r2
1159 |
1160 iperf |
1161 r0-----r1
1162 |
1163 |_______r4
1164 """
1165
1166 tgen = get_topogen()
1167 tc_name = request.node.name
1168 write_test_header(tc_name)
1169
1170 # Don"t run this test if we have any failure.
1171 if tgen.routers_have_failure():
1172 pytest.skip(tgen.errors)
1173
1174 step("Creating configuration from JSON")
1175 reset_config_on_routers(tgen)
1176 app_helper.stop_all_hosts()
1177 clear_mroute(tgen)
1178 clear_pim_interface_traffic(tgen, TOPO)
1179
1180 step("Enable IGMP on r1 interface")
1181 step("Configure RP on r2 (loopback interface) for the group range " "224.0.0.0/4")
1182 step("Configure RP on r4 (loopback interface) for the group range " "225.1.1.1/32")
1183
1184 step("r3 : Make all interface not reachable")
1185 dut = "r3"
1186 intf = "r3-r1-eth0"
1187 shutdown_bringup_interface(tgen, dut, intf, False)
1188 intf = "r3-r2-eth1"
1189 shutdown_bringup_interface(tgen, dut, intf, False)
1190 intf = "r3-r4-eth2"
1191 shutdown_bringup_interface(tgen, dut, intf, False)
1192
1193 dut = "r2"
1194 intf = "r2-r3-eth1"
1195 shutdown_bringup_interface(tgen, dut, intf, False)
1196
1197 dut = "r4"
1198 intf = "r4-r3-eth1"
1199 shutdown_bringup_interface(tgen, dut, intf, False)
1200
1201 dut = "r1"
1202 intf = "r1-r3-eth2"
1203 shutdown_bringup_interface(tgen, dut, intf, False)
1204
1205 step("r1 : Verify joinTx count before sending join")
1206 state_dict = {"r1": {"r1-r4-eth3": ["joinTx"], "r1-r2-eth1": ["pruneTx"]}}
1207
1208 state_before = get_pim_interface_traffic(tgen, state_dict)
1209 assert isinstance(
1210 state_before, dict
1211 ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
1212 tc_name, state_before
1213 )
1214
1215 step("r0 : Send IGMP join for 225.1.1.1")
1216 result = app_helper.run_join("r0", GROUP_ADDRESS, "r1")
1217 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1218
1219 step("r1 : Verify IGMP groups")
1220 dut = "r1"
1221 oif = "r1-r0-eth0"
1222 result = verify_igmp_groups(tgen, dut, oif, GROUP_ADDRESS)
1223 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1224
1225 step("Configure static RP for group 225.1.1.1/32")
1226 input_dict = {
1227 "r4": {
1228 "pim": {
1229 "rp": [
1230 {
1231 "rp_addr": "1.0.4.17",
1232 "group_addr_range": ["225.1.1.1/32"],
1233 }
1234 ]
1235 }
1236 }
1237 }
1238
1239 result = create_pim_config(tgen, TOPO, input_dict)
1240 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1241
1242 step("r1 : Verify RP info for group 224.0.0.0/4")
1243 rp_address_1 = "1.0.2.17"
1244 iif = "r1-r2-eth1"
1245 result = verify_pim_rp_info(
1246 tgen, TOPO, dut, GROUP_RANGE_ALL, iif, rp_address_1, SOURCE
1247 )
1248 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1249
1250 step("r1 : Verify RP info for group 225.1.1.1")
1251 rp_address_2 = "1.0.4.17"
1252 iif = "r1-r4-eth3"
1253 result = verify_pim_rp_info(tgen, TOPO, dut, GROUP_RANGE, iif, rp_address_2, SOURCE)
1254 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1255
1256 step("r1 : Verify join is sent to higher preferred RP")
1257 step("r1 : Verify prune is sent to lower preferred RP")
1258 state_after = get_pim_interface_traffic(tgen, state_dict)
1259 assert isinstance(
1260 state_after, dict
1261 ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
1262 tc_name, result
1263 )
1264
1265 result = verify_state_incremented(state_before, state_after)
1266 assert result is True, "Testcase{} : Failed Error: {}".format(tc_name, result)
1267
1268 step("r1 : Verify ip mroutes")
1269 iif = "r1-r4-eth3"
1270 result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif)
1271 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1272
1273 step("r1 : Verify PIM state")
1274 result = verify_pim_state(tgen, dut, iif, oif, GROUP_ADDRESS)
1275 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1276
1277 step("r1 : Verify upstream IIF interface")
1278 result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS)
1279 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1280
1281 step("r1 : Verify upstream join state and join timer")
1282 result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS)
1283 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1284
1285 clear_pim_interface_traffic(tgen, TOPO)
1286
1287 step("r1 : Verify joinTx, pruneTx count before RP gets deleted")
1288 state_dict = {"r1": {"r1-r2-eth1": ["joinTx"], "r1-r4-eth3": ["pruneTx"]}}
1289
1290 state_before = get_pim_interface_traffic(tgen, state_dict)
1291 assert isinstance(
1292 state_before, dict
1293 ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
1294 tc_name, result
1295 )
1296
1297 step("r1 : Delete RP configuration for 225.1.1.1")
1298 input_dict = {
1299 "r1": {
1300 "pim": {
1301 "rp": [
1302 {
1303 "rp_addr": "1.0.4.17",
1304 "group_addr_range": ["225.1.1.1/32"],
1305 "delete": True,
1306 }
1307 ]
1308 }
1309 }
1310 }
1311
1312 result = create_pim_config(tgen, TOPO, input_dict)
1313 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1314
1315 step("r1 : Verify rp-info for group 224.0.0.0/4")
1316 iif = "r1-r2-eth1"
1317 result = verify_pim_rp_info(
1318 tgen, TOPO, dut, GROUP_RANGE_ALL, iif, rp_address_1, SOURCE
1319 )
1320 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1321
1322 step("r1 : Verify rp-info for group 225.1.1.1")
1323 iif = "r1-r4-eth3"
1324 result = verify_pim_rp_info(
1325 tgen, TOPO, dut, GROUP_RANGE, oif, rp_address_2, SOURCE, expected=False
1326 )
1327 assert result is not True, (
1328 "Testcase {} : Failed \n "
1329 "Expected: [{}]: RP-info should not be present \n "
1330 "Found: {}".format(tc_name, dut, result)
1331 )
1332
1333 step(
1334 "r1 : Verify RPF interface updated in mroute when higher preferred"
1335 "RP gets deleted"
1336 )
1337 iif = "r1-r2-eth1"
1338 result = verify_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif)
1339 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1340 logger.info("Expected behavior: %s", result)
1341
1342 step(
1343 "r1 : Verify IIF and OIL in show ip pim state updated when higher"
1344 "preferred overlapping RP is deleted"
1345 )
1346 result = verify_pim_state(tgen, dut, iif, oif, GROUP_ADDRESS)
1347 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1348
1349 step(
1350 "r1 : Verify upstream IIF updated when higher preferred overlapping"
1351 "RP deleted"
1352 )
1353 result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS)
1354 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1355
1356 step(
1357 "r1 : Verify upstream join state and join timer updated when higher"
1358 "preferred overlapping RP deleted"
1359 )
1360 result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS)
1361 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1362
1363 step(
1364 "r1 : Verify join is sent to lower preferred RP, when higher"
1365 "preferred RP gets deleted"
1366 )
1367 step(
1368 "r1 : Verify prune is sent to higher preferred RP when higher"
1369 " preferred RP gets deleted"
1370 )
1371 state_after = get_pim_interface_traffic(tgen, state_dict)
1372 assert isinstance(
1373 state_after, dict
1374 ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
1375 tc_name, result
1376 )
1377
1378 result = verify_state_incremented(state_before, state_after)
1379 assert result is True, "Testcase{} : Failed Error: {}".format(tc_name, result)
1380
1381 # Uncomment next line for debugging
1382 # tgen.mininet_cli()
1383
1384 write_test_footer(tc_name)
1385
1386
1387 if __name__ == "__main__":
1388 ARGS = ["-s"] + sys.argv[1:]
1389 sys.exit(pytest.main(ARGS))