2 # SPDX-License-Identifier: ISC
5 # Copyright (c) 2019 by VMware, Inc. ("VMware")
6 # Used Copyright (c) 2018 by Network Device Education Foundation,
7 # Inc. ("NetDEF") in this file.
11 Following tests are covered to test Multicast basic functionality:
18 r0-----r1-------------r3-----r5
24 - Create topology (setup module)
27 TC_1 : Verify upstream interfaces(IIF) and join state are updated properly
28 after adding and deleting the static RP
29 TC_2 : Verify IIF and OIL in "show ip pim state" updated properly after
30 adding and deleting the static RP
31 TC_3: (*, G) Mroute entry are cleared when static RP gets deleted
32 TC_4: Verify (*,G) prune is send towards the RP after deleting the static RP
33 TC_5: Verify OIF entry for RP is cleared when RP becomes unreachable
34 TC_6: Verify IIF and OIL in "show ip pim state" updated properly when RP
36 TC_7 : Verify upstream interfaces(IIF) and join state are updated properly
37 after adding and deleting the static RP
38 TC_8: Verify (*,G) prune is send towards the RP when RP becomes unreachable
39 TC_9 : Verify RP configured after IGMP join received, PIM join towards RP is
41 TC_10 : Verify RP becomes reachable after IGMP join received, PIM join
42 towards RP is sent immediately
43 TC_11 : Verify PIM join send towards the higher preferred RP
44 TC_12 : Verify PIM prune send towards the lower preferred RP
45 TC_13 : Verify RPF interface is updated in mroute (kernel) when higher
46 preferred overlapping RP configured
47 TC_14 : Verify IIF and OIL in "show ip pim state" updated properly when higher
48 preferred overlapping RP configured
49 TC_15 : Verify upstream interfaces(IIF) and join state are updated when higher
50 preferred overlapping RP is configured
51 TC_16 : Verify join is send to lower preferred RP, when higher preferred RP
53 TC_17 : Verify prune is send to higher preferred RP when higher preferred RP
55 TC_18 : Verify RPF interface updated in mroute when higher preferred RP gets
57 TC_19 : Verify IIF and OIL in "show ip pim state" updated when higher
58 preferred overlapping RP is deleted
59 TC_20 : Verify PIM upstream IIF updated when higher preferred overlapping RP
61 TC_21_1 : Verify OIF and RFP for (*,G) and (S,G) when static RP configure in
63 TC_21_2 : Verify OIF and RFP for (*,G) and (S,G) when static RP configure in
65 TC_22_1 : Verify OIF and RPF for (*,G) and (S,G) when static RP configure in
67 TC_22_2 : Verify OIF and RPF for (*,G) and (S,G) when static RP configure in
69 TC_23 : Verify (*,G) and (S,G) populated correctly when RPT and SPT path are
71 TC_24 : Verify (*,G) and (S,G) populated correctly when SPT and RPT share the
73 TC_25 : Verify (*,G) and (S,G) populated correctly after clearing the PIM ,
74 IGMP and mroutes joins
75 TC_26 : Restart the PIMd process and verify PIM joins , and mroutes entries
76 TC_27 : Configure multiple groups (10 grps) with same RP address
77 TC_28 : Configure multiple groups (10 grps) with different RP address
78 TC_29 : Verify IIF and OIL in updated in mroute when upstream interface
80 TC_30 : Verify IIF and OIL change to other path after shut the primary path
81 TC_31 : Verify RP info and (*,G) mroute after deleting the RP and shut / no
82 shut the RPF interface.
83 TC_32 : Verify RP info and (*,G) mroute after deleting the RP and shut / no
84 shut the RPF interface
90 from time
import sleep
94 # Save the Current Working Directory to find configuration files.
95 CWD
= os
.path
.dirname(os
.path
.realpath(__file__
))
96 sys
.path
.append(os
.path
.join(CWD
, "../"))
97 sys
.path
.append(os
.path
.join(CWD
, "../lib/"))
99 # Required to instantiate the topology builder class.
101 # pylint: disable=C0413
102 # Import topogen and topotest helpers
104 from lib
.topogen
import Topogen
, get_topogen
105 from lib
.topolog
import logger
106 from lib
.topojson
import build_topo_from_json
, build_config_from_json
108 from lib
.common_config
import (
112 reset_config_on_routers
,
114 shutdown_bringup_interface
,
116 start_router_daemons
,
117 create_static_routes
,
120 from lib
.pim
import (
124 verify_join_state_and_timer
,
126 verify_pim_neighbors
,
127 get_pim_interface_traffic
,
130 clear_pim_interface_traffic
,
131 clear_igmp_interfaces
,
132 clear_pim_interfaces
,
138 pytestmark
= [pytest
.mark
.pimd
, pytest
.mark
.staticd
]
142 GROUP_RANGE_ALL
= "224.0.0.0/4"
143 GROUP_RANGE
= "225.1.1.1/32"
144 GROUP_RANGE_LIST_1
= [
151 GROUP_RANGE_LIST_2
= [
158 GROUP_ADDRESS
= "225.1.1.1"
159 GROUP_ADDRESS_LIST_1
= ["225.1.1.1", "225.1.1.2", "225.1.1.3", "225.1.1.4", "225.1.1.5"]
160 GROUP_ADDRESS_LIST_2
= [
168 SOURCE_ADDRESS
= "10.0.6.2"
172 def build_topo(tgen
):
175 # Building topology from json file
176 build_topo_from_json(tgen
, TOPO
)
179 def setup_module(mod
):
181 Sets up the pytest environment
186 testsuite_run_time
= time
.asctime(time
.localtime(time
.time()))
187 logger
.info("Testsuite start time: %s", testsuite_run_time
)
188 logger
.info("=" * 40)
195 r0-----r1-------------r3-----r5
201 logger
.info("Master Topology: \n %s", topology
)
203 logger
.info("Running setup_module to create topology")
205 # This function initiates the topology build with Topogen...
206 json_file
= "{}/multicast_pim_static_rp.json".format(CWD
)
207 tgen
= Topogen(json_file
, mod
.__name
__)
209 TOPO
= tgen
.json_topo
211 # ... and here it calls Mininet initialization functions.
213 # Starting topology, create tmp files which are loaded to routers
214 # to start daemons and then start routers
217 # Don"t run this test if we have any failure.
218 if tgen
.routers_have_failure():
219 pytest
.skip(tgen
.errors
)
221 # Creating configuration from JSON
222 build_config_from_json(tgen
, TOPO
)
224 # Verify PIM neighbors
225 result
= verify_pim_neighbors(tgen
, TOPO
)
226 assert result
is True, "setup_module :Failed \n Error:" " {}".format(result
)
228 # XXX Replace this using "with McastTesterHelper()... " in each test if possible.
230 app_helper
= McastTesterHelper(tgen
)
232 logger
.info("Running setup_module() done")
235 def teardown_module():
236 """Teardown the pytest environment"""
238 logger
.info("Running teardown_module to delete topology")
244 # Stop toplogy and Remove tmp files
247 logger
.info("Testsuite end time: %s", time
.asctime(time
.localtime(time
.time())))
248 logger
.info("=" * 40)
251 #####################################################
255 #####################################################
258 def verify_mroute_repopulated(uptime_before
, uptime_after
):
260 API to compare uptime for mroutes
264 * `uptime_before` : Uptime dictionary for any particular instance
265 * `uptime_after` : Uptime dictionary for any particular instance
268 for group
in uptime_before
.keys():
269 for source
in uptime_before
[group
].keys():
270 if set(uptime_before
[group
]) != set(uptime_after
[group
]):
272 "mroute (%s, %s) has not come"
273 " up after mroute clear [FAILED!!]" % (source
, group
)
277 d_1
= datetime
.datetime
.strptime(uptime_before
[group
][source
], "%H:%M:%S")
278 d_2
= datetime
.datetime
.strptime(uptime_after
[group
][source
], "%H:%M:%S")
280 errormsg
= "mroute (%s, %s) is not " "repopulated [FAILED!!]" % (
286 logger
.info("mroute (%s, %s) is " "repopulated [PASSED!!]", source
, group
)
291 def verify_state_incremented(state_before
, state_after
):
293 API to compare interface traffic state incrementing
297 * `state_before` : State dictionary for any particular instance
298 * `state_after` : State dictionary for any particular instance
301 for router
, state_data
in state_before
.items():
302 for state
, _
in state_data
.items():
303 if state_before
[router
][state
] >= state_after
[router
][state
]:
305 "[DUT: %s]: state %s value has not"
306 " incremented, Initial value: %s, "
307 "Current value: %s [FAILED!!]"
311 state_before
[router
][state
],
312 state_after
[router
][state
],
318 "[DUT: %s]: State %s value is "
319 "incremented, Initial value: %s, Current value: %s"
323 state_before
[router
][state
],
324 state_after
[router
][state
],
330 def test_add_delete_static_RP_p0(request
):
332 TC_1_P0 : Verify upstream interfaces(IIF) and join state are updated
333 properly after adding and deleting the static RP
334 TC_2_P0 : Verify IIF and OIL in "show ip pim state" updated properly
335 after adding and deleting the static RP
336 TC_3_P0: (*, G) Mroute entry are cleared when static RP gets deleted
337 TC_4_P0: Verify (*,G) prune is send towards the RP after deleting the
346 tc_name
= request
.node
.name
347 write_test_header(tc_name
)
349 # Don"t run this test if we have any failure.
350 if tgen
.routers_have_failure():
351 pytest
.skip(tgen
.errors
)
353 step("pre-configuration to send IGMP join and multicast traffic")
355 step("Enable IGMP on r1 interface and send IGMP " "join (225.1.1.1) to r1")
356 step("Configure r2 loopback interface as RP")
357 step("Enable PIM between r1 and r3")
359 step("r1: Verify show ip igmp group without any IGMP join")
361 interface
= "r1-r0-eth0"
362 result
= verify_igmp_groups(tgen
, dut
, interface
, GROUP_ADDRESS
, expected
=False)
363 assert result
is not True, (
364 "Testcase {} : Failed \n "
365 "Expected: [{}]: IGMP groups should not be present without any IGMP join\n "
366 "Found: {}".format(tc_name
, dut
, result
)
369 step("r1: Verify show ip pim interface traffic without any IGMP join")
370 state_dict
= {"r1": {"r1-r2-eth1": ["pruneTx"]}}
372 state_before
= get_pim_interface_traffic(tgen
, state_dict
)
375 ), "Testcase {} : Failed \n state_before is not dictionary\n Error: {}".format(
379 step("r0 : Send IGMP join")
380 result
= app_helper
.run_join("r0", GROUP_ADDRESS
, "r1")
381 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
383 step("r1: Verify IGMP groups")
385 result
= verify_igmp_groups(tgen
, dut
, oif
, GROUP_ADDRESS
)
386 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
388 step("r1: Verify RP info")
391 rp_address
= "1.0.2.17"
392 result
= verify_pim_rp_info(
393 tgen
, TOPO
, dut
, GROUP_RANGE_ALL
, iif
, rp_address
, SOURCE
395 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
397 step("r1: Verify upstream IIF interface")
398 result
= verify_upstream_iif(tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
)
399 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
401 step("r1: Verify upstream join state and join timer")
402 result
= verify_join_state_and_timer(tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
)
403 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
404 step("r1: Verify ip mroutes")
405 result
= verify_mroutes(tgen
, dut
, STAR
, GROUP_ADDRESS
, iif
, oif
)
406 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
408 step("r1: Verify ip pim join")
409 result
= verify_join_state_and_timer(tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
)
410 step("r1: Delete RP configuration")
412 # Delete RP configuration
418 "rp_addr": "1.0.2.17",
419 "group_addr_range": GROUP_RANGE_ALL
,
427 result
= create_pim_config(tgen
, TOPO
, input_dict
)
428 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
430 step("r1: Verify RP info")
431 result
= verify_pim_rp_info(
432 tgen
, TOPO
, dut
, GROUP_RANGE_ALL
, iif
, rp_address
, SOURCE
, expected
=False
434 assert result
is not True, (
435 "Testcase {} : Failed \n "
436 "Expected: [{}]: RP info should not be present \n "
437 "Found: {}".format(tc_name
, dut
, result
)
440 step("r1: Verify upstream IIF interface")
441 result
= verify_upstream_iif(tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
, expected
=False)
442 assert result
is not True, (
443 "Testcase {} : Failed \n "
444 "Expected: [{}]: Upstream IIF interface {} should not be present\n "
445 "Found: {}".format(tc_name
, dut
, iif
, result
)
448 step("r1: Verify upstream join state and join timer")
449 result
= verify_join_state_and_timer(
450 tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
, expected
=False
452 assert result
is not True, (
453 "Testcase {} : Failed \n "
454 "Expected: [{}]: Upstream Join State timer should not run\n "
455 "Found: {}".format(tc_name
, dut
, result
)
459 step("r1: Verify PIM state")
460 result
= verify_pim_state(tgen
, dut
, iif
, oif
, GROUP_ADDRESS
, expected
=False)
461 assert result
is not True, (
462 "Testcase {} : Failed \n "
463 "Expected: [{}]: PIM state should not be up \n "
464 "Found: {}".format(tc_name
, dut
, result
)
467 step("r1: Verify ip mroutes")
468 result
= verify_mroutes(tgen
, dut
, STAR
, GROUP_ADDRESS
, iif
, oif
, expected
=False)
469 assert result
is not True, (
470 "Testcase {} : Failed \n "
471 "Expected: [{}]: mroute (*, G) should not be present \n "
472 "Found: {}".format(tc_name
, dut
, result
)
475 step("r1: Verify show ip pim interface traffic without any IGMP join")
476 state_after
= get_pim_interface_traffic(tgen
, state_dict
)
479 ), "Testcase {} : Failed \n state_before is not dictionary \n Error: {}".format(
483 result
= verify_state_incremented(state_before
, state_after
)
484 assert result
is True, "Testcase{} : Failed Error: {}".format(tc_name
, result
)
486 # Uncomment next line for debugging
489 write_test_footer(tc_name
)
492 def test_SPT_RPT_path_same_p1(request
):
494 TC_24_P1 : Verify (*,G) and (S,G) populated correctly when SPT and RPT
509 tc_name
= request
.node
.name
510 write_test_header(tc_name
)
512 # Don"t run this test if we have any failure.
513 if tgen
.routers_have_failure():
514 pytest
.skip(tgen
.errors
)
516 step("Creating configuration from JSON")
517 reset_config_on_routers(tgen
)
518 app_helper
.stop_all_hosts()
520 clear_pim_interface_traffic(tgen
, TOPO
)
524 shutdown_bringup_interface(tgen
, dut
, intf
, False)
526 shutdown_bringup_interface(tgen
, dut
, intf
, False)
530 shutdown_bringup_interface(tgen
, dut
, intf
, False)
532 shutdown_bringup_interface(tgen
, dut
, intf
, False)
534 step("Enable IGMP on r1 interface and send IGMP join (225.1.1.1) to R1")
535 step("Configure RP on r2 (loopback interface) for the group range" " 224.0.0.0/4")
536 step("Enable the PIM on all the interfaces of r1, r2, r3 and r4 routers")
537 step("Send multicast traffic from R3")
539 step("r2: Verify RP info")
541 rp_address
= "1.0.2.17"
543 result
= verify_pim_rp_info(
544 tgen
, TOPO
, dut
, GROUP_RANGE_ALL
, iif
, rp_address
, SOURCE
546 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
548 step("r0: Send IGMP join")
549 result
= app_helper
.run_join("r0", GROUP_ADDRESS
, "r1")
550 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
552 step("r1: Verify IGMP groups")
555 result
= verify_igmp_groups(tgen
, dut
, oif
, GROUP_ADDRESS
)
556 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
558 step("r5: Send multicast traffic for group 225.1.1.1")
559 result
= app_helper
.run_traffic("r5", GROUP_ADDRESS
, "r3")
560 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
562 step("r1: Verify (*, G) upstream IIF interface")
565 result
= verify_upstream_iif(tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
)
566 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
568 step("r1: Verify (*, G) upstream join state and join timer")
569 result
= verify_join_state_and_timer(tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
)
570 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
572 step("r1: Verify (*, G) ip mroutes")
573 result
= verify_mroutes(tgen
, dut
, STAR
, GROUP_ADDRESS
, iif
, oif
)
574 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
576 step("r1: Verify (S, G) upstream IIF interface")
578 result
= verify_upstream_iif(tgen
, dut
, iif
, SOURCE_ADDRESS
, GROUP_ADDRESS
)
579 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
581 step("r1: Verify (S, G) upstream join state and join timer")
582 result
= verify_join_state_and_timer(tgen
, dut
, iif
, SOURCE_ADDRESS
, GROUP_ADDRESS
)
583 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
585 step("r1: Verify (S, G) ip mroutes")
586 result
= verify_mroutes(tgen
, dut
, SOURCE_ADDRESS
, GROUP_ADDRESS
, iif
, oif
)
587 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
589 step("r2: Verify (*, G) upstream IIF interface")
592 result
= verify_upstream_iif(tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
)
593 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
595 step("r2: Verify (*, G) upstream join state and join timer")
596 result
= verify_join_state_and_timer(tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
)
597 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
599 step("r2: Verify (*, G) ip mroutes")
601 result
= verify_mroutes(tgen
, dut
, STAR
, GROUP_ADDRESS
, iif
, oif
)
602 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
604 step("r2: Verify (S, G) upstream IIF interface")
606 result
= verify_upstream_iif(tgen
, dut
, iif
, SOURCE_ADDRESS
, GROUP_ADDRESS
)
607 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
609 step("r2: Verify (S, G) upstream join state and join timer")
610 result
= verify_join_state_and_timer(tgen
, dut
, iif
, SOURCE_ADDRESS
, GROUP_ADDRESS
)
611 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
613 step("r2: Verify (S, G) ip mroutes")
614 result
= verify_mroutes(tgen
, dut
, SOURCE_ADDRESS
, GROUP_ADDRESS
, iif
, oif
)
615 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
617 step("r3: Verify (S, G) upstream IIF interface")
620 result
= verify_upstream_iif(tgen
, dut
, iif
, SOURCE_ADDRESS
, GROUP_ADDRESS
)
621 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
623 step("r3: Verify (S, G) upstream join state and join timer")
624 result
= verify_join_state_and_timer(
625 tgen
, dut
, iif
, SOURCE_ADDRESS
, GROUP_ADDRESS
, expected
=False
627 assert result
is not True, (
628 "Testcase {} : Failed \n "
629 "Expected: [{}]: Upstream Join State timer should not run\n "
630 "Found: {}".format(tc_name
, dut
, result
)
633 step("r3: Verify (S, G) ip mroutes")
635 result
= verify_mroutes(tgen
, dut
, SOURCE_ADDRESS
, GROUP_ADDRESS
, iif
, oif
)
636 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
638 # Uncomment next line for debugging
641 write_test_footer(tc_name
)
644 def test_not_reachable_static_RP_p0(request
):
646 TC_5_P0: Verify OIF entry for RP is cleared when RP becomes unreachable
647 TC_6_P0: Verify IIF and OIL in "show ip pim state" updated properly when
648 RP becomes unreachable
649 TC_7_P0 : Verify upstream interfaces(IIF) and join state are updated
650 properly after adding and deleting the static RP
651 TC_8_P0: Verify (*,G) prune is send towards the RP when RP becomes
660 tc_name
= request
.node
.name
661 write_test_header(tc_name
)
663 # Don"t run this test if we have any failure.
664 if tgen
.routers_have_failure():
665 pytest
.skip(tgen
.errors
)
667 step("Creating configuration from JSON")
668 reset_config_on_routers(tgen
)
669 app_helper
.stop_all_hosts()
671 clear_pim_interface_traffic(tgen
, TOPO
)
675 shutdown_bringup_interface(tgen
, dut
, intf
, False)
679 shutdown_bringup_interface(tgen
, dut
, intf
, False)
682 "r1: (*,G) prune is not sent towards the RP interface, verify using"
683 "show ip pim interface traffic"
685 state_dict
= {"r1": {"r1-r2-eth1": ["pruneTx"]}}
686 state_before
= get_pim_interface_traffic(tgen
, state_dict
)
689 ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
690 tc_name
, state_before
693 step("Enable IGMP on r1 interface and send IGMP " "join (225.1.1.1) to r1")
694 step("Configure r2 loopback interface as RP")
695 step("Enable PIM between r1 and r2")
697 step("r0 : Send IGMP join")
698 result
= app_helper
.run_join("r0", GROUP_ADDRESS
, "r1")
699 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
701 step("r1 : Verify rp info")
704 rp_address
= "1.0.2.17"
705 result
= verify_pim_rp_info(
706 tgen
, TOPO
, dut
, GROUP_RANGE_ALL
, iif
, rp_address
, SOURCE
708 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
710 step("r1: Verify IGMP groups")
712 result
= verify_igmp_groups(tgen
, dut
, oif
, GROUP_ADDRESS
)
713 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
715 step("r1: Verify PIM state")
716 result
= verify_pim_state(tgen
, dut
, iif
, oif
, GROUP_ADDRESS
)
717 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
719 step("r1: Verify upstream IIF interface")
720 result
= verify_upstream_iif(tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
)
721 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
723 step("r1: Verify upstream join state and join timer")
724 result
= verify_join_state_and_timer(tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
)
725 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
727 step("r1 :Verify ip mroutes")
728 result
= verify_mroutes(tgen
, dut
, STAR
, GROUP_ADDRESS
, iif
, oif
)
729 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
731 step("r1: Make RP un-reachable")
736 {"network": "1.0.2.17/32", "next_hop": "10.0.1.2", "delete": True}
741 result
= create_static_routes(tgen
, input_dict
)
742 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
744 step("r1: Check RP detail using show ip pim rp-info OIF should be unknown")
745 result
= verify_pim_rp_info(
746 tgen
, TOPO
, dut
, GROUP_RANGE_ALL
, "Unknown", rp_address
, SOURCE
748 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
751 "r1 : OIL should be same and IIF should be cleared on R1 verify"
752 "using show ip pim state"
754 result
= verify_pim_state(tgen
, dut
, iif
, oif
, GROUP_ADDRESS
, expected
=False)
755 assert result
is not True, (
756 "Testcase {} : Failed \n "
757 "Expected: [{}]: OIL should be same and IIF should be cleared\n "
758 "Found: {}".format(tc_name
, dut
, result
)
761 step("r1: upstream IIF should be unknown , verify using show ip pim" "upstream")
762 result
= verify_upstream_iif(tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
, expected
=False)
763 assert result
is not True, (
764 "Testcase {} : Failed \n "
765 "Expected: [{}]: Upstream IIF interface {} should be unknown \n "
766 "Found: {}".format(tc_name
, dut
, iif
, result
)
770 "r1: join state should not be joined and join timer should stop,"
771 "verify using show ip pim upstream"
773 result
= verify_join_state_and_timer(
774 tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
, expected
=False
776 assert result
is not True, (
777 "Testcase {} : Failed \n "
778 "Expected: [{}]: Upstream Join State timer should not run\n "
779 "Found: {}".format(tc_name
, dut
, result
)
783 "r1: (*,G) prune is sent towards the RP interface, verify using"
784 "show ip pim interface traffic"
786 state_after
= get_pim_interface_traffic(tgen
, state_dict
)
789 ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
793 result
= verify_state_incremented(state_before
, state_after
)
794 assert result
is True, "Testcase{} : Failed Error: {}".format(tc_name
, result
)
796 step("r1: (*, G) cleared from mroute table using show ip mroute")
797 result
= verify_mroutes(tgen
, dut
, STAR
, GROUP_ADDRESS
, iif
, oif
, expected
=False)
798 assert result
is not True, (
799 "Testcase {} : Failed \n "
800 "Expected: [{}]: mroute (*, G) should be cleared from mroute table\n "
801 "Found: {}".format(tc_name
, dut
, result
)
804 # Uncomment next line for debugging
807 write_test_footer(tc_name
)
810 def test_add_RP_after_join_received_p1(request
):
812 TC_9_P1 : Verify RP configured after IGMP join received, PIM join towards
813 RP is sent immediately
821 tc_name
= request
.node
.name
822 write_test_header(tc_name
)
824 # Don"t run this test if we have any failure.
825 if tgen
.routers_have_failure():
826 pytest
.skip(tgen
.errors
)
828 step("Creating configuration from JSON")
829 reset_config_on_routers(tgen
)
830 app_helper
.stop_all_hosts()
832 clear_pim_interface_traffic(tgen
, TOPO
)
834 step("Enable IGMP on R1 interface")
835 step("Configure r2 loopback interface as RP")
836 step("Enable PIM between r1 and r2")
837 step("Delete RP configuration from r1")
839 step("r1: Delete RP configuration")
845 "rp_addr": "1.0.2.17",
846 "group_addr_range": GROUP_RANGE_ALL
,
854 result
= create_pim_config(tgen
, TOPO
, input_dict
)
855 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
857 step("r1: Verify rp-info")
859 rp_address
= "1.0.2.17"
861 result
= verify_pim_rp_info(
862 tgen
, TOPO
, dut
, GROUP_RANGE_ALL
, iif
, rp_address
, SOURCE
, expected
=False
864 assert result
is not True, (
865 "Testcase {} : Failed \n "
866 "Expected: [{}]: RP-info should not be present \n "
867 "Found: {}".format(tc_name
, dut
, result
)
870 step("joinTx value before join sent")
871 state_dict
= {"r1": {"r1-r2-eth1": ["joinTx"]}}
872 state_before
= get_pim_interface_traffic(tgen
, state_dict
)
875 ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
879 step("r0 : Send IGMP join (225.1.1.1) to r1, when rp is not configured" "in r1")
880 result
= app_helper
.run_join("r0", GROUP_ADDRESS
, "r1")
881 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
883 step("r1: IGMP group is received on R1 verify using show ip igmp groups")
885 result
= verify_igmp_groups(tgen
, dut
, oif
, GROUP_ADDRESS
)
886 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
888 step("r1: Verify upstream IIF interface")
889 result
= verify_upstream_iif(tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
, expected
=False)
890 assert result
is not True, (
891 "Testcase {} : Failed \n "
892 "Expected: [{}]: Upstream IIF interface {} should not be present \n "
893 "Found: {}".format(tc_name
, dut
, iif
, result
)
896 step("r1: Verify upstream join state and join timer")
898 result
= verify_join_state_and_timer(
899 tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
, expected
=False
901 assert result
is not True, (
902 "Testcase {} : Failed \n "
903 "Expected: [{}]: Upstream Join State timer should not run\n "
904 "Found: {}".format(tc_name
, dut
, result
)
907 step("r1: Verify PIM state")
908 result
= verify_pim_state(tgen
, dut
, iif
, oif
, GROUP_ADDRESS
, expected
=False)
909 assert result
is not True, (
910 "Testcase {} : Failed \n "
911 "Expected: [{}]: PIM state should not be up\n "
912 "Found: {}".format(tc_name
, dut
, result
)
915 step("r1: Verify ip mroutes")
916 result
= verify_mroutes(tgen
, dut
, STAR
, GROUP_ADDRESS
, iif
, oif
, expected
=False)
917 assert result
is not True, (
918 "Testcase {} : Failed \n "
919 "Expected: [{}]: mroute (*, G) should not be present in mroute table \n "
920 "Found: {}".format(tc_name
, dut
, result
)
923 step("r1: Configure static RP")
929 "rp_addr": "1.0.2.17",
930 "group_addr_range": GROUP_RANGE_ALL
,
937 result
= create_pim_config(tgen
, TOPO
, input_dict
)
938 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
940 step("r1: Verify rp-info")
941 result
= verify_pim_rp_info(
942 tgen
, TOPO
, dut
, GROUP_RANGE_ALL
, iif
, rp_address
, SOURCE
944 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
946 step("r1: Verify upstream IIF interface")
947 result
= verify_upstream_iif(tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
)
948 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
950 step("r1 : Verify upstream join state and join timer")
951 result
= verify_join_state_and_timer(tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
)
952 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
954 step("r1: Verify PIM state")
955 result
= verify_pim_state(tgen
, dut
, iif
, oif
, GROUP_ADDRESS
)
956 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
958 step("r1 : Verify ip mroutes")
959 result
= verify_mroutes(tgen
, dut
, STAR
, GROUP_ADDRESS
, iif
, oif
)
960 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
961 logger
.info("Expected behavior: %s", result
)
963 state_after
= get_pim_interface_traffic(tgen
, state_dict
)
966 ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
970 result
= verify_state_incremented(state_before
, state_after
)
971 assert result
is True, "Testcase {} : Failed Error: {}".format(tc_name
, result
)
973 # Uncomment next line for debugging
976 write_test_footer(tc_name
)
979 def test_reachable_static_RP_after_join_p0(request
):
981 TC_10_P0 : Verify RP becomes reachable after IGMP join received, PIM join
982 towards RP is sent immediately
989 tc_name
= request
.node
.name
990 write_test_header(tc_name
)
992 # Don"t run this test if we have any failure.
993 if tgen
.routers_have_failure():
994 pytest
.skip(tgen
.errors
)
996 step("Creating configuration from JSON")
997 reset_config_on_routers(tgen
)
998 app_helper
.stop_all_hosts()
1000 clear_pim_interface_traffic(tgen
, TOPO
)
1002 step("Enable IGMP on r1 interface and send IGMP " "join (225.1.1.1) to r1")
1003 step("Configure r2 loopback interface as RP")
1004 step("Enable PIM between r1 and r2")
1006 step("r1 : Verify pim interface traffic")
1007 state_dict
= {"r1": {"r1-r2-eth1": ["joinTx"]}}
1008 state_before
= get_pim_interface_traffic(tgen
, state_dict
)
1011 ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
1012 tc_name
, state_before
1015 step("r1: Make RP un-reachable")
1018 shutdown_bringup_interface(tgen
, dut
, intf
, False)
1020 shutdown_bringup_interface(tgen
, dut
, intf
, False)
1022 shutdown_bringup_interface(tgen
, dut
, intf
, False)
1024 step("r1: Verify rp-info")
1025 rp_address
= "1.0.2.17"
1026 result
= verify_pim_rp_info(
1027 tgen
, TOPO
, dut
, GROUP_ADDRESS
, "Unknown", rp_address
, SOURCE
1029 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1031 step("r1 : Send IGMP join for 225.1.1.1")
1032 result
= app_helper
.run_join("r0", GROUP_ADDRESS
, "r1")
1033 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1035 step("r1 : Verify IGMP groups")
1037 result
= verify_igmp_groups(tgen
, dut
, oif
, GROUP_ADDRESS
)
1038 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1040 step("r1 : Verify upstream IIF interface")
1042 result
= verify_upstream_iif(tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
, expected
=False)
1043 assert result
is not True, (
1044 "Testcase {} : Failed \n "
1045 "Expected: [{}]: Upstream IIF interface {} should not be present \n "
1046 "Found: {}".format(tc_name
, dut
, iif
, result
)
1049 step("r1 : Verify upstream join state and join timer")
1050 result
= verify_join_state_and_timer(
1051 tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
, expected
=False
1053 assert result
is not True, (
1054 "Testcase {} : Failed \n "
1055 "Expected: [{}]: Upstream Join State timer should not run\n "
1056 "Found: {}".format(tc_name
, dut
, result
)
1059 step("r1 : Verify PIM state")
1060 result
= verify_pim_state(tgen
, dut
, iif
, oif
, GROUP_ADDRESS
, expected
=False)
1061 assert result
is not True, (
1062 "Testcase {} : Failed \n "
1063 "Expected: [{}]: PIM state should not be up \n "
1064 "Found: {}".format(tc_name
, dut
, result
)
1067 step("r1 : Verify ip mroutes")
1068 result
= verify_mroutes(tgen
, dut
, STAR
, GROUP_ADDRESS
, iif
, oif
, expected
=False)
1069 assert result
is not True, (
1070 "Testcase {} : Failed \n "
1071 "Expected: [{}]: mroute (*, G) should not be present \n "
1072 "Found: {}".format(tc_name
, dut
, result
)
1075 step("r1: Make RP reachable")
1077 shutdown_bringup_interface(tgen
, dut
, intf
, True)
1079 shutdown_bringup_interface(tgen
, dut
, intf
, True)
1081 shutdown_bringup_interface(tgen
, dut
, intf
, True)
1083 step("r1 : Verify rp-info")
1084 result
= verify_pim_rp_info(
1085 tgen
, TOPO
, dut
, GROUP_RANGE_ALL
, iif
, rp_address
, SOURCE
1087 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1089 step("r1: Verify upstream IIF interface")
1090 result
= verify_upstream_iif(tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
)
1091 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1093 step("r1 : Verify upstream join state and join timer")
1094 result
= verify_join_state_and_timer(tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
)
1095 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1097 step("r1 : Verify PIM state")
1098 result
= verify_pim_state(tgen
, dut
, iif
, oif
, GROUP_ADDRESS
)
1099 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1101 step("r1 : Verify ip mroutes")
1102 result
= verify_mroutes(tgen
, dut
, STAR
, GROUP_ADDRESS
, iif
, oif
)
1103 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1104 logger
.info("Expected behavior: %s", result
)
1106 step("r1 : Verify pim interface traffic")
1107 state_after
= get_pim_interface_traffic(tgen
, state_dict
)
1110 ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
1114 result
= verify_state_incremented(state_before
, state_after
)
1115 assert result
is True, "Testcase{} : Failed Error: {}".format(tc_name
, result
)
1117 # Uncomment next line for debugging
1118 # tgen.mininet_cli()
1120 write_test_footer(tc_name
)
1123 def test_send_join_on_higher_preffered_rp_p1(request
):
1125 TC_11_P1 : Verify PIM join send towards the higher preferred RP
1126 TC_12_P1 : Verify PIM prune send towards the lower preferred RP
1127 TC_13_P1 : Verify RPF interface is updated in mroute (kernel) when higher
1128 preferred overlapping RP configured
1129 TC_14_P1 : Verify IIF and OIL in "show ip pim state" updated properly when
1130 higher preferred overlapping RP configured
1131 TC_15_P1 : Verify upstream interfaces(IIF) and join state are updated when
1132 higher preferred overlapping RP is configured
1133 TC_16_P1 : Verify join is send to lower preferred RP, when higher
1134 preferred RP gets deleted
1135 TC_17_P1 : Verify prune is send to higher preferred RP when higher
1136 preferred RP gets deleted
1137 TC_18_P1 : Verify RPF interface updated in mroute when higher preferred RP
1139 TC_19_P1 : Verify IIF and OIL in "show ip pim state" updated when higher
1140 preferred overlapping RP is deleted
1141 TC_20_P1 : Verify PIM upstream IIF updated when higher preferred
1142 overlapping RP deleted
1153 tgen
= get_topogen()
1154 tc_name
= request
.node
.name
1155 write_test_header(tc_name
)
1157 # Don"t run this test if we have any failure.
1158 if tgen
.routers_have_failure():
1159 pytest
.skip(tgen
.errors
)
1161 step("Creating configuration from JSON")
1162 reset_config_on_routers(tgen
)
1163 app_helper
.stop_all_hosts()
1165 clear_pim_interface_traffic(tgen
, TOPO
)
1167 step("Enable IGMP on r1 interface")
1168 step("Configure RP on r2 (loopback interface) for the group range " "224.0.0.0/4")
1169 step("Configure RP on r4 (loopback interface) for the group range " "225.1.1.1/32")
1171 step("r3 : Make all interface not reachable")
1174 shutdown_bringup_interface(tgen
, dut
, intf
, False)
1176 shutdown_bringup_interface(tgen
, dut
, intf
, False)
1178 shutdown_bringup_interface(tgen
, dut
, intf
, False)
1182 shutdown_bringup_interface(tgen
, dut
, intf
, False)
1186 shutdown_bringup_interface(tgen
, dut
, intf
, False)
1190 shutdown_bringup_interface(tgen
, dut
, intf
, False)
1192 step("r1 : Verify joinTx count before sending join")
1193 state_dict
= {"r1": {"r1-r4-eth3": ["joinTx"], "r1-r2-eth1": ["pruneTx"]}}
1195 state_before
= get_pim_interface_traffic(tgen
, state_dict
)
1198 ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
1199 tc_name
, state_before
1202 step("r0 : Send IGMP join for 225.1.1.1")
1203 result
= app_helper
.run_join("r0", GROUP_ADDRESS
, "r1")
1204 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1206 step("r1 : Verify IGMP groups")
1209 result
= verify_igmp_groups(tgen
, dut
, oif
, GROUP_ADDRESS
)
1210 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1212 step("Configure static RP for group 225.1.1.1/32")
1218 "rp_addr": "1.0.4.17",
1219 "group_addr_range": ["225.1.1.1/32"],
1226 result
= create_pim_config(tgen
, TOPO
, input_dict
)
1227 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1229 step("r1 : Verify RP info for group 224.0.0.0/4")
1230 rp_address_1
= "1.0.2.17"
1232 result
= verify_pim_rp_info(
1233 tgen
, TOPO
, dut
, GROUP_RANGE_ALL
, iif
, rp_address_1
, SOURCE
1235 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1237 step("r1 : Verify RP info for group 225.1.1.1")
1238 rp_address_2
= "1.0.4.17"
1240 result
= verify_pim_rp_info(tgen
, TOPO
, dut
, GROUP_RANGE
, iif
, rp_address_2
, SOURCE
)
1241 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1243 step("r1 : Verify join is sent to higher preferred RP")
1244 step("r1 : Verify prune is sent to lower preferred RP")
1245 state_after
= get_pim_interface_traffic(tgen
, state_dict
)
1248 ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
1252 result
= verify_state_incremented(state_before
, state_after
)
1253 assert result
is True, "Testcase{} : Failed Error: {}".format(tc_name
, result
)
1255 step("r1 : Verify ip mroutes")
1257 result
= verify_mroutes(tgen
, dut
, STAR
, GROUP_ADDRESS
, iif
, oif
)
1258 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1260 step("r1 : Verify PIM state")
1261 result
= verify_pim_state(tgen
, dut
, iif
, oif
, GROUP_ADDRESS
)
1262 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1264 step("r1 : Verify upstream IIF interface")
1265 result
= verify_upstream_iif(tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
)
1266 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1268 step("r1 : Verify upstream join state and join timer")
1269 result
= verify_join_state_and_timer(tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
)
1270 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1272 clear_pim_interface_traffic(tgen
, TOPO
)
1274 step("r1 : Verify joinTx, pruneTx count before RP gets deleted")
1275 state_dict
= {"r1": {"r1-r2-eth1": ["joinTx"], "r1-r4-eth3": ["pruneTx"]}}
1277 state_before
= get_pim_interface_traffic(tgen
, state_dict
)
1280 ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
1284 step("r1 : Delete RP configuration for 225.1.1.1")
1290 "rp_addr": "1.0.4.17",
1291 "group_addr_range": ["225.1.1.1/32"],
1299 result
= create_pim_config(tgen
, TOPO
, input_dict
)
1300 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1302 step("r1 : Verify rp-info for group 224.0.0.0/4")
1304 result
= verify_pim_rp_info(
1305 tgen
, TOPO
, dut
, GROUP_RANGE_ALL
, iif
, rp_address_1
, SOURCE
1307 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1309 step("r1 : Verify rp-info for group 225.1.1.1")
1311 result
= verify_pim_rp_info(
1312 tgen
, TOPO
, dut
, GROUP_RANGE
, oif
, rp_address_2
, SOURCE
, expected
=False
1314 assert result
is not True, (
1315 "Testcase {} : Failed \n "
1316 "Expected: [{}]: RP-info should not be present \n "
1317 "Found: {}".format(tc_name
, dut
, result
)
1321 "r1 : Verify RPF interface updated in mroute when higher preferred"
1325 result
= verify_mroutes(tgen
, dut
, STAR
, GROUP_ADDRESS
, iif
, oif
)
1326 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1327 logger
.info("Expected behavior: %s", result
)
1330 "r1 : Verify IIF and OIL in show ip pim state updated when higher"
1331 "preferred overlapping RP is deleted"
1333 result
= verify_pim_state(tgen
, dut
, iif
, oif
, GROUP_ADDRESS
)
1334 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1337 "r1 : Verify upstream IIF updated when higher preferred overlapping"
1340 result
= verify_upstream_iif(tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
)
1341 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1344 "r1 : Verify upstream join state and join timer updated when higher"
1345 "preferred overlapping RP deleted"
1347 result
= verify_join_state_and_timer(tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
)
1348 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1351 "r1 : Verify join is sent to lower preferred RP, when higher"
1352 "preferred RP gets deleted"
1355 "r1 : Verify prune is sent to higher preferred RP when higher"
1356 " preferred RP gets deleted"
1358 state_after
= get_pim_interface_traffic(tgen
, state_dict
)
1361 ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
1365 result
= verify_state_incremented(state_before
, state_after
)
1366 assert result
is True, "Testcase{} : Failed Error: {}".format(tc_name
, result
)
1368 # Uncomment next line for debugging
1369 # tgen.mininet_cli()
1371 write_test_footer(tc_name
)
1374 if __name__
== "__main__":
1375 ARGS
= ["-s"] + sys
.argv
[1:]
1376 sys
.exit(pytest
.main(ARGS
))