Skip to content

Commit

Permalink
Enhancement of test_sensors.py to address several issues (#14154)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
mhen1 authored and mssonicbld committed Sep 10, 2024
1 parent b159beb commit d2a693a
Show file tree
Hide file tree
Showing 4 changed files with 134 additions and 16 deletions.
82 changes: 77 additions & 5 deletions tests/platform_tests/sensors_utils/psu_data.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
sensors_checks:
MTEF-PSF-AC-A:
MTEF-AC-A:
alarms:
fan:
- dps460-i2c-*-*/PSU-* Fan 1/fan1_alarm
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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: { }
53 changes: 49 additions & 4 deletions tests/platform_tests/sensors_utils/psu_sensor_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()


Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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):
"""
Expand Down Expand Up @@ -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
8 changes: 4 additions & 4 deletions tests/platform_tests/sensors_utils/psu_sensors.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
]
Expand Down Expand Up @@ -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"
]
Expand Down
7 changes: 4 additions & 3 deletions tests/platform_tests/test_sensors.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down

0 comments on commit d2a693a

Please sign in to comment.