Skip to content

Commit 401d784

Browse files
Provide BMC defaults for system status LED methods in ChassisBase (#731)
* Provide BMC defaults for system status LED methods in ChassisBase `show system-health` (sonic-utilities) calls initizalize_system_led(), set_status_led() and get_status_led() unconditionally on the chassis, but BMC platforms have no controllable system status LED. ChassisBase left set/get as NotImplementedError and had no initizalize_system_led at all, so the CLI failed on BMC images. Provide BMC defaults in ChassisBase, gated on is_switch_bmc(): initizalize_system_led() returns True, set_status_led() returns False, and get_status_led() returns "N/A". Non-BMC platforms are unaffected: they fall through to NotImplementedError as before, or override these methods. Signed-off-by: shreyansh-nexthop <shreyansh@nexthop.ai> * Add unit tests for the ChassisBase system LED BMC defaults Cover both branches of initizalize_system_led(), set_status_led() and get_status_led(): the BMC defaults when is_switch_bmc() is true, and the NotImplementedError path for non-BMC platforms. Signed-off-by: shreyansh-nexthop <shreyansh@nexthop.ai> --------- Signed-off-by: shreyansh-nexthop <shreyansh@nexthop.ai>
1 parent 01cada1 commit 401d784

2 files changed

Lines changed: 73 additions & 0 deletions

File tree

sonic_platform_base/chassis_base.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -884,6 +884,18 @@ def get_port_or_cage_type(self, index):
884884
# System LED methods
885885
##############################################
886886

887+
def initizalize_system_led(self):
888+
"""
889+
Initialize the system status LED.
890+
891+
Returns:
892+
bool: True if the system LED was initialized successfully.
893+
"""
894+
if device_info and device_info.is_switch_bmc():
895+
# BMC platforms have no controllable system LED, nothing to initialize.
896+
return True
897+
raise NotImplementedError
898+
887899
def set_status_led(self, color):
888900
"""
889901
Sets the state of the system LED
@@ -895,6 +907,9 @@ def set_status_led(self, color):
895907
Returns:
896908
bool: True if system LED state is set successfully, False if not
897909
"""
910+
if device_info and device_info.is_switch_bmc():
911+
# BMC platforms have no controllable system LED.
912+
return False
898913
raise NotImplementedError
899914

900915
def get_status_led(self):
@@ -905,6 +920,9 @@ def get_status_led(self):
905920
A string, one of the valid LED color strings which could be vendor
906921
specified.
907922
"""
923+
if device_info and device_info.is_switch_bmc():
924+
# BMC platforms have no controllable system LED.
925+
return "N/A"
908926
raise NotImplementedError
909927

910928
##############################################

tests/chassis_base_test.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,61 @@ def test_chassis_base(self):
5858

5959
assert exception_raised
6060

61+
@mock.patch('sonic_py_common.device_info.is_switch_bmc', return_value=True)
62+
def test_system_led_bmc(self, _mock_is_switch_bmc):
63+
# BMC platforms have no controllable system LED, so the base class
64+
# provides no-op defaults instead of raising NotImplementedError.
65+
chassis = ChassisBase()
66+
assert(chassis.initizalize_system_led() == True)
67+
assert(chassis.set_status_led("green") == False)
68+
assert(chassis.get_status_led() == "N/A")
69+
70+
@mock.patch.object(chassis_base, 'device_info', None)
71+
def test_system_led_no_device_info(self):
72+
# chassis_base tolerates device_info being None when sonic_py_common is
73+
# shadowed by a partial mock. These methods must still raise
74+
# NotImplementedError rather than AttributeError in that case.
75+
chassis = ChassisBase()
76+
not_implemented_methods = [
77+
[chassis.initizalize_system_led, [], {}],
78+
[chassis.set_status_led, ["COLOR"], {}],
79+
[chassis.get_status_led, [], {}],
80+
]
81+
82+
for method in not_implemented_methods:
83+
exception_raised = False
84+
try:
85+
func = method[0]
86+
args = method[1]
87+
kwargs = method[2]
88+
func(*args, **kwargs)
89+
except NotImplementedError:
90+
exception_raised = True
91+
92+
assert exception_raised
93+
94+
@mock.patch('sonic_py_common.device_info.is_switch_bmc', return_value=False)
95+
def test_system_led_non_bmc(self, _mock_is_switch_bmc):
96+
# Non-BMC platforms are expected to implement these themselves.
97+
chassis = ChassisBase()
98+
not_implemented_methods = [
99+
[chassis.initizalize_system_led, [], {}],
100+
[chassis.set_status_led, ["COLOR"], {}],
101+
[chassis.get_status_led, [], {}],
102+
]
103+
104+
for method in not_implemented_methods:
105+
exception_raised = False
106+
try:
107+
func = method[0]
108+
args = method[1]
109+
kwargs = method[2]
110+
func(*args, **kwargs)
111+
except NotImplementedError:
112+
exception_raised = True
113+
114+
assert exception_raised
115+
61116
def test_smartswitch(self):
62117
chassis = ChassisBase()
63118
assert(chassis.is_smartswitch() == False)

0 commit comments

Comments
 (0)