Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 60 additions & 28 deletions tests/crm/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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),
Expand All @@ -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'), \
Expand All @@ -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)


Expand Down
28 changes: 16 additions & 12 deletions tests/crm/test_crm.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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")

Expand Down Expand Up @@ -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']
Expand Down Expand Up @@ -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 \
Expand Down Expand Up @@ -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']
Expand Down
Loading