diff --git a/supervisor/arch.py b/supervisor/arch.py index adbeb996e..e1a176117 100644 --- a/supervisor/arch.py +++ b/supervisor/arch.py @@ -28,6 +28,7 @@ class CpuArch(CoreSysAttributes): """Initialize CPU Architecture handler.""" self.coresys = coresys self._supported_arch: list[str] = [] + self._supported_set: set[str] = set() self._default_arch: str @property @@ -70,9 +71,11 @@ class CpuArch(CoreSysAttributes): if native_support not in self._supported_arch: self._supported_arch.append(native_support) + self._supported_set = set(self._supported_arch) + def is_supported(self, arch_list: list[str]) -> bool: """Return True if there is a supported arch by this platform.""" - return not set(self.supported).isdisjoint(set(arch_list)) + return not self._supported_set.isdisjoint(arch_list) def match(self, arch_list: list[str]) -> str: """Return best match for this CPU/Platform.""" diff --git a/tests/addons/test_addon.py b/tests/addons/test_addon.py index e419f601d..112bc445e 100644 --- a/tests/addons/test_addon.py +++ b/tests/addons/test_addon.py @@ -12,7 +12,6 @@ from securetar import SecureTarFile from supervisor.addons.addon import Addon from supervisor.addons.const import AddonBackupMode from supervisor.addons.model import AddonModel -from supervisor.arch import CpuArch from supervisor.const import AddonState, BusEvent from supervisor.coresys import CoreSys from supervisor.docker.addon import DockerAddon @@ -197,19 +196,17 @@ async def test_watchdog_on_stop(coresys: CoreSys, install_addon_ssh: Addon) -> N restart.assert_called_once() -async def test_listener_attached_on_install(coresys: CoreSys, repository): +async def test_listener_attached_on_install( + coresys: CoreSys, mock_amd64_arch_supported: None, repository +): """Test events listener attached on addon install.""" coresys.hardware.disk.get_disk_free_space = lambda x: 5000 container_collection = MagicMock() container_collection.get.side_effect = DockerException() with patch( - "supervisor.arch.CpuArch.supported", new=PropertyMock(return_value=["amd64"]) - ), patch( "supervisor.docker.manager.DockerAPI.containers", new=PropertyMock(return_value=container_collection), - ), patch( - "pathlib.Path.is_dir", return_value=True - ), patch( + ), patch("pathlib.Path.is_dir", return_value=True), patch( "supervisor.addons.addon.Addon.need_build", new=PropertyMock(return_value=False) ), patch( "supervisor.addons.model.AddonModel.with_ingress", @@ -556,6 +553,7 @@ async def test_restore( status: str, tmp_supervisor_data, path_extern, + mock_aarch64_arch_supported: None, ) -> None: """Test restoring an addon.""" coresys.hardware.disk.get_disk_free_space = lambda x: 5000 @@ -563,9 +561,7 @@ async def test_restore( await install_addon_ssh.load() tarfile = SecureTarFile(get_fixture_path(f"backup_local_ssh_{status}.tar.gz"), "r") - with patch.object(DockerAddon, "is_running", return_value=False), patch.object( - CpuArch, "supported", new=PropertyMock(return_value=["aarch64"]) - ): + with patch.object(DockerAddon, "is_running", return_value=False): start_task = await coresys.addons.restore(TEST_ADDON_SLUG, tarfile) assert bool(start_task) is (status == "running") @@ -577,6 +573,7 @@ async def test_restore_while_running( container: MagicMock, tmp_supervisor_data, path_extern, + mock_aarch64_arch_supported: None, ): """Test restore of a running addon.""" container.status = "running" @@ -586,8 +583,8 @@ async def test_restore_while_running( tarfile = SecureTarFile(get_fixture_path("backup_local_ssh_stopped.tar.gz"), "r") with patch.object(DockerAddon, "is_running", return_value=True), patch.object( - CpuArch, "supported", new=PropertyMock(return_value=["aarch64"]) - ), patch.object(Ingress, "update_hass_panel"): + Ingress, "update_hass_panel" + ): start_task = await coresys.addons.restore(TEST_ADDON_SLUG, tarfile) assert bool(start_task) is False @@ -600,6 +597,7 @@ async def test_restore_while_running_with_watchdog( container: MagicMock, tmp_supervisor_data, path_extern, + mock_aarch64_arch_supported: None, ): """Test restore of a running addon with watchdog interference.""" container.status = "running" @@ -619,8 +617,6 @@ async def test_restore_while_running_with_watchdog( with patch.object(Addon, "start") as start, patch.object( Addon, "restart" ) as restart, patch.object(DockerAddon, "stop", new=mock_stop), patch.object( - CpuArch, "supported", new=PropertyMock(return_value=["aarch64"]) - ), patch.object( Ingress, "update_hass_panel" ): await coresys.addons.restore(TEST_ADDON_SLUG, tarfile) @@ -650,16 +646,18 @@ async def test_start_when_running( async def test_local_example_install( - coresys: CoreSys, container: MagicMock, tmp_supervisor_data: Path, repository + coresys: CoreSys, + container: MagicMock, + tmp_supervisor_data: Path, + repository, + mock_aarch64_arch_supported: None, ): """Test install of an addon.""" assert not ( data_dir := tmp_supervisor_data / "addons" / "data" / "local_example" ).exists() - with patch.object( - CpuArch, "supported", new=PropertyMock(return_value=["aarch64"]) - ), patch.object(DockerAddon, "install") as install: + with patch.object(DockerAddon, "install") as install: await coresys.addons.install("local_example") install.assert_called_once() diff --git a/tests/conftest.py b/tests/conftest.py index 140b5080c..170cd6368 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -320,6 +320,7 @@ async def coresys( # Mock test client coresys_obj.arch._default_arch = "amd64" + coresys_obj.arch._supported_set = {"amd64"} coresys_obj._machine = "qemux86-64" coresys_obj._machine_id = uuid4() @@ -695,3 +696,17 @@ async def container(docker: DockerAPI) -> MagicMock: addon.status = "stopped" addon.attrs = {"State": {"ExitCode": 0}} yield addon + + +@pytest.fixture +def mock_amd64_arch_supported(coresys: CoreSys) -> None: + """Mock amd64 arch as supported.""" + with patch.object(coresys.arch, "_supported_set", {"amd64"}): + yield + + +@pytest.fixture +def mock_aarch64_arch_supported(coresys: CoreSys) -> None: + """Mock aarch64 arch as supported.""" + with patch.object(coresys.arch, "_supported_set", {"aarch64"}): + yield diff --git a/tests/test_arch.py b/tests/test_arch.py index cb9a9a86f..193356fe7 100644 --- a/tests/test_arch.py +++ b/tests/test_arch.py @@ -111,6 +111,10 @@ async def test_yellow_arch(coresys, sys_machine, sys_supervisor): assert coresys.arch.default == "aarch64" assert coresys.arch.supported == ["aarch64", "armv7", "armhf"] + assert coresys.arch.is_supported(["aarch64"]) is True + assert coresys.arch.is_supported(["armv7"]) is True + assert coresys.arch.is_supported(["armhf"]) is True + assert coresys.arch.is_supported(["x86_64", "i386"]) is False async def test_green_arch(coresys, sys_machine, sys_supervisor):