1
0
mirror of https://github.com/home-assistant/supervisor.git synced 2025-12-24 20:35:55 +00:00

Addon startup waits for healthy (#4376)

* Addon startup waits for healthy

* fix import for pylint

* wait_for to 5 in tests

* Adjust tests to simplify async tasks

* Remove wait_boot time from addons.boot tests

* Eliminate async task race conditions in tests
This commit is contained in:
Mike Degatano
2023-06-20 10:13:15 -04:00
committed by GitHub
parent e4ee3e4226
commit 254ec2d1af
23 changed files with 846 additions and 65 deletions

View File

@@ -8,10 +8,12 @@ import pytest
from supervisor.addons.addon import Addon
from supervisor.arch import CpuArch
from supervisor.const import AddonBoot, AddonStartup, AddonState
from supervisor.const import AddonBoot, AddonStartup, AddonState, BusEvent
from supervisor.coresys import CoreSys
from supervisor.docker.addon import DockerAddon
from supervisor.docker.const import ContainerState
from supervisor.docker.interface import DockerInterface
from supervisor.docker.monitor import DockerContainerStateEvent
from supervisor.exceptions import (
AddonConfigurationError,
AddonsError,
@@ -34,6 +36,12 @@ async def fixture_mock_arch_disk() -> None:
yield
@pytest.fixture(autouse=True)
async def fixture_remove_wait_boot(coresys: CoreSys) -> None:
"""Remove default wait boot time for tests."""
coresys.config.wait_boot = 0
async def test_image_added_removed_on_update(
coresys: CoreSys, install_addon_ssh: Addon
):
@@ -182,3 +190,89 @@ async def test_load(
write_hosts.assert_called_once()
assert "Found 1 installed add-ons" in caplog.text
async def test_boot_waits_for_addons(
coresys: CoreSys,
install_addon_ssh: Addon,
container,
tmp_supervisor_data,
path_extern,
):
"""Test addon manager boot waits for addons."""
install_addon_ssh.path_data.mkdir()
await install_addon_ssh.load()
assert install_addon_ssh.state == AddonState.STOPPED
addon_state: AddonState | None = None
async def fire_container_event(*args, **kwargs):
nonlocal addon_state
addon_state = install_addon_ssh.state
coresys.bus.fire_event(
BusEvent.DOCKER_CONTAINER_STATE_CHANGE,
DockerContainerStateEvent(
name=f"addon_{TEST_ADDON_SLUG}",
state=ContainerState.RUNNING,
id="abc123",
time=1,
),
)
with patch.object(DockerAddon, "run", new=fire_container_event):
await coresys.addons.boot(AddonStartup.APPLICATION)
assert addon_state == AddonState.STOPPED
assert install_addon_ssh.state == AddonState.STARTED
@pytest.mark.parametrize("status", ["running", "stopped"])
async def test_update(
coresys: CoreSys,
install_addon_ssh: Addon,
container: MagicMock,
status: str,
tmp_supervisor_data,
path_extern,
):
"""Test addon update."""
container.status = status
install_addon_ssh.path_data.mkdir()
await install_addon_ssh.load()
with patch(
"supervisor.store.data.read_json_or_yaml_file",
return_value=load_json_fixture("addon-config-add-image.json"),
):
await coresys.store.data.update()
assert install_addon_ssh.need_update is True
with patch.object(DockerInterface, "_install"), patch.object(
DockerAddon, "_is_running", return_value=False
):
start_task = await coresys.addons.update(TEST_ADDON_SLUG)
assert bool(start_task) is (status == "running")
@pytest.mark.parametrize("status", ["running", "stopped"])
async def test_rebuild(
coresys: CoreSys,
install_addon_ssh: Addon,
container: MagicMock,
status: str,
tmp_supervisor_data,
path_extern,
):
"""Test addon rebuild."""
container.status = status
install_addon_ssh.path_data.mkdir()
await install_addon_ssh.load()
with patch.object(DockerAddon, "_build"), patch.object(
DockerAddon, "_is_running", return_value=False
), patch.object(Addon, "need_build", new=PropertyMock(return_value=True)):
start_task = await coresys.addons.rebuild(TEST_ADDON_SLUG)
assert bool(start_task) is (status == "running")