core/tests/components/hassio/test_addon_manager.py

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