From: sarita patra Date: Mon, 9 May 2022 11:03:52 +0000 (-0700) Subject: tests: Inroduced pim passive test cases X-Git-Tag: base_8.3~74^2 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=c28e6ef53c9e3a3e62d1a40381ab6aedbf13a142;p=matthieu%2Ffrr.git tests: Inroduced pim passive test cases Co-authored-by: Vijay Kumar Gupta Signed-off-by: sarita patra --- diff --git a/tests/topotests/lib/pim.py b/tests/topotests/lib/pim.py index 1423f3fecc..47892a5218 100644 --- a/tests/topotests/lib/pim.py +++ b/tests/topotests/lib/pim.py @@ -3550,6 +3550,69 @@ class McastTesterHelper(HostApplicationHelper): return True + +def verify_pim_interface_traffic(tgen, input_dict, return_stats=True): + """ + Verify ip pim interface traffice by running + "show ip pim interface traffic" cli + + Parameters + ---------- + * `tgen`: topogen object + * `input_dict(dict)`: defines DUT, what and from which interfaces + traffic needs to be verified + Usage + ----- + input_dict = { + "r1": { + "r1-r0-eth0": { + "helloRx": 0, + "helloTx": 1, + "joinRx": 0, + "joinTx": 0 + } + } + } + + result = verify_pim_interface_traffic(tgen, input_dict) + + Returns + ------- + errormsg(str) or True + """ + + logger.debug("Entering lib API: {}".format(sys._getframe().f_code.co_name)) + + output_dict = {} + for dut in input_dict.keys(): + if dut not in tgen.routers(): + continue + + rnode = tgen.routers()[dut] + + logger.info("[DUT: %s]: Verifying pim interface traffic", dut) + show_pim_intf_traffic_json = run_frr_cmd( + rnode, "show ip pim interface traffic json", isjson=True + ) + + output_dict[dut] = {} + for intf, data in input_dict[dut].items(): + interface_json = show_pim_intf_traffic_json[intf] + for state in data: + + # Verify Tx/Rx + if state in interface_json: + output_dict[dut][state] = interface_json[state] + else: + errormsg = ( + "[DUT %s]: %s is not present" + "for interface %s [FAILED]!! " % (dut, state, intf) + ) + return errormsg + + logger.debug("Exiting lib API: {}".format(sys._getframe().f_code.co_name)) + return True if return_stats == False else output_dict + # def cleanup(self): # super(McastTesterHelper, self).cleanup() diff --git a/tests/topotests/multicast_pim_sm_topo3/test_multicast_pim_sm_topo3.py b/tests/topotests/multicast_pim_sm_topo3/test_multicast_pim_sm_topo3.py index cbd1090648..b71c2d65eb 100755 --- a/tests/topotests/multicast_pim_sm_topo3/test_multicast_pim_sm_topo3.py +++ b/tests/topotests/multicast_pim_sm_topo3/test_multicast_pim_sm_topo3.py @@ -54,6 +54,7 @@ import sys import time import datetime import pytest +from time import sleep pytestmark = pytest.mark.pimd @@ -95,6 +96,7 @@ from lib.pim import ( verify_pim_rp_info, verify_multicast_flag_state, McastTesterHelper, + verify_pim_interface_traffic, ) from lib.topolog import logger from lib.topojson import build_config_from_json @@ -354,6 +356,45 @@ def find_tos_in_tcpdump(tgen, router, message, cap_file): return True +def verify_pim_stats_increament(stats_before, stats_after): + """ + API to compare pim interface control plane traffic + + Parameters + ---------- + * `stats_before` : Stats dictionary for any particular instance + * `stats_after` : Stats dictionary for any particular instance + """ + + for router, stats_data in stats_before.items(): + for stats, value in stats_data.items(): + if stats_before[router][stats] >= stats_after[router][stats]: + errormsg = ( + "[DUT: %s]: state %s value has not" + " incremented, Initial value: %s, " + "Current value: %s [FAILED!!]" + % ( + router, + stats, + stats_before[router][stats], + stats_after[router][stats], + ) + ) + return errormsg + + logger.info( + "[DUT: %s]: State %s value is " + "incremented, Initial value: %s, Current value: %s" + " [PASSED!!]", + router, + stats, + stats_before[router][stats], + stats_after[router][stats], + ) + + return True + + def test_verify_oil_when_join_prune_sent_scenario_1_p1(request): """ TC_21_1: @@ -4490,6 +4531,259 @@ def test_verify_multicast_traffic_when_FHR_connected_to_RP_p1(request): write_test_footer(tc_name) +def test_PIM_passive_p1(request): + """ + TC Verify PIM passive functionality" + """ + + tgen = get_topogen() + tc_name = request.node.name + write_test_header(tc_name) + app_helper.stop_all_hosts() + # Creating configuration from JSON + clear_mroute(tgen) + if tgen.routers_have_failure(): + check_router_status(tgen) + reset_config_on_routers(tgen) + clear_pim_interface_traffic(tgen, topo) + + step("Enable the PIM on all the interfaces of FRR1, FRR2, FRR3") + step( + "Enable IGMP of FRR1 interface and send IGMP joins " + " from FRR1 node for group range (225.1.1.1-5)" + ) + + intf_c1_i4 = topo["routers"]["c1"]["links"]["i4"]["interface"] + + step( + "configure PIM passive on receiver interface to verify no impact on IGMP join" + "and multicast traffic on pim passive interface" + ) + + raw_config = { + "c1": {"raw_config": ["interface {}".format(intf_c1_i4), "ip pim passive"]} + } + result = apply_raw_config(tgen, raw_config) + assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result) + + step("configure IGMPv2 and send IGMP joinon on PIM passive interface") + input_dict = { + "c1": {"igmp": {"interfaces": {intf_c1_i4: {"igmp": {"version": "2"}}}}} + } + result = create_igmp_config(tgen, topo, input_dict) + assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result) + + input_join = {"i4": topo["routers"]["i4"]["links"]["c1"]["interface"]} + for recvr, recvr_intf in input_join.items(): + result = app_helper.run_join(recvr, IGMP_JOIN_RANGE_1, join_intf=recvr_intf) + assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result) + + step("Configure static RP for (225.1.1.1-5) as R2") + + input_dict = { + "r2": { + "pim": { + "rp": [ + { + "rp_addr": topo["routers"]["r2"]["links"]["lo"]["ipv4"].split( + "/" + )[0], + "group_addr_range": GROUP_RANGE_1, + } + ] + } + } + } + + result = create_pim_config(tgen, topo, input_dict) + assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result) + + step("Send Mcast traffic from C2 to all the groups ( 225.1.1.1 to 225.1.1.5)") + + input_src = {"i5": topo["routers"]["i5"]["links"]["c2"]["interface"]} + for src, src_intf in input_src.items(): + result = app_helper.run_traffic(src, IGMP_JOIN_RANGE_1, bind_intf=src_intf) + assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result) + + source_i5 = topo["routers"]["i5"]["links"]["c2"]["ipv4"].split("/")[0] + + input_dict_starg = [ + { + "dut": "c1", + "src_address": "*", + "iif": topo["routers"]["c1"]["links"]["l1"]["interface"], + "oil": topo["routers"]["c1"]["links"]["i4"]["interface"], + } + ] + + input_dict_sg = [ + { + "dut": "c1", + "src_address": source_i5, + "iif": topo["routers"]["c1"]["links"]["c2"]["interface"], + "oil": topo["routers"]["c1"]["links"]["i4"]["interface"], + } + ] + + step("(*,G) and (S,G) created on f1 and node verify using 'show ip mroute'") + + for data in input_dict_sg: + result = verify_mroutes( + tgen, + data["dut"], + data["src_address"], + IGMP_JOIN_RANGE_1, + data["iif"], + data["oil"], + ) + assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result) + + for data in input_dict_sg: + result = verify_mroutes( + tgen, + data["dut"], + data["src_address"], + IGMP_JOIN_RANGE_1, + data["iif"], + data["oil"], + ) + assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result) + + for data in input_dict_starg: + result = verify_mroutes( + tgen, + data["dut"], + data["src_address"], + IGMP_JOIN_RANGE_1, + data["iif"], + data["oil"], + ) + assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result) + + intf_c1_c2 = topo["routers"]["c1"]["links"]["c2"]["interface"] + intf_c2_c1 = topo["routers"]["c2"]["links"]["c1"]["interface"] + + step( + "configure PIM passive on upstream interface to verify" + "hello tx/rx counts are not incremented" + ) + + # Changing hello timer to 3sec for checking more number of packets + + raw_config = { + "c1": { + "raw_config": [ + "interface {}".format(intf_c1_c2), + "ip pim passive", + "ip pim hello 3", + ] + }, + "c2": {"raw_config": ["interface {}".format(intf_c2_c1), "ip pim hello 3"]}, + } + result = apply_raw_config(tgen, raw_config) + assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result) + + step("verify PIM hello tx/rx stats on C1") + state_dict = { + "c1": { + intf_c1_c2: ["helloTx", "helloRx"], + } + } + + logger.info("waiting for 5 sec config to get apply and hello count update") + sleep(5) + + c1_state_before = verify_pim_interface_traffic(tgen, state_dict) + assert isinstance( + c1_state_before, dict + ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format( + tc_name, result + ) + + logger.info( + "sleeping for 30 sec hello interval timer to verify count are not increamented" + ) + sleep(35) + + c1_state_after = verify_pim_interface_traffic(tgen, state_dict) + assert isinstance( + c1_state_after, dict + ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format( + tc_name, result + ) + + step("verify stats not increamented on c1") + result = verify_pim_stats_increament(c1_state_before, c1_state_after) + assert ( + result is not True + ), "Testcase{} : Failed Error: {}" "stats incremented".format(tc_name, result) + + step("No impact observed on mroutes") + for data in input_dict_sg: + result = verify_mroutes( + tgen, + data["dut"], + data["src_address"], + IGMP_JOIN_RANGE_1, + data["iif"], + data["oil"], + ) + assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result) + + for data in input_dict_sg: + result = verify_mroutes( + tgen, + data["dut"], + data["src_address"], + IGMP_JOIN_RANGE_1, + data["iif"], + data["oil"], + ) + assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result) + + for data in input_dict_starg: + result = verify_mroutes( + tgen, + data["dut"], + data["src_address"], + IGMP_JOIN_RANGE_1, + data["iif"], + data["oil"], + ) + assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result) + + step("remove PIM passive and verify hello tx/rx is increamented") + raw_config = { + "c1": { + "raw_config": [ + "interface {}".format(intf_c1_c2), + "no ip pim passive", + "ip pim hello 3", + ] + } + } + result = apply_raw_config(tgen, raw_config) + assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result) + + logger.info("waiting for 30 sec for pim hello to receive") + sleep(30) + + c1_state_after = verify_pim_interface_traffic(tgen, state_dict) + assert isinstance( + c1_state_after, dict + ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format( + tc_name, result + ) + + step("verify stats increamented on c1 after removing pim passive") + result = verify_pim_stats_increament(c1_state_before, c1_state_after) + assert result is True, "Testcase{} : Failed Error: {}" "stats incremented".format( + tc_name, result + ) + + write_test_footer(tc_name) + + if __name__ == "__main__": args = ["-s"] + sys.argv[1:] sys.exit(pytest.main(args))