diff --git a/tests/crm/conftest.py b/tests/crm/conftest.py index 982bf2cc75..d0c2b189a2 100755 --- a/tests/crm/conftest.py +++ b/tests/crm/conftest.py @@ -8,7 +8,7 @@ from test_crm import RESTORE_CMDS, get_nh_ip from tests.common.helpers.crm import CRM_POLLING_INTERVAL from tests.common.errors import RunAnsibleModuleFail -from tests.common.utilities import wait_until, recover_acl_rule +from tests.common.utilities import wait_until, recover_acl_rule, is_ipv6_only_topology from tests.common.platform.interface_utils import parse_intf_status from tests.common.mellanox_data import is_mellanox_device from tests.common.helpers.dut_utils import get_sai_sdk_dump_file @@ -194,7 +194,7 @@ def check_interface_status(duthost, intf_list, expected_oper='up'): return True -def configure_a_route_with_same_prefix_as_vlan_for_mlnx(duthost, asichost, tbinfo, crm_interface): +def configure_a_route_with_same_prefix_as_vlan_for_mlnx(duthost, asichost, tbinfo, crm_interface, ip_ver): """ For mellanox device, the crm available counter is related to LPM tree. When shutdown all interfaces in vlan (e.g. vlan 1000), @@ -205,55 +205,87 @@ def configure_a_route_with_same_prefix_as_vlan_for_mlnx(duthost, asichost, tbinf but we cannot estimate how long the change is ready. Therefore, it will lead the first case of test_crm_route fail occasionally because the expected available counter is not decreased. - So, we add another route with the same prefix(21) as the vlan's so that the LPM tree is not changed. + So, we add another route with the same prefix as the vlan's so that the LPM tree is not changed. """ # Get NH IP - nh_ip = get_nh_ip(duthost, asichost, crm_interface, '4') - - dump_ip_for_construct_test_route_with_same_prefix_as_vlan_interface = '21.21.21.21' - network_with_same_prefix_as_vlan_interface = str( - ipaddress.IPv4Interface( - f"{dump_ip_for_construct_test_route_with_same_prefix_as_vlan_interface}/" - f"{get_vlan_ipv4_prefix_len(asichost, tbinfo)}").network) - add_route_command = f"sudo ip route add {network_with_same_prefix_as_vlan_interface} via {nh_ip}" - duthost.shell(add_route_command) - assert wait_until(30, 5, 0, check_route_exist, duthost, network_with_same_prefix_as_vlan_interface, nh_ip), \ - f"Failed to add route {network_with_same_prefix_as_vlan_interface} via {nh_ip} " - - # Get sai sdk dump file in case test fail, we can get the LPM tree information - get_sai_sdk_dump_file(duthost, "sai_sdk_dump_before_shutdown_vlan_ports") + nh_ip = get_nh_ip(duthost, asichost, crm_interface, ip_ver) + prefix_len = get_vlan_prefix_len_per_ip_ver(asichost, tbinfo, ip_ver) + + if ip_ver == "4": + dump_ip_for_construct_test_route_with_same_prefix_as_vlan_interface = '21.21.21.21' + network_with_same_prefix_as_vlan_interface = str( + ipaddress.IPv4Interface( + f"{dump_ip_for_construct_test_route_with_same_prefix_as_vlan_interface}/{prefix_len}").network) + elif ip_ver == "6": + dump_ip_for_construct_test_route_with_same_prefix_as_vlan_interface = '2021:21:21:21::21' + network_with_same_prefix_as_vlan_interface = str( + ipaddress.IPv6Interface( + f"{dump_ip_for_construct_test_route_with_same_prefix_as_vlan_interface}/{prefix_len}").network) + + add_route_command = ( + f"sudo ip {'-6' if ip_ver == '6' else ''} " + f"route add {network_with_same_prefix_as_vlan_interface} via {nh_ip}" + ) + + route_check_command = ( + f"show {'ipv6' if ip_ver == '6' else 'ip'} " + f"route {network_with_same_prefix_as_vlan_interface}" + ) + + del_dump_route_with_same_prefix_as_vlan_interface_cmd = ( + f"sudo ip {'-6' if ip_ver == '6' else ''} " + f"route del {network_with_same_prefix_as_vlan_interface} via {nh_ip}" + ) + + duthost.shell(add_route_command, module_ignore_errors=True) + + assert wait_until( + 30, + 5, + 0, + check_route_exist, + duthost, + network_with_same_prefix_as_vlan_interface, + nh_ip, + route_check_command, + ), ( + f"Failed to add route " + f"{network_with_same_prefix_as_vlan_interface} via {nh_ip}" + ) - del_dump_route_with_same_prefix_as_vlan_interface_cmd = \ - f" sudo ip route del {network_with_same_prefix_as_vlan_interface} via {nh_ip}" + get_sai_sdk_dump_file(duthost, "sai_sdk_dump_before_shutdown_vlan_ports") return del_dump_route_with_same_prefix_as_vlan_interface_cmd -def check_route_exist(duthost, network_with_same_prefix_as_vlan_interface, nh_ip): - route_output = duthost.shell(f"show ip route {network_with_same_prefix_as_vlan_interface}")["stdout"] +def check_route_exist(duthost, network_with_same_prefix_as_vlan_interface, nh_ip, route_check_command): + route_output = duthost.shell(route_check_command)["stdout"] return f"Routing entry for {network_with_same_prefix_as_vlan_interface}" in route_output and nh_ip in route_output -def get_vlan_ipv4_prefix_len(asichost, tbinfo): +def get_vlan_prefix_len_per_ip_ver(asichost, tbinfo, ip_ver): mg_facts = asichost.get_extended_minigraph_facts(tbinfo) for vlan_port_data in mg_facts["minigraph_vlan_interfaces"]: - if ipaddress.ip_interface(vlan_port_data['addr']).version == 4: - logger.info(f"vlan interface v4 prefix is :{vlan_port_data['prefixlen']}") + if ipaddress.ip_interface(vlan_port_data['addr']).version == int(ip_ver): + logger.info(f"vlan interface {ip_ver} prefix is :{vlan_port_data['prefixlen']}") return vlan_port_data['prefixlen'] - assert False, "Not find v4 prefix for vlan interface config" + assert False, f"Not find {ip_ver} prefix for vlan interface config" @pytest.fixture(scope="module", autouse=True) def shutdown_unnecessary_intf( - duthosts, tbinfo, enum_frontend_asic_index, enum_rand_one_per_hwsku_frontend_hostname, crm_interface): + duthosts, tbinfo, enum_frontend_asic_index, enum_rand_one_per_hwsku_frontend_hostname, crm_interface, request): """ Shutdown unused interfaces to avoid fdb entry influenced by mac learning """ duthost = duthosts[enum_rand_one_per_hwsku_frontend_hostname] asichost = duthost.asic_instance(enum_frontend_asic_index) intfs_connect_with_ptf = get_intf_list(duthost, tbinfo, enum_frontend_asic_index) + ip_ver = "4" if not is_ipv6_only_topology(tbinfo) else "6" + + del_dump_route_with_same_prefix_as_vlan_interface_cmd = None if intfs_connect_with_ptf: if is_mellanox_device(duthost): del_dump_route_with_same_prefix_as_vlan_interface_cmd = configure_a_route_with_same_prefix_as_vlan_for_mlnx( - duthost, asichost, tbinfo, crm_interface) + duthost, asichost, tbinfo, crm_interface, ip_ver) logger.info("Shutdown interfaces: {}".format(intfs_connect_with_ptf)) duthost.shutdown_multiple(intfs_connect_with_ptf) assert wait_until(300, 20, 0, check_interface_status, duthost, intfs_connect_with_ptf, 'down'), \ @@ -270,7 +302,7 @@ def shutdown_unnecessary_intf( duthost.no_shutdown_multiple(intfs_connect_with_ptf) assert wait_until(300, 20, 0, check_interface_status, duthost, intfs_connect_with_ptf), \ "All interfaces should be up!" - if is_mellanox_device(duthost): + if is_mellanox_device(duthost) and del_dump_route_with_same_prefix_as_vlan_interface_cmd: duthost.shell(del_dump_route_with_same_prefix_as_vlan_interface_cmd) diff --git a/tests/crm/test_crm.py b/tests/crm/test_crm.py index 357f5fc263..12411391a3 100755 --- a/tests/crm/test_crm.py +++ b/tests/crm/test_crm.py @@ -16,7 +16,7 @@ EXPECT_CLEAR, THR_VERIFY_CMDS from tests.common.fixtures.duthost_utils import disable_route_checker # noqa F401 from tests.common.fixtures.duthost_utils import disable_fdb_aging # noqa F401 -from tests.common.utilities import wait_until, get_data_acl +from tests.common.utilities import wait_until, get_data_acl, is_ipv6_only_topology from tests.common.mellanox_data import is_mellanox_device from tests.common.helpers.dut_utils import get_sai_sdk_dump_file @@ -494,14 +494,6 @@ def test_crm_route(duthosts, enum_rand_one_per_hwsku_frontend_hostname, enum_fro asic_type = duthost.facts['asic_type'] skip_stats_check = True if asic_type == "vs" else False RESTORE_CMDS["crm_threshold_name"] = "ipv{ip_ver}_route".format(ip_ver=ip_ver) - - # will be changed to use is_ipv6_only_topology from tests.common.utilities - # once PR #19639 is merged - is_ipv6_only_topology = ( - "-v6-" in tbinfo["topo"]["name"] - if tbinfo and "topo" in tbinfo and "name" in tbinfo["topo"] - else False - ) if is_ipv6_only_topology and ip_ver == "4": pytest.skip("Skipping IPv4 test on IPv6-only topology") @@ -658,7 +650,11 @@ def get_expected_crm_stats_route_available(crm_stats_route_available, crm_stats_ @pytest.mark.parametrize("ip_ver,nexthop", [("4", "2.2.2.2"), ("6", "2001::1")]) def test_crm_nexthop(duthosts, enum_rand_one_per_hwsku_frontend_hostname, - enum_frontend_asic_index, crm_interface, ip_ver, nexthop, ptfhost, cleanup_ptf_interface): + enum_frontend_asic_index, crm_interface, ip_ver, nexthop, ptfhost, cleanup_ptf_interface, tbinfo): + + if ip_ver == "4" and is_ipv6_only_topology(tbinfo): + pytest.skip("Skipping IPv4 test on IPv6-only topology") + duthost = duthosts[enum_rand_one_per_hwsku_frontend_hostname] asichost = duthost.asic_instance(enum_frontend_asic_index) asic_type = duthost.facts['asic_type'] @@ -748,7 +744,11 @@ def test_crm_nexthop(duthosts, enum_rand_one_per_hwsku_frontend_hostname, @pytest.mark.parametrize("ip_ver,neighbor,host", [("4", "2.2.2.2", "2.2.2.1/8"), ("6", "2001::1", "2001::2/64")]) def test_crm_neighbor(duthosts, enum_rand_one_per_hwsku_frontend_hostname, - enum_frontend_asic_index, crm_interface, ip_ver, neighbor, host): + enum_frontend_asic_index, crm_interface, ip_ver, neighbor, host, tbinfo): + + if ip_ver == "4" and is_ipv6_only_topology(tbinfo): + pytest.skip("Skipping IPv4 test on IPv6-only topology") + duthost = duthosts[enum_rand_one_per_hwsku_frontend_hostname] asichost = duthost.asic_instance(enum_frontend_asic_index) get_nexthop_stats = "{db_cli} COUNTERS_DB HMGET CRM:STATS \ @@ -828,7 +828,11 @@ def test_crm_neighbor(duthosts, enum_rand_one_per_hwsku_frontend_hostname, @pytest.mark.usefixtures('disable_route_checker') @pytest.mark.parametrize("group_member,network", [(False, "2.2.2.0/24"), (True, "2.2.2.0/24")]) def test_crm_nexthop_group(duthosts, enum_rand_one_per_hwsku_frontend_hostname, - enum_frontend_asic_index, crm_interface, group_member, network): + enum_frontend_asic_index, crm_interface, group_member, tbinfo, network): + + if is_ipv6_only_topology(tbinfo): + pytest.skip("Skipping IPv4 test on IPv6-only topology") + duthost = duthosts[enum_rand_one_per_hwsku_frontend_hostname] asichost = duthost.asic_instance(enum_frontend_asic_index) asic_type = duthost.facts['asic_type']