-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Mellanox] Implement auto_firmware_update platform API for to support…
… fwutil auto-update (#7721) Why I did it The Mellanox platform is required to support the fwutil auto-update feature defined here This is to allow switches, when performing SONiC upgrades to choose whether to perform firmware upgrades that may interrupt the data plane through a cold boot. How I did it Two methods were added to the component implementations for mellanox. In the base Component class we add a default function that chooses to skip the installation of any firmware unless the cold boot option is provided. This is because the Mellanox platform, by default, does not support installing firmware on ONIE, the CPLD, or the BIOS "on-the-fly". In the ComponentSSD class we add a function that behaves similarly but uses the Mellanox specific SSD firmware upgrade tool to check if the current SSD supports being upgraded on the fly in order to decide whether to skip or perform the installation. How to verify it Unit tests are included with this PR. These test will run on build of target sonic-mellanox.bin You may also perform fwutil auto-update ... commands after sonic-net/sonic-utilities#1242 is merged in.
- Loading branch information
1 parent
df62e9c
commit 2960136
Showing
2 changed files
with
145 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
82 changes: 82 additions & 0 deletions
82
platform/mellanox/mlnx-platform-api/tests/test_firmware.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
import os | ||
import sys | ||
import pytest | ||
from mock import MagicMock | ||
from .mock_platform import MockFan | ||
|
||
test_path = os.path.dirname(os.path.abspath(__file__)) | ||
modules_path = os.path.dirname(test_path) | ||
sys.path.insert(0, modules_path) | ||
|
||
from sonic_platform.component import Component, ComponentSSD | ||
|
||
from sonic_platform_base.component_base import ComponentBase, \ | ||
FW_AUTO_INSTALLED, \ | ||
FW_AUTO_ERR_BOOT_TYPE, \ | ||
FW_AUTO_ERR_IMAGE, \ | ||
FW_AUTO_ERR_UKNOWN | ||
|
||
def mock_install_firmware_success(image_path): | ||
return True | ||
|
||
def mock_install_firmware_fail(image_path): | ||
return False | ||
|
||
def mock_update_notification_cold_boot(image_path): | ||
return "Immediate power cycle is required to complete NAME firmware update" | ||
|
||
def mock_update_notification_warm_boot(image_path): | ||
return None | ||
|
||
def mock_update_notification_error(image_path): | ||
raise RuntimeError("Failed to parse NAME firmware upgrade status") | ||
|
||
test_data_default = [ | ||
(None, False, None, FW_AUTO_ERR_IMAGE), | ||
(None, True, 'warm', FW_AUTO_ERR_BOOT_TYPE), | ||
(mock_install_firmware_fail, True, 'cold', FW_AUTO_ERR_UKNOWN), | ||
(mock_install_firmware_success, True, 'cold', FW_AUTO_INSTALLED) | ||
] | ||
|
||
test_data_ssd = [ | ||
(None, None, False, None, FW_AUTO_ERR_IMAGE), | ||
(None, mock_update_notification_error, True, None, FW_AUTO_ERR_UKNOWN), | ||
(mock_install_firmware_fail, mock_update_notification_cold_boot, True, 'cold', FW_AUTO_ERR_UKNOWN), | ||
(mock_install_firmware_success, mock_update_notification_cold_boot, True, 'warm', FW_AUTO_ERR_BOOT_TYPE), | ||
(mock_install_firmware_success, mock_update_notification_cold_boot, True, 'cold', FW_AUTO_INSTALLED), | ||
(mock_install_firmware_success, mock_update_notification_warm_boot, True, 'warm', FW_AUTO_INSTALLED), | ||
(mock_install_firmware_success, mock_update_notification_warm_boot, True, 'cold', FW_AUTO_INSTALLED) | ||
] | ||
|
||
@pytest.mark.parametrize('install_func, image_found, boot_type, expect', test_data_default) | ||
def test_auto_update_firmware_default(monkeypatch, install_func, image_found, boot_type, expect): | ||
|
||
def mock_path_exists(path): | ||
return image_found | ||
|
||
test_component = Component() | ||
|
||
monkeypatch.setattr(test_component, 'install_firmware', install_func) | ||
monkeypatch.setattr(os.path, 'exists', mock_path_exists) | ||
|
||
result = test_component.auto_update_firmware(None, boot_type) | ||
|
||
assert result == expect | ||
|
||
|
||
@pytest.mark.parametrize('install_func, notify, image_found, boot_type, expect', test_data_ssd) | ||
def test_auto_update_firmware_default(monkeypatch, install_func, notify, image_found, boot_type, expect): | ||
|
||
def mock_path_exists(path): | ||
return image_found | ||
|
||
test_component_ssd = ComponentSSD() | ||
|
||
monkeypatch.setattr(test_component_ssd, 'install_firmware', install_func) | ||
monkeypatch.setattr(test_component_ssd, 'get_firmware_update_notification', notify) | ||
monkeypatch.setattr(os.path, 'exists', mock_path_exists) | ||
|
||
result = test_component_ssd.auto_update_firmware(None, boot_type) | ||
|
||
assert result == expect | ||
|