diff --git a/tests/crm/conftest.py b/tests/crm/conftest.py index 857cace30a6..7f18af1e5fb 100755 --- a/tests/crm/conftest.py +++ b/tests/crm/conftest.py @@ -55,6 +55,9 @@ def pytest_runtest_teardown(item, nextitem): # Restore DUT after specific test steps # Test case name is used to mitigate incorrect cleanup if some of tests was failed on cleanup step and list of # cleanup commands was not cleared + if test_name not in RESTORE_CMDS: + return + for cmd in RESTORE_CMDS[test_name]: logger.info(cmd) try: @@ -303,3 +306,48 @@ def cleanup_ptf_interface(duthosts, ip_ver, enum_rand_one_per_hwsku_frontend_hos if "Ethernet1" not in output['stdout']: asichost.sonichost.add_member_to_vlan(1000, 'Ethernet1', is_tagged=False) ptfhost.remove_ip_addresses() + + +@pytest.fixture(scope="module", autouse=True) +def crm_resources(duthosts, rand_one_dut_hostname): + """ + Parse the CRM resource table from the 'crm show resources all' command output + and return a dictionary of the form: + { + "ipv4_route": {"used": 6475, "available": 140981}, + "ipv6_route": {"used": 6460, "available": 9924}, + ... + } + """ + duthost = duthosts[rand_one_dut_hostname] + + cmd_output = duthost.shell("crm show resources all")["stdout"] + + resources_dict = {} + lines = cmd_output.splitlines() + started = False + + for line in lines: + # Detect the start of the first resource table + if re.search(r"^Resource Name\s+Used Count\s+Available Count", line): + started = True + continue + + if started: + # Once we hit an empty or non-data line, stop + if not line.strip() or re.search(r"^Stage\s+Bind Point", line): + break + if re.match(r"^-+\s+-+\s+-+$", line): + continue + + parts = line.split() + if len(parts) >= 3: + resource_name = parts[0].strip() + used_count = int(parts[1]) + available_count = int(parts[2]) + resources_dict[resource_name] = { + "used": used_count, + "available": available_count + } + + return resources_dict diff --git a/tests/crm/test_crm_available.py b/tests/crm/test_crm_available.py new file mode 100644 index 00000000000..7d01e6f9b39 --- /dev/null +++ b/tests/crm/test_crm_available.py @@ -0,0 +1,43 @@ +import pytest +import logging +from tests.common.helpers.assertions import pytest_assert + +pytestmark = [ + pytest.mark.topology('t0', 't1', 'm0', 'mx', 'm1', 'm2', 'm3'), +] + +logger = logging.getLogger(__name__) + +NEXTHOP_GROUP_TOTAL = 256 + +SKU_NEXTHOP_THRESHOLDS = { + 'arista-720dt-g48s4': 15, + 'nokia-m0-7215': 126, + 'nokia-7215-a1': 126, + 'nokia-7215': 126, +} + +DEFAULT_NEXTHOP_THRESHOLD = 256 + + +def test_crm_next_hop_group(duthosts, enum_rand_one_per_hwsku_frontend_hostname, crm_resources): + """ + test that runs `crm show resources` and parses next-hop group usage. + """ + # Example check: ensure next-hop group usage is below a certain threshold + # This is a placeholder for the actual resource name; adjust as needed + duthost = duthosts[enum_rand_one_per_hwsku_frontend_hostname] + + hwsku = duthost.facts["hwsku"].lower() + + nexthop_group_threshold = SKU_NEXTHOP_THRESHOLDS.get(hwsku, DEFAULT_NEXTHOP_THRESHOLD) + + resource_name = "nexthop_group" + if resource_name in crm_resources: + used = crm_resources[resource_name]["used"] + available = crm_resources[resource_name]["available"] + total = used + available + pytest_assert(total >= nexthop_group_threshold, + f"next-hop groups ({total}) should be greater than or equal to {nexthop_group_threshold} on platform '{hwsku}'") # noqa + else: + pytest.fail(f"Resource '{resource_name}' not found in CRM resources output on platform '{hwsku}'.")