mirror of https://github.com/home-assistant/core
1050 lines
30 KiB
Python
1050 lines
30 KiB
Python
"""Test the addon manager."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import asyncio
|
|
from typing import Any
|
|
from unittest.mock import AsyncMock, call
|
|
from uuid import uuid4
|
|
|
|
from aiohasupervisor import SupervisorError
|
|
from aiohasupervisor.models import AddonsOptions, Discovery
|
|
import pytest
|
|
|
|
from homeassistant.components.hassio.addon_manager import (
|
|
AddonError,
|
|
AddonInfo,
|
|
AddonManager,
|
|
AddonState,
|
|
)
|
|
from homeassistant.components.hassio.handler import HassioAPIError
|
|
from homeassistant.core import HomeAssistant
|
|
|
|
|
|
async def test_not_installed_raises_exception(
|
|
addon_manager: AddonManager,
|
|
addon_not_installed: dict[str, Any],
|
|
) -> None:
|
|
"""Test addon not installed raises exception."""
|
|
addon_config = {"test_key": "test"}
|
|
|
|
with pytest.raises(AddonError) as err:
|
|
await addon_manager.async_configure_addon(addon_config)
|
|
|
|
assert str(err.value) == "Test add-on is not installed"
|
|
|
|
with pytest.raises(AddonError) as err:
|
|
await addon_manager.async_update_addon()
|
|
|
|
assert str(err.value) == "Test add-on is not installed"
|
|
|
|
|
|
async def test_not_available_raises_exception(
|
|
addon_manager: AddonManager,
|
|
addon_store_info: AsyncMock,
|
|
addon_info: AsyncMock,
|
|
) -> None:
|
|
"""Test addon not available raises exception."""
|
|
addon_store_info.return_value.available = False
|
|
addon_info.return_value.available = False
|
|
|
|
with pytest.raises(AddonError) as err:
|
|
await addon_manager.async_install_addon()
|
|
|
|
assert str(err.value) == "Test add-on is not available"
|
|
|
|
with pytest.raises(AddonError) as err:
|
|
await addon_manager.async_update_addon()
|
|
|
|
assert str(err.value) == "Test add-on is not available"
|
|
|
|
|
|
async def test_get_addon_discovery_info(
|
|
addon_manager: AddonManager, get_addon_discovery_info: AsyncMock
|
|
) -> None:
|
|
"""Test get addon discovery info."""
|
|
get_addon_discovery_info.return_value = [
|
|
Discovery(
|
|
addon="test_addon", service="", uuid=uuid4(), config={"test_key": "test"}
|
|
)
|
|
]
|
|
|
|
assert await addon_manager.async_get_addon_discovery_info() == {"test_key": "test"}
|
|
|
|
assert get_addon_discovery_info.call_count == 1
|
|
|
|
|
|
async def test_missing_addon_discovery_info(
|
|
addon_manager: AddonManager, get_addon_discovery_info: AsyncMock
|
|
) -> None:
|
|
"""Test missing addon discovery info."""
|
|
with pytest.raises(AddonError):
|
|
await addon_manager.async_get_addon_discovery_info()
|
|
|
|
assert get_addon_discovery_info.call_count == 1
|
|
|
|
|
|
async def test_get_addon_discovery_info_error(
|
|
addon_manager: AddonManager, get_addon_discovery_info: AsyncMock
|
|
) -> None:
|
|
"""Test get addon discovery info raises error."""
|
|
get_addon_discovery_info.side_effect = SupervisorError("Boom")
|
|
|
|
with pytest.raises(AddonError) as err:
|
|
assert await addon_manager.async_get_addon_discovery_info()
|
|
|
|
assert str(err.value) == "Failed to get the Test add-on discovery info: Boom"
|
|
|
|
assert get_addon_discovery_info.call_count == 1
|
|
|
|
|
|
async def test_get_addon_info_not_installed(
|
|
addon_manager: AddonManager, addon_not_installed: AsyncMock
|
|
) -> None:
|
|
"""Test get addon info when addon is not installed.."""
|
|
assert await addon_manager.async_get_addon_info() == AddonInfo(
|
|
available=True,
|
|
hostname=None,
|
|
options={},
|
|
state=AddonState.NOT_INSTALLED,
|
|
update_available=False,
|
|
version=None,
|
|
)
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
("addon_info_state", "addon_state"),
|
|
[("started", AddonState.RUNNING), ("stopped", AddonState.NOT_RUNNING)],
|
|
)
|
|
async def test_get_addon_info(
|
|
addon_manager: AddonManager,
|
|
addon_installed: AsyncMock,
|
|
addon_info_state: str,
|
|
addon_state: AddonState,
|
|
) -> None:
|
|
"""Test get addon info when addon is installed."""
|
|
addon_installed.return_value.state = addon_info_state
|
|
assert await addon_manager.async_get_addon_info() == AddonInfo(
|
|
available=True,
|
|
hostname="core-test-addon",
|
|
options={},
|
|
state=addon_state,
|
|
update_available=False,
|
|
version="1.0.0",
|
|
)
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
(
|
|
"addon_info_error",
|
|
"addon_info_calls",
|
|
"addon_store_info_error",
|
|
"addon_store_info_calls",
|
|
),
|
|
[(SupervisorError("Boom"), 1, None, 1), (None, 0, SupervisorError("Boom"), 1)],
|
|
)
|
|
async def test_get_addon_info_error(
|
|
addon_manager: AddonManager,
|
|
addon_info: AsyncMock,
|
|
addon_store_info: AsyncMock,
|
|
addon_installed: AsyncMock,
|
|
addon_info_error: Exception | None,
|
|
addon_info_calls: int,
|
|
addon_store_info_error: Exception | None,
|
|
addon_store_info_calls: int,
|
|
) -> None:
|
|
"""Test get addon info raises error."""
|
|
addon_info.side_effect = addon_info_error
|
|
addon_store_info.side_effect = addon_store_info_error
|
|
|
|
with pytest.raises(AddonError) as err:
|
|
await addon_manager.async_get_addon_info()
|
|
|
|
assert str(err.value) == "Failed to get the Test add-on info: Boom"
|
|
|
|
assert addon_info.call_count == addon_info_calls
|
|
assert addon_store_info.call_count == addon_store_info_calls
|
|
|
|
|
|
async def test_set_addon_options(
|
|
hass: HomeAssistant, addon_manager: AddonManager, set_addon_options: AsyncMock
|
|
) -> None:
|
|
"""Test set addon options."""
|
|
await addon_manager.async_set_addon_options({"test_key": "test"})
|
|
|
|
assert set_addon_options.call_count == 1
|
|
assert set_addon_options.call_args == call(
|
|
"test_addon", AddonsOptions(config={"test_key": "test"})
|
|
)
|
|
|
|
|
|
async def test_set_addon_options_error(
|
|
hass: HomeAssistant, addon_manager: AddonManager, set_addon_options: AsyncMock
|
|
) -> None:
|
|
"""Test set addon options raises error."""
|
|
set_addon_options.side_effect = SupervisorError("Boom")
|
|
|
|
with pytest.raises(AddonError) as err:
|
|
await addon_manager.async_set_addon_options({"test_key": "test"})
|
|
|
|
assert str(err.value) == "Failed to set the Test add-on options: Boom"
|
|
|
|
assert set_addon_options.call_count == 1
|
|
assert set_addon_options.call_args == call(
|
|
"test_addon", AddonsOptions(config={"test_key": "test"})
|
|
)
|
|
|
|
|
|
async def test_install_addon(
|
|
addon_manager: AddonManager,
|
|
install_addon: AsyncMock,
|
|
addon_store_info: AsyncMock,
|
|
addon_info: AsyncMock,
|
|
) -> None:
|
|
"""Test install addon."""
|
|
addon_store_info.return_value.available = True
|
|
addon_info.return_value.available = True
|
|
|
|
await addon_manager.async_install_addon()
|
|
|
|
assert install_addon.call_count == 1
|
|
|
|
|
|
async def test_install_addon_error(
|
|
addon_manager: AddonManager,
|
|
install_addon: AsyncMock,
|
|
addon_store_info: AsyncMock,
|
|
addon_info: AsyncMock,
|
|
) -> None:
|
|
"""Test install addon raises error."""
|
|
addon_store_info.return_value.available = True
|
|
addon_info.return_value.available = True
|
|
install_addon.side_effect = SupervisorError("Boom")
|
|
|
|
with pytest.raises(AddonError) as err:
|
|
await addon_manager.async_install_addon()
|
|
|
|
assert str(err.value) == "Failed to install the Test add-on: Boom"
|
|
|
|
assert install_addon.call_count == 1
|
|
|
|
|
|
async def test_schedule_install_addon(
|
|
addon_manager: AddonManager,
|
|
addon_installed: AsyncMock,
|
|
install_addon: AsyncMock,
|
|
) -> None:
|
|
"""Test schedule install addon."""
|
|
install_task = addon_manager.async_schedule_install_addon()
|
|
|
|
assert addon_manager.task_in_progress() is True
|
|
|
|
assert await addon_manager.async_get_addon_info() == AddonInfo(
|
|
available=True,
|
|
hostname="core-test-addon",
|
|
options={},
|
|
state=AddonState.INSTALLING,
|
|
update_available=False,
|
|
version="1.0.0",
|
|
)
|
|
|
|
# Make sure that actually only one install task is running.
|
|
install_task_two = addon_manager.async_schedule_install_addon()
|
|
|
|
await asyncio.gather(install_task, install_task_two)
|
|
|
|
assert addon_manager.task_in_progress() is False
|
|
assert install_addon.call_count == 1
|
|
|
|
install_addon.reset_mock()
|
|
|
|
# Test that another call can be made after the install is done.
|
|
await addon_manager.async_schedule_install_addon()
|
|
|
|
assert install_addon.call_count == 1
|
|
|
|
|
|
async def test_schedule_install_addon_error(
|
|
addon_manager: AddonManager,
|
|
addon_installed: AsyncMock,
|
|
install_addon: AsyncMock,
|
|
) -> None:
|
|
"""Test schedule install addon raises error."""
|
|
install_addon.side_effect = SupervisorError("Boom")
|
|
|
|
with pytest.raises(AddonError) as err:
|
|
await addon_manager.async_schedule_install_addon()
|
|
|
|
assert str(err.value) == "Failed to install the Test add-on: Boom"
|
|
|
|
assert install_addon.call_count == 1
|
|
|
|
|
|
async def test_schedule_install_addon_logs_error(
|
|
addon_manager: AddonManager,
|
|
addon_installed: AsyncMock,
|
|
install_addon: AsyncMock,
|
|
caplog: pytest.LogCaptureFixture,
|
|
) -> None:
|
|
"""Test schedule install addon logs error."""
|
|
install_addon.side_effect = SupervisorError("Boom")
|
|
|
|
await addon_manager.async_schedule_install_addon(catch_error=True)
|
|
|
|
assert "Failed to install the Test add-on: Boom" in caplog.text
|
|
assert install_addon.call_count == 1
|
|
|
|
|
|
async def test_uninstall_addon(
|
|
addon_manager: AddonManager, uninstall_addon: AsyncMock
|
|
) -> None:
|
|
"""Test uninstall addon."""
|
|
await addon_manager.async_uninstall_addon()
|
|
|
|
assert uninstall_addon.call_count == 1
|
|
|
|
|
|
async def test_uninstall_addon_error(
|
|
addon_manager: AddonManager, uninstall_addon: AsyncMock
|
|
) -> None:
|
|
"""Test uninstall addon raises error."""
|
|
uninstall_addon.side_effect = SupervisorError("Boom")
|
|
|
|
with pytest.raises(AddonError) as err:
|
|
await addon_manager.async_uninstall_addon()
|
|
|
|
assert str(err.value) == "Failed to uninstall the Test add-on: Boom"
|
|
|
|
assert uninstall_addon.call_count == 1
|
|
|
|
|
|
async def test_start_addon(addon_manager: AddonManager, start_addon: AsyncMock) -> None:
|
|
"""Test start addon."""
|
|
await addon_manager.async_start_addon()
|
|
|
|
assert start_addon.call_count == 1
|
|
|
|
|
|
async def test_start_addon_error(
|
|
addon_manager: AddonManager, start_addon: AsyncMock
|
|
) -> None:
|
|
"""Test start addon raises error."""
|
|
start_addon.side_effect = SupervisorError("Boom")
|
|
|
|
with pytest.raises(AddonError) as err:
|
|
await addon_manager.async_start_addon()
|
|
|
|
assert str(err.value) == "Failed to start the Test add-on: Boom"
|
|
|
|
assert start_addon.call_count == 1
|
|
|
|
|
|
async def test_schedule_start_addon(
|
|
addon_manager: AddonManager,
|
|
addon_installed: AsyncMock,
|
|
start_addon: AsyncMock,
|
|
) -> None:
|
|
"""Test schedule start addon."""
|
|
start_task = addon_manager.async_schedule_start_addon()
|
|
|
|
assert addon_manager.task_in_progress() is True
|
|
|
|
# Make sure that actually only one start task is running.
|
|
start_task_two = addon_manager.async_schedule_start_addon()
|
|
|
|
await asyncio.gather(start_task, start_task_two)
|
|
|
|
assert addon_manager.task_in_progress() is False
|
|
assert start_addon.call_count == 1
|
|
|
|
start_addon.reset_mock()
|
|
|
|
# Test that another call can be made after the start is done.
|
|
await addon_manager.async_schedule_start_addon()
|
|
|
|
assert start_addon.call_count == 1
|
|
|
|
|
|
async def test_schedule_start_addon_error(
|
|
addon_manager: AddonManager,
|
|
addon_installed: AsyncMock,
|
|
start_addon: AsyncMock,
|
|
) -> None:
|
|
"""Test schedule start addon raises error."""
|
|
start_addon.side_effect = SupervisorError("Boom")
|
|
|
|
with pytest.raises(AddonError) as err:
|
|
await addon_manager.async_schedule_start_addon()
|
|
|
|
assert str(err.value) == "Failed to start the Test add-on: Boom"
|
|
|
|
assert start_addon.call_count == 1
|
|
|
|
|
|
async def test_schedule_start_addon_logs_error(
|
|
addon_manager: AddonManager,
|
|
addon_installed: AsyncMock,
|
|
start_addon: AsyncMock,
|
|
caplog: pytest.LogCaptureFixture,
|
|
) -> None:
|
|
"""Test schedule start addon logs error."""
|
|
start_addon.side_effect = SupervisorError("Boom")
|
|
|
|
await addon_manager.async_schedule_start_addon(catch_error=True)
|
|
|
|
assert "Failed to start the Test add-on: Boom" in caplog.text
|
|
assert start_addon.call_count == 1
|
|
|
|
|
|
async def test_restart_addon(
|
|
addon_manager: AddonManager, restart_addon: AsyncMock
|
|
) -> None:
|
|
"""Test restart addon."""
|
|
await addon_manager.async_restart_addon()
|
|
|
|
assert restart_addon.call_count == 1
|
|
|
|
|
|
async def test_restart_addon_error(
|
|
addon_manager: AddonManager, restart_addon: AsyncMock
|
|
) -> None:
|
|
"""Test restart addon raises error."""
|
|
restart_addon.side_effect = SupervisorError("Boom")
|
|
|
|
with pytest.raises(AddonError) as err:
|
|
await addon_manager.async_restart_addon()
|
|
|
|
assert str(err.value) == "Failed to restart the Test add-on: Boom"
|
|
|
|
assert restart_addon.call_count == 1
|
|
|
|
|
|
async def test_schedule_restart_addon(
|
|
addon_manager: AddonManager,
|
|
addon_installed: AsyncMock,
|
|
restart_addon: AsyncMock,
|
|
) -> None:
|
|
"""Test schedule restart addon."""
|
|
restart_task = addon_manager.async_schedule_restart_addon()
|
|
|
|
assert addon_manager.task_in_progress() is True
|
|
|
|
# Make sure that actually only one start task is running.
|
|
restart_task_two = addon_manager.async_schedule_restart_addon()
|
|
|
|
await asyncio.gather(restart_task, restart_task_two)
|
|
|
|
assert addon_manager.task_in_progress() is False
|
|
assert restart_addon.call_count == 1
|
|
|
|
restart_addon.reset_mock()
|
|
|
|
# Test that another call can be made after the restart is done.
|
|
await addon_manager.async_schedule_restart_addon()
|
|
|
|
assert restart_addon.call_count == 1
|
|
|
|
|
|
async def test_schedule_restart_addon_error(
|
|
addon_manager: AddonManager,
|
|
addon_installed: AsyncMock,
|
|
restart_addon: AsyncMock,
|
|
) -> None:
|
|
"""Test schedule restart addon raises error."""
|
|
restart_addon.side_effect = SupervisorError("Boom")
|
|
|
|
with pytest.raises(AddonError) as err:
|
|
await addon_manager.async_schedule_restart_addon()
|
|
|
|
assert str(err.value) == "Failed to restart the Test add-on: Boom"
|
|
|
|
assert restart_addon.call_count == 1
|
|
|
|
|
|
async def test_schedule_restart_addon_logs_error(
|
|
addon_manager: AddonManager,
|
|
addon_installed: AsyncMock,
|
|
restart_addon: AsyncMock,
|
|
caplog: pytest.LogCaptureFixture,
|
|
) -> None:
|
|
"""Test schedule restart addon logs error."""
|
|
restart_addon.side_effect = SupervisorError("Boom")
|
|
|
|
await addon_manager.async_schedule_restart_addon(catch_error=True)
|
|
|
|
assert "Failed to restart the Test add-on: Boom" in caplog.text
|
|
assert restart_addon.call_count == 1
|
|
|
|
|
|
async def test_stop_addon(addon_manager: AddonManager, stop_addon: AsyncMock) -> None:
|
|
"""Test stop addon."""
|
|
await addon_manager.async_stop_addon()
|
|
|
|
assert stop_addon.call_count == 1
|
|
|
|
|
|
async def test_stop_addon_error(
|
|
addon_manager: AddonManager, stop_addon: AsyncMock
|
|
) -> None:
|
|
"""Test stop addon raises error."""
|
|
stop_addon.side_effect = SupervisorError("Boom")
|
|
|
|
with pytest.raises(AddonError) as err:
|
|
await addon_manager.async_stop_addon()
|
|
|
|
assert str(err.value) == "Failed to stop the Test add-on: Boom"
|
|
|
|
assert stop_addon.call_count == 1
|
|
|
|
|
|
async def test_update_addon(
|
|
hass: HomeAssistant,
|
|
addon_manager: AddonManager,
|
|
addon_info: AsyncMock,
|
|
addon_installed: AsyncMock,
|
|
create_backup: AsyncMock,
|
|
update_addon: AsyncMock,
|
|
) -> None:
|
|
"""Test update addon."""
|
|
addon_info.return_value.update_available = True
|
|
|
|
await addon_manager.async_update_addon()
|
|
|
|
assert addon_info.call_count == 2
|
|
assert create_backup.call_count == 1
|
|
assert create_backup.call_args == call(
|
|
hass, {"name": "addon_test_addon_1.0.0", "addons": ["test_addon"]}, partial=True
|
|
)
|
|
assert update_addon.call_count == 1
|
|
|
|
|
|
async def test_update_addon_no_update(
|
|
addon_manager: AddonManager,
|
|
addon_info: AsyncMock,
|
|
addon_installed: AsyncMock,
|
|
create_backup: AsyncMock,
|
|
update_addon: AsyncMock,
|
|
) -> None:
|
|
"""Test update addon without update available."""
|
|
addon_info.return_value.update_available = False
|
|
|
|
await addon_manager.async_update_addon()
|
|
|
|
assert addon_info.call_count == 1
|
|
assert create_backup.call_count == 0
|
|
assert update_addon.call_count == 0
|
|
|
|
|
|
async def test_update_addon_error(
|
|
hass: HomeAssistant,
|
|
addon_manager: AddonManager,
|
|
addon_info: AsyncMock,
|
|
addon_installed: AsyncMock,
|
|
create_backup: AsyncMock,
|
|
update_addon: AsyncMock,
|
|
) -> None:
|
|
"""Test update addon raises error."""
|
|
addon_info.return_value.update_available = True
|
|
update_addon.side_effect = SupervisorError("Boom")
|
|
|
|
with pytest.raises(AddonError) as err:
|
|
await addon_manager.async_update_addon()
|
|
|
|
assert str(err.value) == "Failed to update the Test add-on: Boom"
|
|
|
|
assert addon_info.call_count == 2
|
|
assert create_backup.call_count == 1
|
|
assert create_backup.call_args == call(
|
|
hass, {"name": "addon_test_addon_1.0.0", "addons": ["test_addon"]}, partial=True
|
|
)
|
|
assert update_addon.call_count == 1
|
|
|
|
|
|
async def test_schedule_update_addon(
|
|
hass: HomeAssistant,
|
|
addon_manager: AddonManager,
|
|
addon_info: AsyncMock,
|
|
addon_installed: AsyncMock,
|
|
create_backup: AsyncMock,
|
|
update_addon: AsyncMock,
|
|
) -> None:
|
|
"""Test schedule update addon."""
|
|
addon_info.return_value.update_available = True
|
|
|
|
update_task = addon_manager.async_schedule_update_addon()
|
|
|
|
assert addon_manager.task_in_progress() is True
|
|
|
|
assert await addon_manager.async_get_addon_info() == AddonInfo(
|
|
available=True,
|
|
hostname="core-test-addon",
|
|
options={},
|
|
state=AddonState.UPDATING,
|
|
update_available=True,
|
|
version="1.0.0",
|
|
)
|
|
|
|
# Make sure that actually only one update task is running.
|
|
update_task_two = addon_manager.async_schedule_update_addon()
|
|
|
|
await asyncio.gather(update_task, update_task_two)
|
|
|
|
assert addon_manager.task_in_progress() is False
|
|
assert addon_info.call_count == 3
|
|
assert create_backup.call_count == 1
|
|
assert create_backup.call_args == call(
|
|
hass, {"name": "addon_test_addon_1.0.0", "addons": ["test_addon"]}, partial=True
|
|
)
|
|
assert update_addon.call_count == 1
|
|
|
|
update_addon.reset_mock()
|
|
|
|
# Test that another call can be made after the update is done.
|
|
await addon_manager.async_schedule_update_addon()
|
|
|
|
assert update_addon.call_count == 1
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
(
|
|
"create_backup_error",
|
|
"create_backup_calls",
|
|
"update_addon_error",
|
|
"update_addon_calls",
|
|
"error_message",
|
|
),
|
|
[
|
|
(
|
|
HassioAPIError("Boom"),
|
|
1,
|
|
None,
|
|
0,
|
|
"Failed to create a backup of the Test add-on: Boom",
|
|
),
|
|
(
|
|
None,
|
|
1,
|
|
SupervisorError("Boom"),
|
|
1,
|
|
"Failed to update the Test add-on: Boom",
|
|
),
|
|
],
|
|
)
|
|
async def test_schedule_update_addon_error(
|
|
addon_manager: AddonManager,
|
|
addon_installed: AsyncMock,
|
|
create_backup: AsyncMock,
|
|
update_addon: AsyncMock,
|
|
create_backup_error: Exception | None,
|
|
create_backup_calls: int,
|
|
update_addon_error: Exception | None,
|
|
update_addon_calls: int,
|
|
error_message: str,
|
|
) -> None:
|
|
"""Test schedule update addon raises error."""
|
|
addon_installed.return_value.update_available = True
|
|
create_backup.side_effect = create_backup_error
|
|
update_addon.side_effect = update_addon_error
|
|
|
|
with pytest.raises(AddonError) as err:
|
|
await addon_manager.async_schedule_update_addon()
|
|
|
|
assert str(err.value) == error_message
|
|
|
|
assert create_backup.call_count == create_backup_calls
|
|
assert update_addon.call_count == update_addon_calls
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
(
|
|
"create_backup_error",
|
|
"create_backup_calls",
|
|
"update_addon_error",
|
|
"update_addon_calls",
|
|
"error_log",
|
|
),
|
|
[
|
|
(
|
|
HassioAPIError("Boom"),
|
|
1,
|
|
None,
|
|
0,
|
|
"Failed to create a backup of the Test add-on: Boom",
|
|
),
|
|
(
|
|
None,
|
|
1,
|
|
SupervisorError("Boom"),
|
|
1,
|
|
"Failed to update the Test add-on: Boom",
|
|
),
|
|
],
|
|
)
|
|
async def test_schedule_update_addon_logs_error(
|
|
addon_manager: AddonManager,
|
|
addon_installed: AsyncMock,
|
|
create_backup: AsyncMock,
|
|
update_addon: AsyncMock,
|
|
create_backup_error: Exception | None,
|
|
create_backup_calls: int,
|
|
update_addon_error: Exception | None,
|
|
update_addon_calls: int,
|
|
error_log: str,
|
|
caplog: pytest.LogCaptureFixture,
|
|
) -> None:
|
|
"""Test schedule update addon logs error."""
|
|
addon_installed.return_value.update_available = True
|
|
create_backup.side_effect = create_backup_error
|
|
update_addon.side_effect = update_addon_error
|
|
|
|
await addon_manager.async_schedule_update_addon(catch_error=True)
|
|
|
|
assert error_log in caplog.text
|
|
assert create_backup.call_count == create_backup_calls
|
|
assert update_addon.call_count == update_addon_calls
|
|
|
|
|
|
async def test_create_backup(
|
|
hass: HomeAssistant,
|
|
addon_manager: AddonManager,
|
|
addon_info: AsyncMock,
|
|
addon_installed: AsyncMock,
|
|
create_backup: AsyncMock,
|
|
) -> None:
|
|
"""Test creating a backup of the addon."""
|
|
await addon_manager.async_create_backup()
|
|
|
|
assert addon_info.call_count == 1
|
|
assert create_backup.call_count == 1
|
|
assert create_backup.call_args == call(
|
|
hass, {"name": "addon_test_addon_1.0.0", "addons": ["test_addon"]}, partial=True
|
|
)
|
|
|
|
|
|
async def test_create_backup_error(
|
|
hass: HomeAssistant,
|
|
addon_manager: AddonManager,
|
|
addon_info: AsyncMock,
|
|
addon_installed: AsyncMock,
|
|
create_backup: AsyncMock,
|
|
) -> None:
|
|
"""Test creating a backup of the addon raises error."""
|
|
create_backup.side_effect = HassioAPIError("Boom")
|
|
|
|
with pytest.raises(AddonError) as err:
|
|
await addon_manager.async_create_backup()
|
|
|
|
assert str(err.value) == "Failed to create a backup of the Test add-on: Boom"
|
|
|
|
assert addon_info.call_count == 1
|
|
assert create_backup.call_count == 1
|
|
assert create_backup.call_args == call(
|
|
hass, {"name": "addon_test_addon_1.0.0", "addons": ["test_addon"]}, partial=True
|
|
)
|
|
|
|
|
|
@pytest.mark.usefixtures("addon_installed")
|
|
@pytest.mark.parametrize("set_addon_options_side_effect", [None])
|
|
async def test_schedule_install_setup_addon(
|
|
addon_manager: AddonManager,
|
|
install_addon: AsyncMock,
|
|
set_addon_options: AsyncMock,
|
|
start_addon: AsyncMock,
|
|
) -> None:
|
|
"""Test schedule install setup addon."""
|
|
install_task = addon_manager.async_schedule_install_setup_addon(
|
|
{"test_key": "test"}
|
|
)
|
|
|
|
assert addon_manager.task_in_progress() is True
|
|
|
|
# Make sure that actually only one install task is running.
|
|
install_task_two = addon_manager.async_schedule_install_setup_addon(
|
|
{"test_key": "test"}
|
|
)
|
|
|
|
await asyncio.gather(install_task, install_task_two)
|
|
|
|
assert addon_manager.task_in_progress() is False
|
|
assert install_addon.call_count == 1
|
|
assert set_addon_options.call_count == 1
|
|
assert start_addon.call_count == 1
|
|
|
|
install_addon.reset_mock()
|
|
set_addon_options.reset_mock()
|
|
start_addon.reset_mock()
|
|
|
|
# Test that another call can be made after the install is done.
|
|
await addon_manager.async_schedule_install_setup_addon({"test_key": "test"})
|
|
|
|
assert install_addon.call_count == 1
|
|
assert set_addon_options.call_count == 1
|
|
assert start_addon.call_count == 1
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
(
|
|
"install_addon_error",
|
|
"install_addon_calls",
|
|
"set_addon_options_error",
|
|
"set_addon_options_calls",
|
|
"start_addon_error",
|
|
"start_addon_calls",
|
|
"error_message",
|
|
),
|
|
[
|
|
(
|
|
SupervisorError("Boom"),
|
|
1,
|
|
None,
|
|
0,
|
|
None,
|
|
0,
|
|
"Failed to install the Test add-on: Boom",
|
|
),
|
|
(
|
|
None,
|
|
1,
|
|
SupervisorError("Boom"),
|
|
1,
|
|
None,
|
|
0,
|
|
"Failed to set the Test add-on options: Boom",
|
|
),
|
|
(
|
|
None,
|
|
1,
|
|
None,
|
|
1,
|
|
SupervisorError("Boom"),
|
|
1,
|
|
"Failed to start the Test add-on: Boom",
|
|
),
|
|
],
|
|
)
|
|
async def test_schedule_install_setup_addon_error(
|
|
addon_manager: AddonManager,
|
|
addon_installed: AsyncMock,
|
|
install_addon: AsyncMock,
|
|
set_addon_options: AsyncMock,
|
|
start_addon: AsyncMock,
|
|
install_addon_error: Exception | None,
|
|
install_addon_calls: int,
|
|
set_addon_options_error: Exception | None,
|
|
set_addon_options_calls: int,
|
|
start_addon_error: Exception | None,
|
|
start_addon_calls: int,
|
|
error_message: str,
|
|
) -> None:
|
|
"""Test schedule install setup addon raises error."""
|
|
install_addon.side_effect = install_addon_error
|
|
set_addon_options.side_effect = set_addon_options_error
|
|
start_addon.side_effect = start_addon_error
|
|
|
|
with pytest.raises(AddonError) as err:
|
|
await addon_manager.async_schedule_install_setup_addon({"test_key": "test"})
|
|
|
|
assert str(err.value) == error_message
|
|
|
|
assert install_addon.call_count == install_addon_calls
|
|
assert set_addon_options.call_count == set_addon_options_calls
|
|
assert start_addon.call_count == start_addon_calls
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
(
|
|
"install_addon_error",
|
|
"install_addon_calls",
|
|
"set_addon_options_error",
|
|
"set_addon_options_calls",
|
|
"start_addon_error",
|
|
"start_addon_calls",
|
|
"error_log",
|
|
),
|
|
[
|
|
(
|
|
SupervisorError("Boom"),
|
|
1,
|
|
None,
|
|
0,
|
|
None,
|
|
0,
|
|
"Failed to install the Test add-on: Boom",
|
|
),
|
|
(
|
|
None,
|
|
1,
|
|
SupervisorError("Boom"),
|
|
1,
|
|
None,
|
|
0,
|
|
"Failed to set the Test add-on options: Boom",
|
|
),
|
|
(
|
|
None,
|
|
1,
|
|
None,
|
|
1,
|
|
SupervisorError("Boom"),
|
|
1,
|
|
"Failed to start the Test add-on: Boom",
|
|
),
|
|
],
|
|
)
|
|
async def test_schedule_install_setup_addon_logs_error(
|
|
addon_manager: AddonManager,
|
|
addon_installed: AsyncMock,
|
|
install_addon: AsyncMock,
|
|
set_addon_options: AsyncMock,
|
|
start_addon: AsyncMock,
|
|
install_addon_error: Exception | None,
|
|
install_addon_calls: int,
|
|
set_addon_options_error: Exception | None,
|
|
set_addon_options_calls: int,
|
|
start_addon_error: Exception | None,
|
|
start_addon_calls: int,
|
|
error_log: str,
|
|
caplog: pytest.LogCaptureFixture,
|
|
) -> None:
|
|
"""Test schedule install setup addon logs error."""
|
|
install_addon.side_effect = install_addon_error
|
|
set_addon_options.side_effect = set_addon_options_error
|
|
start_addon.side_effect = start_addon_error
|
|
|
|
await addon_manager.async_schedule_install_setup_addon(
|
|
{"test_key": "test"}, catch_error=True
|
|
)
|
|
|
|
assert error_log in caplog.text
|
|
assert install_addon.call_count == install_addon_calls
|
|
assert set_addon_options.call_count == set_addon_options_calls
|
|
assert start_addon.call_count == start_addon_calls
|
|
|
|
|
|
@pytest.mark.usefixtures("addon_installed")
|
|
@pytest.mark.parametrize("set_addon_options_side_effect", [None])
|
|
async def test_schedule_setup_addon(
|
|
addon_manager: AddonManager, set_addon_options: AsyncMock, start_addon: AsyncMock
|
|
) -> None:
|
|
"""Test schedule setup addon."""
|
|
start_task = addon_manager.async_schedule_setup_addon({"test_key": "test"})
|
|
|
|
assert addon_manager.task_in_progress() is True
|
|
|
|
# Make sure that actually only one start task is running.
|
|
start_task_two = addon_manager.async_schedule_setup_addon({"test_key": "test"})
|
|
|
|
await asyncio.gather(start_task, start_task_two)
|
|
|
|
assert addon_manager.task_in_progress() is False
|
|
assert set_addon_options.call_count == 1
|
|
assert start_addon.call_count == 1
|
|
|
|
set_addon_options.reset_mock()
|
|
start_addon.reset_mock()
|
|
|
|
# Test that another call can be made after the start is done.
|
|
await addon_manager.async_schedule_setup_addon({"test_key": "test"})
|
|
|
|
assert set_addon_options.call_count == 1
|
|
assert start_addon.call_count == 1
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
(
|
|
"set_addon_options_error",
|
|
"set_addon_options_calls",
|
|
"start_addon_error",
|
|
"start_addon_calls",
|
|
"error_message",
|
|
),
|
|
[
|
|
(
|
|
SupervisorError("Boom"),
|
|
1,
|
|
None,
|
|
0,
|
|
"Failed to set the Test add-on options: Boom",
|
|
),
|
|
(
|
|
None,
|
|
1,
|
|
SupervisorError("Boom"),
|
|
1,
|
|
"Failed to start the Test add-on: Boom",
|
|
),
|
|
],
|
|
)
|
|
async def test_schedule_setup_addon_error(
|
|
addon_manager: AddonManager,
|
|
addon_installed: AsyncMock,
|
|
set_addon_options: AsyncMock,
|
|
start_addon: AsyncMock,
|
|
set_addon_options_error: Exception | None,
|
|
set_addon_options_calls: int,
|
|
start_addon_error: Exception | None,
|
|
start_addon_calls: int,
|
|
error_message: str,
|
|
) -> None:
|
|
"""Test schedule setup addon raises error."""
|
|
set_addon_options.side_effect = set_addon_options_error
|
|
start_addon.side_effect = start_addon_error
|
|
|
|
with pytest.raises(AddonError) as err:
|
|
await addon_manager.async_schedule_setup_addon({"test_key": "test"})
|
|
|
|
assert str(err.value) == error_message
|
|
|
|
assert set_addon_options.call_count == set_addon_options_calls
|
|
assert start_addon.call_count == start_addon_calls
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
(
|
|
"set_addon_options_error",
|
|
"set_addon_options_calls",
|
|
"start_addon_error",
|
|
"start_addon_calls",
|
|
"error_log",
|
|
),
|
|
[
|
|
(
|
|
SupervisorError("Boom"),
|
|
1,
|
|
None,
|
|
0,
|
|
"Failed to set the Test add-on options: Boom",
|
|
),
|
|
(
|
|
None,
|
|
1,
|
|
SupervisorError("Boom"),
|
|
1,
|
|
"Failed to start the Test add-on: Boom",
|
|
),
|
|
],
|
|
)
|
|
async def test_schedule_setup_addon_logs_error(
|
|
addon_manager: AddonManager,
|
|
addon_installed: AsyncMock,
|
|
set_addon_options: AsyncMock,
|
|
start_addon: AsyncMock,
|
|
set_addon_options_error: Exception | None,
|
|
set_addon_options_calls: int,
|
|
start_addon_error: Exception | None,
|
|
start_addon_calls: int,
|
|
error_log: str,
|
|
caplog: pytest.LogCaptureFixture,
|
|
) -> None:
|
|
"""Test schedule setup addon logs error."""
|
|
set_addon_options.side_effect = set_addon_options_error
|
|
start_addon.side_effect = start_addon_error
|
|
|
|
await addon_manager.async_schedule_setup_addon(
|
|
{"test_key": "test"}, catch_error=True
|
|
)
|
|
|
|
assert error_log in caplog.text
|
|
assert set_addon_options.call_count == set_addon_options_calls
|
|
assert start_addon.call_count == start_addon_calls
|