From d2a693a047c08acc266f9ab419744aa6079be3f5 Mon Sep 17 00:00:00 2001 From: mhen1 Date: Tue, 10 Sep 2024 05:21:34 +0300 Subject: [PATCH] Enhancement of test_sensors.py to address several issues (#14154) Details: 1. Updated PSU mapping of msn4600-r0 platform. 2. Updated test to support both Forward (PSF) and Reversed (PSR) versions of each PSU Model. 3. Added support to PSU Model MTEF-AC-G. --- .../sensors_utils/psu_data.yaml | 82 +++++++++++++++++-- .../sensors_utils/psu_sensor_utils.py | 53 +++++++++++- .../sensors_utils/psu_sensors.json | 8 +- tests/platform_tests/test_sensors.py | 7 +- 4 files changed, 134 insertions(+), 16 deletions(-) diff --git a/tests/platform_tests/sensors_utils/psu_data.yaml b/tests/platform_tests/sensors_utils/psu_data.yaml index 75a6460ca9..6da9d62d82 100644 --- a/tests/platform_tests/sensors_utils/psu_data.yaml +++ b/tests/platform_tests/sensors_utils/psu_data.yaml @@ -1,5 +1,5 @@ sensors_checks: - MTEF-PSF-AC-A: + MTEF-AC-A: alarms: fan: - dps460-i2c-*-*/PSU-* Fan 1/fan1_alarm @@ -29,7 +29,7 @@ sensors_checks: temp: [ ] psu_skips: { } sensor_skip_per_version: { } - MTEF-PSF-AC-C: + MTEF-AC-C: alarms: fan: - dps460-i2c-*-*/PSU-* Fan 1/fan1_alarm @@ -80,7 +80,7 @@ sensors_checks: temp: [ ] psu_skips: { } sensor_skip_per_version: { } - MTEF-PSF-AC-E: + MTEF-AC-E: alarms: fan: - dps460-i2c-*-*/PSU-* Fan 1/fan1_alarm @@ -110,7 +110,7 @@ sensors_checks: temp: [ ] psu_skips: { } sensor_skip_per_version: { } - MTEF-PSF-AC-F: + MTEF-AC-F: alarms: fan: - dps460-i2c-*-*/PSU-* Fan 1/fan1_alarm @@ -153,7 +153,7 @@ sensors_checks: temp: [ ] psu_skips: { } sensor_skip_per_version: { } - MTEF-PSF-AC-M: + MTEF-AC-M: alarms: fan: - pmbus-i2c-*-*/PSU-* Fan1/fan1_alarm @@ -239,3 +239,75 @@ sensors_checks: temp: [ ] psu_skips: { } sensor_skip_per_version: { } + MTEF-AC-C-SS1: + alarms: + fan: + - dps460-i2c-*-*/PSU-* Fan 1/fan1_alarm + - dps460-i2c-*-*/PSU-* Fan 1/fan1_fault + power: + - dps460-i2c-*-*/PSU-* 220V Rail (in)/in1_min_alarm + - dps460-i2c-*-*/PSU-* 220V Rail (in)/in1_max_alarm + - dps460-i2c-*-*/PSU-* 220V Rail (in)/in1_lcrit_alarm + - dps460-i2c-*-*/PSU-* 220V Rail (in)/in1_crit_alarm + - dps460-i2c-*-*/PSU-* 12V Rail (out)/in3_min_alarm + - dps460-i2c-*-*/PSU-* 12V Rail (out)/in3_max_alarm + - dps460-i2c-*-*/PSU-* 12V Rail (out)/in3_lcrit_alarm + - dps460-i2c-*-*/PSU-* 12V Rail (out)/in3_crit_alarm + - dps460-i2c-*-*/PSU-* 220V Rail Pwr (in)/power1_alarm + - dps460-i2c-*-*/PSU-* 12V Rail Pwr (out)/power2_max_alarm + - dps460-i2c-*-*/PSU-* 12V Rail Pwr (out)/power2_crit_alarm + - dps460-i2c-*-*/PSU-* 220V Rail Curr (in)/curr1_max_alarm + - dps460-i2c-*-*/PSU-* 12V Rail Curr (out)/curr2_max_alarm + - dps460-i2c-*-*/PSU-* 12V Rail Curr (out)/curr2_crit_alarm + temp: + - dps460-i2c-*-*/PSU-* Temp 1/temp1_max_alarm + - dps460-i2c-*-*/PSU-* Temp 1/temp1_crit_alarm + - dps460-i2c-*-*/PSU-* Temp 2/temp2_max_alarm + - dps460-i2c-*-*/PSU-* Temp 2/temp2_crit_alarm + - dps460-i2c-*-*/PSU-* Temp 3/temp3_max_alarm + - dps460-i2c-*-*/PSU-* Temp 3/temp3_crit_alarm + compares: + power: [ ] + temp: + - - dps460-i2c-*-*/PSU-* Temp 1/temp1_input + - dps460-i2c-*-*/PSU-* Temp 1/temp1_crit + - - dps460-i2c-*-*/PSU-* Temp 2/temp2_input + - dps460-i2c-*-*/PSU-* Temp 2/temp2_crit + - - dps460-i2c-*-*/PSU-* Temp 3/temp3_input + - dps460-i2c-*-*/PSU-* Temp 3/temp3_crit + non_zero: + fan: [ ] + power: [ ] + temp: [ ] + psu_skips: { } + sensor_skip_per_version: { } + MTEF-AC-G: + alarms: + fan: + - dps460-i2c-*-*/PSU-* Fan 1/fan1_alarm + - dps460-i2c-*-*/PSU-* Fan 1/fan1_fault + power: + - dps460-i2c-*-*/PSU-* 220V Rail (in)/in1_alarm + - dps460-i2c-*-*/PSU-* 12V Rail (out)/in2_lcrit_alarm + - dps460-i2c-*-*/PSU-* 12V Rail (out)/in2_crit_alarm + - dps460-i2c-*-*/PSU-* 220V Rail Pwr (in)/power1_alarm + - dps460-i2c-*-*/PSU-* 12V Rail Pwr (out)/power2_max_alarm + - dps460-i2c-*-*/PSU-* 220V Rail Curr (in)/curr1_max_alarm + - dps460-i2c-*-*/PSU-* 12V Rail Curr (out)/curr2_max_alarm + - dps460-i2c-*-*/PSU-* 12V Rail Curr (out)/curr2_lcrit_alarm + temp: + - dps460-i2c-*-*/PSU-* Temp 1/temp1_max_alarm + - dps460-i2c-*-*/PSU-* Temp 2/temp2_max_alarm + compares: + power: [ ] + temp: + - - dps460-i2c-*-*/PSU-* Temp 1/temp1_input + - dps460-i2c-*-*/PSU-* Temp 1/temp1_max + - - dps460-i2c-*-*/PSU-* Temp 2/temp2_input + - dps460-i2c-*-*/PSU-* Temp 2/temp2_max + non_zero: + fan: [ ] + power: [ ] + temp: [ ] + psu_skips: { } + sensor_skip_per_version: { } diff --git a/tests/platform_tests/sensors_utils/psu_sensor_utils.py b/tests/platform_tests/sensors_utils/psu_sensor_utils.py index 5de70615ae..effb1951f8 100644 --- a/tests/platform_tests/sensors_utils/psu_sensor_utils.py +++ b/tests/platform_tests/sensors_utils/psu_sensor_utils.py @@ -9,6 +9,11 @@ MISSING_PSU = "N/A" PSU_NUM_SENSOR_PATTERN = r'PSU-(\d+)(?:\([A-Z]\))?' SKIPPED_CHECK_TYPES = ["psu_skips", "sensor_skip_per_version"] +PSU_FAN_DIR_PATTERN = r'-(PSF|PSR)-' +# PSUs in this dictionary are only supported with the specified manufacturers +PSU_MANUFACTURER_SUPPORT = {'MTEF-AC-G': ['ACBEL']} +VPD_DATA_PATH_FORMAT = "/var/run/hw-management/eeprom/psu{PSU_INDEX}_vpd" +PSU_VPD_MANUFACTURER_FIELD = 'MFR_NAME' logger = logging.getLogger() @@ -106,6 +111,20 @@ def update_sensor_data(alarm_data, psu_platform_data, psu_numbers): return updated_alarm_data +def parse_psu_manufacturer(duthost, psu_index): + """ + The function parses the psu manufacturer of the psu installed at the given index from the vpd_data + :param duthost: duthost fixture + :param psu_index: Index of the psu + :return: The psu manufacturer name as it appears in the psu vpd_data + """ + vpd_data_path = VPD_DATA_PATH_FORMAT.format(PSU_INDEX=psu_index) + manufacturer_cmd = f"cat {vpd_data_path} | grep {PSU_VPD_MANUFACTURER_FIELD}" + psu_manufacturer_line = duthost.shell(manufacturer_cmd)["stdout"] + manufacturer_name_ind = 1 + return psu_manufacturer_line.split(':')[manufacturer_name_ind].strip() + + class SensorHelper: """ Helper class to the test_sensors tests @@ -159,16 +178,17 @@ def read_psus_from_dut(self): self.missing_psus = set() if self.supports_dynamic_psus: psu_data = json.loads(self.duthost.shell('show platform psu --json')['stdout']) - covered_psus = set(self.psu_sensors_checks.keys()) for psu in psu_data: psu_index, psu_model = psu["index"], psu["model"] - if psu_model in covered_psus: - self.psu_dict[psu_index] = psu_model + # Ignore PSR/PSF part, as we don't care if the fan is reversed (PSR) or not (PSF) + psu_model_no_fan_dir = re.sub(PSU_FAN_DIR_PATTERN, '-', psu_model) + if self.is_supported_psu_model(psu_index, psu_model_no_fan_dir): + self.psu_dict[psu_index] = psu_model_no_fan_dir elif psu["model"] == MISSING_PSU: self.missing_psus.add(psu_index) logger.warning(f"Slot {psu_index} is missing a PSU.") else: - self.uncovered_psus.add(psu_model) + self.uncovered_psus.add(psu_model_no_fan_dir) def platform_supports_dynamic_psu(self): """ @@ -277,3 +297,28 @@ def parse_psu_json_mapping(self, psu_nums_to_replace, hardware_version): bus_number = bus_data[0].split('-')[1] psu_json_data[psu_num] = (bus_number, bus_address, psu_side) return psu_json_data + + def is_supported_psu_model(self, psu_index, psu_model): + """ + This function returns whether the given psu_model should be supported or not + :param psu_index: The index the psu is installed in + :param psu_model: A psu model (without fan direction) + :returns: A boolean stating whether the psu dynamic feature is supported with this psu model + """ + covered_psus = set(self.psu_sensors_checks.keys()) + + return psu_model in covered_psus and self.is_psu_manufacturer_supported(psu_index, psu_model) + + def is_psu_manufacturer_supported(self, psu_index, psu_model): + """ + This function returns whether the given psu_model is installed with supported manufacturers + :param psu_index: The index the psu is installed in + :param psu_model: A psu model (without fan direction) + :returns: A boolean stating whether the psu dynamic feature is supported with this psu model its manufacturer + """ + manufacturer_supported = True + if psu_model in PSU_MANUFACTURER_SUPPORT: + supported_psu_manufacturers = PSU_MANUFACTURER_SUPPORT[psu_model] + psu_manufacturer = parse_psu_manufacturer(self.duthost, psu_index) + manufacturer_supported &= psu_manufacturer in supported_psu_manufacturers + return manufacturer_supported diff --git a/tests/platform_tests/sensors_utils/psu_sensors.json b/tests/platform_tests/sensors_utils/psu_sensors.json index a838fd5e63..1188d5411a 100644 --- a/tests/platform_tests/sensors_utils/psu_sensors.json +++ b/tests/platform_tests/sensors_utils/psu_sensors.json @@ -232,11 +232,11 @@ "i2c-1-mux (chan_id 3)" ], "chip": { - "dps460-i2c-*-58": [ + "dps460-i2c-*-59": [ "1", "L" ], - "dps460-i2c-*-59": [ + "dps460-i2c-*-58": [ "2", "R" ] @@ -282,11 +282,11 @@ "i2c-1-mux (chan_id 3)" ], "chip": { - "dps460-i2c-*-58": [ + "dps460-i2c-*-59": [ "1", "L" ], - "dps460-i2c-*-59": [ + "dps460-i2c-*-58": [ "2", "R" ] diff --git a/tests/platform_tests/test_sensors.py b/tests/platform_tests/test_sensors.py index e57c6887e4..408b1cfd16 100644 --- a/tests/platform_tests/test_sensors.py +++ b/tests/platform_tests/test_sensors.py @@ -53,14 +53,15 @@ def update_sensors_checks(duthost, sensors_checks, hardware_version): if psu_models_to_replace: logging.info(f"Fetching PSU sensors for PSUS: {psu_models_to_replace}\n") if sensor_helper.get_uncovered_psus(): - logging.warning(f"Unsupported PSUs in psu-sensors-data.yml: {sensor_helper.get_uncovered_psus()}\n") + logging.warning(f"Unsupported PSUs (regardless of fan direction) in psu_data.yml: " + f"{sensor_helper.get_uncovered_psus()}\n") sensor_helper.remove_psu_checks(sensors_checks, set(psu_models_to_replace.keys())) sensor_helper.update_psu_sensors(sensors_checks, psu_models_to_replace, hardware_version) else: - logging.warning(f"PSU sensors not covered by psu-sensors-data.yml. " - f"Unsupported PSUs: {sensor_helper.get_uncovered_psus()}\n") + logging.warning(f"PSU sensors not covered by psu_data.yml. Unsupported PSUs" + f" (regardless of fan direction): {sensor_helper.get_uncovered_psus()}\n") def test_sensors(duthosts, rand_one_dut_hostname, sensors_data):