diff --git a/tests/arp/arp_utils.py b/tests/arp/arp_utils.py index 3b4c73270a..de6504a6b4 100644 --- a/tests/arp/arp_utils.py +++ b/tests/arp/arp_utils.py @@ -10,11 +10,12 @@ BASE_MAC_PREFIX = "00:00:01" -def clear_dut_arp_cache(duthost, ns_option=None): +def clear_dut_arp_cache(duthost, ns_option=None, is_ipv6=False): logger.info("Clearing {} neighbor table".format(duthost.hostname)) - arp_flush_cmd = "ip -stats neigh flush all" + ipv6_cmd = '-6' if is_ipv6 else '' + arp_flush_cmd = "ip {} -stats neigh flush all".format(ipv6_cmd) if ns_option: - arp_flush_cmd = "ip -stats {} neigh flush all".format(ns_option) + arp_flush_cmd = "ip {} -stats {} neigh flush all".format(ipv6_cmd, ns_option) duthost.shell(arp_flush_cmd) diff --git a/tests/arp/test_stress_arp.py b/tests/arp/test_stress_arp.py index 8ee72f6f1d..61ced3ad49 100644 --- a/tests/arp/test_stress_arp.py +++ b/tests/arp/test_stress_arp.py @@ -9,7 +9,7 @@ from scapy.all import Ether, IPv6, ICMPv6ND_NS, ICMPv6NDOptSrcLLAddr, in6_getnsmac, \ in6_getnsma, inet_pton, inet_ntop, socket from ipaddress import ip_address, ip_network -from tests.common.utilities import wait_until, increment_ipv6_addr +from tests.common.utilities import wait_until, increment_ipv6_addr, is_ipv6_only_topology from tests.common.errors import RunAnsibleModuleFail @@ -22,7 +22,8 @@ logger = logging.getLogger(__name__) pytestmark = [ - pytest.mark.topology('t0') + pytest.mark.topology('t0'), + pytest.mark.dualtor_active_standby_toggle_to_enum_tor ] LOOP_TIMES_LEVEL_MAP = { @@ -35,9 +36,11 @@ @pytest.fixture(autouse=True) -def arp_cache_fdb_cleanup(duthost): +def arp_cache_fdb_cleanup(duthosts, rand_one_dut_hostname, tbinfo): + is_ipv6_only = is_ipv6_only_topology(tbinfo) + duthost = duthosts[rand_one_dut_hostname] try: - clear_dut_arp_cache(duthost) + clear_dut_arp_cache(duthost, is_ipv6=is_ipv6_only) fdb_cleanup(duthost) except RunAnsibleModuleFail as e: if 'Failed to send flush request: No such file or directory' in str(e): @@ -51,8 +54,10 @@ def arp_cache_fdb_cleanup(duthost): # Ensure clean test environment even after failing try: - clear_dut_arp_cache(duthost) - fdb_cleanup(duthost) + dut_list = duthosts if "dualtor-aa" in tbinfo["topo"]["name"] else [duthost] + for dut in dut_list: + clear_dut_arp_cache(dut, is_ipv6=is_ipv6_only) + fdb_cleanup(dut) except RunAnsibleModuleFail as e: if 'Failed to send flush request: No such file or directory' in str(e): logger.warning("Failed to clear arp cache or cleanup fdb table, file may not exist yet") @@ -90,13 +95,15 @@ def genrate_ipv4_ip(): return list(ptf_intf_ipv4_hosts) -def test_ipv4_arp(duthost, garp_enabled, ip_and_intf_info, intfs_for_test, +def test_ipv4_arp(duthosts, enum_rand_one_per_hwsku_frontend_hostname, + garp_enabled, ip_and_intf_info, intfs_for_test, ptfadapter, get_function_completeness_level): """ Send gratuitous ARP (GARP) packet sfrom the PTF to the DUT The DUT should learn the (previously unseen) ARP info from the packet """ + duthost = duthosts[enum_rand_one_per_hwsku_frontend_hostname] normalized_level = get_function_completeness_level if normalized_level is None: normalized_level = "debug" @@ -106,6 +113,11 @@ def test_ipv4_arp(duthost, garp_enabled, ip_and_intf_info, intfs_for_test, pytest_assert(ipv4_available > 0 and fdb_available > 0, "Entries have been filled") arp_available = min(min(ipv4_available, fdb_available), ENTRIES_NUMBERS) + # Limit ARP scale based on available NH entries + asic_type = duthost.facts["asic_type"] + if 'cisco-8000' in asic_type: + ipv4_nh_available = get_crm_resources(duthost, "ipv4_nexthop", "available") + arp_available = min(arp_available, ipv4_nh_available) pytest_require(garp_enabled, 'Gratuitous ARP not enabled for this device') ptf_intf_ipv4_hosts = genrate_ipv4_ip() @@ -181,8 +193,11 @@ def add_nd(ptfadapter, ip_and_intf_info, ptf_intf_index, nd_available): logger.info("Sending {} ipv6 neighbor entries".format(nd_available)) -def test_ipv6_nd(duthost, ptfhost, config_facts, tbinfo, ip_and_intf_info, +def test_ipv6_nd(duthosts, enum_rand_one_per_hwsku_frontend_hostname, + ptfhost, config_facts, tbinfo, ip_and_intf_info, ptfadapter, get_function_completeness_level, proxy_arp_enabled): + duthost = duthosts[enum_rand_one_per_hwsku_frontend_hostname] + is_ipv6_only = is_ipv6_only_topology(tbinfo) _, _, ptf_intf_ipv6_addr, _, ptf_intf_index = ip_and_intf_info ptf_intf_ipv6_addr = increment_ipv6_addr(ptf_intf_ipv6_addr) pytest_require(proxy_arp_enabled, 'Proxy ARP not enabled for all VLANs') @@ -198,7 +213,10 @@ def test_ipv6_nd(duthost, ptfhost, config_facts, tbinfo, ip_and_intf_info, pytest_assert(ipv6_available > 0 and fdb_available > 0, "Entries have been filled") nd_available = min(min(ipv6_available, fdb_available), ENTRIES_NUMBERS) - + asic_type = duthost.facts["asic_type"] + if 'cisco-8000' in asic_type: + ipv6_nh_available = get_crm_resources(duthost, "ipv6_nexthop", "available") + nd_available = min(nd_available, ipv6_nh_available) while loop_times > 0: loop_times -= 1 try: @@ -213,7 +231,7 @@ def test_ipv6_nd(duthost, ptfhost, config_facts, tbinfo, ip_and_intf_info, "Neighbor Table Add failed") finally: try: - clear_dut_arp_cache(duthost) + clear_dut_arp_cache(duthost, is_ipv6=is_ipv6_only) fdb_cleanup(duthost) except RunAnsibleModuleFail as e: if 'Failed to send flush request: No such file or directory' in str(e): @@ -246,6 +264,7 @@ def test_ipv6_nd_incomplete(duthost, ptfhost, config_facts, tbinfo, ip_and_intf_ ptfadapter, get_function_completeness_level, proxy_arp_enabled): _, _, ptf_intf_ipv6_addr, _, ptf_intf_index = ip_and_intf_info ptf_intf_ipv6_addr = increment_ipv6_addr(ptf_intf_ipv6_addr) + is_ipv6_only = is_ipv6_only_topology(tbinfo) pytest_require(proxy_arp_enabled, 'Proxy ARP not enabled for all VLANs') pytest_require(ptf_intf_ipv6_addr is not None, 'No IPv6 VLAN address configured on device') @@ -272,7 +291,7 @@ def test_ipv6_nd_incomplete(duthost, ptfhost, config_facts, tbinfo, ip_and_intf_ logger.info("original nf_conntrack_icmpv6_timeout: {}".format(orig_conntrack_icmpv6_timeout)) try: - clear_dut_arp_cache(duthost) + clear_dut_arp_cache(duthost, is_ipv6=is_ipv6_only) duthost.command("conntrack -F") @@ -286,7 +305,7 @@ def test_ipv6_nd_incomplete(duthost, ptfhost, config_facts, tbinfo, ip_and_intf_ conntrack_cnt_post = int(duthost.command("cat /proc/sys/net/netfilter/nf_conntrack_count")["stdout"]) logger.info("nf_conntrack_count post test: {}".format(conntrack_cnt_post)) - pytest_assert((conntrack_cnt_post - conntrack_cnt_pre) < tgt_conntrack_cnt * 0.1, + pytest_assert((conntrack_cnt_post - conntrack_cnt_pre) < tgt_conntrack_cnt, "{} echo requests cause large increase in conntrack entries".format(tgt_conntrack_cnt)) pytest_assert("[UNREPLIED]" not in duthost.command("conntrack -f ipv6 -L dying")["stdout"], @@ -302,4 +321,4 @@ def test_ipv6_nd_incomplete(duthost, ptfhost, config_facts, tbinfo, ip_and_intf_ duthost.command("conntrack -F") - clear_dut_arp_cache(duthost) + clear_dut_arp_cache(duthost, is_ipv6=is_ipv6_only)