Merge "Silence loud logging when no NetworkAdapters"

This commit is contained in:
Zuul 2026-01-10 20:33:14 +00:00 committed by Gerrit Code Review
commit 118d2e3284
3 changed files with 165 additions and 7 deletions

View file

@ -172,12 +172,26 @@ class RedfishFirmware(base.FirmwareInterface):
try:
chassis = redfish_utils.get_chassis(task.node, system)
except exception.RedfishError:
LOG.warning('No chassis available to retrieve NetworkAdapters '
'firmware information on node %(node_uuid)s',
{'node_uuid': task.node.uuid})
LOG.debug('No chassis available to retrieve NetworkAdapters '
'firmware information on node %(node_uuid)s',
{'node_uuid': task.node.uuid})
return nic_list
for net_adp in chassis.network_adapters.get_members():
try:
network_adapters = chassis.network_adapters
if network_adapters is None:
LOG.debug('NetworkAdapters not available on chassis for '
'node %(node_uuid)s',
{'node_uuid': task.node.uuid})
return nic_list
adapters = network_adapters.get_members()
except sushy.exceptions.MissingAttributeError:
LOG.debug('NetworkAdapters not available on chassis for '
'node %(node_uuid)s',
{'node_uuid': task.node.uuid})
return nic_list
for net_adp in adapters:
for net_adp_ctrl in net_adp.controllers:
fw_pkg_v = net_adp_ctrl.firmware_package_version
if not fw_pkg_v:
@ -382,9 +396,16 @@ class RedfishFirmware(base.FirmwareInterface):
# Test Manager resource
redfish_utils.get_manager(node, system)
# Test NetworkAdapters resource
# Test Chassis and NetworkAdapters resource (if available)
# Some systems may not have NetworkAdapters, which is valid
chassis = redfish_utils.get_chassis(node, system)
chassis.network_adapters.get_members()
try:
network_adapters = chassis.network_adapters
if network_adapters is not None:
network_adapters.get_members()
except sushy.exceptions.MissingAttributeError:
# NetworkAdapters not available is acceptable
pass
# All resources successful
consecutive_successes += 1

View file

