mirror of
https://github.com/home-assistant/core.git
synced 2025-04-24 09:17:53 +00:00
Backup method to aiohasupervisor
This commit is contained in:
parent
e388e9f396
commit
645cdf5692
@ -116,7 +116,6 @@ from .discovery import async_setup_discovery_view # noqa: F401
|
||||
from .handler import ( # noqa: F401
|
||||
HassIO,
|
||||
HassioAPIError,
|
||||
async_create_backup,
|
||||
async_get_green_settings,
|
||||
async_get_yellow_settings,
|
||||
async_reboot_host,
|
||||
|
@ -15,13 +15,14 @@ from aiohasupervisor.models import (
|
||||
AddonsOptions,
|
||||
AddonState as SupervisorAddonState,
|
||||
InstalledAddonComplete,
|
||||
PartialBackupOptions,
|
||||
StoreAddonUpdate,
|
||||
)
|
||||
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
|
||||
from .handler import HassioAPIError, async_create_backup, get_supervisor_client
|
||||
from .handler import get_supervisor_client
|
||||
|
||||
type _FuncType[_T, **_P, _R] = Callable[Concatenate[_T, _P], Awaitable[_R]]
|
||||
type _ReturnFuncType[_T, **_P, _R] = Callable[
|
||||
@ -31,18 +32,15 @@ type _ReturnFuncType[_T, **_P, _R] = Callable[
|
||||
|
||||
def api_error[_AddonManagerT: AddonManager, **_P, _R](
|
||||
error_message: str,
|
||||
*,
|
||||
expected_error_type: type[HassioAPIError | SupervisorError] | None = None,
|
||||
) -> Callable[
|
||||
[_FuncType[_AddonManagerT, _P, _R]], _ReturnFuncType[_AddonManagerT, _P, _R]
|
||||
]:
|
||||
"""Handle HassioAPIError and raise a specific AddonError."""
|
||||
error_type = expected_error_type or (HassioAPIError, SupervisorError)
|
||||
"""Handle SupervisorError and raise a specific AddonError."""
|
||||
|
||||
def handle_hassio_api_error(
|
||||
def handle_supervisor_api_error(
|
||||
func: _FuncType[_AddonManagerT, _P, _R],
|
||||
) -> _ReturnFuncType[_AddonManagerT, _P, _R]:
|
||||
"""Handle a HassioAPIError."""
|
||||
"""Handle a SupervisorError."""
|
||||
|
||||
@wraps(func)
|
||||
async def wrapper(
|
||||
@ -51,7 +49,7 @@ def api_error[_AddonManagerT: AddonManager, **_P, _R](
|
||||
"""Wrap an add-on manager method."""
|
||||
try:
|
||||
return_value = await func(self, *args, **kwargs)
|
||||
except error_type as err:
|
||||
except SupervisorError as err:
|
||||
raise AddonError(
|
||||
f"{error_message.format(addon_name=self.addon_name)}: {err}"
|
||||
) from err
|
||||
@ -60,7 +58,7 @@ def api_error[_AddonManagerT: AddonManager, **_P, _R](
|
||||
|
||||
return wrapper
|
||||
|
||||
return handle_hassio_api_error
|
||||
return handle_supervisor_api_error
|
||||
|
||||
|
||||
@dataclass
|
||||
@ -123,10 +121,7 @@ class AddonManager:
|
||||
)
|
||||
)
|
||||
|
||||
@api_error(
|
||||
"Failed to get the {addon_name} add-on discovery info",
|
||||
expected_error_type=SupervisorError,
|
||||
)
|
||||
@api_error("Failed to get the {addon_name} add-on discovery info")
|
||||
async def async_get_addon_discovery_info(self) -> dict:
|
||||
"""Return add-on discovery info."""
|
||||
discovery_info = next(
|
||||
@ -143,10 +138,7 @@ class AddonManager:
|
||||
|
||||
return discovery_info.config
|
||||
|
||||
@api_error(
|
||||
"Failed to get the {addon_name} add-on info",
|
||||
expected_error_type=SupervisorError,
|
||||
)
|
||||
@api_error("Failed to get the {addon_name} add-on info")
|
||||
async def async_get_addon_info(self) -> AddonInfo:
|
||||
"""Return and cache manager add-on info."""
|
||||
addon_store_info = await self._supervisor_client.store.addon_info(
|
||||
@ -188,10 +180,7 @@ class AddonManager:
|
||||
|
||||
return addon_state
|
||||
|
||||
@api_error(
|
||||
"Failed to set the {addon_name} add-on options",
|
||||
expected_error_type=SupervisorError,
|
||||
)
|
||||
@api_error("Failed to set the {addon_name} add-on options")
|
||||
async def async_set_addon_options(self, config: dict) -> None:
|
||||
"""Set manager add-on options."""
|
||||
await self._supervisor_client.addons.set_addon_options(
|
||||
@ -203,9 +192,7 @@ class AddonManager:
|
||||
if not addon_info.available:
|
||||
raise AddonError(f"{self.addon_name} add-on is not available")
|
||||
|
||||
@api_error(
|
||||
"Failed to install the {addon_name} add-on", expected_error_type=SupervisorError
|
||||
)
|
||||
@api_error("Failed to install the {addon_name} add-on")
|
||||
async def async_install_addon(self) -> None:
|
||||
"""Install the managed add-on."""
|
||||
addon_info = await self.async_get_addon_info()
|
||||
@ -214,10 +201,7 @@ class AddonManager:
|
||||
|
||||
await self._supervisor_client.store.install_addon(self.addon_slug)
|
||||
|
||||
@api_error(
|
||||
"Failed to uninstall the {addon_name} add-on",
|
||||
expected_error_type=SupervisorError,
|
||||
)
|
||||
@api_error("Failed to uninstall the {addon_name} add-on")
|
||||
async def async_uninstall_addon(self) -> None:
|
||||
"""Uninstall the managed add-on."""
|
||||
await self._supervisor_client.addons.uninstall_addon(self.addon_slug)
|
||||
@ -240,23 +224,17 @@ class AddonManager:
|
||||
self.addon_slug, StoreAddonUpdate(backup=False)
|
||||
)
|
||||
|
||||
@api_error(
|
||||
"Failed to start the {addon_name} add-on", expected_error_type=SupervisorError
|
||||
)
|
||||
@api_error("Failed to start the {addon_name} add-on")
|
||||
async def async_start_addon(self) -> None:
|
||||
"""Start the managed add-on."""
|
||||
await self._supervisor_client.addons.start_addon(self.addon_slug)
|
||||
|
||||
@api_error(
|
||||
"Failed to restart the {addon_name} add-on", expected_error_type=SupervisorError
|
||||
)
|
||||
@api_error("Failed to restart the {addon_name} add-on")
|
||||
async def async_restart_addon(self) -> None:
|
||||
"""Restart the managed add-on."""
|
||||
await self._supervisor_client.addons.restart_addon(self.addon_slug)
|
||||
|
||||
@api_error(
|
||||
"Failed to stop the {addon_name} add-on", expected_error_type=SupervisorError
|
||||
)
|
||||
@api_error("Failed to stop the {addon_name} add-on")
|
||||
async def async_stop_addon(self) -> None:
|
||||
"""Stop the managed add-on."""
|
||||
await self._supervisor_client.addons.stop_addon(self.addon_slug)
|
||||
@ -268,10 +246,8 @@ class AddonManager:
|
||||
name = f"addon_{self.addon_slug}_{addon_info.version}"
|
||||
|
||||
self._logger.debug("Creating backup: %s", name)
|
||||
await async_create_backup(
|
||||
self._hass,
|
||||
{"name": name, "addons": [self.addon_slug]},
|
||||
partial=True,
|
||||
await self._supervisor_client.backups.partial_backup(
|
||||
PartialBackupOptions(name=name, addons={self.addon_slug})
|
||||
)
|
||||
|
||||
async def async_configure_addon(
|
||||
|
@ -76,21 +76,6 @@ async def async_update_diagnostics(hass: HomeAssistant, diagnostics: bool) -> bo
|
||||
return await hassio.update_diagnostics(diagnostics)
|
||||
|
||||
|
||||
@bind_hass
|
||||
@api_data
|
||||
async def async_create_backup(
|
||||
hass: HomeAssistant, payload: dict, partial: bool = False
|
||||
) -> dict:
|
||||
"""Create a full or partial backup.
|
||||
|
||||
The caller of the function should handle HassioAPIError.
|
||||
"""
|
||||
hassio: HassIO = hass.data[DOMAIN]
|
||||
backup_type = "partial" if partial else "full"
|
||||
command = f"/backups/new/{backup_type}"
|
||||
return await hassio.send_command(command, payload=payload, timeout=None)
|
||||
|
||||
|
||||
@api_data
|
||||
async def async_get_green_settings(hass: HomeAssistant) -> dict[str, bool]:
|
||||
"""Return settings specific to Home Assistant Green."""
|
||||
|
@ -11,6 +11,7 @@ from unittest.mock import AsyncMock, MagicMock, patch
|
||||
|
||||
from aiohasupervisor.models import (
|
||||
Discovery,
|
||||
NewBackup,
|
||||
Repository,
|
||||
ResolutionInfo,
|
||||
StoreAddon,
|
||||
@ -417,13 +418,22 @@ def uninstall_addon_fixture(supervisor_client: AsyncMock) -> AsyncMock:
|
||||
return supervisor_client.addons.uninstall_addon
|
||||
|
||||
|
||||
@pytest.fixture(name="create_backup")
|
||||
def create_backup_fixture() -> Generator[AsyncMock]:
|
||||
"""Mock create backup."""
|
||||
# pylint: disable-next=import-outside-toplevel
|
||||
from .hassio.common import mock_create_backup
|
||||
@pytest.fixture(name="create_partial_backup")
|
||||
def create_partial_backup_fixture(supervisor_client: AsyncMock) -> AsyncMock:
|
||||
"""Mock create partial backup."""
|
||||
supervisor_client.backups.partial_backup.return_value = NewBackup(
|
||||
"job123", "backup123"
|
||||
)
|
||||
return supervisor_client.backups.partial_backup
|
||||
|
||||
yield from mock_create_backup()
|
||||
|
||||
@pytest.fixture(name="create_full_backup")
|
||||
def create_backup_fixture(supervisor_client: AsyncMock) -> AsyncMock:
|
||||
"""Mock create full backup."""
|
||||
supervisor_client.backups.full_backup.return_value = NewBackup(
|
||||
"job123", "backup123"
|
||||
)
|
||||
return supervisor_client.backups.full_backup
|
||||
|
||||
|
||||
@pytest.fixture(name="update_addon")
|
||||
@ -505,6 +515,7 @@ def supervisor_client() -> Generator[AsyncMock]:
|
||||
"""Mock the supervisor client."""
|
||||
supervisor_client = AsyncMock()
|
||||
supervisor_client.addons = AsyncMock()
|
||||
supervisor_client.backups = AsyncMock()
|
||||
supervisor_client.discovery = AsyncMock()
|
||||
supervisor_client.homeassistant = AsyncMock()
|
||||
supervisor_client.os = AsyncMock()
|
||||
|
@ -2,12 +2,11 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Generator
|
||||
from dataclasses import fields
|
||||
import logging
|
||||
from types import MethodType
|
||||
from typing import Any
|
||||
from unittest.mock import AsyncMock, Mock, patch
|
||||
from unittest.mock import AsyncMock, Mock
|
||||
|
||||
from aiohasupervisor.models import (
|
||||
AddonsOptions,
|
||||
@ -198,14 +197,6 @@ def mock_set_addon_options_side_effect(addon_options: dict[str, Any]) -> Any | N
|
||||
return set_addon_options
|
||||
|
||||
|
||||
def mock_create_backup() -> Generator[AsyncMock]:
|
||||
"""Mock create backup."""
|
||||
with patch(
|
||||
"homeassistant.components.hassio.addon_manager.async_create_backup"
|
||||
) as create_backup:
|
||||
yield create_backup
|
||||
|
||||
|
||||
def mock_addon_stats(supervisor_client: AsyncMock) -> AsyncMock:
|
||||
"""Mock addon stats."""
|
||||
supervisor_client.addons.addon_stats.return_value = addon_stats = Mock(
|
||||
|
@ -8,7 +8,7 @@ from unittest.mock import AsyncMock, call
|
||||
from uuid import uuid4
|
||||
|
||||
from aiohasupervisor import SupervisorError
|
||||
from aiohasupervisor.models import AddonsOptions, Discovery
|
||||
from aiohasupervisor.models import AddonsOptions, Discovery, PartialBackupOptions
|
||||
import pytest
|
||||
|
||||
from homeassistant.components.hassio.addon_manager import (
|
||||
@ -17,7 +17,6 @@ from homeassistant.components.hassio.addon_manager import (
|
||||
AddonManager,
|
||||
AddonState,
|
||||
)
|
||||
from homeassistant.components.hassio.handler import HassioAPIError
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
|
||||
@ -502,7 +501,7 @@ async def test_update_addon(
|
||||
addon_manager: AddonManager,
|
||||
addon_info: AsyncMock,
|
||||
addon_installed: AsyncMock,
|
||||
create_backup: AsyncMock,
|
||||
create_partial_backup: AsyncMock,
|
||||
update_addon: AsyncMock,
|
||||
) -> None:
|
||||
"""Test update addon."""
|
||||
@ -511,9 +510,8 @@ async def test_update_addon(
|
||||
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
|
||||
create_partial_backup.assert_called_once_with(
|
||||
PartialBackupOptions(name="addon_test_addon_1.0.0", addons={"test_addon"})
|
||||
)
|
||||
assert update_addon.call_count == 1
|
||||
|
||||
@ -522,7 +520,7 @@ async def test_update_addon_no_update(
|
||||
addon_manager: AddonManager,
|
||||
addon_info: AsyncMock,
|
||||
addon_installed: AsyncMock,
|
||||
create_backup: AsyncMock,
|
||||
create_partial_backup: AsyncMock,
|
||||
update_addon: AsyncMock,
|
||||
) -> None:
|
||||
"""Test update addon without update available."""
|
||||
@ -531,7 +529,7 @@ async def test_update_addon_no_update(
|
||||
await addon_manager.async_update_addon()
|
||||
|
||||
assert addon_info.call_count == 1
|
||||
assert create_backup.call_count == 0
|
||||
assert create_partial_backup.call_count == 0
|
||||
assert update_addon.call_count == 0
|
||||
|
||||
|
||||
@ -540,7 +538,7 @@ async def test_update_addon_error(
|
||||
addon_manager: AddonManager,
|
||||
addon_info: AsyncMock,
|
||||
addon_installed: AsyncMock,
|
||||
create_backup: AsyncMock,
|
||||
create_partial_backup: AsyncMock,
|
||||
update_addon: AsyncMock,
|
||||
) -> None:
|
||||
"""Test update addon raises error."""
|
||||
@ -553,9 +551,8 @@ async def test_update_addon_error(
|
||||
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
|
||||
create_partial_backup.assert_called_once_with(
|
||||
PartialBackupOptions(name="addon_test_addon_1.0.0", addons={"test_addon"})
|
||||
)
|
||||
assert update_addon.call_count == 1
|
||||
|
||||
@ -565,7 +562,7 @@ async def test_schedule_update_addon(
|
||||
addon_manager: AddonManager,
|
||||
addon_info: AsyncMock,
|
||||
addon_installed: AsyncMock,
|
||||
create_backup: AsyncMock,
|
||||
create_partial_backup: AsyncMock,
|
||||
update_addon: AsyncMock,
|
||||
) -> None:
|
||||
"""Test schedule update addon."""
|
||||
@ -591,9 +588,8 @@ async def test_schedule_update_addon(
|
||||
|
||||
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
|
||||
create_partial_backup.assert_called_once_with(
|
||||
PartialBackupOptions(name="addon_test_addon_1.0.0", addons={"test_addon"})
|
||||
)
|
||||
assert update_addon.call_count == 1
|
||||
|
||||
@ -607,15 +603,15 @@ async def test_schedule_update_addon(
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
(
|
||||
"create_backup_error",
|
||||
"create_backup_calls",
|
||||
"create_partial_backup_error",
|
||||
"create_partial_backup_calls",
|
||||
"update_addon_error",
|
||||
"update_addon_calls",
|
||||
"error_message",
|
||||
),
|
||||
[
|
||||
(
|
||||
HassioAPIError("Boom"),
|
||||
SupervisorError("Boom"),
|
||||
1,
|
||||
None,
|
||||
0,
|
||||
@ -633,17 +629,17 @@ async def test_schedule_update_addon(
|
||||
async def test_schedule_update_addon_error(
|
||||
addon_manager: AddonManager,
|
||||
addon_installed: AsyncMock,
|
||||
create_backup: AsyncMock,
|
||||
create_partial_backup: AsyncMock,
|
||||
update_addon: AsyncMock,
|
||||
create_backup_error: Exception | None,
|
||||
create_backup_calls: int,
|
||||
create_partial_backup_error: Exception | None,
|
||||
create_partial_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
|
||||
create_partial_backup.side_effect = create_partial_backup_error
|
||||
update_addon.side_effect = update_addon_error
|
||||
|
||||
with pytest.raises(AddonError) as err:
|
||||
@ -651,21 +647,21 @@ async def test_schedule_update_addon_error(
|
||||
|
||||
assert str(err.value) == error_message
|
||||
|
||||
assert create_backup.call_count == create_backup_calls
|
||||
assert create_partial_backup.call_count == create_partial_backup_calls
|
||||
assert update_addon.call_count == update_addon_calls
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
(
|
||||
"create_backup_error",
|
||||
"create_backup_calls",
|
||||
"create_partial_backup_error",
|
||||
"create_partial_backup_calls",
|
||||
"update_addon_error",
|
||||
"update_addon_calls",
|
||||
"error_log",
|
||||
),
|
||||
[
|
||||
(
|
||||
HassioAPIError("Boom"),
|
||||
SupervisorError("Boom"),
|
||||
1,
|
||||
None,
|
||||
0,
|
||||
@ -683,10 +679,10 @@ async def test_schedule_update_addon_error(
|
||||
async def test_schedule_update_addon_logs_error(
|
||||
addon_manager: AddonManager,
|
||||
addon_installed: AsyncMock,
|
||||
create_backup: AsyncMock,
|
||||
create_partial_backup: AsyncMock,
|
||||
update_addon: AsyncMock,
|
||||
create_backup_error: Exception | None,
|
||||
create_backup_calls: int,
|
||||
create_partial_backup_error: Exception | None,
|
||||
create_partial_backup_calls: int,
|
||||
update_addon_error: Exception | None,
|
||||
update_addon_calls: int,
|
||||
error_log: str,
|
||||
@ -694,13 +690,13 @@ async def test_schedule_update_addon_logs_error(
|
||||
) -> None:
|
||||
"""Test schedule update addon logs error."""
|
||||
addon_installed.return_value.update_available = True
|
||||
create_backup.side_effect = create_backup_error
|
||||
create_partial_backup.side_effect = create_partial_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 create_partial_backup.call_count == create_partial_backup_calls
|
||||
assert update_addon.call_count == update_addon_calls
|
||||
|
||||
|
||||
@ -709,15 +705,14 @@ async def test_create_backup(
|
||||
addon_manager: AddonManager,
|
||||
addon_info: AsyncMock,
|
||||
addon_installed: AsyncMock,
|
||||
create_backup: AsyncMock,
|
||||
create_partial_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
|
||||
create_partial_backup.assert_called_once_with(
|
||||
PartialBackupOptions(name="addon_test_addon_1.0.0", addons={"test_addon"})
|
||||
)
|
||||
|
||||
|
||||
@ -726,10 +721,10 @@ async def test_create_backup_error(
|
||||
addon_manager: AddonManager,
|
||||
addon_info: AsyncMock,
|
||||
addon_installed: AsyncMock,
|
||||
create_backup: AsyncMock,
|
||||
create_partial_backup: AsyncMock,
|
||||
) -> None:
|
||||
"""Test creating a backup of the addon raises error."""
|
||||
create_backup.side_effect = HassioAPIError("Boom")
|
||||
create_partial_backup.side_effect = SupervisorError("Boom")
|
||||
|
||||
with pytest.raises(AddonError) as err:
|
||||
await addon_manager.async_create_backup()
|
||||
@ -737,9 +732,8 @@ async def test_create_backup_error(
|
||||
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
|
||||
create_partial_backup.assert_called_once_with(
|
||||
PartialBackupOptions(name="addon_test_addon_1.0.0", addons={"test_addon"})
|
||||
)
|
||||
|
||||
|
||||
|
@ -7,6 +7,7 @@ from collections.abc import Generator
|
||||
from unittest.mock import AsyncMock, MagicMock, call, patch
|
||||
|
||||
from aiohasupervisor import SupervisorError
|
||||
from aiohasupervisor.models import PartialBackupOptions
|
||||
from matter_server.client.exceptions import (
|
||||
CannotConnect,
|
||||
NotConnected,
|
||||
@ -16,7 +17,6 @@ from matter_server.client.exceptions import (
|
||||
from matter_server.common.errors import MatterError
|
||||
import pytest
|
||||
|
||||
from homeassistant.components.hassio import HassioAPIError
|
||||
from homeassistant.components.matter.const import DOMAIN
|
||||
from homeassistant.config_entries import ConfigEntryDisabler, ConfigEntryState
|
||||
from homeassistant.const import STATE_UNAVAILABLE
|
||||
@ -377,7 +377,7 @@ async def test_addon_info_failure(
|
||||
"update_calls",
|
||||
"backup_calls",
|
||||
"update_addon_side_effect",
|
||||
"create_backup_side_effect",
|
||||
"create_partial_backup_side_effect",
|
||||
"connect_side_effect",
|
||||
),
|
||||
[
|
||||
@ -399,7 +399,7 @@ async def test_addon_info_failure(
|
||||
0,
|
||||
1,
|
||||
None,
|
||||
HassioAPIError("Boom"),
|
||||
SupervisorError("Boom"),
|
||||
ServerVersionTooOld("Invalid version"),
|
||||
),
|
||||
],
|
||||
@ -411,7 +411,7 @@ async def test_update_addon(
|
||||
addon_info: AsyncMock,
|
||||
install_addon: AsyncMock,
|
||||
start_addon: AsyncMock,
|
||||
create_backup: AsyncMock,
|
||||
create_partial_backup: AsyncMock,
|
||||
update_addon: AsyncMock,
|
||||
matter_client: MagicMock,
|
||||
addon_version: str,
|
||||
@ -419,13 +419,13 @@ async def test_update_addon(
|
||||
update_calls: int,
|
||||
backup_calls: int,
|
||||
update_addon_side_effect: Exception | None,
|
||||
create_backup_side_effect: Exception | None,
|
||||
create_partial_backup_side_effect: Exception | None,
|
||||
connect_side_effect: Exception,
|
||||
) -> None:
|
||||
"""Test update the Matter add-on during entry setup."""
|
||||
addon_info.return_value.version = addon_version
|
||||
addon_info.return_value.update_available = update_available
|
||||
create_backup.side_effect = create_backup_side_effect
|
||||
create_partial_backup.side_effect = create_partial_backup_side_effect
|
||||
update_addon.side_effect = update_addon_side_effect
|
||||
matter_client.connect.side_effect = connect_side_effect
|
||||
entry = MockConfigEntry(
|
||||
@ -442,7 +442,7 @@ async def test_update_addon(
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert entry.state is ConfigEntryState.SETUP_RETRY
|
||||
assert create_backup.call_count == backup_calls
|
||||
assert create_partial_backup.call_count == backup_calls
|
||||
assert update_addon.call_count == update_calls
|
||||
|
||||
|
||||
@ -548,7 +548,7 @@ async def test_remove_entry(
|
||||
hass: HomeAssistant,
|
||||
addon_installed: AsyncMock,
|
||||
stop_addon: AsyncMock,
|
||||
create_backup: AsyncMock,
|
||||
create_partial_backup: AsyncMock,
|
||||
uninstall_addon: AsyncMock,
|
||||
caplog: pytest.LogCaptureFixture,
|
||||
) -> None:
|
||||
@ -581,18 +581,17 @@ async def test_remove_entry(
|
||||
|
||||
assert stop_addon.call_count == 1
|
||||
assert stop_addon.call_args == call("core_matter_server")
|
||||
assert create_backup.call_count == 1
|
||||
assert create_backup.call_args == call(
|
||||
hass,
|
||||
{"name": "addon_core_matter_server_1.0.0", "addons": ["core_matter_server"]},
|
||||
partial=True,
|
||||
create_partial_backup.assert_called_once_with(
|
||||
PartialBackupOptions(
|
||||
name="addon_core_matter_server_1.0.0", addons={"core_matter_server"}
|
||||
)
|
||||
)
|
||||
assert uninstall_addon.call_count == 1
|
||||
assert uninstall_addon.call_args == call("core_matter_server")
|
||||
assert entry.state is ConfigEntryState.NOT_LOADED
|
||||
assert len(hass.config_entries.async_entries(DOMAIN)) == 0
|
||||
stop_addon.reset_mock()
|
||||
create_backup.reset_mock()
|
||||
create_partial_backup.reset_mock()
|
||||
uninstall_addon.reset_mock()
|
||||
|
||||
# test add-on stop failure
|
||||
@ -604,38 +603,37 @@ async def test_remove_entry(
|
||||
|
||||
assert stop_addon.call_count == 1
|
||||
assert stop_addon.call_args == call("core_matter_server")
|
||||
assert create_backup.call_count == 0
|
||||
assert create_partial_backup.call_count == 0
|
||||
assert uninstall_addon.call_count == 0
|
||||
assert entry.state is ConfigEntryState.NOT_LOADED
|
||||
assert len(hass.config_entries.async_entries(DOMAIN)) == 0
|
||||
assert "Failed to stop the Matter Server add-on" in caplog.text
|
||||
stop_addon.side_effect = None
|
||||
stop_addon.reset_mock()
|
||||
create_backup.reset_mock()
|
||||
create_partial_backup.reset_mock()
|
||||
uninstall_addon.reset_mock()
|
||||
|
||||
# test create backup failure
|
||||
entry.add_to_hass(hass)
|
||||
assert len(hass.config_entries.async_entries(DOMAIN)) == 1
|
||||
create_backup.side_effect = HassioAPIError()
|
||||
create_partial_backup.side_effect = SupervisorError()
|
||||
|
||||
await hass.config_entries.async_remove(entry.entry_id)
|
||||
|
||||
assert stop_addon.call_count == 1
|
||||
assert stop_addon.call_args == call("core_matter_server")
|
||||
assert create_backup.call_count == 1
|
||||
assert create_backup.call_args == call(
|
||||
hass,
|
||||
{"name": "addon_core_matter_server_1.0.0", "addons": ["core_matter_server"]},
|
||||
partial=True,
|
||||
create_partial_backup.assert_called_once_with(
|
||||
PartialBackupOptions(
|
||||
name="addon_core_matter_server_1.0.0", addons={"core_matter_server"}
|
||||
)
|
||||
)
|
||||
assert uninstall_addon.call_count == 0
|
||||
assert entry.state is ConfigEntryState.NOT_LOADED
|
||||
assert len(hass.config_entries.async_entries(DOMAIN)) == 0
|
||||
assert "Failed to create a backup of the Matter Server add-on" in caplog.text
|
||||
create_backup.side_effect = None
|
||||
create_partial_backup.side_effect = None
|
||||
stop_addon.reset_mock()
|
||||
create_backup.reset_mock()
|
||||
create_partial_backup.reset_mock()
|
||||
uninstall_addon.reset_mock()
|
||||
|
||||
# test add-on uninstall failure
|
||||
@ -647,11 +645,10 @@ async def test_remove_entry(
|
||||
|
||||
assert stop_addon.call_count == 1
|
||||
assert stop_addon.call_args == call("core_matter_server")
|
||||
assert create_backup.call_count == 1
|
||||
assert create_backup.call_args == call(
|
||||
hass,
|
||||
{"name": "addon_core_matter_server_1.0.0", "addons": ["core_matter_server"]},
|
||||
partial=True,
|
||||
create_partial_backup.assert_called_once_with(
|
||||
PartialBackupOptions(
|
||||
name="addon_core_matter_server_1.0.0", addons={"core_matter_server"}
|
||||
)
|
||||
)
|
||||
assert uninstall_addon.call_count == 1
|
||||
assert uninstall_addon.call_args == call("core_matter_server")
|
||||
|
@ -6,7 +6,7 @@ import logging
|
||||
from unittest.mock import AsyncMock, call, patch
|
||||
|
||||
from aiohasupervisor import SupervisorError
|
||||
from aiohasupervisor.models import AddonsOptions
|
||||
from aiohasupervisor.models import AddonsOptions, PartialBackupOptions
|
||||
import pytest
|
||||
from zwave_js_server.client import Client
|
||||
from zwave_js_server.event import Event
|
||||
@ -14,7 +14,6 @@ from zwave_js_server.exceptions import BaseZwaveJSServerError, InvalidServerVers
|
||||
from zwave_js_server.model.node import Node
|
||||
from zwave_js_server.model.version import VersionInfo
|
||||
|
||||
from homeassistant.components.hassio import HassioAPIError
|
||||
from homeassistant.components.logger import DOMAIN as LOGGER_DOMAIN, SERVICE_SET_LEVEL
|
||||
from homeassistant.components.persistent_notification import async_dismiss
|
||||
from homeassistant.components.zwave_js import DOMAIN
|
||||
@ -743,13 +742,13 @@ async def test_addon_options_changed(
|
||||
"update_calls",
|
||||
"backup_calls",
|
||||
"update_addon_side_effect",
|
||||
"create_backup_side_effect",
|
||||
"create_partial_backup_side_effect",
|
||||
),
|
||||
[
|
||||
("1.0.0", True, 1, 1, None, None),
|
||||
("1.0.0", False, 0, 0, None, None),
|
||||
("1.0.0", True, 1, 1, SupervisorError("Boom"), None),
|
||||
("1.0.0", True, 0, 1, None, HassioAPIError("Boom")),
|
||||
("1.0.0", True, 0, 1, None, SupervisorError("Boom")),
|
||||
],
|
||||
)
|
||||
async def test_update_addon(
|
||||
@ -758,7 +757,7 @@ async def test_update_addon(
|
||||
addon_info,
|
||||
addon_installed,
|
||||
addon_running,
|
||||
create_backup,
|
||||
create_partial_backup,
|
||||
update_addon,
|
||||
addon_options,
|
||||
addon_version,
|
||||
@ -766,7 +765,7 @@ async def test_update_addon(
|
||||
update_calls,
|
||||
backup_calls,
|
||||
update_addon_side_effect,
|
||||
create_backup_side_effect,
|
||||
create_partial_backup_side_effect,
|
||||
version_state,
|
||||
) -> None:
|
||||
"""Test update the Z-Wave JS add-on during entry setup."""
|
||||
@ -776,7 +775,7 @@ async def test_update_addon(
|
||||
addon_options["network_key"] = network_key
|
||||
addon_info.return_value.version = addon_version
|
||||
addon_info.return_value.update_available = update_available
|
||||
create_backup.side_effect = create_backup_side_effect
|
||||
create_partial_backup.side_effect = create_partial_backup_side_effect
|
||||
update_addon.side_effect = update_addon_side_effect
|
||||
client.connect.side_effect = InvalidServerVersion(
|
||||
VersionInfo("a", "b", 1, 1, 1), 1, "Invalid version"
|
||||
@ -797,7 +796,7 @@ async def test_update_addon(
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert entry.state is ConfigEntryState.SETUP_RETRY
|
||||
assert create_backup.call_count == backup_calls
|
||||
assert create_partial_backup.call_count == backup_calls
|
||||
assert update_addon.call_count == update_calls
|
||||
|
||||
|
||||
@ -897,7 +896,7 @@ async def test_remove_entry(
|
||||
hass: HomeAssistant,
|
||||
addon_installed,
|
||||
stop_addon,
|
||||
create_backup,
|
||||
create_partial_backup,
|
||||
uninstall_addon,
|
||||
caplog: pytest.LogCaptureFixture,
|
||||
) -> None:
|
||||
@ -930,18 +929,15 @@ async def test_remove_entry(
|
||||
|
||||
assert stop_addon.call_count == 1
|
||||
assert stop_addon.call_args == call("core_zwave_js")
|
||||
assert create_backup.call_count == 1
|
||||
assert create_backup.call_args == call(
|
||||
hass,
|
||||
{"name": "addon_core_zwave_js_1.0.0", "addons": ["core_zwave_js"]},
|
||||
partial=True,
|
||||
create_partial_backup.assert_called_once_with(
|
||||
PartialBackupOptions(name="addon_core_zwave_js_1.0.0", addons={"core_zwave_js"})
|
||||
)
|
||||
assert uninstall_addon.call_count == 1
|
||||
assert uninstall_addon.call_args == call("core_zwave_js")
|
||||
assert entry.state is ConfigEntryState.NOT_LOADED
|
||||
assert len(hass.config_entries.async_entries(DOMAIN)) == 0
|
||||
stop_addon.reset_mock()
|
||||
create_backup.reset_mock()
|
||||
create_partial_backup.reset_mock()
|
||||
uninstall_addon.reset_mock()
|
||||
|
||||
# test add-on stop failure
|
||||
@ -953,38 +949,35 @@ async def test_remove_entry(
|
||||
|
||||
assert stop_addon.call_count == 1
|
||||
assert stop_addon.call_args == call("core_zwave_js")
|
||||
assert create_backup.call_count == 0
|
||||
assert create_partial_backup.call_count == 0
|
||||
assert uninstall_addon.call_count == 0
|
||||
assert entry.state is ConfigEntryState.NOT_LOADED
|
||||
assert len(hass.config_entries.async_entries(DOMAIN)) == 0
|
||||
assert "Failed to stop the Z-Wave JS add-on" in caplog.text
|
||||
stop_addon.side_effect = None
|
||||
stop_addon.reset_mock()
|
||||
create_backup.reset_mock()
|
||||
create_partial_backup.reset_mock()
|
||||
uninstall_addon.reset_mock()
|
||||
|
||||
# test create backup failure
|
||||
entry.add_to_hass(hass)
|
||||
assert len(hass.config_entries.async_entries(DOMAIN)) == 1
|
||||
create_backup.side_effect = HassioAPIError()
|
||||
create_partial_backup.side_effect = SupervisorError()
|
||||
|
||||
await hass.config_entries.async_remove(entry.entry_id)
|
||||
|
||||
assert stop_addon.call_count == 1
|
||||
assert stop_addon.call_args == call("core_zwave_js")
|
||||
assert create_backup.call_count == 1
|
||||
assert create_backup.call_args == call(
|
||||
hass,
|
||||
{"name": "addon_core_zwave_js_1.0.0", "addons": ["core_zwave_js"]},
|
||||
partial=True,
|
||||
create_partial_backup.assert_called_once_with(
|
||||
PartialBackupOptions(name="addon_core_zwave_js_1.0.0", addons={"core_zwave_js"})
|
||||
)
|
||||
assert uninstall_addon.call_count == 0
|
||||
assert entry.state is ConfigEntryState.NOT_LOADED
|
||||
assert len(hass.config_entries.async_entries(DOMAIN)) == 0
|
||||
assert "Failed to create a backup of the Z-Wave JS add-on" in caplog.text
|
||||
create_backup.side_effect = None
|
||||
create_partial_backup.side_effect = None
|
||||
stop_addon.reset_mock()
|
||||
create_backup.reset_mock()
|
||||
create_partial_backup.reset_mock()
|
||||
uninstall_addon.reset_mock()
|
||||
|
||||
# test add-on uninstall failure
|
||||
@ -996,11 +989,8 @@ async def test_remove_entry(
|
||||
|
||||
assert stop_addon.call_count == 1
|
||||
assert stop_addon.call_args == call("core_zwave_js")
|
||||
assert create_backup.call_count == 1
|
||||
assert create_backup.call_args == call(
|
||||
hass,
|
||||
{"name": "addon_core_zwave_js_1.0.0", "addons": ["core_zwave_js"]},
|
||||
partial=True,
|
||||
create_partial_backup.assert_called_once_with(
|
||||
PartialBackupOptions(name="addon_core_zwave_js_1.0.0", addons={"core_zwave_js"})
|
||||
)
|
||||
assert uninstall_addon.call_count == 1
|
||||
assert uninstall_addon.call_args == call("core_zwave_js")
|
||||
|
Loading…
x
Reference in New Issue
Block a user