From 1d7737c017d188e22c238a75b135f53c45f0164e Mon Sep 17 00:00:00 2001 From: Mor Hen Date: Wed, 9 Oct 2024 11:03:15 +0300 Subject: [PATCH] Add fixes to test_intf_fec.py 1. Correct inequality direction in test_verify_fec_stats_counters 2. Delete commans before using int() in test_verify_fec_stats_counters 3. Add fixture to disable/enable BGP before/after test to allow faster fec configuration. 4. Add retry mechanism to fec configuration to allow time for configuration to take place. --- tests/common/platform/transceiver_utils.py | 13 +++++ tests/platform_tests/test_intf_fec.py | 60 +++++++++++++--------- 2 files changed, 50 insertions(+), 23 deletions(-) diff --git a/tests/common/platform/transceiver_utils.py b/tests/common/platform/transceiver_utils.py index d4ac0b37c71..32138883d35 100644 --- a/tests/common/platform/transceiver_utils.py +++ b/tests/common/platform/transceiver_utils.py @@ -387,3 +387,16 @@ def is_passive_cable(sfp_eeprom_info): "CR" in spec_compliance.get("Extended Specification Compliance", " "): return True return False + + +def get_passive_cable_port_list(dut): + passive_cable_port_list = [] + cmd_show_eeprom = "sudo sfputil show eeprom -d" + eeprom_infos = dut.command(cmd_show_eeprom)['stdout'] + eeprom_infos = parse_sfp_eeprom_infos(eeprom_infos) + for port_name, eeprom_info in eeprom_infos.items(): + if is_passive_cable(eeprom_info): + logging.info(f"{port_name} is passive cable") + passive_cable_port_list.append(port_name) + logging.info(f"Ports with passive cable are: {passive_cable_port_list}") + return passive_cable_port_list diff --git a/tests/platform_tests/test_intf_fec.py b/tests/platform_tests/test_intf_fec.py index 88b6fcdc557..db88fb5ac3f 100644 --- a/tests/platform_tests/test_intf_fec.py +++ b/tests/platform_tests/test_intf_fec.py @@ -1,7 +1,9 @@ import logging import pytest -from tests.common.utilities import skip_release, wait_until +from tests.common.utilities import skip_release +from tests.common.platform.transceiver_utils import get_passive_cable_port_list +from retry.api import retry_call pytestmark = [ pytest.mark.disable_loganalyzer, # disable automatic loganalyzer @@ -18,6 +20,16 @@ "100G", "200G", "400G", "800G", "1600G" ] +FEC_CONFIG_DEFAULT_RETRIES = 5 +FEC_CONFIG_NON_COPPER_RETRIES = 10 + + +@pytest.fixture(scope="module", autouse=True) +def disable_bgp(duthost): + duthost.shell("sudo config feature state bgp disabled") + yield + duthost.shell("sudo config feature state bgp enabled") + @pytest.fixture(autouse=True) def is_supported_platform(duthost): @@ -65,7 +77,7 @@ def test_config_fec_oper_mode(duthosts, enum_rand_one_per_hwsku_frontend_hostnam logging.info("Get output of '{}'".format("show interface status")) intf_status = duthost.show_and_parse("show interface status") - + passive_copper_ports = get_passive_cable_port_list(duthost) for intf in intf_status: sfp_presence = duthost.show_and_parse("sudo sfpshow presence -p {}" .format(intf['interface'])) @@ -80,14 +92,10 @@ def test_config_fec_oper_mode(duthosts, enum_rand_one_per_hwsku_frontend_hostnam config_status = duthost.command("sudo config interface fec {} rs" .format(intf['interface'])) if config_status: - wait_until(30, 2, 0, duthost.is_interface_status_up, intf["interface"]) - # Verify the FEC operational mode is restored - logging.info("Get output of '{} {}'".format("show interfaces fec status", intf['interface'])) - fec_status = duthost.show_and_parse("show interfaces fec status {}".format(intf['interface'])) - fec = fec_status[0].get('fec oper', '').lower() - - if not (fec == "rs"): - pytest.fail("FEC status is not restored for interface {}".format(intf['interface'])) + # interfaces that are not copper could take longer to configure fec + tries = FEC_CONFIG_NON_COPPER_RETRIES if (intf['interface'] + not in passive_copper_ports) else FEC_CONFIG_DEFAULT_RETRIES + retry_call(validate_fec_oper_status, fargs=[duthost, intf['interface']], tries=tries, delay=3) def get_interface_speed(duthost, interface_name): @@ -105,8 +113,6 @@ def get_interface_speed(duthost, interface_name): logging.info(f"Interface {interface_name} has speed {speed}") return speed - pytest.fail(f"Interface {interface_name} not found") - def test_verify_fec_stats_counters(duthosts, enum_rand_one_per_hwsku_frontend_hostname, enum_frontend_asic_index, conn_graph_facts): @@ -125,14 +131,15 @@ def test_verify_fec_stats_counters(duthosts, enum_rand_one_per_hwsku_frontend_ho if speed not in SUPPORTED_SPEEDS: continue - fec_corr = intf.get('fec_corr', '').lower() - fec_uncorr = intf.get('fec_uncorr', '').lower() - fec_symbol_err = intf.get('fec_symbol_err', '').lower() + # Removes commas from "show interfaces counters fec-stats" (i.e. 12,354 --> 12354) to allow int conversion + fec_corr = intf.get('fec_corr', '').replace(',', '').lower() + fec_uncorr = intf.get('fec_uncorr', '').replace(',', '').lower() + fec_symbol_err = intf.get('fec_symbol_err', '').replace(',', '').lower() # Check if fec_corr, fec_uncorr, and fec_symbol_err are valid integers try: - fec_corr_int = int(fec_corr.replace(',', '')) - fec_uncorr_int = int(fec_uncorr.replace(',', '')) - fec_symbol_err_int = int(fec_symbol_err.replace(',', '')) + fec_corr_int = int(fec_corr) + fec_uncorr_int = int(fec_uncorr) + fec_symbol_err_int = int(fec_symbol_err) except ValueError: pytest.fail("FEC stat counters are not valid integers for interface {}, \ fec_corr: {} fec_uncorr: {} fec_symbol_err: {}" @@ -142,8 +149,15 @@ def test_verify_fec_stats_counters(duthosts, enum_rand_one_per_hwsku_frontend_ho if fec_uncorr_int > 0: pytest.fail("FEC uncorrectable errors are non-zero for interface {}: {}" .format(intf_name, fec_uncorr_int)) - - # Check for valid FEC correctable codeword errors > FEC symbol errors - if fec_symbol_err_int > fec_corr_int: - pytest.fail("FEC symbol errors:{} are higher than FEC correctable errors:{} for interface {}" - .format(intf_name, fec_symbol_err_int, fec_corr_int)) + # Check for valid FEC symbol errors > FEC correctable codeword errors + if fec_corr_int > fec_symbol_err_int: + pytest.fail("FEC correctable errors:{} are higher than FEC symbol errors:{} for interface {}" + .format(intf_name, fec_corr_int, fec_symbol_err_int)) + + +def validate_fec_oper_status(duthost, interface): + # Verify the FEC operational mode is restored + logging.info("Get output of '{} {}'".format("show interfaces fec status", interface)) + fec_status = duthost.show_and_parse("show interfaces fec status {}".format(interface)) + fec = fec_status[0].get('fec oper', '').lower() + assert fec == "rs", "FEC status is not restored for interface {}".format(interface)