@ -262,7 +262,7 @@ class RedfishFirmwareTestCase(db_base.DbTestCase):
shared=True) as task:
task.driver.firmware.cache_firmware_components(task)
log_mock.warning.assert_any_call(
log_mock.debug.assert_any_call(
'No chassis available to retrieve NetworkAdapters firmware '
'information on node %(node_uuid)s',
{'node_uuid': self.node.uuid}
@ -411,6 +411,70 @@ class RedfishFirmwareTestCase(db_base.DbTestCase):
fw_cmp_mock.assert_has_calls(fw_cmp_calls)
log_mock.warning.assert_not_called()
@mock.patch.object(redfish_fw, 'LOG', autospec=True)
@mock.patch.object(redfish_utils, 'get_system', autospec=True)
@mock.patch.object(redfish_utils, 'get_manager', autospec=True)
@mock.patch.object(redfish_utils, 'get_chassis', autospec=True)
@mock.patch.object(objects, 'FirmwareComponentList', autospec=True)
def test_retrieve_nic_components_network_adapters_none(
self, fw_cmp_list, chassis_mock, manager_mock,
system_mock, log_mock):
"""Test that None network_adapters is handled gracefully."""
fw_cmp_list.sync_firmware_components.return_value = (
[{'component': 'bios', 'current_version': '1.0.0'},
{'component': 'bmc', 'current_version': '1.0.0'}],
[], [])
with task_manager.acquire(self.context, self.node.uuid,
shared=True) as task:
system_mock.return_value.bios_version = '1.0.0'
manager_mock.return_value.firmware_version = '1.0.0'
# network_adapters is None
chassis_mock.return_value.network_adapters = None
task.driver.firmware.cache_firmware_components(task)
# Should log at debug level, not warning
log_mock.debug.assert_any_call(
'NetworkAdapters not available on chassis for '
'node %(node_uuid)s',
{'node_uuid': self.node.uuid}
)
log_mock.warning.assert_not_called()
@mock.patch.object(redfish_fw, 'LOG', autospec=True)
@mock.patch.object(redfish_utils, 'get_system', autospec=True)
@mock.patch.object(redfish_utils, 'get_manager', autospec=True)
@mock.patch.object(redfish_utils, 'get_chassis', autospec=True)
@mock.patch.object(objects, 'FirmwareComponentList', autospec=True)
def test_retrieve_nic_components_missing_attribute_error(
self, fw_cmp_list, chassis_mock, manager_mock,
system_mock, log_mock):
"""Test that MissingAttributeError is handled gracefully."""
fw_cmp_list.sync_firmware_components.return_value = (
[{'component': 'bios', 'current_version': '1.0.0'},
{'component': 'bmc', 'current_version': '1.0.0'}],
[], [])
with task_manager.acquire(self.context, self.node.uuid,
shared=True) as task:
system_mock.return_value.bios_version = '1.0.0'
manager_mock.return_value.firmware_version = '1.0.0'
# network_adapters raises MissingAttributeError
type(chassis_mock.return_value).network_adapters = (
mock.PropertyMock(
side_effect=sushy.exceptions.MissingAttributeError))
task.driver.firmware.cache_firmware_components(task)
# Should log at debug level, not warning
log_mock.debug.assert_any_call(
'NetworkAdapters not available on chassis for '
'node %(node_uuid)s',
{'node_uuid': self.node.uuid}
)
log_mock.warning.assert_not_called()
@mock.patch.object(redfish_utils, 'LOG', autospec=True)
@mock.patch.object(redfish_utils, '_get_connection', autospec=True)
def test_missing_updateservice(self, conn_mock, log_mock):
@ -1372,6 +1436,71 @@ class RedfishFirmwareTestCase(db_base.DbTestCase):
expected_calls = [mock.call(5)] * 4 # 4 sleeps between 5
sleep_mock.assert_has_calls(expected_calls)
def test__validate_resources_stability_network_adapters_none(self):
"""Test validation succeeds when network_adapters is None."""
firmware = redfish_fw.RedfishFirmware()
with task_manager.acquire(self.context, self.node.uuid,
shared=True) as task:
with mock.patch.object(redfish_utils, 'get_system',
autospec=True) as system_mock, \
mock.patch.object(redfish_utils, 'get_manager',
autospec=True) as manager_mock, \
mock.patch.object(redfish_utils, 'get_chassis',
autospec=True) as chassis_mock, \
mock.patch.object(time, 'time', autospec=True) as time_mock, \
mock.patch.object(time, 'sleep', autospec=True):
# Mock successful resource responses but network_adapters None
system_mock.return_value = mock.Mock()
manager_mock.return_value = mock.Mock()
chassis_mock.return_value.network_adapters = None
# Mock time progression to simulate consecutive successes
time_mock.side_effect = [0, 1, 2, 3]
# Should complete successfully (None network_adapters is OK)
firmware._validate_resources_stability(task.node)
# Verify all resources were checked 3 times
self.assertEqual(system_mock.call_count, 3)
self.assertEqual(manager_mock.call_count, 3)
self.assertEqual(chassis_mock.call_count, 3)
def test__validate_resources_stability_network_adapters_missing_attr(self):
"""Test validation succeeds when network_adapters is missing."""
firmware = redfish_fw.RedfishFirmware()
with task_manager.acquire(self.context, self.node.uuid,
shared=True) as task:
with mock.patch.object(redfish_utils, 'get_system',
autospec=True) as system_mock, \
mock.patch.object(redfish_utils, 'get_manager',
autospec=True) as manager_mock, \
mock.patch.object(redfish_utils, 'get_chassis',
autospec=True) as chassis_mock, \
mock.patch.object(time, 'time', autospec=True) as time_mock, \
mock.patch.object(time, 'sleep', autospec=True):
# Mock successful resource responses
system_mock.return_value = mock.Mock()
manager_mock.return_value = mock.Mock()
# network_adapters raises MissingAttributeError
type(chassis_mock.return_value).network_adapters = (
mock.PropertyMock(
side_effect=sushy.exceptions.MissingAttributeError))
# Mock time progression to simulate consecutive successes
time_mock.side_effect = [0, 1, 2, 3]
# Should complete successfully (missing network_adapters is OK)
firmware._validate_resources_stability(task.node)
# Verify all resources were checked 3 times
self.assertEqual(system_mock.call_count, 3)
self.assertEqual(manager_mock.call_count, 3)
self.assertEqual(chassis_mock.call_count, 3)
def test__validate_resources_stability_badrequest_error(self):
"""Test BMC resource validation handles BadRequestError correctly."""
firmware = redfish_fw.RedfishFirmware()

View file

@ -0,0 +1,8 @@
---
fixes:
- |
Fixes excessive logging when Redfish-managed servers do not have
NetworkAdapters endpoints. Previously, servers without NetworkAdapters
would generate warning-level log messages during firmware component
caching. Now these messages are logged at debug level since having no
NetworkAdapters is a valid hardware configuration.