4 # Copyright (c) 2019 by VMware, Inc. ("VMware")
5 # Used Copyright (c) 2018 by Network Device Education Foundation,
6 # Inc. ("NetDEF") in this file.
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
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
24 Following tests are covered to test Multicast basic functionality:
31 r0-----r1-------------r3-----r5
37 - Create topology (setup module)
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
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
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
66 TC_17 : Verify prune is send to higher preferred RP when higher preferred RP
68 TC_18 : Verify RPF interface updated in mroute when higher preferred RP gets
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
74 TC_21_1 : Verify OIF and RFP for (*,G) and (S,G) when static RP configure in
76 TC_21_2 : Verify OIF and RFP for (*,G) and (S,G) when static RP configure in
78 TC_22_1 : Verify OIF and RPF for (*,G) and (S,G) when static RP configure in
80 TC_22_2 : Verify OIF and RPF for (*,G) and (S,G) when static RP configure in
82 TC_23 : Verify (*,G) and (S,G) populated correctly when RPT and SPT path are
84 TC_24 : Verify (*,G) and (S,G) populated correctly when SPT and RPT share the
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
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
103 from time
import sleep
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/"))
112 # Required to instantiate the topology builder class.
114 # pylint: disable=C0413
115 # Import topogen and topotest helpers
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
121 from lib
.common_config
import (
125 reset_config_on_routers
,
127 shutdown_bringup_interface
,
129 start_router_daemons
,
130 create_static_routes
,
133 from lib
.pim
import (
137 verify_join_state_and_timer
,
139 verify_pim_neighbors
,
140 get_pim_interface_traffic
,
143 clear_pim_interface_traffic
,
144 clear_igmp_interfaces
,
145 clear_pim_interfaces
,
151 pytestmark
= [pytest
.mark
.pimd
, pytest
.mark
.staticd
]
155 GROUP_RANGE_ALL
= "224.0.0.0/4"
156 GROUP_RANGE
= "225.1.1.1/32"
157 GROUP_RANGE_LIST_1
= [
164 GROUP_RANGE_LIST_2
= [
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
= [
181 SOURCE_ADDRESS
= "10.0.6.2"
185 def build_topo(tgen
):
188 # Building topology from json file
189 build_topo_from_json(tgen
, TOPO
)
192 def setup_module(mod
):
194 Sets up the pytest environment
199 testsuite_run_time
= time
.asctime(time
.localtime(time
.time()))
200 logger
.info("Testsuite start time: %s", testsuite_run_time
)
201 logger
.info("=" * 40)
208 r0-----r1-------------r3-----r5
214 logger
.info("Master Topology: \n %s", topology
)
216 logger
.info("Running setup_module to create topology")
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
__)
222 TOPO
= tgen
.json_topo
224 # ... and here it calls Mininet initialization functions.
226 # get list of daemons needs to be started for this suite.
227 daemons
= topo_daemons(tgen
, TOPO
)
229 # Starting topology, create tmp files which are loaded to routers
230 # to start daemons and then start routers
231 start_topology(tgen
, daemons
)
233 # Don"t run this test if we have any failure.
234 if tgen
.routers_have_failure():
235 pytest
.skip(tgen
.errors
)
237 # Creating configuration from JSON
238 build_config_from_json(tgen
, TOPO
)
240 # Verify PIM neighbors
241 result
= verify_pim_neighbors(tgen
, TOPO
)
242 assert result
is True, "setup_module :Failed \n Error:" " {}".format(result
)
244 # XXX Replace this using "with McastTesterHelper()... " in each test if possible.
246 app_helper
= McastTesterHelper(tgen
)
248 logger
.info("Running setup_module() done")
251 def teardown_module():
252 """Teardown the pytest environment"""
254 logger
.info("Running teardown_module to delete topology")
260 # Stop toplogy and Remove tmp files
263 logger
.info("Testsuite end time: %s", time
.asctime(time
.localtime(time
.time())))
264 logger
.info("=" * 40)
267 #####################################################
271 #####################################################
274 def verify_mroute_repopulated(uptime_before
, uptime_after
):
276 API to compare uptime for mroutes
280 * `uptime_before` : Uptime dictionary for any particular instance
281 * `uptime_after` : Uptime dictionary for any particular instance
284 for group
in uptime_before
.keys():
285 for source
in uptime_before
[group
].keys():
286 if set(uptime_before
[group
]) != set(uptime_after
[group
]):
288 "mroute (%s, %s) has not come"
289 " up after mroute clear [FAILED!!]" % (source
, group
)
293 d_1
= datetime
.datetime
.strptime(uptime_before
[group
][source
], "%H:%M:%S")
294 d_2
= datetime
.datetime
.strptime(uptime_after
[group
][source
], "%H:%M:%S")
296 errormsg
= "mroute (%s, %s) is not " "repopulated [FAILED!!]" % (
302 logger
.info("mroute (%s, %s) is " "repopulated [PASSED!!]", source
, group
)
307 def verify_state_incremented(state_before
, state_after
):
309 API to compare interface traffic state incrementing
313 * `state_before` : State dictionary for any particular instance
314 * `state_after` : State dictionary for any particular instance
317 for router
, state_data
in state_before
.items():
318 for state
, _
in state_data
.items():
319 if state_before
[router
][state
] >= state_after
[router
][state
]:
321 "[DUT: %s]: state %s value has not"
322 " incremented, Initial value: %s, "
323 "Current value: %s [FAILED!!]"
327 state_before
[router
][state
],
328 state_after
[router
][state
],
334 "[DUT: %s]: State %s value is "
335 "incremented, Initial value: %s, Current value: %s"
339 state_before
[router
][state
],
340 state_after
[router
][state
],
346 def test_add_delete_static_RP_p0(request
):
348 TC_1_P0 : Verify upstream interfaces(IIF) and join state are updated
349 properly after adding and deleting the static RP
350 TC_2_P0 : Verify IIF and OIL in "show ip pim state" updated properly
351 after adding and deleting the static RP
352 TC_3_P0: (*, G) Mroute entry are cleared when static RP gets deleted
353 TC_4_P0: Verify (*,G) prune is send towards the RP after deleting the
362 tc_name
= request
.node
.name
363 write_test_header(tc_name
)
365 # Don"t run this test if we have any failure.
366 if tgen
.routers_have_failure():
367 pytest
.skip(tgen
.errors
)
369 step("pre-configuration to send IGMP join and multicast traffic")
371 step("Enable IGMP on r1 interface and send IGMP " "join (225.1.1.1) to r1")
372 step("Configure r2 loopback interface as RP")
373 step("Enable PIM between r1 and r3")
375 step("r1: Verify show ip igmp group without any IGMP join")
377 interface
= "r1-r0-eth0"
378 result
= verify_igmp_groups(tgen
, dut
, interface
, GROUP_ADDRESS
, expected
=False)
379 assert result
is not True, (
380 "Testcase {} : Failed \n "
381 "r1: igmp group present without any IGMP join \n Error: {}".format(
386 step("r1: Verify show ip pim interface traffic without any IGMP join")
387 state_dict
= {"r1": {"r1-r2-eth1": ["pruneTx"]}}
389 state_before
= get_pim_interface_traffic(tgen
, state_dict
)
392 ), "Testcase {} : Failed \n state_before is not dictionary\n Error: {}".format(
396 step("r0 : Send IGMP join")
397 result
= app_helper
.run_join("r0", GROUP_ADDRESS
, "r1")
398 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
400 step("r1: Verify IGMP groups")
402 result
= verify_igmp_groups(tgen
, dut
, oif
, GROUP_ADDRESS
)
403 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
405 step("r1: Verify RP info")
408 rp_address
= "1.0.2.17"
409 result
= verify_pim_rp_info(
410 tgen
, TOPO
, dut
, GROUP_RANGE_ALL
, iif
, rp_address
, SOURCE
412 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
414 step("r1: Verify upstream IIF interface")
415 result
= verify_upstream_iif(tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
)
416 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
418 step("r1: Verify upstream join state and join timer")
419 result
= verify_join_state_and_timer(tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
)
420 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
421 step("r1: Verify ip mroutes")
422 result
= verify_mroutes(tgen
, dut
, STAR
, GROUP_ADDRESS
, iif
, oif
)
423 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
425 step("r1: Verify ip pim join")
426 result
= verify_join_state_and_timer(tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
)
427 step("r1: Delete RP configuration")
429 # Delete RP configuration
435 "rp_addr": "1.0.2.17",
436 "group_addr_range": GROUP_RANGE_ALL
,
444 result
= create_pim_config(tgen
, TOPO
, input_dict
)
445 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
447 step("r1: Verify RP info")
448 result
= verify_pim_rp_info(
449 tgen
, TOPO
, dut
, GROUP_RANGE_ALL
, iif
, rp_address
, SOURCE
, expected
=False
453 ), "Testcase {} : Failed \n " "r1: RP info present \n Error: {}".format(
457 step("r1: Verify upstream IIF interface")
458 result
= verify_upstream_iif(tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
, expected
=False)
459 assert result
is not True, (
460 "Testcase {} : Failed \n "
461 "r1: upstream IIF interface present \n Error: {}".format(tc_name
, result
)
464 step("r1: Verify upstream join state and join timer")
465 result
= verify_join_state_and_timer(
466 tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
, expected
=False
468 assert result
is not True, (
469 "Testcase {} : Failed \n "
470 "r1: upstream join state is up and join timer is running \n Error: {}".format(
476 step("r1: Verify PIM state")
477 result
= verify_pim_state(tgen
, dut
, iif
, oif
, GROUP_ADDRESS
, expected
=False)
478 assert result
is not True, "Testcase {} :Failed \n Error: {}".format(
482 step("r1: Verify ip mroutes")
483 result
= verify_mroutes(tgen
, dut
, STAR
, GROUP_ADDRESS
, iif
, oif
, expected
=False)
486 ), "Testcase {} : Failed \n " "r1: mroutes are still present \n Error: {}".format(
490 step("r1: Verify show ip pim interface traffic without any IGMP join")
491 state_after
= get_pim_interface_traffic(tgen
, state_dict
)
494 ), "Testcase {} : Failed \n state_before is not dictionary \n Error: {}".format(
498 result
= verify_state_incremented(state_before
, state_after
)
499 assert result
is True, "Testcase{} : Failed Error: {}".format(tc_name
, result
)
501 # Uncomment next line for debugging
504 write_test_footer(tc_name
)
507 def test_SPT_RPT_path_same_p1(request
):
509 TC_24_P1 : Verify (*,G) and (S,G) populated correctly when SPT and RPT
524 tc_name
= request
.node
.name
525 write_test_header(tc_name
)
527 # Don"t run this test if we have any failure.
528 if tgen
.routers_have_failure():
529 pytest
.skip(tgen
.errors
)
531 step("Creating configuration from JSON")
532 reset_config_on_routers(tgen
)
533 app_helper
.stop_all_hosts()
535 clear_pim_interface_traffic(tgen
, TOPO
)
539 shutdown_bringup_interface(tgen
, dut
, intf
, False)
541 shutdown_bringup_interface(tgen
, dut
, intf
, False)
545 shutdown_bringup_interface(tgen
, dut
, intf
, False)
547 shutdown_bringup_interface(tgen
, dut
, intf
, False)
549 step("Enable IGMP on r1 interface and send IGMP join (225.1.1.1) to R1")
550 step("Configure RP on r2 (loopback interface) for the group range" " 224.0.0.0/4")
551 step("Enable the PIM on all the interfaces of r1, r2, r3 and r4 routers")
552 step("Send multicast traffic from R3")
554 step("r2: Verify RP info")
556 rp_address
= "1.0.2.17"
558 result
= verify_pim_rp_info(
559 tgen
, TOPO
, dut
, GROUP_RANGE_ALL
, iif
, rp_address
, SOURCE
561 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
563 step("r0: Send IGMP join")
564 result
= app_helper
.run_join("r0", GROUP_ADDRESS
, "r1")
565 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
567 step("r1: Verify IGMP groups")
570 result
= verify_igmp_groups(tgen
, dut
, oif
, GROUP_ADDRESS
)
571 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
573 step("r5: Send multicast traffic for group 225.1.1.1")
574 result
= app_helper
.run_traffic("r5", GROUP_ADDRESS
, "r3")
575 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
577 step("r1: Verify (*, G) upstream IIF interface")
580 result
= verify_upstream_iif(tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
)
581 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
583 step("r1: Verify (*, G) upstream join state and join timer")
584 result
= verify_join_state_and_timer(tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
)
585 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
587 step("r1: Verify (*, G) ip mroutes")
588 result
= verify_mroutes(tgen
, dut
, STAR
, GROUP_ADDRESS
, iif
, oif
)
589 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
591 step("r1: Verify (S, G) upstream IIF interface")
593 result
= verify_upstream_iif(tgen
, dut
, iif
, SOURCE_ADDRESS
, GROUP_ADDRESS
)
594 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
596 step("r1: Verify (S, G) upstream join state and join timer")
597 result
= verify_join_state_and_timer(tgen
, dut
, iif
, SOURCE_ADDRESS
, GROUP_ADDRESS
)
598 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
600 step("r1: Verify (S, G) ip mroutes")
601 result
= verify_mroutes(tgen
, dut
, SOURCE_ADDRESS
, GROUP_ADDRESS
, iif
, oif
)
602 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
604 step("r2: Verify (*, G) upstream IIF interface")
607 result
= verify_upstream_iif(tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
)
608 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
610 step("r2: Verify (*, G) upstream join state and join timer")
611 result
= verify_join_state_and_timer(tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
)
612 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
614 step("r2: Verify (*, G) ip mroutes")
616 result
= verify_mroutes(tgen
, dut
, STAR
, GROUP_ADDRESS
, iif
, oif
)
617 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
619 step("r2: Verify (S, G) upstream IIF interface")
621 result
= verify_upstream_iif(tgen
, dut
, iif
, SOURCE_ADDRESS
, GROUP_ADDRESS
)
622 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
624 step("r2: Verify (S, G) upstream join state and join timer")
625 result
= verify_join_state_and_timer(tgen
, dut
, iif
, SOURCE_ADDRESS
, GROUP_ADDRESS
)
626 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
628 step("r2: Verify (S, G) ip mroutes")
629 result
= verify_mroutes(tgen
, dut
, SOURCE_ADDRESS
, GROUP_ADDRESS
, iif
, oif
)
630 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
632 step("r3: Verify (S, G) upstream IIF interface")
635 result
= verify_upstream_iif(tgen
, dut
, iif
, SOURCE_ADDRESS
, GROUP_ADDRESS
)
636 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
638 step("r3: Verify (S, G) upstream join state and join timer")
639 result
= verify_join_state_and_timer(
640 tgen
, dut
, iif
, SOURCE_ADDRESS
, GROUP_ADDRESS
, expected
=False
642 assert result
is not True, (
643 "Testcase {} : Failed \n "
644 "r3: (S, G) upstream join state is up and join timer is running\n Error: {}".format(
649 step("r3: Verify (S, G) ip mroutes")
651 result
= verify_mroutes(tgen
, dut
, SOURCE_ADDRESS
, GROUP_ADDRESS
, iif
, oif
)
652 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
654 # Uncomment next line for debugging
657 write_test_footer(tc_name
)
660 def test_not_reachable_static_RP_p0(request
):
662 TC_5_P0: Verify OIF entry for RP is cleared when RP becomes unreachable
663 TC_6_P0: Verify IIF and OIL in "show ip pim state" updated properly when
664 RP becomes unreachable
665 TC_7_P0 : Verify upstream interfaces(IIF) and join state are updated
666 properly after adding and deleting the static RP
667 TC_8_P0: Verify (*,G) prune is send towards the RP when RP becomes
676 tc_name
= request
.node
.name
677 write_test_header(tc_name
)
679 # Don"t run this test if we have any failure.
680 if tgen
.routers_have_failure():
681 pytest
.skip(tgen
.errors
)
683 step("Creating configuration from JSON")
684 reset_config_on_routers(tgen
)
685 app_helper
.stop_all_hosts()
687 clear_pim_interface_traffic(tgen
, TOPO
)
691 shutdown_bringup_interface(tgen
, dut
, intf
, False)
695 shutdown_bringup_interface(tgen
, dut
, intf
, False)
698 "r1: (*,G) prune is not sent towards the RP interface, verify using"
699 "show ip pim interface traffic"
701 state_dict
= {"r1": {"r1-r2-eth1": ["pruneTx"]}}
702 state_before
= get_pim_interface_traffic(tgen
, state_dict
)
705 ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
706 tc_name
, state_before
709 step("Enable IGMP on r1 interface and send IGMP " "join (225.1.1.1) to r1")
710 step("Configure r2 loopback interface as RP")
711 step("Enable PIM between r1 and r2")
713 step("r0 : Send IGMP join")
714 result
= app_helper
.run_join("r0", GROUP_ADDRESS
, "r1")
715 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
717 step("r1 : Verify rp info")
720 rp_address
= "1.0.2.17"
721 result
= verify_pim_rp_info(
722 tgen
, TOPO
, dut
, GROUP_RANGE_ALL
, iif
, rp_address
, SOURCE
724 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
726 step("r1: Verify IGMP groups")
728 result
= verify_igmp_groups(tgen
, dut
, oif
, GROUP_ADDRESS
)
729 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
731 step("r1: Verify PIM state")
732 result
= verify_pim_state(tgen
, dut
, iif
, oif
, GROUP_ADDRESS
)
733 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
735 step("r1: Verify upstream IIF interface")
736 result
= verify_upstream_iif(tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
)
737 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
739 step("r1: Verify upstream join state and join timer")
740 result
= verify_join_state_and_timer(tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
)
741 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
743 step("r1 :Verify ip mroutes")
744 result
= verify_mroutes(tgen
, dut
, STAR
, GROUP_ADDRESS
, iif
, oif
)
745 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
747 step("r1: Make RP un-reachable")
752 {"network": "1.0.2.17/32", "next_hop": "10.0.1.2", "delete": True}
757 result
= create_static_routes(tgen
, input_dict
)
758 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
760 step("r1: Check RP detail using show ip pim rp-info OIF should be unknown")
761 result
= verify_pim_rp_info(
762 tgen
, TOPO
, dut
, GROUP_RANGE_ALL
, "Unknown", rp_address
, SOURCE
764 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
767 "r1 : OIL should be same and IIF should be cleared on R1 verify"
768 "using show ip pim state"
770 result
= verify_pim_state(tgen
, dut
, iif
, oif
, GROUP_ADDRESS
, expected
=False)
771 assert result
is not True, (
772 "Testcase {} : Failed \n "
773 "OIL is not same and IIF is not cleared on R1 \n Error: {}".format(
778 step("r1: upstream IIF should be unknown , verify using show ip pim" "upstream")
779 result
= verify_upstream_iif(tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
, expected
=False)
780 assert result
is not True, (
781 "Testcase {} : Failed \n "
782 "r1: upstream IIF is not unknown \n Error: {}".format(tc_name
, result
)
786 "r1: join state should not be joined and join timer should stop,"
787 "verify using show ip pim upstream"
789 result
= verify_join_state_and_timer(
790 tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
, expected
=False
792 assert result
is not True, (
793 "Testcase {} : Failed \n "
794 "r1: join state is joined and timer is not stopped \n Error: {}".format(
800 "r1: (*,G) prune is sent towards the RP interface, verify using"
801 "show ip pim interface traffic"
803 state_after
= get_pim_interface_traffic(tgen
, state_dict
)
806 ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
810 result
= verify_state_incremented(state_before
, state_after
)
811 assert result
is True, "Testcase{} : Failed Error: {}".format(tc_name
, result
)
813 step("r1: (*, G) cleared from mroute table using show ip mroute")
814 result
= verify_mroutes(tgen
, dut
, STAR
, GROUP_ADDRESS
, iif
, oif
, expected
=False)
815 assert result
is not True, (
816 "Testcase {} : Failed \n "
817 "r1: (*, G) are not cleared from mroute table \n Error: {}".format(
821 logger
.info("Expected behavior: %s", result
)
823 # Uncomment next line for debugging
826 write_test_footer(tc_name
)
829 def test_add_RP_after_join_received_p1(request
):
831 TC_9_P1 : Verify RP configured after IGMP join received, PIM join towards
832 RP is sent immediately
840 tc_name
= request
.node
.name
841 write_test_header(tc_name
)
843 # Don"t run this test if we have any failure.
844 if tgen
.routers_have_failure():
845 pytest
.skip(tgen
.errors
)
847 step("Creating configuration from JSON")
848 reset_config_on_routers(tgen
)
849 app_helper
.stop_all_hosts()
851 clear_pim_interface_traffic(tgen
, TOPO
)
853 step("Enable IGMP on R1 interface")
854 step("Configure r2 loopback interface as RP")
855 step("Enable PIM between r1 and r2")
856 step("Delete RP configuration from r1")
858 step("r1: Delete RP configuration")
864 "rp_addr": "1.0.2.17",
865 "group_addr_range": GROUP_RANGE_ALL
,
873 result
= create_pim_config(tgen
, TOPO
, input_dict
)
874 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
876 step("r1: Verify rp-info")
878 rp_address
= "1.0.2.17"
880 result
= verify_pim_rp_info(
881 tgen
, TOPO
, dut
, GROUP_RANGE_ALL
, iif
, rp_address
, SOURCE
, expected
=False
885 ), "Testcase {} : Failed \n " "r1: rp-info is present \n Error: {}".format(
889 step("joinTx value before join sent")
890 state_dict
= {"r1": {"r1-r2-eth1": ["joinTx"]}}
891 state_before
= get_pim_interface_traffic(tgen
, state_dict
)
894 ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
898 step("r0 : Send IGMP join (225.1.1.1) to r1, when rp is not configured" "in r1")
899 result
= app_helper
.run_join("r0", GROUP_ADDRESS
, "r1")
900 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
902 step("r1: IGMP group is received on R1 verify using show ip igmp groups")
904 result
= verify_igmp_groups(tgen
, dut
, oif
, GROUP_ADDRESS
)
905 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
907 step("r1: Verify upstream IIF interface")
908 result
= verify_upstream_iif(tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
, expected
=False)
909 assert result
is not True, (
910 "Testcase {} : Failed \n "
911 "r1: upstream IFF interface is present \n Error: {}".format(tc_name
, result
)
914 step("r1: Verify upstream join state and join timer")
916 result
= verify_join_state_and_timer(
917 tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
, expected
=False
919 assert result
is not True, (
920 "Testcase {} : Failed \n "
921 "r1: upstream join state is joined and timer is running \n Error: {}".format(
926 step("r1: Verify PIM state")
927 result
= verify_pim_state(tgen
, dut
, iif
, oif
, GROUP_ADDRESS
, expected
=False)
930 ), "Testcase {} : Failed \n " "r1: PIM state is up\n Error: {}".format(
934 step("r1: Verify ip mroutes")
935 result
= verify_mroutes(tgen
, dut
, STAR
, GROUP_ADDRESS
, iif
, oif
, expected
=False)
938 ), "Testcase {} : Failed \n " "r1: mroutes are still present\n Error: {}".format(
942 step("r1: Configure static RP")
948 "rp_addr": "1.0.2.17",
949 "group_addr_range": GROUP_RANGE_ALL
,
956 result
= create_pim_config(tgen
, TOPO
, input_dict
)
957 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
959 step("r1: Verify rp-info")
960 result
= verify_pim_rp_info(
961 tgen
, TOPO
, dut
, GROUP_RANGE_ALL
, iif
, rp_address
, SOURCE
963 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
965 step("r1: Verify upstream IIF interface")
966 result
= verify_upstream_iif(tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
)
967 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
969 step("r1 : Verify upstream join state and join timer")
970 result
= verify_join_state_and_timer(tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
)
971 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
973 step("r1: Verify PIM state")
974 result
= verify_pim_state(tgen
, dut
, iif
, oif
, GROUP_ADDRESS
)
975 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
977 step("r1 : Verify ip mroutes")
978 result
= verify_mroutes(tgen
, dut
, STAR
, GROUP_ADDRESS
, iif
, oif
)
979 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
980 logger
.info("Expected behavior: %s", result
)
982 state_after
= get_pim_interface_traffic(tgen
, state_dict
)
985 ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
989 result
= verify_state_incremented(state_before
, state_after
)
990 assert result
is True, "Testcase {} : Failed Error: {}".format(tc_name
, result
)
992 # Uncomment next line for debugging
995 write_test_footer(tc_name
)
998 def test_reachable_static_RP_after_join_p0(request
):
1000 TC_10_P0 : Verify RP becomes reachable after IGMP join received, PIM join
1001 towards RP is sent immediately
1007 tgen
= get_topogen()
1008 tc_name
= request
.node
.name
1009 write_test_header(tc_name
)
1011 # Don"t run this test if we have any failure.
1012 if tgen
.routers_have_failure():
1013 pytest
.skip(tgen
.errors
)
1015 step("Creating configuration from JSON")
1016 reset_config_on_routers(tgen
)
1017 app_helper
.stop_all_hosts()
1019 clear_pim_interface_traffic(tgen
, TOPO
)
1021 step("Enable IGMP on r1 interface and send IGMP " "join (225.1.1.1) to r1")
1022 step("Configure r2 loopback interface as RP")
1023 step("Enable PIM between r1 and r2")
1025 step("r1 : Verify pim interface traffic")
1026 state_dict
= {"r1": {"r1-r2-eth1": ["joinTx"]}}
1027 state_before
= get_pim_interface_traffic(tgen
, state_dict
)
1030 ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
1031 tc_name
, state_before
1034 step("r1: Make RP un-reachable")
1037 shutdown_bringup_interface(tgen
, dut
, intf
, False)
1039 shutdown_bringup_interface(tgen
, dut
, intf
, False)
1041 shutdown_bringup_interface(tgen
, dut
, intf
, False)
1043 step("r1: Verify rp-info")
1044 rp_address
= "1.0.2.17"
1045 result
= verify_pim_rp_info(
1046 tgen
, TOPO
, dut
, GROUP_ADDRESS
, "Unknown", rp_address
, SOURCE
1048 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1050 step("r1 : Send IGMP join for 225.1.1.1")
1051 result
= app_helper
.run_join("r0", GROUP_ADDRESS
, "r1")
1052 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1054 step("r1 : Verify IGMP groups")
1056 result
= verify_igmp_groups(tgen
, dut
, oif
, GROUP_ADDRESS
)
1057 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1059 step("r1 : Verify upstream IIF interface")
1061 result
= verify_upstream_iif(tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
, expected
=False)
1062 assert result
is not True, (
1063 "Testcase {} : Failed \n "
1064 "r1: upstream IIF interface is present\n Error: {}".format(tc_name
, result
)
1067 step("r1 : Verify upstream join state and join timer")
1068 result
= verify_join_state_and_timer(
1069 tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
, expected
=False
1071 assert result
is not True, (
1072 "Testcase {} : Failed \n "
1073 "r1: upstream join state is joined and timer is running\n Error: {}".format(
1078 step("r1 : Verify PIM state")
1079 result
= verify_pim_state(tgen
, dut
, iif
, oif
, GROUP_ADDRESS
, expected
=False)
1082 ), "Testcase {} : Failed \n " "r1: PIM state is up\n Error: {}".format(
1086 step("r1 : Verify ip mroutes")
1087 result
= verify_mroutes(tgen
, dut
, STAR
, GROUP_ADDRESS
, iif
, oif
, expected
=False)
1090 ), "Testcase {} : Failed \n " "r1: mroutes are still present\n Error: {}".format(
1094 step("r1: Make RP reachable")
1096 shutdown_bringup_interface(tgen
, dut
, intf
, True)
1098 shutdown_bringup_interface(tgen
, dut
, intf
, True)
1100 shutdown_bringup_interface(tgen
, dut
, intf
, True)
1102 step("r1 : Verify rp-info")
1103 result
= verify_pim_rp_info(
1104 tgen
, TOPO
, dut
, GROUP_RANGE_ALL
, iif
, rp_address
, SOURCE
1106 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1108 step("r1: Verify upstream IIF interface")
1109 result
= verify_upstream_iif(tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
)
1110 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1112 step("r1 : Verify upstream join state and join timer")
1113 result
= verify_join_state_and_timer(tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
)
1114 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1116 step("r1 : Verify PIM state")
1117 result
= verify_pim_state(tgen
, dut
, iif
, oif
, GROUP_ADDRESS
)
1118 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1120 step("r1 : Verify ip mroutes")
1121 result
= verify_mroutes(tgen
, dut
, STAR
, GROUP_ADDRESS
, iif
, oif
)
1122 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1123 logger
.info("Expected behavior: %s", result
)
1125 step("r1 : Verify pim interface traffic")
1126 state_after
= get_pim_interface_traffic(tgen
, state_dict
)
1129 ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
1133 result
= verify_state_incremented(state_before
, state_after
)
1134 assert result
is True, "Testcase{} : Failed Error: {}".format(tc_name
, result
)
1136 # Uncomment next line for debugging
1137 # tgen.mininet_cli()
1139 write_test_footer(tc_name
)
1142 def test_send_join_on_higher_preffered_rp_p1(request
):
1144 TC_11_P1 : Verify PIM join send towards the higher preferred RP
1145 TC_12_P1 : Verify PIM prune send towards the lower preferred RP
1146 TC_13_P1 : Verify RPF interface is updated in mroute (kernel) when higher
1147 preferred overlapping RP configured
1148 TC_14_P1 : Verify IIF and OIL in "show ip pim state" updated properly when
1149 higher preferred overlapping RP configured
1150 TC_15_P1 : Verify upstream interfaces(IIF) and join state are updated when
1151 higher preferred overlapping RP is configured
1152 TC_16_P1 : Verify join is send to lower preferred RP, when higher
1153 preferred RP gets deleted
1154 TC_17_P1 : Verify prune is send to higher preferred RP when higher
1155 preferred RP gets deleted
1156 TC_18_P1 : Verify RPF interface updated in mroute when higher preferred RP
1158 TC_19_P1 : Verify IIF and OIL in "show ip pim state" updated when higher
1159 preferred overlapping RP is deleted
1160 TC_20_P1 : Verify PIM upstream IIF updated when higher preferred
1161 overlapping RP deleted
1172 tgen
= get_topogen()
1173 tc_name
= request
.node
.name
1174 write_test_header(tc_name
)
1176 # Don"t run this test if we have any failure.
1177 if tgen
.routers_have_failure():
1178 pytest
.skip(tgen
.errors
)
1180 step("Creating configuration from JSON")
1181 reset_config_on_routers(tgen
)
1182 app_helper
.stop_all_hosts()
1184 clear_pim_interface_traffic(tgen
, TOPO
)
1186 step("Enable IGMP on r1 interface")
1187 step("Configure RP on r2 (loopback interface) for the group range " "224.0.0.0/4")
1188 step("Configure RP on r4 (loopback interface) for the group range " "225.1.1.1/32")
1190 step("r3 : Make all interface not reachable")
1193 shutdown_bringup_interface(tgen
, dut
, intf
, False)
1195 shutdown_bringup_interface(tgen
, dut
, intf
, False)
1197 shutdown_bringup_interface(tgen
, dut
, intf
, False)
1201 shutdown_bringup_interface(tgen
, dut
, intf
, False)
1205 shutdown_bringup_interface(tgen
, dut
, intf
, False)
1209 shutdown_bringup_interface(tgen
, dut
, intf
, False)
1211 step("r1 : Verify joinTx count before sending join")
1212 state_dict
= {"r1": {"r1-r4-eth3": ["joinTx"], "r1-r2-eth1": ["pruneTx"]}}
1214 state_before
= get_pim_interface_traffic(tgen
, state_dict
)
1217 ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
1218 tc_name
, state_before
1221 step("r0 : Send IGMP join for 225.1.1.1")
1222 result
= app_helper
.run_join("r0", GROUP_ADDRESS
, "r1")
1223 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1225 step("r1 : Verify IGMP groups")
1228 result
= verify_igmp_groups(tgen
, dut
, oif
, GROUP_ADDRESS
)
1229 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1231 step("Configure static RP for group 225.1.1.1/32")
1237 "rp_addr": "1.0.4.17",
1238 "group_addr_range": ["225.1.1.1/32"],
1245 result
= create_pim_config(tgen
, TOPO
, input_dict
)
1246 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1248 step("r1 : Verify RP info for group 224.0.0.0/4")
1249 rp_address_1
= "1.0.2.17"
1251 result
= verify_pim_rp_info(
1252 tgen
, TOPO
, dut
, GROUP_RANGE_ALL
, iif
, rp_address_1
, SOURCE
1254 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1256 step("r1 : Verify RP info for group 225.1.1.1")
1257 rp_address_2
= "1.0.4.17"
1259 result
= verify_pim_rp_info(tgen
, TOPO
, dut
, GROUP_RANGE
, iif
, rp_address_2
, SOURCE
)
1260 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1262 step("r1 : Verify join is sent to higher preferred RP")
1263 step("r1 : Verify prune is sent to lower preferred RP")
1264 state_after
= get_pim_interface_traffic(tgen
, state_dict
)
1267 ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
1271 result
= verify_state_incremented(state_before
, state_after
)
1272 assert result
is True, "Testcase{} : Failed Error: {}".format(tc_name
, result
)
1274 step("r1 : Verify ip mroutes")
1276 result
= verify_mroutes(tgen
, dut
, STAR
, GROUP_ADDRESS
, iif
, oif
)
1277 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1279 step("r1 : Verify PIM state")
1280 result
= verify_pim_state(tgen
, dut
, iif
, oif
, GROUP_ADDRESS
)
1281 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1283 step("r1 : Verify upstream IIF interface")
1284 result
= verify_upstream_iif(tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
)
1285 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1287 step("r1 : Verify upstream join state and join timer")
1288 result
= verify_join_state_and_timer(tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
)
1289 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1291 clear_pim_interface_traffic(tgen
, TOPO
)
1293 step("r1 : Verify joinTx, pruneTx count before RP gets deleted")
1294 state_dict
= {"r1": {"r1-r2-eth1": ["joinTx"], "r1-r4-eth3": ["pruneTx"]}}
1296 state_before
= get_pim_interface_traffic(tgen
, state_dict
)
1299 ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
1303 step("r1 : Delete RP configuration for 225.1.1.1")
1309 "rp_addr": "1.0.4.17",
1310 "group_addr_range": ["225.1.1.1/32"],
1318 result
= create_pim_config(tgen
, TOPO
, input_dict
)
1319 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1321 step("r1 : Verify rp-info for group 224.0.0.0/4")
1323 result
= verify_pim_rp_info(
1324 tgen
, TOPO
, dut
, GROUP_RANGE_ALL
, iif
, rp_address_1
, SOURCE
1326 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1328 step("r1 : Verify rp-info for group 225.1.1.1")
1330 result
= verify_pim_rp_info(
1331 tgen
, TOPO
, dut
, GROUP_RANGE
, oif
, rp_address_2
, SOURCE
, expected
=False
1333 assert result
is not True, (
1334 "Testcase {} : Failed \n "
1335 "r1: rp-info is present for group 225.1.1.1 \n Error: {}".format(
1341 "r1 : Verify RPF interface updated in mroute when higher preferred"
1345 result
= verify_mroutes(tgen
, dut
, STAR
, GROUP_ADDRESS
, iif
, oif
)
1346 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1347 logger
.info("Expected behavior: %s", result
)
1350 "r1 : Verify IIF and OIL in show ip pim state updated when higher"
1351 "preferred overlapping RP is deleted"
1353 result
= verify_pim_state(tgen
, dut
, iif
, oif
, GROUP_ADDRESS
)
1354 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1357 "r1 : Verify upstream IIF updated when higher preferred overlapping"
1360 result
= verify_upstream_iif(tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
)
1361 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1364 "r1 : Verify upstream join state and join timer updated when higher"
1365 "preferred overlapping RP deleted"
1367 result
= verify_join_state_and_timer(tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
)
1368 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1371 "r1 : Verify join is sent to lower preferred RP, when higher"
1372 "preferred RP gets deleted"
1375 "r1 : Verify prune is sent to higher preferred RP when higher"
1376 " preferred RP gets deleted"
1378 state_after
= get_pim_interface_traffic(tgen
, state_dict
)
1381 ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
1385 result
= verify_state_incremented(state_before
, state_after
)
1386 assert result
is True, "Testcase{} : Failed Error: {}".format(tc_name
, result
)
1388 # Uncomment next line for debugging
1389 # tgen.mininet_cli()
1391 write_test_footer(tc_name
)
1394 if __name__
== "__main__":
1395 ARGS
= ["-s"] + sys
.argv
[1:]
1396 sys
.exit(pytest
.main(ARGS
))