Skip to content

Commit 9995df9

Browse files
committed
UT
1 parent f9119cc commit 9995df9

File tree

1 file changed

+192
-0
lines changed

1 file changed

+192
-0
lines changed

tests/bmc_fw_update_test.py

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
"""
2+
bmc_fw_update_test.py
3+
4+
Unit tests for bmc-fw-update.py script
5+
"""
6+
7+
8+
import sys
9+
import pytest
10+
if sys.version_info.major == 3:
11+
from unittest import mock
12+
else:
13+
import mock
14+
15+
try:
16+
from sonic_py_common import logger
17+
except ImportError:
18+
sys.modules['sonic_py_common'] = mock.MagicMock()
19+
sys.modules['sonic_py_common.logger'] = mock.MagicMock()
20+
21+
sys.modules['sonic_platform'] = mock.MagicMock()
22+
sys.modules['sonic_platform.platform'] = mock.MagicMock()
23+
24+
import importlib.util
25+
import os
26+
27+
bmc_fw_update_path = os.path.join(
28+
os.path.dirname(__file__),
29+
'..',
30+
'sonic_platform_base',
31+
'bmc-fw-update.py'
32+
)
33+
34+
spec = importlib.util.spec_from_file_location("bmc_fw_update", bmc_fw_update_path)
35+
bmc_fw_update = importlib.util.module_from_spec(spec)
36+
37+
38+
class TestBMCFWUpdate:
39+
"""Test class for BMC firmware update script"""
40+
41+
def setup_method(self):
42+
"""Set up test fixtures"""
43+
self.mock_logger = mock.MagicMock()
44+
self.mock_bmc = mock.MagicMock()
45+
self.mock_bmc.update_firmware.return_value = (0, ('Update successful', ['BMC_FW_0']))
46+
self.mock_bmc.get_firmware_id.return_value = 'BMC_FW_0'
47+
self.mock_bmc.request_bmc_reset.return_value = (0, 'Reset successful')
48+
self.mock_chassis = mock.MagicMock()
49+
self.mock_chassis.get_bmc.return_value = self.mock_bmc
50+
self.mock_platform = mock.MagicMock()
51+
self.mock_platform.get_chassis.return_value = self.mock_chassis
52+
53+
@mock.patch('sys.exit')
54+
@mock.patch('sonic_py_common.logger.Logger')
55+
@mock.patch('sonic_platform.platform.Platform')
56+
def test_main_success_bmc_firmware_updated(self, mock_platform_class, mock_logger_class, mock_exit):
57+
"""Test successful firmware update with BMC firmware component updated"""
58+
mock_logger_class.return_value = self.mock_logger
59+
mock_platform_class.return_value = self.mock_platform
60+
61+
test_args = ['bmc-fw-update.py', '/path/to/firmware.bin']
62+
with mock.patch.object(sys, 'argv', test_args):
63+
spec.loader.exec_module(bmc_fw_update)
64+
bmc_fw_update.main()
65+
66+
mock_logger_class.assert_called_once_with('bmc-fw-update')
67+
mock_platform_class.assert_called_once()
68+
self.mock_platform.get_chassis.assert_called_once()
69+
self.mock_chassis.get_bmc.assert_called_once()
70+
self.mock_bmc.update_firmware.assert_called_once_with('/path/to/firmware.bin')
71+
self.mock_bmc.get_firmware_id.assert_called_once()
72+
self.mock_bmc.request_bmc_reset.assert_called_once()
73+
74+
self.mock_logger.log_notice.assert_any_call('Starting BMC firmware update with /path/to/firmware.bin')
75+
self.mock_logger.log_notice.assert_any_call("Firmware updated successfully via the BMC. Updated components: ['BMC_FW_0']")
76+
self.mock_logger.log_notice.assert_any_call('BMC firmware updated successfully, restarting BMC...')
77+
self.mock_logger.log_notice.assert_any_call('BMC firmware update completed successfully')
78+
79+
mock_exit.assert_not_called()
80+
81+
@mock.patch('sys.exit')
82+
@mock.patch('sonic_py_common.logger.Logger')
83+
def test_main_missing_arguments(self, mock_logger_class, mock_exit):
84+
"""Test main function with missing firmware image path argument"""
85+
mock_logger_class.return_value = self.mock_logger
86+
87+
test_args = ['bmc-fw-update.py']
88+
with mock.patch.object(sys, 'argv', test_args):
89+
spec.loader.exec_module(bmc_fw_update)
90+
bmc_fw_update.main()
91+
92+
self.mock_logger.log_error.assert_called_once_with("Missing firmware image path argument")
93+
mock_exit.assert_called_once_with(1)
94+
95+
@mock.patch('sys.exit')
96+
@mock.patch('sonic_py_common.logger.Logger')
97+
@mock.patch('sonic_platform.platform.Platform')
98+
def test_main_no_bmc_instance(self, mock_platform_class, mock_logger_class, mock_exit):
99+
"""Test main function when BMC instance is None"""
100+
self.mock_chassis.get_bmc.return_value = None
101+
102+
mock_logger_class.return_value = self.mock_logger
103+
mock_platform_class.return_value = self.mock_platform
104+
105+
test_args = ['bmc-fw-update.py', '/path/to/firmware.bin']
106+
with mock.patch.object(sys, 'argv', test_args):
107+
spec.loader.exec_module(bmc_fw_update)
108+
bmc_fw_update.main()
109+
110+
self.mock_logger.log_error.assert_called_with("Failed to get BMC instance from chassis")
111+
mock_exit.assert_called_with(1)
112+
113+
@mock.patch('sys.exit')
114+
@mock.patch('sonic_py_common.logger.Logger')
115+
@mock.patch('sonic_platform.platform.Platform')
116+
def test_main_update_firmware_failure(self, mock_platform_class, mock_logger_class, mock_exit):
117+
"""Test main function when update_firmware returns error"""
118+
self.mock_bmc.update_firmware.return_value = (1, ('Update failed', []))
119+
120+
mock_logger_class.return_value = self.mock_logger
121+
mock_platform_class.return_value = self.mock_platform
122+
123+
test_args = ['bmc-fw-update.py', '/path/to/firmware.bin']
124+
with mock.patch.object(sys, 'argv', test_args):
125+
spec.loader.exec_module(bmc_fw_update)
126+
bmc_fw_update.main()
127+
128+
self.mock_logger.log_notice.assert_called_with('Starting BMC firmware update with /path/to/firmware.bin')
129+
self.mock_logger.log_error.assert_called_with('Failed to update BMC firmware. Error 1: Update failed')
130+
mock_exit.assert_called_with(1)
131+
132+
@mock.patch('sys.exit')
133+
@mock.patch('sonic_py_common.logger.Logger')
134+
@mock.patch('sonic_platform.platform.Platform')
135+
def test_main_bmc_reset_failure(self, mock_platform_class, mock_logger_class, mock_exit):
136+
"""Test main function when BMC reset fails"""
137+
self.mock_bmc.request_bmc_reset.return_value = (1, 'Reset failed')
138+
139+
mock_logger_class.return_value = self.mock_logger
140+
mock_platform_class.return_value = self.mock_platform
141+
142+
test_args = ['bmc-fw-update.py', '/path/to/firmware.bin']
143+
with mock.patch.object(sys, 'argv', test_args):
144+
spec.loader.exec_module(bmc_fw_update)
145+
bmc_fw_update.main()
146+
147+
self.mock_bmc.update_firmware.assert_called_once()
148+
self.mock_bmc.request_bmc_reset.assert_called_once()
149+
150+
self.mock_logger.log_error.assert_called_with('Failed to restart BMC. Error 1: Reset failed')
151+
mock_exit.assert_called_with(1)
152+
153+
@mock.patch('sys.exit')
154+
@mock.patch('sonic_py_common.logger.Logger')
155+
@mock.patch('sonic_platform.platform.Platform')
156+
def test_main_general_exception(self, mock_platform_class, mock_logger_class, mock_exit):
157+
"""Test main function when unexpected exception occurs"""
158+
mock_platform_class.side_effect = RuntimeError("Unexpected error")
159+
160+
mock_logger_class.return_value = self.mock_logger
161+
162+
test_args = ['bmc-fw-update.py', '/path/to/firmware.bin']
163+
with mock.patch.object(sys, 'argv', test_args):
164+
spec.loader.exec_module(bmc_fw_update)
165+
bmc_fw_update.main()
166+
167+
self.mock_logger.log_error.assert_called_with('BMC firmware update exception: Unexpected error')
168+
mock_exit.assert_called_with(1)
169+
170+
@mock.patch('sys.exit')
171+
@mock.patch('sonic_py_common.logger.Logger')
172+
@mock.patch('sonic_platform.platform.Platform')
173+
def test_main_empty_updated_components(self, mock_platform_class, mock_logger_class, mock_exit):
174+
"""Test successful firmware update with empty updated components list"""
175+
self.mock_bmc.update_firmware.return_value = (0, ('No components updated', []))
176+
self.mock_bmc.get_firmware_id.return_value = 'BMC_FW_0'
177+
178+
mock_logger_class.return_value = self.mock_logger
179+
mock_platform_class.return_value = self.mock_platform
180+
181+
test_args = ['bmc-fw-update.py', '/path/to/firmware.bin']
182+
with mock.patch.object(sys, 'argv', test_args):
183+
spec.loader.exec_module(bmc_fw_update)
184+
bmc_fw_update.main()
185+
186+
self.mock_bmc.update_firmware.assert_called_once_with('/path/to/firmware.bin')
187+
self.mock_bmc.get_firmware_id.assert_called_once()
188+
self.mock_bmc.request_bmc_reset.assert_not_called()
189+
190+
self.mock_logger.log_notice.assert_any_call("Firmware updated successfully via the BMC. Updated components: []")
191+
192+
mock_exit.assert_not_called()

0 commit comments

Comments
 (0)