def test_lpmode(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): """This function tests both the get_lpmode() and set_lpmode() APIs""" for i in self.candidate_sfp: # First ensure that the transceiver type supports low-power mode info_dict = sfp.get_transceiver_info(platform_api_conn, i) if not self.expect( info_dict is not None, "Unable to retrieve transceiver {} info".format(i)): continue if not self.is_xcvr_optical(info_dict): logger.warning( "test_lpmode: Skipping transceiver {} (not applicable for this transceiver type)" .format(i)) continue # Enable and disable low-power mode on each transceiver for state in [True, False]: ret = sfp.set_lpmode(platform_api_conn, i, state) self.expect( ret is True, "Failed to {} low-power mode for transceiver {}".format( "enable" if state is True else "disable", i)) lpmode = sfp.get_lpmode(platform_api_conn, i) if self.expect( lpmode is not None, "Unable to retrieve transceiver {} low-power mode". format(i)): self.expect( lpmode == state, "Transceiver {} low-power is incorrect".format(i)) self.assert_expectations()
def test_power_override(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): """This function tests both the get_power_override() and set_power_override() APIs""" duthost = duthosts[enum_rand_one_per_hwsku_hostname] skip_release_for_platform(duthost, ["202012"], ["arista", "mlnx", "nokia"]) for i in self.sfp_setup["sfp_test_port_indices"]: info_dict = sfp.get_transceiver_info(platform_api_conn, i) if not self.expect(info_dict is not None, "Unable to retrieve transceiver {} info".format(i)): continue if not self.is_xcvr_support_power_override(info_dict): logger.warning("test_power_override: Skipping transceiver {} (not applicable for this transceiver type)".format(i)) continue # Enable power override in both low-power and high-power modes for state in [True, False]: ret = sfp.set_power_override(platform_api_conn, i, True, state) self.expect(ret is True, "Failed to {} power override for transceiver {}".format("enable" if state is True else "disable", i)) power_override = sfp.get_power_override(platform_api_conn, i) if self.expect(power_override is not None, "Unable to retrieve transceiver {} power override data".format(i)): self.expect(power_override is True, "Transceiver {} power override data is incorrect".format(i)) # Disable power override ret = sfp.set_power_override(platform_api_conn, i, False, None) self.expect(ret is True, "Failed to disable power override for transceiver {}".format(i)) power_override = sfp.get_power_override(platform_api_conn, i) if self.expect(power_override is not None, "Unable to retrieve transceiver {} power override data".format(i)): self.expect(power_override is False, "Transceiver {} power override data is incorrect".format(i)) self.assert_expectations()
def test_tx_disable(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): """This function tests both the get_tx_disable() and tx_disable() APIs""" for i in self.candidate_sfp: # First ensure that the transceiver type supports setting TX disable info_dict = sfp.get_transceiver_info(platform_api_conn, i) if not self.expect( info_dict is not None, "Unable to retrieve transceiver {} info".format(i)): continue if not self.is_xcvr_optical(info_dict): logger.warning( "test_tx_disable: Skipping transceiver {} (not applicable for this transceiver type)" .format(i)) continue for state in [True, False]: ret = sfp.tx_disable(platform_api_conn, i, state) if self.expect( ret is True, "Failed to {} TX disable for transceiver {}".format( "set" if state is True else "clear", i)): tx_disable = sfp.get_tx_disable(platform_api_conn, i) if self.expect( tx_disable is not None, "Unable to retrieve transceiver {} TX disable data" .format(i)): self.expect( isinstance(tx_disable, list) and (all(item == state) for item in tx_disable), "Transceiver {} TX disable data is incorrect". format(i)) self.assert_expectations()
def test_power_override(self, duthost, localhost, platform_api_conn): """This function tests both the get_power_override() and set_power_override() APIs""" for i in range(self.num_sfps): info_dict = sfp.get_transceiver_info(platform_api_conn, i) if not self.expect(info_dict is not None, "Unable to retrieve transceiver {} info".format(i)): continue if not self.is_xcvr_optical(info_dict): logger.warning("test_power_override: Skipping transceiver {} (not applicable for this transceiver type)".format(i)) continue # Enable power override in both low-power and high-power modes for state in [True, False]: ret = sfp.set_power_override(platform_api_conn, i, True, state) self.expect(ret is True, "Failed to {} power override for transceiver {}".format("enable" if state is True else "disable", i)) power_override = sfp.get_power_override(platform_api_conn, i) if self.expect(power_override is not None, "Unable to retrieve transceiver {} power override data".format(i)): self.expect(power_override is True, "Transceiver {} power override data is incorrect".format(i)) # Disable power override ret = sfp.set_power_override(platform_api_conn, i, False, None) self.expect(ret is True, "Failed to disable power override for transceiver {}".format(i)) power_override = sfp.get_power_override(platform_api_conn, i) if self.expect(power_override is not None, "Unable to retrieve transceiver {} power override data".format(i)): self.expect(power_override is False, "Transceiver {} power override data is incorrect".format(i)) self.assert_expectations()
def test_tx_disable_channel(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): """This function tests both the get_tx_disable_channel() and tx_disable_channel() APIs""" duthost = duthosts[enum_rand_one_per_hwsku_hostname] skip_release_for_platform(duthost, ["202012"], ["arista", "mlnx", "nokia"]) for i in self.sfp_setup["sfp_test_port_indices"]: # First ensure that the transceiver type supports setting TX disable on individual channels info_dict = sfp.get_transceiver_info(platform_api_conn, i) if not self.expect(info_dict is not None, "Unable to retrieve transceiver {} info".format(i)): continue if not self.is_xcvr_optical(info_dict): logger.warning("test_tx_disable_channel: Skipping transceiver {} (not applicable for this transceiver type)".format(i)) continue # Test all TX disable combinations for a four-channel transceiver (i.e., 0x0 through 0xF) # We iterate in reverse here so that we end with 0x0 (no channels disabled) for expected_mask in range(0xF, 0x0, -1): # Enable TX on all channels ret = sfp.tx_disable_channel(platform_api_conn, i, 0xF, False) self.expect(ret is True, "Failed to enable TX on all channels for transceiver {}".format(i)) ret = sfp.tx_disable_channel(platform_api_conn, i, expected_mask, True) self.expect(ret is True, "Failed to disable TX channels using mask '{}' for transceiver {}".format(expected_mask, i)) tx_disable_chan_mask = sfp.get_tx_disable_channel(platform_api_conn, i) if self.expect(tx_disable_chan_mask is not None, "Unable to retrieve transceiver {} TX disabled channel data".format(i)): self.expect(tx_disable_chan_mask == expected_mask, "Transceiver {} TX disabled channel data is incorrect".format(i)) self.assert_expectations()
def test_get_transceiver_info(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): # TODO: Do more sanity checking on transceiver info values for i in self.sfp_setup["sfp_test_port_indices"]: info_dict = sfp.get_transceiver_info(platform_api_conn, i) if self.expect(info_dict is not None, "Unable to retrieve transceiver {} info".format(i)): if self.expect(isinstance(info_dict, dict), "Transceiver {} info appears incorrect".format(i)): actual_keys = info_dict.keys() duthost = duthosts[enum_rand_one_per_hwsku_hostname] # NOTE: No more releases to be added here. Platform should use SFP-refactor. # 'hardware_rev' is ONLY applicable to QSFP-DD/OSFP modules if duthost.sonic_release in ["201811", "201911", "202012", "202106", "202111"]: EXPECTED_XCVR_INFO_KEYS = [key if key != 'vendor_rev' else 'hardware_rev' for key in self.EXPECTED_XCVR_INFO_KEYS] self.EXPECTED_XCVR_INFO_KEYS = EXPECTED_XCVR_INFO_KEYS missing_keys = set(self.EXPECTED_XCVR_INFO_KEYS) - set(actual_keys) for key in missing_keys: self.expect(False, "Transceiver {} info does not contain field: '{}'".format(i, key)) # TODO: Remove this once we can include these keys in EXPECTED_XCVR_INFO_KEYS for key in self.NEWLY_ADDED_XCVR_INFO_KEYS: if key not in actual_keys: logger.warning("test_get_transceiver_info: Transceiver {} info missing field '{}'. Vendor needs to add support.".format(i, key)) elif info_dict[key] == "N/A": logger.warning("test_get_transceiver_info: Transceiver {} info value for '{}' is 'N/A'. Vendor needs to add support.".format(i, key)) unexpected_keys = set(actual_keys) - set(self.EXPECTED_XCVR_INFO_KEYS + self.NEWLY_ADDED_XCVR_INFO_KEYS) for key in unexpected_keys: #hardware_rev is applicable only for QSFP-DD if key == 'hardware_rev' and info_dict["type_abbrv_name"] == "QSFP-DD": continue self.expect(False, "Transceiver {} info contains unexpected field '{}'".format(i, key)) self.assert_expectations()
def test_get_tx_power(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): # TODO: Do more sanity checking on the data we retrieve duthost = duthosts[enum_rand_one_per_hwsku_hostname] skip_release_for_platform(duthost, ["202012"], ["arista", "mlnx"]) for i in self.sfp_setup["sfp_test_port_indices"]: tx_power = sfp.get_tx_power(platform_api_conn, i) if self.expect( tx_power is not None, "Unable to retrieve transceiver {} TX power data".format( i)): continue # Determine whether the transceiver type supports RX power # If the transceiver is non-optical, e.g., DAC, we should receive a list of "N/A" strings info_dict = sfp.get_transceiver_info(platform_api_conn, i) if not self.expect( info_dict is not None, "Unable to retrieve transceiver {} info".format(i)): continue if not self.is_xcvr_optical(info_dict): self.expect( isinstance(tx_power, list) and (all(item == "N/A" for item in tx_power)), "Transceiver {} TX power data appears incorrect".format(i)) else: self.expect( isinstance(tx_power, list) and (all(isinstance(item, float) for item in tx_power)), "Transceiver {} TX power data appears incorrect".format(i)) self.assert_expectations()
def test_get_tx_power(self, duthost, localhost, platform_api_conn): # TODO: Do more sanity checking on the data we retrieve for i in range(self.num_sfps): tx_power = sfp.get_tx_power(platform_api_conn, i) if self.expect( tx_power is not None, "Unable to retrieve transceiver {} TX power data".format( i)): continue # Determine whether the transceiver type supports RX power # If the transceiver is non-optical, e.g., DAC, we should receive a list of "N/A" strings info_dict = sfp.get_transceiver_info(platform_api_conn, i) if not self.expect( info_dict is not None, "Unable to retrieve transceiver {} info".format(i)): continue if not self.is_xcvr_optical(info_dict): self.expect( isinstance(tx_power, list) and (all(item == "N/A" for item in tx_power)), "Transceiver {} TX power data appears incorrect".format(i)) else: self.expect( isinstance(tx_power, list) and (all(isinstance(item, float) for item in tx_power)), "Transceiver {} TX power data appears incorrect".format(i)) self.assert_expectations()
def test_get_rx_power(self, duthost, localhost, platform_api_conn): # TODO: Do more sanity checking on the data we retrieve # TODO: Should we should expect get_rx_power() to return None or a list of "N/A" strings # if the transceiver is non-optical, e.g., DAC for i in range(self.num_sfps): # Determine whether the transceiver type supports RX power info_dict = sfp.get_transceiver_info(platform_api_conn, i) if not self.expect( info_dict is not None, "Unable to retrieve transceiver {} info".format(i)): continue if not self.is_xcvr_optical(info_dict): logger.warning( "test_get_rx_power: Skipping transceiver {} (not applicable for this transceiver type)" .format(i)) continue rx_power = sfp.get_rx_power(platform_api_conn, i) if self.expect( rx_power is not None, "Unable to retrieve transceiver {} RX power data".format( i)): self.expect( isinstance(rx_power, list) and (all(isinstance(item, float) for item in rx_power)), "Transceiver {} RX power data appears incorrect".format(i)) self.assert_expectations()
def test_get_transceiver_info(self, duthost, localhost, platform_api_conn): # TODO: Do more sanity checking on transceiver info values for i in range(self.num_sfps): info_dict = sfp.get_transceiver_info(platform_api_conn, i) if self.expect(info_dict is not None, "Unable to retrieve transceiver {} info".format(i)): if self.expect( isinstance(info_dict, dict), "Transceiver {} info appears incorrect".format(i)): actual_keys = info_dict.keys() missing_keys = set( self.EXPECTED_XCVR_INFO_KEYS) - set(actual_keys) for key in missing_keys: self.expect( False, "Transceiver {} info does not contain field: '{}'". format(i, key)) unexpected_keys = set(actual_keys) - set( self.EXPECTED_XCVR_INFO_KEYS) for key in unexpected_keys: self.expect( False, "Transceiver {} info contains unexpected field '{}'" .format(i, key)) self.assert_expectations()
def test_get_rx_power(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): duthost = duthosts[enum_rand_one_per_hwsku_hostname] skip_release_for_platform(duthost, ["202012"], ["arista", "mlnx"]) # TODO: Do more sanity checking on the data we retrieve # TODO: Should we should expect get_rx_power() to return None or a list of "N/A" strings # if the transceiver is non-optical, e.g., DAC for i in self.sfp_setup["sfp_test_port_indices"]: # Determine whether the transceiver type supports RX power info_dict = sfp.get_transceiver_info(platform_api_conn, i) if not self.expect( info_dict is not None, "Unable to retrieve transceiver {} info".format(i)): continue if not self.is_xcvr_optical(info_dict): logger.warning( "test_get_rx_power: Skipping transceiver {} (not applicable for this transceiver type)" .format(i)) continue rx_power = sfp.get_rx_power(platform_api_conn, i) if self.expect( rx_power is not None, "Unable to retrieve transceiver {} RX power data".format( i)): self.expect( isinstance(rx_power, list) and (all(isinstance(item, float) for item in rx_power)), "Transceiver {} RX power data appears incorrect".format(i)) self.assert_expectations()
def test_lpmode(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): """This function tests both the get_lpmode() and set_lpmode() APIs""" for i in self.sfp_setup["sfp_test_port_indices"]: # First ensure that the transceiver type supports low-power mode info_dict = sfp.get_transceiver_info(platform_api_conn, i) if not self.expect( info_dict is not None, "Unable to retrieve transceiver {} info".format(i)): continue if not self.is_xcvr_support_lpmode(info_dict): logger.warning( "test_lpmode: Skipping transceiver {} (not applicable for this transceiver type)" .format(i)) continue # Enable and disable low-power mode on each transceiver for state in [True, False]: ret = sfp.set_lpmode(platform_api_conn, i, state) if ret is None: logger.warning( "test_lpmode: Skipping transceiver {} (not supported on this platform)" .format(i)) break self.expect( ret is True, "Failed to {} low-power mode for transceiver {}".format( "enable" if state is True else "disable", i)) self.expect( wait_until(5, 1, 0, self._check_lpmode_status, sfp, platform_api_conn, i, state), "Transceiver {} expected low-power state {} is not aligned with the real state" .format(i, "enable" if state is True else "disable")) self.assert_expectations()
def test_get_tx_bias(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): duthost = duthosts[enum_rand_one_per_hwsku_hostname] skip_release_for_platform(duthost, ["202012"], ["arista", "mlnx"]) # TODO: Do more sanity checking on the data we retrieve for i in self.sfp_setup["sfp_test_port_indices"]: info_dict = sfp.get_transceiver_info(platform_api_conn, i) # Determine whether the transceiver type supports TX Bias if not self.is_xcvr_optical(info_dict): logger.warning("test_get_tx_bias: Skipping transceiver {} (not applicable for this transceiver type)".format(i)) continue tx_bias = sfp.get_tx_bias(platform_api_conn, i) if self.expect(tx_bias is not None, "Unable to retrieve transceiver {} TX bias data".format(i)): self.expect(isinstance(tx_bias, list) and (all(isinstance(item, float) for item in tx_bias)), "Transceiver {} TX bias data appears incorrect".format(i)) self.assert_expectations()
def test_get_voltage(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): # TODO: Do more sanity checking on the data we retrieve duthost = duthosts[enum_rand_one_per_hwsku_hostname] skip_release_for_platform(duthost, ["202012"], ["arista", "mlnx"]) for i in self.sfp_setup["sfp_test_port_indices"]: info_dict = sfp.get_transceiver_info(platform_api_conn, i) if not self.is_xcvr_optical(info_dict): logger.info("test_get_voltage: Skipping transceiver {} (not applicable for this transceiver type)".format(i)) continue voltage = sfp.get_voltage(platform_api_conn, i) if self.expect(voltage is not None, "Unable to retrieve transceiver {} voltage".format(i)): self.expect(isinstance(voltage, float), "Transceiver {} voltage appears incorrect".format(i)) self.assert_expectations()
def test_reset(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): # TODO: Verify that the transceiver was actually reset duthost = duthosts[enum_rand_one_per_hwsku_hostname] skip_release_for_platform(duthost, ["202012"], ["arista", "mlnx"]) for i in self.sfp_setup["sfp_test_port_indices"]: info_dict = sfp.get_transceiver_info(platform_api_conn, i) if not self.expect(info_dict is not None, "Unable to retrieve transceiver {} info".format(i)): continue ret = sfp.reset(platform_api_conn, i) if self.is_xcvr_resettable(info_dict): self.expect(ret is True, "Failed to reset transceiver {}".format(i)) else: self.expect(ret is False, "Resetting transceiver {} succeeded but should have failed".format(i)) self.assert_expectations()
def test_get_rx_los(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): # TODO: Do more sanity checking on the data we retrieve duthost = duthosts[enum_rand_one_per_hwsku_hostname] skip_release_for_platform(duthost, ["202012"], ["arista", "mlnx"]) for i in self.sfp_setup["sfp_test_port_indices"]: info_dict = sfp.get_transceiver_info(platform_api_conn, i) if not self.is_xcvr_optical(info_dict): logger.info("test_get_rx_los: Skipping transceiver {} (not applicable for this transceiver type)".format(i)) continue rx_los = sfp.get_rx_los(platform_api_conn, i) if self.expect(rx_los is not None, "Unable to retrieve transceiver {} RX loss-of-signal data".format(i)): self.expect(isinstance(rx_los, list) and (all(isinstance(item, bool) for item in rx_los)), "Transceiver {} RX loss-of-signal data appears incorrect".format(i)) self.assert_expectations()
def test_reset(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): # TODO: Verify that the transceiver was actually reset for i in self.candidate_sfp: info_dict = sfp.get_transceiver_info(platform_api_conn, i) if not self.expect( info_dict is not None, "Unable to retrieve transceiver {} info".format(i)): continue ret = sfp.reset(platform_api_conn, i) if self.is_xcvr_resettable(info_dict): self.expect(ret is True, "Failed to reset transceiver {}".format(i)) else: self.expect( ret is False, "Resetting transceiver {} succeeded but should have failed" .format(i)) self.assert_expectations()
def test_get_transceiver_info(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): # TODO: Do more sanity checking on transceiver info values for i in self.sfp_setup["sfp_test_port_indices"]: info_dict = sfp.get_transceiver_info(platform_api_conn, i) if self.expect(info_dict is not None, "Unable to retrieve transceiver {} info".format(i)): if self.expect( isinstance(info_dict, dict), "Transceiver {} info appears incorrect".format(i)): actual_keys = info_dict.keys() missing_keys = set( self.EXPECTED_XCVR_INFO_KEYS) - set(actual_keys) for key in missing_keys: self.expect( False, "Transceiver {} info does not contain field: '{}'". format(i, key)) # TODO: Remove this once we can include these keys in EXPECTED_XCVR_INFO_KEYS for key in self.NEWLY_ADDED_XCVR_INFO_KEYS: if key not in actual_keys: logger.warning( "test_get_transceiver_info: Transceiver {} info missing field '{}'. Vendor needs to add support." .format(i, key)) elif info_dict[key] == "N/A": logger.warning( "test_get_transceiver_info: Transceiver {} info value for '{}' is 'N/A'. Vendor needs to add support." .format(i, key)) unexpected_keys = set( actual_keys) - set(self.EXPECTED_XCVR_INFO_KEYS + self.NEWLY_ADDED_XCVR_INFO_KEYS) for key in unexpected_keys: self.expect( False, "Transceiver {} info contains unexpected field '{}'" .format(i, key)) self.assert_expectations()