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 # Starting topology, create tmp files which are loaded to routers
227 # to start daemons and then start routers
230 # Don"t run this test if we have any failure.
231 if tgen
.routers_have_failure():
232 pytest
.skip(tgen
.errors
)
234 # Creating configuration from JSON
235 build_config_from_json(tgen
, TOPO
)
237 # Verify PIM neighbors
238 result
= verify_pim_neighbors(tgen
, TOPO
)
239 assert result
is True, "setup_module :Failed \n Error:" " {}".format(result
)
241 # XXX Replace this using "with McastTesterHelper()... " in each test if possible.
243 app_helper
= McastTesterHelper(tgen
)
245 logger
.info("Running setup_module() done")
248 def teardown_module():
249 """Teardown the pytest environment"""
251 logger
.info("Running teardown_module to delete topology")
257 # Stop toplogy and Remove tmp files
260 logger
.info("Testsuite end time: %s", time
.asctime(time
.localtime(time
.time())))
261 logger
.info("=" * 40)
264 #####################################################
268 #####################################################
271 def verify_mroute_repopulated(uptime_before
, uptime_after
):
273 API to compare uptime for mroutes
277 * `uptime_before` : Uptime dictionary for any particular instance
278 * `uptime_after` : Uptime dictionary for any particular instance
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
]):
285 "mroute (%s, %s) has not come"
286 " up after mroute clear [FAILED!!]" % (source
, group
)
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")
293 errormsg
= "mroute (%s, %s) is not " "repopulated [FAILED!!]" % (
299 logger
.info("mroute (%s, %s) is " "repopulated [PASSED!!]", source
, group
)
304 def verify_state_incremented(state_before
, state_after
):
306 API to compare interface traffic state incrementing
310 * `state_before` : State dictionary for any particular instance
311 * `state_after` : State dictionary for any particular instance
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
]:
318 "[DUT: %s]: state %s value has not"
319 " incremented, Initial value: %s, "
320 "Current value: %s [FAILED!!]"
324 state_before
[router
][state
],
325 state_after
[router
][state
],
331 "[DUT: %s]: State %s value is "
332 "incremented, Initial value: %s, Current value: %s"
336 state_before
[router
][state
],
337 state_after
[router
][state
],
343 def test_add_delete_static_RP_p0(request
):
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
359 tc_name
= request
.node
.name
360 write_test_header(tc_name
)
362 # Don"t run this test if we have any failure.
363 if tgen
.routers_have_failure():
364 pytest
.skip(tgen
.errors
)
366 step("pre-configuration to send IGMP join and multicast traffic")
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")
372 step("r1: Verify show ip igmp group without any IGMP join")
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 "r1: igmp group present without any IGMP join \n Error: {}".format(
383 step("r1: Verify show ip pim interface traffic without any IGMP join")
384 state_dict
= {"r1": {"r1-r2-eth1": ["pruneTx"]}}
386 state_before
= get_pim_interface_traffic(tgen
, state_dict
)
389 ), "Testcase {} : Failed \n state_before is not dictionary\n Error: {}".format(
393 step("r0 : Send IGMP join")
394 result
= app_helper
.run_join("r0", GROUP_ADDRESS
, "r1")
395 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
397 step("r1: Verify IGMP groups")
399 result
= verify_igmp_groups(tgen
, dut
, oif
, GROUP_ADDRESS
)
400 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
402 step("r1: Verify RP info")
405 rp_address
= "1.0.2.17"
406 result
= verify_pim_rp_info(
407 tgen
, TOPO
, dut
, GROUP_RANGE_ALL
, iif
, rp_address
, SOURCE
409 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
411 step("r1: Verify upstream IIF interface")
412 result
= verify_upstream_iif(tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
)
413 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
415 step("r1: Verify upstream join state and join timer")
416 result
= verify_join_state_and_timer(tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
)
417 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
418 step("r1: Verify ip mroutes")
419 result
= verify_mroutes(tgen
, dut
, STAR
, GROUP_ADDRESS
, iif
, oif
)
420 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
422 step("r1: Verify ip pim join")
423 result
= verify_join_state_and_timer(tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
)
424 step("r1: Delete RP configuration")
426 # Delete RP configuration
432 "rp_addr": "1.0.2.17",
433 "group_addr_range": GROUP_RANGE_ALL
,
441 result
= create_pim_config(tgen
, TOPO
, input_dict
)
442 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
444 step("r1: Verify RP info")
445 result
= verify_pim_rp_info(
446 tgen
, TOPO
, dut
, GROUP_RANGE_ALL
, iif
, rp_address
, SOURCE
, expected
=False
450 ), "Testcase {} : Failed \n " "r1: RP info present \n Error: {}".format(
454 step("r1: Verify upstream IIF interface")
455 result
= verify_upstream_iif(tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
, expected
=False)
456 assert result
is not True, (
457 "Testcase {} : Failed \n "
458 "r1: upstream IIF interface present \n Error: {}".format(tc_name
, result
)
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
465 assert result
is not True, (
466 "Testcase {} : Failed \n "
467 "r1: upstream join state is up and join timer is running \n Error: {}".format(
473 step("r1: Verify PIM state")
474 result
= verify_pim_state(tgen
, dut
, iif
, oif
, GROUP_ADDRESS
, expected
=False)
475 assert result
is not True, "Testcase {} :Failed \n Error: {}".format(
479 step("r1: Verify ip mroutes")
480 result
= verify_mroutes(tgen
, dut
, STAR
, GROUP_ADDRESS
, iif
, oif
, expected
=False)
483 ), "Testcase {} : Failed \n " "r1: mroutes are still present \n Error: {}".format(
487 step("r1: Verify show ip pim interface traffic without any IGMP join")
488 state_after
= get_pim_interface_traffic(tgen
, state_dict
)
491 ), "Testcase {} : Failed \n state_before is not dictionary \n Error: {}".format(
495 result
= verify_state_incremented(state_before
, state_after
)
496 assert result
is True, "Testcase{} : Failed Error: {}".format(tc_name
, result
)
498 # Uncomment next line for debugging
501 write_test_footer(tc_name
)
504 def test_SPT_RPT_path_same_p1(request
):
506 TC_24_P1 : Verify (*,G) and (S,G) populated correctly when SPT and RPT
521 tc_name
= request
.node
.name
522 write_test_header(tc_name
)
524 # Don"t run this test if we have any failure.
525 if tgen
.routers_have_failure():
526 pytest
.skip(tgen
.errors
)
528 step("Creating configuration from JSON")
529 reset_config_on_routers(tgen
)
530 app_helper
.stop_all_hosts()
532 clear_pim_interface_traffic(tgen
, TOPO
)
536 shutdown_bringup_interface(tgen
, dut
, intf
, False)
538 shutdown_bringup_interface(tgen
, dut
, intf
, False)
542 shutdown_bringup_interface(tgen
, dut
, intf
, False)
544 shutdown_bringup_interface(tgen
, dut
, intf
, False)
546 step("Enable IGMP on r1 interface and send IGMP join (225.1.1.1) to R1")
547 step("Configure RP on r2 (loopback interface) for the group range" " 224.0.0.0/4")
548 step("Enable the PIM on all the interfaces of r1, r2, r3 and r4 routers")
549 step("Send multicast traffic from R3")
551 step("r2: Verify RP info")
553 rp_address
= "1.0.2.17"
555 result
= verify_pim_rp_info(
556 tgen
, TOPO
, dut
, GROUP_RANGE_ALL
, iif
, rp_address
, SOURCE
558 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
560 step("r0: Send IGMP join")
561 result
= app_helper
.run_join("r0", GROUP_ADDRESS
, "r1")
562 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
564 step("r1: Verify IGMP groups")
567 result
= verify_igmp_groups(tgen
, dut
, oif
, GROUP_ADDRESS
)
568 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
570 step("r5: Send multicast traffic for group 225.1.1.1")
571 result
= app_helper
.run_traffic("r5", GROUP_ADDRESS
, "r3")
572 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
574 step("r1: Verify (*, G) upstream IIF interface")
577 result
= verify_upstream_iif(tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
)
578 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
580 step("r1: Verify (*, G) upstream join state and join timer")
581 result
= verify_join_state_and_timer(tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
)
582 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
584 step("r1: Verify (*, G) ip mroutes")
585 result
= verify_mroutes(tgen
, dut
, STAR
, GROUP_ADDRESS
, iif
, oif
)
586 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
588 step("r1: Verify (S, G) upstream IIF interface")
590 result
= verify_upstream_iif(tgen
, dut
, iif
, SOURCE_ADDRESS
, GROUP_ADDRESS
)
591 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
593 step("r1: Verify (S, G) upstream join state and join timer")
594 result
= verify_join_state_and_timer(tgen
, dut
, iif
, SOURCE_ADDRESS
, GROUP_ADDRESS
)
595 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
597 step("r1: Verify (S, G) ip mroutes")
598 result
= verify_mroutes(tgen
, dut
, SOURCE_ADDRESS
, GROUP_ADDRESS
, iif
, oif
)
599 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
601 step("r2: Verify (*, G) upstream IIF interface")
604 result
= verify_upstream_iif(tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
)
605 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
607 step("r2: Verify (*, G) upstream join state and join timer")
608 result
= verify_join_state_and_timer(tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
)
609 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
611 step("r2: Verify (*, G) ip mroutes")
613 result
= verify_mroutes(tgen
, dut
, STAR
, GROUP_ADDRESS
, iif
, oif
)
614 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
616 step("r2: Verify (S, G) upstream IIF interface")
618 result
= verify_upstream_iif(tgen
, dut
, iif
, SOURCE_ADDRESS
, GROUP_ADDRESS
)
619 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
621 step("r2: Verify (S, G) upstream join state and join timer")
622 result
= verify_join_state_and_timer(tgen
, dut
, iif
, SOURCE_ADDRESS
, GROUP_ADDRESS
)
623 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
625 step("r2: Verify (S, G) ip mroutes")
626 result
= verify_mroutes(tgen
, dut
, SOURCE_ADDRESS
, GROUP_ADDRESS
, iif
, oif
)
627 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
629 step("r3: Verify (S, G) upstream IIF interface")
632 result
= verify_upstream_iif(tgen
, dut
, iif
, SOURCE_ADDRESS
, GROUP_ADDRESS
)
633 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
635 step("r3: Verify (S, G) upstream join state and join timer")
636 result
= verify_join_state_and_timer(
637 tgen
, dut
, iif
, SOURCE_ADDRESS
, GROUP_ADDRESS
, expected
=False
639 assert result
is not True, (
640 "Testcase {} : Failed \n "
641 "r3: (S, G) upstream join state is up and join timer is running\n Error: {}".format(
646 step("r3: Verify (S, G) ip mroutes")
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
)
651 # Uncomment next line for debugging
654 write_test_footer(tc_name
)
657 def test_not_reachable_static_RP_p0(request
):
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
673 tc_name
= request
.node
.name
674 write_test_header(tc_name
)
676 # Don"t run this test if we have any failure.
677 if tgen
.routers_have_failure():
678 pytest
.skip(tgen
.errors
)
680 step("Creating configuration from JSON")
681 reset_config_on_routers(tgen
)
682 app_helper
.stop_all_hosts()
684 clear_pim_interface_traffic(tgen
, TOPO
)
688 shutdown_bringup_interface(tgen
, dut
, intf
, False)
692 shutdown_bringup_interface(tgen
, dut
, intf
, False)
695 "r1: (*,G) prune is not sent towards the RP interface, verify using"
696 "show ip pim interface traffic"
698 state_dict
= {"r1": {"r1-r2-eth1": ["pruneTx"]}}
699 state_before
= get_pim_interface_traffic(tgen
, state_dict
)
702 ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
703 tc_name
, state_before
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")
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
)
714 step("r1 : Verify rp info")
717 rp_address
= "1.0.2.17"
718 result
= verify_pim_rp_info(
719 tgen
, TOPO
, dut
, GROUP_RANGE_ALL
, iif
, rp_address
, SOURCE
721 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
723 step("r1: Verify IGMP groups")
725 result
= verify_igmp_groups(tgen
, dut
, oif
, GROUP_ADDRESS
)
726 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
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
)
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
)
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
)
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
)
744 step("r1: Make RP un-reachable")
749 {"network": "1.0.2.17/32", "next_hop": "10.0.1.2", "delete": True}
754 result
= create_static_routes(tgen
, input_dict
)
755 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
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
761 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
764 "r1 : OIL should be same and IIF should be cleared on R1 verify"
765 "using show ip pim state"
767 result
= verify_pim_state(tgen
, dut
, iif
, oif
, GROUP_ADDRESS
, expected
=False)
768 assert result
is not True, (
769 "Testcase {} : Failed \n "
770 "OIL is not same and IIF is not cleared on R1 \n Error: {}".format(
775 step("r1: upstream IIF should be unknown , verify using show ip pim" "upstream")
776 result
= verify_upstream_iif(tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
, expected
=False)
777 assert result
is not True, (
778 "Testcase {} : Failed \n "
779 "r1: upstream IIF is not unknown \n Error: {}".format(tc_name
, result
)
783 "r1: join state should not be joined and join timer should stop,"
784 "verify using show ip pim upstream"
786 result
= verify_join_state_and_timer(
787 tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
, expected
=False
789 assert result
is not True, (
790 "Testcase {} : Failed \n "
791 "r1: join state is joined and timer is not stopped \n Error: {}".format(
797 "r1: (*,G) prune is sent towards the RP interface, verify using"
798 "show ip pim interface traffic"
800 state_after
= get_pim_interface_traffic(tgen
, state_dict
)
803 ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
807 result
= verify_state_incremented(state_before
, state_after
)
808 assert result
is True, "Testcase{} : Failed Error: {}".format(tc_name
, result
)
810 step("r1: (*, G) cleared from mroute table using show ip mroute")
811 result
= verify_mroutes(tgen
, dut
, STAR
, GROUP_ADDRESS
, iif
, oif
, expected
=False)
812 assert result
is not True, (
813 "Testcase {} : Failed \n "
814 "r1: (*, G) are not cleared from mroute table \n Error: {}".format(
818 logger
.info("Expected behavior: %s", result
)
820 # Uncomment next line for debugging
823 write_test_footer(tc_name
)
826 def test_add_RP_after_join_received_p1(request
):
828 TC_9_P1 : Verify RP configured after IGMP join received, PIM join towards
829 RP is sent immediately
837 tc_name
= request
.node
.name
838 write_test_header(tc_name
)
840 # Don"t run this test if we have any failure.
841 if tgen
.routers_have_failure():
842 pytest
.skip(tgen
.errors
)
844 step("Creating configuration from JSON")
845 reset_config_on_routers(tgen
)
846 app_helper
.stop_all_hosts()
848 clear_pim_interface_traffic(tgen
, TOPO
)
850 step("Enable IGMP on R1 interface")
851 step("Configure r2 loopback interface as RP")
852 step("Enable PIM between r1 and r2")
853 step("Delete RP configuration from r1")
855 step("r1: Delete RP configuration")
861 "rp_addr": "1.0.2.17",
862 "group_addr_range": GROUP_RANGE_ALL
,
870 result
= create_pim_config(tgen
, TOPO
, input_dict
)
871 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
873 step("r1: Verify rp-info")
875 rp_address
= "1.0.2.17"
877 result
= verify_pim_rp_info(
878 tgen
, TOPO
, dut
, GROUP_RANGE_ALL
, iif
, rp_address
, SOURCE
, expected
=False
882 ), "Testcase {} : Failed \n " "r1: rp-info is present \n Error: {}".format(
886 step("joinTx value before join sent")
887 state_dict
= {"r1": {"r1-r2-eth1": ["joinTx"]}}
888 state_before
= get_pim_interface_traffic(tgen
, state_dict
)
891 ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
895 step("r0 : Send IGMP join (225.1.1.1) to r1, when rp is not configured" "in r1")
896 result
= app_helper
.run_join("r0", GROUP_ADDRESS
, "r1")
897 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
899 step("r1: IGMP group is received on R1 verify using show ip igmp groups")
901 result
= verify_igmp_groups(tgen
, dut
, oif
, GROUP_ADDRESS
)
902 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
904 step("r1: Verify upstream IIF interface")
905 result
= verify_upstream_iif(tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
, expected
=False)
906 assert result
is not True, (
907 "Testcase {} : Failed \n "
908 "r1: upstream IFF interface is present \n Error: {}".format(tc_name
, result
)
911 step("r1: Verify upstream join state and join timer")
913 result
= verify_join_state_and_timer(
914 tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
, expected
=False
916 assert result
is not True, (
917 "Testcase {} : Failed \n "
918 "r1: upstream join state is joined and timer is running \n Error: {}".format(
923 step("r1: Verify PIM state")
924 result
= verify_pim_state(tgen
, dut
, iif
, oif
, GROUP_ADDRESS
, expected
=False)
927 ), "Testcase {} : Failed \n " "r1: PIM state is up\n Error: {}".format(
931 step("r1: Verify ip mroutes")
932 result
= verify_mroutes(tgen
, dut
, STAR
, GROUP_ADDRESS
, iif
, oif
, expected
=False)
935 ), "Testcase {} : Failed \n " "r1: mroutes are still present\n Error: {}".format(
939 step("r1: Configure static RP")
945 "rp_addr": "1.0.2.17",
946 "group_addr_range": GROUP_RANGE_ALL
,
953 result
= create_pim_config(tgen
, TOPO
, input_dict
)
954 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
956 step("r1: Verify rp-info")
957 result
= verify_pim_rp_info(
958 tgen
, TOPO
, dut
, GROUP_RANGE_ALL
, iif
, rp_address
, SOURCE
960 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
962 step("r1: Verify upstream IIF interface")
963 result
= verify_upstream_iif(tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
)
964 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
966 step("r1 : Verify upstream join state and join timer")
967 result
= verify_join_state_and_timer(tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
)
968 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
970 step("r1: Verify PIM state")
971 result
= verify_pim_state(tgen
, dut
, iif
, oif
, GROUP_ADDRESS
)
972 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
974 step("r1 : Verify ip mroutes")
975 result
= verify_mroutes(tgen
, dut
, STAR
, GROUP_ADDRESS
, iif
, oif
)
976 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
977 logger
.info("Expected behavior: %s", result
)
979 state_after
= get_pim_interface_traffic(tgen
, state_dict
)
982 ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
986 result
= verify_state_incremented(state_before
, state_after
)
987 assert result
is True, "Testcase {} : Failed Error: {}".format(tc_name
, result
)
989 # Uncomment next line for debugging
992 write_test_footer(tc_name
)
995 def test_reachable_static_RP_after_join_p0(request
):
997 TC_10_P0 : Verify RP becomes reachable after IGMP join received, PIM join
998 towards RP is sent immediately
1004 tgen
= get_topogen()
1005 tc_name
= request
.node
.name
1006 write_test_header(tc_name
)
1008 # Don"t run this test if we have any failure.
1009 if tgen
.routers_have_failure():
1010 pytest
.skip(tgen
.errors
)
1012 step("Creating configuration from JSON")
1013 reset_config_on_routers(tgen
)
1014 app_helper
.stop_all_hosts()
1016 clear_pim_interface_traffic(tgen
, TOPO
)
1018 step("Enable IGMP on r1 interface and send IGMP " "join (225.1.1.1) to r1")
1019 step("Configure r2 loopback interface as RP")
1020 step("Enable PIM between r1 and r2")
1022 step("r1 : Verify pim interface traffic")
1023 state_dict
= {"r1": {"r1-r2-eth1": ["joinTx"]}}
1024 state_before
= get_pim_interface_traffic(tgen
, state_dict
)
1027 ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
1028 tc_name
, state_before
1031 step("r1: Make RP un-reachable")
1034 shutdown_bringup_interface(tgen
, dut
, intf
, False)
1036 shutdown_bringup_interface(tgen
, dut
, intf
, False)
1038 shutdown_bringup_interface(tgen
, dut
, intf
, False)
1040 step("r1: Verify rp-info")
1041 rp_address
= "1.0.2.17"
1042 result
= verify_pim_rp_info(
1043 tgen
, TOPO
, dut
, GROUP_ADDRESS
, "Unknown", rp_address
, SOURCE
1045 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1047 step("r1 : Send IGMP join for 225.1.1.1")
1048 result
= app_helper
.run_join("r0", GROUP_ADDRESS
, "r1")
1049 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1051 step("r1 : Verify IGMP groups")
1053 result
= verify_igmp_groups(tgen
, dut
, oif
, GROUP_ADDRESS
)
1054 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1056 step("r1 : Verify upstream IIF interface")
1058 result
= verify_upstream_iif(tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
, expected
=False)
1059 assert result
is not True, (
1060 "Testcase {} : Failed \n "
1061 "r1: upstream IIF interface is present\n Error: {}".format(tc_name
, result
)
1064 step("r1 : Verify upstream join state and join timer")
1065 result
= verify_join_state_and_timer(
1066 tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
, expected
=False
1068 assert result
is not True, (
1069 "Testcase {} : Failed \n "
1070 "r1: upstream join state is joined and timer is running\n Error: {}".format(
1075 step("r1 : Verify PIM state")
1076 result
= verify_pim_state(tgen
, dut
, iif
, oif
, GROUP_ADDRESS
, expected
=False)
1079 ), "Testcase {} : Failed \n " "r1: PIM state is up\n Error: {}".format(
1083 step("r1 : Verify ip mroutes")
1084 result
= verify_mroutes(tgen
, dut
, STAR
, GROUP_ADDRESS
, iif
, oif
, expected
=False)
1087 ), "Testcase {} : Failed \n " "r1: mroutes are still present\n Error: {}".format(
1091 step("r1: Make RP reachable")
1093 shutdown_bringup_interface(tgen
, dut
, intf
, True)
1095 shutdown_bringup_interface(tgen
, dut
, intf
, True)
1097 shutdown_bringup_interface(tgen
, dut
, intf
, True)
1099 step("r1 : Verify rp-info")
1100 result
= verify_pim_rp_info(
1101 tgen
, TOPO
, dut
, GROUP_RANGE_ALL
, iif
, rp_address
, SOURCE
1103 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1105 step("r1: Verify upstream IIF interface")
1106 result
= verify_upstream_iif(tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
)
1107 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1109 step("r1 : Verify upstream join state and join timer")
1110 result
= verify_join_state_and_timer(tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
)
1111 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1113 step("r1 : Verify PIM state")
1114 result
= verify_pim_state(tgen
, dut
, iif
, oif
, GROUP_ADDRESS
)
1115 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1117 step("r1 : Verify ip mroutes")
1118 result
= verify_mroutes(tgen
, dut
, STAR
, GROUP_ADDRESS
, iif
, oif
)
1119 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1120 logger
.info("Expected behavior: %s", result
)
1122 step("r1 : Verify pim interface traffic")
1123 state_after
= get_pim_interface_traffic(tgen
, state_dict
)
1126 ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
1130 result
= verify_state_incremented(state_before
, state_after
)
1131 assert result
is True, "Testcase{} : Failed Error: {}".format(tc_name
, result
)
1133 # Uncomment next line for debugging
1134 # tgen.mininet_cli()
1136 write_test_footer(tc_name
)
1139 def test_send_join_on_higher_preffered_rp_p1(request
):
1141 TC_11_P1 : Verify PIM join send towards the higher preferred RP
1142 TC_12_P1 : Verify PIM prune send towards the lower preferred RP
1143 TC_13_P1 : Verify RPF interface is updated in mroute (kernel) when higher
1144 preferred overlapping RP configured
1145 TC_14_P1 : Verify IIF and OIL in "show ip pim state" updated properly when
1146 higher preferred overlapping RP configured
1147 TC_15_P1 : Verify upstream interfaces(IIF) and join state are updated when
1148 higher preferred overlapping RP is configured
1149 TC_16_P1 : Verify join is send to lower preferred RP, when higher
1150 preferred RP gets deleted
1151 TC_17_P1 : Verify prune is send to higher preferred RP when higher
1152 preferred RP gets deleted
1153 TC_18_P1 : Verify RPF interface updated in mroute when higher preferred RP
1155 TC_19_P1 : Verify IIF and OIL in "show ip pim state" updated when higher
1156 preferred overlapping RP is deleted
1157 TC_20_P1 : Verify PIM upstream IIF updated when higher preferred
1158 overlapping RP deleted
1169 tgen
= get_topogen()
1170 tc_name
= request
.node
.name
1171 write_test_header(tc_name
)
1173 # Don"t run this test if we have any failure.
1174 if tgen
.routers_have_failure():
1175 pytest
.skip(tgen
.errors
)
1177 step("Creating configuration from JSON")
1178 reset_config_on_routers(tgen
)
1179 app_helper
.stop_all_hosts()
1181 clear_pim_interface_traffic(tgen
, TOPO
)
1183 step("Enable IGMP on r1 interface")
1184 step("Configure RP on r2 (loopback interface) for the group range " "224.0.0.0/4")
1185 step("Configure RP on r4 (loopback interface) for the group range " "225.1.1.1/32")
1187 step("r3 : Make all interface not reachable")
1190 shutdown_bringup_interface(tgen
, dut
, intf
, False)
1192 shutdown_bringup_interface(tgen
, dut
, intf
, False)
1194 shutdown_bringup_interface(tgen
, dut
, intf
, False)
1198 shutdown_bringup_interface(tgen
, dut
, intf
, False)
1202 shutdown_bringup_interface(tgen
, dut
, intf
, False)
1206 shutdown_bringup_interface(tgen
, dut
, intf
, False)
1208 step("r1 : Verify joinTx count before sending join")
1209 state_dict
= {"r1": {"r1-r4-eth3": ["joinTx"], "r1-r2-eth1": ["pruneTx"]}}
1211 state_before
= get_pim_interface_traffic(tgen
, state_dict
)
1214 ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
1215 tc_name
, state_before
1218 step("r0 : Send IGMP join for 225.1.1.1")
1219 result
= app_helper
.run_join("r0", GROUP_ADDRESS
, "r1")
1220 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1222 step("r1 : Verify IGMP groups")
1225 result
= verify_igmp_groups(tgen
, dut
, oif
, GROUP_ADDRESS
)
1226 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1228 step("Configure static RP for group 225.1.1.1/32")
1234 "rp_addr": "1.0.4.17",
1235 "group_addr_range": ["225.1.1.1/32"],
1242 result
= create_pim_config(tgen
, TOPO
, input_dict
)
1243 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1245 step("r1 : Verify RP info for group 224.0.0.0/4")
1246 rp_address_1
= "1.0.2.17"
1248 result
= verify_pim_rp_info(
1249 tgen
, TOPO
, dut
, GROUP_RANGE_ALL
, iif
, rp_address_1
, SOURCE
1251 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1253 step("r1 : Verify RP info for group 225.1.1.1")
1254 rp_address_2
= "1.0.4.17"
1256 result
= verify_pim_rp_info(tgen
, TOPO
, dut
, GROUP_RANGE
, iif
, rp_address_2
, SOURCE
)
1257 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1259 step("r1 : Verify join is sent to higher preferred RP")
1260 step("r1 : Verify prune is sent to lower preferred RP")
1261 state_after
= get_pim_interface_traffic(tgen
, state_dict
)
1264 ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
1268 result
= verify_state_incremented(state_before
, state_after
)
1269 assert result
is True, "Testcase{} : Failed Error: {}".format(tc_name
, result
)
1271 step("r1 : Verify ip mroutes")
1273 result
= verify_mroutes(tgen
, dut
, STAR
, GROUP_ADDRESS
, iif
, oif
)
1274 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1276 step("r1 : Verify PIM state")
1277 result
= verify_pim_state(tgen
, dut
, iif
, oif
, GROUP_ADDRESS
)
1278 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1280 step("r1 : Verify upstream IIF interface")
1281 result
= verify_upstream_iif(tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
)
1282 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1284 step("r1 : Verify upstream join state and join timer")
1285 result
= verify_join_state_and_timer(tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
)
1286 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1288 clear_pim_interface_traffic(tgen
, TOPO
)
1290 step("r1 : Verify joinTx, pruneTx count before RP gets deleted")
1291 state_dict
= {"r1": {"r1-r2-eth1": ["joinTx"], "r1-r4-eth3": ["pruneTx"]}}
1293 state_before
= get_pim_interface_traffic(tgen
, state_dict
)
1296 ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
1300 step("r1 : Delete RP configuration for 225.1.1.1")
1306 "rp_addr": "1.0.4.17",
1307 "group_addr_range": ["225.1.1.1/32"],
1315 result
= create_pim_config(tgen
, TOPO
, input_dict
)
1316 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1318 step("r1 : Verify rp-info for group 224.0.0.0/4")
1320 result
= verify_pim_rp_info(
1321 tgen
, TOPO
, dut
, GROUP_RANGE_ALL
, iif
, rp_address_1
, SOURCE
1323 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1325 step("r1 : Verify rp-info for group 225.1.1.1")
1327 result
= verify_pim_rp_info(
1328 tgen
, TOPO
, dut
, GROUP_RANGE
, oif
, rp_address_2
, SOURCE
, expected
=False
1330 assert result
is not True, (
1331 "Testcase {} : Failed \n "
1332 "r1: rp-info is present for group 225.1.1.1 \n Error: {}".format(
1338 "r1 : Verify RPF interface updated in mroute when higher preferred"
1342 result
= verify_mroutes(tgen
, dut
, STAR
, GROUP_ADDRESS
, iif
, oif
)
1343 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1344 logger
.info("Expected behavior: %s", result
)
1347 "r1 : Verify IIF and OIL in show ip pim state updated when higher"
1348 "preferred overlapping RP is deleted"
1350 result
= verify_pim_state(tgen
, dut
, iif
, oif
, GROUP_ADDRESS
)
1351 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1354 "r1 : Verify upstream IIF updated when higher preferred overlapping"
1357 result
= verify_upstream_iif(tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
)
1358 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1361 "r1 : Verify upstream join state and join timer updated when higher"
1362 "preferred overlapping RP deleted"
1364 result
= verify_join_state_and_timer(tgen
, dut
, iif
, STAR
, GROUP_ADDRESS
)
1365 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1368 "r1 : Verify join is sent to lower preferred RP, when higher"
1369 "preferred RP gets deleted"
1372 "r1 : Verify prune is sent to higher preferred RP when higher"
1373 " preferred RP gets deleted"
1375 state_after
= get_pim_interface_traffic(tgen
, state_dict
)
1378 ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
1382 result
= verify_state_incremented(state_before
, state_after
)
1383 assert result
is True, "Testcase{} : Failed Error: {}".format(tc_name
, result
)
1385 # Uncomment next line for debugging
1386 # tgen.mininet_cli()
1388 write_test_footer(tc_name
)
1391 if __name__
== "__main__":
1392 ARGS
= ["-s"] + sys
.argv
[1:]
1393 sys
.exit(pytest
.main(ARGS
))