Skip to content

Commit 78c6d46

Browse files
[python tests] Fix determine-reboot-cause_test.py importing module sonic_platform
This test, `determine-reboot-cause_test.py` and the script it tests, `scripts/determine-reboot-cause` expect the module `sonic_platform` to not exist on the system during unit tests on build hosts. The script implementation handles this situation by trying to import `sonic_platform` in the funciton calls, and having them return fake values in an `ImportError` exception handler. Otherwise, if `sonic_platform` is present in the build system when running unit tests, it will throw exceptions because the platform code is designed to run an a real SONiC device host. However, on the build system, there are races in the build, and it is possible for `sonic_platform` to be installed and loaded. This will break this test. This PR adds a fixture to remove the module and block it using temporary monkeypatching. `None` is assigned to `system.modules['sonic_platform']` to evict any cached loaded modules and block future loading, until the test is complete. This PR is in response to the following unit test failures appearing during builds on some occasions: ``` FAILED tests/determine-reboot-cause_test.py::TestDetermineRebootCause::test_find_hardware_reboot_cause_not_installed_or_not_implemented - TypeError: join() argument must be str, bytes, or os.PathLike object, not 'NoneType' FAILED tests/determine-reboot-cause_test.py::TestDetermineRebootCause::test_determine_reboot_cause_main_without_reboot_cause_dir - TypeError: join() argument must be str, bytes, or os.PathLike object, not 'NoneType' FAILED tests/determine-reboot-cause_test.py::TestDetermineRebootCause::test_determine_reboot_cause_main_with_reboot_cause_dir - TypeError: join() argument must be str, bytes, or os.PathLike object, not 'NoneType' ``` With details similar to: ``` _ TestDetermineRebootCause.test_find_hardware_reboot_cause_not_installed_or_not_implemented _ self = <tests.determine-reboot-cause_test.TestDetermineRebootCause object at 0x7f9c4a940d50> def test_find_hardware_reboot_cause_not_installed_or_not_implemented(self): > result = determine_reboot_cause.find_hardware_reboot_cause() tests/determine-reboot-cause_test.py:140: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ scripts/determine-reboot-cause:127: in find_hardware_reboot_cause hardware_reboot_cause_major, hardware_reboot_cause_minor = get_reboot_cause_from_platform() scripts/determine-reboot-cause:115: in get_reboot_cause_from_platform platform = sonic_platform.platform.Platform() /usr/local/lib/python3.13/dist-packages/sonic_platform/platform.py:34: in __init__ if DeviceDataManager.get_dpu_count(): /usr/local/lib/python3.13/dist-packages/sonic_platform/utils.py:183: in _impl method.return_value = method(*args, **kwargs) /usr/local/lib/python3.13/dist-packages/sonic_platform/device_data.py:372: in get_dpu_count dpu_data = cls.get_platform_dpus_data() /usr/local/lib/python3.13/dist-packages/sonic_platform/utils.py:183: in _impl method.return_value = method(*args, **kwargs) /usr/local/lib/python3.13/dist-packages/sonic_platform/device_data.py:357: in get_platform_dpus_data platform_path = device_info.get_path_to_platform_dir() /usr/local/lib/python3.13/dist-packages/sonic_py_common/device_info.py:283: in get_path_to_platform_dir platform_path_host = os.path.join(HOST_DEVICE_PATH, platform) <frozen posixpath>:90: in join ??? _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ funcname = 'join', args = ('/usr/share/sonic/device', None), hasstr = True hasbytes = False, s = None > ??? E TypeError: join() argument must be str, bytes, or os.PathLike object, not 'NoneType' <frozen genericpath>:188: TypeError ``` Signed-off-by: Judson Wilson <[email protected]>
1 parent 2c5bf36 commit 78c6d46

1 file changed

Lines changed: 15 additions & 0 deletions

File tree

tests/determine-reboot-cause_test.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,21 @@
99
from swsscommon import swsscommon
1010
from sonic_py_common.general import load_module_from_source
1111

12+
13+
# The platform-specific module `sonic_platform` may or may not be installed on the system hosting
14+
# the tests. In the build containers, it may coincidentally be installed, depending on the build
15+
# order. But, this test and the modules it tests are designed for the `sonic_platform` module to be
16+
# absent in the test environment. E.g., code that depends on DeviceInfo is bypassed when
17+
# `import sonic_platform` fails; otherwise, if it succeeds, and the environment is not set up like
18+
# a SONiC device host, the platform information may not be available and exceptions are thrown.
19+
# So remove the module if it's imported, and set to None to block a future import.
20+
@pytest.fixture(scope="module", autouse=True)
21+
def _remove_sonic_platform():
22+
with pytest.MonkeyPatch.context() as mp:
23+
mp.setitem(sys.modules, 'sonic_platform', None)
24+
yield
25+
26+
1227
# TODO: Remove this if/else block once we no longer support Python 2
1328
if sys.version_info.major == 3:
1429
from unittest import mock

0 commit comments

Comments
 (0)