Skip to content
Open
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
24 changes: 20 additions & 4 deletions sonic-psud/scripts/psud
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,7 @@ class PsuStatus(object):
self.check_psu_power_threshold = False
self.power_exceeded_threshold = False
self.logger = logger
self.led_status = NOT_AVAILABLE

def set_presence(self, presence):
"""
Expand Down Expand Up @@ -358,6 +359,18 @@ class PsuStatus(object):
self.power_exceeded_threshold = power_exceeded_threshold
return True

def set_led_status(self, led_status):
"""
Set and cache PSU LED status
:param led_status: PSU LED status
:return: True if status changed else False
"""
if led_status == self.led_status:
return False

self.led_status = led_status
return True

def is_ok(self):
return self.presence and self.power_good and self.voltage_good and self.temperature_good

Expand Down Expand Up @@ -670,10 +683,13 @@ class DaemonPsud(daemon_base.DaemonBase):
return

for index, psu_status in self.psu_status_dict.items():
fvs = swsscommon.FieldValuePairs([
('led_status', str(try_get(psu_status.psu.get_status_led, NOT_AVAILABLE)))
])
self.psu_tbl.set(get_psu_key(index), fvs)
led_status = try_get(psu_status.psu.get_status_led, NOT_AVAILABLE)
led_status_changed = psu_status.set_led_status(led_status)
if led_status_changed:
fvs = swsscommon.FieldValuePairs([
('led_status', str(led_status))
])
self.psu_tbl.set(get_psu_key(index), fvs)
self._update_psu_fan_led_status(psu_status.psu, index)

def _update_psu_fan_led_status(self, psu, psu_index):
Expand Down
48 changes: 47 additions & 1 deletion sonic-psud/tests/test_DaemonPsud.py
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,7 @@ def test_update_led_color(self):
assert daemon_psud.psu_tbl.set.call_count == 0
assert daemon_psud._update_psu_fan_led_status.call_count == 0

# First run: LED status is OFF, should write to DB (initial state)
psud.platform_chassis = MockChassis()
daemon_psud.psu_status_dict[1] = psu_status
expected_fvp = psud.swsscommon.FieldValuePairs([('led_status', MockPsu.STATUS_LED_COLOR_OFF)])
Expand All @@ -401,6 +402,15 @@ def test_update_led_color(self):
daemon_psud.psu_tbl.reset_mock()
daemon_psud._update_psu_fan_led_status.reset_mock()

# Second run: LED status is still OFF, should NOT write to DB (no change)
daemon_psud._update_led_color()
assert daemon_psud.psu_tbl.set.call_count == 0
assert daemon_psud._update_psu_fan_led_status.call_count == 1 # Fan LED status still checked

daemon_psud.psu_tbl.reset_mock()
daemon_psud._update_psu_fan_led_status.reset_mock()

# LED changes from OFF to GREEN, should write to DB
mock_psu.set_status_led(MockPsu.STATUS_LED_COLOR_GREEN)
expected_fvp = psud.swsscommon.FieldValuePairs([('led_status', MockPsu.STATUS_LED_COLOR_GREEN)])
daemon_psud._update_led_color()
Expand All @@ -412,6 +422,15 @@ def test_update_led_color(self):
daemon_psud.psu_tbl.reset_mock()
daemon_psud._update_psu_fan_led_status.reset_mock()

# LED status is still GREEN, should NOT write to DB (no change)
daemon_psud._update_led_color()
assert daemon_psud.psu_tbl.set.call_count == 0
assert daemon_psud._update_psu_fan_led_status.call_count == 1

daemon_psud.psu_tbl.reset_mock()
daemon_psud._update_psu_fan_led_status.reset_mock()

# LED changes from GREEN to RED, should write to DB
mock_psu.set_status_led(MockPsu.STATUS_LED_COLOR_RED)
expected_fvp = psud.swsscommon.FieldValuePairs([('led_status', MockPsu.STATUS_LED_COLOR_RED)])
daemon_psud._update_led_color()
Expand All @@ -423,7 +442,26 @@ def test_update_led_color(self):
daemon_psud.psu_tbl.reset_mock()
daemon_psud._update_psu_fan_led_status.reset_mock()

# Test exception handling
# LED status is still RED, should NOT write to DB (no change)
daemon_psud._update_led_color()
assert daemon_psud.psu_tbl.set.call_count == 0
assert daemon_psud._update_psu_fan_led_status.call_count == 1

daemon_psud.psu_tbl.reset_mock()
daemon_psud._update_psu_fan_led_status.reset_mock()

# LED changes back from RED to GREEN, should write to DB
mock_psu.set_status_led(MockPsu.STATUS_LED_COLOR_GREEN)
expected_fvp = psud.swsscommon.FieldValuePairs([('led_status', MockPsu.STATUS_LED_COLOR_GREEN)])
daemon_psud._update_led_color()
assert daemon_psud.psu_tbl.set.call_count == 1
daemon_psud.psu_tbl.set.assert_called_with(psud.PSU_INFO_KEY_TEMPLATE.format(1), expected_fvp)
assert daemon_psud._update_psu_fan_led_status.call_count == 1

daemon_psud.psu_tbl.reset_mock()
daemon_psud._update_psu_fan_led_status.reset_mock()

# Test exception handling - LED status becomes N/A, should write to DB
mock_psu.get_status_led = mock.Mock(side_effect=NotImplementedError)
expected_fvp = psud.swsscommon.FieldValuePairs([('led_status', psud.NOT_AVAILABLE)])
daemon_psud._update_led_color()
Expand All @@ -432,6 +470,14 @@ def test_update_led_color(self):
assert daemon_psud._update_psu_fan_led_status.call_count == 1
daemon_psud._update_psu_fan_led_status.assert_called_with(mock_psu, 1)

daemon_psud.psu_tbl.reset_mock()
daemon_psud._update_psu_fan_led_status.reset_mock()

# LED status is still N/A, should NOT write to DB (no change)
daemon_psud._update_led_color()
assert daemon_psud.psu_tbl.set.call_count == 0
assert daemon_psud._update_psu_fan_led_status.call_count == 1

def test_update_psu_fan_led_status(self):
mock_fan = MockFan("PSU 1 Test Fan 1", MockFan.FAN_DIRECTION_INTAKE)
mock_psu = MockPsu("PSU 1", 0, True, True)
Expand Down
Loading