Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions src/system-health/health_checker/hardware_checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,12 +171,17 @@ def _check_psu_status(self, config):
:param config: Health checker configuration
:return:
"""
if config.ignore_devices and 'psu' in config.ignore_devices and 'pdb' in config.ignore_devices:
ignore_psu = bool(config.ignore_devices) and 'psu' in config.ignore_devices
ignore_pdb = bool(config.ignore_devices) and 'pdb' in config.ignore_devices
if ignore_psu and ignore_pdb:
return

keys = self._db.keys(self._db.STATE_DB, HardwareChecker.PSU_TABLE_NAME + '*')
if not keys:
self.set_object_not_ok('PSU', 'PSU', 'Failed to get PSU information')
# An empty PSU_INFO table is only a failure when PSU monitoring is expected.
# Platforms without PSUs (e.g. DPUs) ignore 'psu' to suppress this alarm.
if not ignore_psu:
self.set_object_not_ok('PSU', 'PSU', 'Failed to get PSU information')
return

for key in natsorted(keys):
Expand All @@ -189,6 +194,12 @@ def _check_psu_status(self, config):
if config.ignore_devices and name in config.ignore_devices:
continue

# PSU and PDB rows share PSU_INFO (PDB keys look like "PDB 1"); honor each
# category-level ignore independently so ignoring one does not check the other.
is_pdb = name.upper().startswith('PDB')
if (is_pdb and ignore_pdb) or (not is_pdb and ignore_psu):
continue

data_dict = self._db.get_all(self._db.STATE_DB, key)
presence = data_dict.get('presence', 'false')
if presence.lower() != 'true':
Expand Down
32 changes: 32 additions & 0 deletions src/system-health/tests/test_system_health.py
Original file line number Diff line number Diff line change
Expand Up @@ -905,6 +905,38 @@ def test_hardware_checker_psu_pdb_ignore_both_skips_psu_check():
assert 'PSU 1' not in checker._info


def test_hardware_checker_psu_ignore_no_psu_info():
"""Ignoring 'psu' on a platform with no PSU_INFO (e.g. a DPU) must not report a PSU failure."""
MockConnector.data.clear()
config = Config()
config.ignore_devices = ['psu', 'fan']
checker = HardwareChecker()
checker.check(config)
assert 'PSU' not in checker._info


def test_hardware_checker_psu_ignore_skips_psu_but_checks_pdb():
"""Ignoring only 'psu' skips PSU rows but still evaluates PDB rows."""
MockConnector.data.clear()
MockConnector.data.update({
'PSU_INFO|PSU 1': {
'presence': 'False',
'status': 'True',
},
'PSU_INFO|PDB 1': {
'presence': 'True',
'status': 'False',
},
})
config = Config()
config.ignore_devices = ['psu']
checker = HardwareChecker()
checker.check(config)
assert 'PSU 1' not in checker._info
assert 'PDB 1' in checker._info
assert checker._info['PDB 1'][HealthChecker.INFO_FIELD_OBJECT_STATUS] == HealthChecker.STATUS_NOT_OK


def test_config():
config = Config()
config._config_file = os.path.join(test_path, Config.CONFIG_FILE)
Expand Down
Loading