Add BaseBackupManager as a common interface for backup managers (#126611)
* Add BaseBackupManager as a common interface for backup managers * Document the key * Update homeassistant/components/backup/manager.py Co-authored-by: Martin Hjelmare <marhje52@gmail.com> --------- Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
This commit is contained in:
parent
78fce90178
commit
a14cb13194
8 changed files with 78 additions and 44 deletions
|
@ -32,7 +32,7 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
||||||
|
|
||||||
async def async_handle_create_service(call: ServiceCall) -> None:
|
async def async_handle_create_service(call: ServiceCall) -> None:
|
||||||
"""Service handler for creating backups."""
|
"""Service handler for creating backups."""
|
||||||
await backup_manager.generate_backup()
|
await backup_manager.async_create_backup()
|
||||||
|
|
||||||
hass.services.async_register(DOMAIN, "create", async_handle_create_service)
|
hass.services.async_register(DOMAIN, "create", async_handle_create_service)
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ from homeassistant.core import HomeAssistant, callback
|
||||||
from homeassistant.util import slugify
|
from homeassistant.util import slugify
|
||||||
|
|
||||||
from .const import DOMAIN
|
from .const import DOMAIN
|
||||||
from .manager import BackupManager
|
from .manager import BaseBackupManager
|
||||||
|
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
|
@ -36,8 +36,8 @@ class DownloadBackupView(HomeAssistantView):
|
||||||
if not request["hass_user"].is_admin:
|
if not request["hass_user"].is_admin:
|
||||||
return Response(status=HTTPStatus.UNAUTHORIZED)
|
return Response(status=HTTPStatus.UNAUTHORIZED)
|
||||||
|
|
||||||
manager: BackupManager = request.app[KEY_HASS].data[DOMAIN]
|
manager: BaseBackupManager = request.app[KEY_HASS].data[DOMAIN]
|
||||||
backup = await manager.get_backup(slug)
|
backup = await manager.async_get_backup(slug=slug)
|
||||||
|
|
||||||
if backup is None or not backup.path.exists():
|
if backup is None or not backup.path.exists():
|
||||||
return Response(status=HTTPStatus.NOT_FOUND)
|
return Response(status=HTTPStatus.NOT_FOUND)
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import abc
|
||||||
import asyncio
|
import asyncio
|
||||||
from dataclasses import asdict, dataclass
|
from dataclasses import asdict, dataclass
|
||||||
import hashlib
|
import hashlib
|
||||||
|
@ -53,15 +54,48 @@ class BackupPlatformProtocol(Protocol):
|
||||||
"""Perform operations after a backup finishes."""
|
"""Perform operations after a backup finishes."""
|
||||||
|
|
||||||
|
|
||||||
class BackupManager:
|
class BaseBackupManager(abc.ABC):
|
||||||
"""Backup manager for the Backup integration."""
|
"""Define the format that backup managers can have."""
|
||||||
|
|
||||||
def __init__(self, hass: HomeAssistant) -> None:
|
def __init__(self, hass: HomeAssistant) -> None:
|
||||||
"""Initialize the backup manager."""
|
"""Initialize the backup manager."""
|
||||||
self.hass = hass
|
self.hass = hass
|
||||||
self.backup_dir = Path(hass.config.path("backups"))
|
|
||||||
self.backing_up = False
|
|
||||||
self.backups: dict[str, Backup] = {}
|
self.backups: dict[str, Backup] = {}
|
||||||
|
self.backing_up = False
|
||||||
|
|
||||||
|
async def async_post_backup_actions(self, **kwargs: Any) -> None:
|
||||||
|
"""Post backup actions."""
|
||||||
|
|
||||||
|
async def async_pre_backup_actions(self, **kwargs: Any) -> None:
|
||||||
|
"""Pre backup actions."""
|
||||||
|
|
||||||
|
@abc.abstractmethod
|
||||||
|
async def async_create_backup(self, **kwargs: Any) -> Backup:
|
||||||
|
"""Generate a backup."""
|
||||||
|
|
||||||
|
@abc.abstractmethod
|
||||||
|
async def async_get_backups(self, **kwargs: Any) -> dict[str, Backup]:
|
||||||
|
"""Get backups.
|
||||||
|
|
||||||
|
Return a dictionary of Backup instances keyed by their slug.
|
||||||
|
"""
|
||||||
|
|
||||||
|
@abc.abstractmethod
|
||||||
|
async def async_get_backup(self, *, slug: str, **kwargs: Any) -> Backup | None:
|
||||||
|
"""Get a backup."""
|
||||||
|
|
||||||
|
@abc.abstractmethod
|
||||||
|
async def async_remove_backup(self, *, slug: str, **kwargs: Any) -> None:
|
||||||
|
"""Remove a backup."""
|
||||||
|
|
||||||
|
|
||||||
|
class BackupManager(BaseBackupManager):
|
||||||
|
"""Backup manager for the Backup integration."""
|
||||||
|
|
||||||
|
def __init__(self, hass: HomeAssistant) -> None:
|
||||||
|
"""Initialize the backup manager."""
|
||||||
|
super().__init__(hass=hass)
|
||||||
|
self.backup_dir = Path(hass.config.path("backups"))
|
||||||
self.platforms: dict[str, BackupPlatformProtocol] = {}
|
self.platforms: dict[str, BackupPlatformProtocol] = {}
|
||||||
self.loaded_backups = False
|
self.loaded_backups = False
|
||||||
self.loaded_platforms = False
|
self.loaded_platforms = False
|
||||||
|
@ -84,7 +118,7 @@ class BackupManager:
|
||||||
return
|
return
|
||||||
self.platforms[integration_domain] = platform
|
self.platforms[integration_domain] = platform
|
||||||
|
|
||||||
async def pre_backup_actions(self) -> None:
|
async def async_pre_backup_actions(self, **kwargs: Any) -> None:
|
||||||
"""Perform pre backup actions."""
|
"""Perform pre backup actions."""
|
||||||
if not self.loaded_platforms:
|
if not self.loaded_platforms:
|
||||||
await self.load_platforms()
|
await self.load_platforms()
|
||||||
|
@ -100,7 +134,7 @@ class BackupManager:
|
||||||
if isinstance(result, Exception):
|
if isinstance(result, Exception):
|
||||||
raise result
|
raise result
|
||||||
|
|
||||||
async def post_backup_actions(self) -> None:
|
async def async_post_backup_actions(self, **kwargs: Any) -> None:
|
||||||
"""Perform post backup actions."""
|
"""Perform post backup actions."""
|
||||||
if not self.loaded_platforms:
|
if not self.loaded_platforms:
|
||||||
await self.load_platforms()
|
await self.load_platforms()
|
||||||
|
@ -151,14 +185,14 @@ class BackupManager:
|
||||||
LOGGER.warning("Unable to read backup %s: %s", backup_path, err)
|
LOGGER.warning("Unable to read backup %s: %s", backup_path, err)
|
||||||
return backups
|
return backups
|
||||||
|
|
||||||
async def get_backups(self) -> dict[str, Backup]:
|
async def async_get_backups(self, **kwargs: Any) -> dict[str, Backup]:
|
||||||
"""Return backups."""
|
"""Return backups."""
|
||||||
if not self.loaded_backups:
|
if not self.loaded_backups:
|
||||||
await self.load_backups()
|
await self.load_backups()
|
||||||
|
|
||||||
return self.backups
|
return self.backups
|
||||||
|
|
||||||
async def get_backup(self, slug: str) -> Backup | None:
|
async def async_get_backup(self, *, slug: str, **kwargs: Any) -> Backup | None:
|
||||||
"""Return a backup."""
|
"""Return a backup."""
|
||||||
if not self.loaded_backups:
|
if not self.loaded_backups:
|
||||||
await self.load_backups()
|
await self.load_backups()
|
||||||
|
@ -180,23 +214,23 @@ class BackupManager:
|
||||||
|
|
||||||
return backup
|
return backup
|
||||||
|
|
||||||
async def remove_backup(self, slug: str) -> None:
|
async def async_remove_backup(self, *, slug: str, **kwargs: Any) -> None:
|
||||||
"""Remove a backup."""
|
"""Remove a backup."""
|
||||||
if (backup := await self.get_backup(slug)) is None:
|
if (backup := await self.async_get_backup(slug=slug)) is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
await self.hass.async_add_executor_job(backup.path.unlink, True)
|
await self.hass.async_add_executor_job(backup.path.unlink, True)
|
||||||
LOGGER.debug("Removed backup located at %s", backup.path)
|
LOGGER.debug("Removed backup located at %s", backup.path)
|
||||||
self.backups.pop(slug)
|
self.backups.pop(slug)
|
||||||
|
|
||||||
async def generate_backup(self) -> Backup:
|
async def async_create_backup(self, **kwargs: Any) -> Backup:
|
||||||
"""Generate a backup."""
|
"""Generate a backup."""
|
||||||
if self.backing_up:
|
if self.backing_up:
|
||||||
raise HomeAssistantError("Backup already in progress")
|
raise HomeAssistantError("Backup already in progress")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.backing_up = True
|
self.backing_up = True
|
||||||
await self.pre_backup_actions()
|
await self.async_pre_backup_actions()
|
||||||
backup_name = f"Core {HAVERSION}"
|
backup_name = f"Core {HAVERSION}"
|
||||||
date_str = dt_util.now().isoformat()
|
date_str = dt_util.now().isoformat()
|
||||||
slug = _generate_slug(date_str, backup_name)
|
slug = _generate_slug(date_str, backup_name)
|
||||||
|
@ -229,7 +263,7 @@ class BackupManager:
|
||||||
return backup
|
return backup
|
||||||
finally:
|
finally:
|
||||||
self.backing_up = False
|
self.backing_up = False
|
||||||
await self.post_backup_actions()
|
await self.async_post_backup_actions()
|
||||||
|
|
||||||
def _mkdir_and_generate_backup_contents(
|
def _mkdir_and_generate_backup_contents(
|
||||||
self,
|
self,
|
||||||
|
|
|
@ -33,7 +33,7 @@ async def handle_info(
|
||||||
) -> None:
|
) -> None:
|
||||||
"""List all stored backups."""
|
"""List all stored backups."""
|
||||||
manager = hass.data[DATA_MANAGER]
|
manager = hass.data[DATA_MANAGER]
|
||||||
backups = await manager.get_backups()
|
backups = await manager.async_get_backups()
|
||||||
connection.send_result(
|
connection.send_result(
|
||||||
msg["id"],
|
msg["id"],
|
||||||
{
|
{
|
||||||
|
@ -57,7 +57,7 @@ async def handle_remove(
|
||||||
msg: dict[str, Any],
|
msg: dict[str, Any],
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Remove a backup."""
|
"""Remove a backup."""
|
||||||
await hass.data[DATA_MANAGER].remove_backup(msg["slug"])
|
await hass.data[DATA_MANAGER].async_remove_backup(slug=msg["slug"])
|
||||||
connection.send_result(msg["id"])
|
connection.send_result(msg["id"])
|
||||||
|
|
||||||
|
|
||||||
|
@ -70,7 +70,7 @@ async def handle_create(
|
||||||
msg: dict[str, Any],
|
msg: dict[str, Any],
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Generate a backup."""
|
"""Generate a backup."""
|
||||||
backup = await hass.data[DATA_MANAGER].generate_backup()
|
backup = await hass.data[DATA_MANAGER].async_create_backup()
|
||||||
connection.send_result(msg["id"], backup)
|
connection.send_result(msg["id"], backup)
|
||||||
|
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@ async def handle_backup_start(
|
||||||
LOGGER.debug("Backup start notification")
|
LOGGER.debug("Backup start notification")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
await manager.pre_backup_actions()
|
await manager.async_pre_backup_actions()
|
||||||
except Exception as err: # noqa: BLE001
|
except Exception as err: # noqa: BLE001
|
||||||
connection.send_error(msg["id"], "pre_backup_actions_failed", str(err))
|
connection.send_error(msg["id"], "pre_backup_actions_failed", str(err))
|
||||||
return
|
return
|
||||||
|
@ -110,7 +110,7 @@ async def handle_backup_end(
|
||||||
LOGGER.debug("Backup end notification")
|
LOGGER.debug("Backup end notification")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
await manager.post_backup_actions()
|
await manager.async_post_backup_actions()
|
||||||
except Exception as err: # noqa: BLE001
|
except Exception as err: # noqa: BLE001
|
||||||
connection.send_error(msg["id"], "post_backup_actions_failed", str(err))
|
connection.send_error(msg["id"], "post_backup_actions_failed", str(err))
|
||||||
return
|
return
|
||||||
|
|
|
@ -23,7 +23,7 @@ async def test_downloading_backup(
|
||||||
|
|
||||||
with (
|
with (
|
||||||
patch(
|
patch(
|
||||||
"homeassistant.components.backup.manager.BackupManager.get_backup",
|
"homeassistant.components.backup.manager.BackupManager.async_get_backup",
|
||||||
return_value=TEST_BACKUP,
|
return_value=TEST_BACKUP,
|
||||||
),
|
),
|
||||||
patch("pathlib.Path.exists", return_value=True),
|
patch("pathlib.Path.exists", return_value=True),
|
||||||
|
|
|
@ -33,7 +33,7 @@ async def test_create_service(
|
||||||
await setup_backup_integration(hass)
|
await setup_backup_integration(hass)
|
||||||
|
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.backup.manager.BackupManager.generate_backup",
|
"homeassistant.components.backup.manager.BackupManager.async_create_backup",
|
||||||
) as generate_backup:
|
) as generate_backup:
|
||||||
await hass.services.async_call(
|
await hass.services.async_call(
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
|
|
|
@ -62,7 +62,7 @@ async def _mock_backup_generation(manager: BackupManager):
|
||||||
"2025.1.0",
|
"2025.1.0",
|
||||||
),
|
),
|
||||||
):
|
):
|
||||||
await manager.generate_backup()
|
await manager.async_create_backup()
|
||||||
|
|
||||||
assert mocked_json_bytes.call_count == 1
|
assert mocked_json_bytes.call_count == 1
|
||||||
backup_json_dict = mocked_json_bytes.call_args[0][0]
|
backup_json_dict = mocked_json_bytes.call_args[0][0]
|
||||||
|
@ -108,7 +108,7 @@ async def test_load_backups(hass: HomeAssistant) -> None:
|
||||||
),
|
),
|
||||||
):
|
):
|
||||||
await manager.load_backups()
|
await manager.load_backups()
|
||||||
backups = await manager.get_backups()
|
backups = await manager.async_get_backups()
|
||||||
assert backups == {TEST_BACKUP.slug: TEST_BACKUP}
|
assert backups == {TEST_BACKUP.slug: TEST_BACKUP}
|
||||||
|
|
||||||
|
|
||||||
|
@ -123,7 +123,7 @@ async def test_load_backups_with_exception(
|
||||||
patch("tarfile.open", side_effect=OSError("Test exception")),
|
patch("tarfile.open", side_effect=OSError("Test exception")),
|
||||||
):
|
):
|
||||||
await manager.load_backups()
|
await manager.load_backups()
|
||||||
backups = await manager.get_backups()
|
backups = await manager.async_get_backups()
|
||||||
assert f"Unable to read backup {TEST_BACKUP.path}: Test exception" in caplog.text
|
assert f"Unable to read backup {TEST_BACKUP.path}: Test exception" in caplog.text
|
||||||
assert backups == {}
|
assert backups == {}
|
||||||
|
|
||||||
|
@ -138,7 +138,7 @@ async def test_removing_backup(
|
||||||
manager.loaded_backups = True
|
manager.loaded_backups = True
|
||||||
|
|
||||||
with patch("pathlib.Path.exists", return_value=True):
|
with patch("pathlib.Path.exists", return_value=True):
|
||||||
await manager.remove_backup(TEST_BACKUP.slug)
|
await manager.async_remove_backup(slug=TEST_BACKUP.slug)
|
||||||
assert "Removed backup located at" in caplog.text
|
assert "Removed backup located at" in caplog.text
|
||||||
|
|
||||||
|
|
||||||
|
@ -149,7 +149,7 @@ async def test_removing_non_existing_backup(
|
||||||
"""Test removing not existing backup."""
|
"""Test removing not existing backup."""
|
||||||
manager = BackupManager(hass)
|
manager = BackupManager(hass)
|
||||||
|
|
||||||
await manager.remove_backup("non_existing")
|
await manager.async_remove_backup(slug="non_existing")
|
||||||
assert "Removed backup located at" not in caplog.text
|
assert "Removed backup located at" not in caplog.text
|
||||||
|
|
||||||
|
|
||||||
|
@ -163,7 +163,7 @@ async def test_getting_backup_that_does_not_exist(
|
||||||
manager.loaded_backups = True
|
manager.loaded_backups = True
|
||||||
|
|
||||||
with patch("pathlib.Path.exists", return_value=False):
|
with patch("pathlib.Path.exists", return_value=False):
|
||||||
backup = await manager.get_backup(TEST_BACKUP.slug)
|
backup = await manager.async_get_backup(slug=TEST_BACKUP.slug)
|
||||||
assert backup is None
|
assert backup is None
|
||||||
|
|
||||||
assert (
|
assert (
|
||||||
|
@ -172,15 +172,15 @@ async def test_getting_backup_that_does_not_exist(
|
||||||
) in caplog.text
|
) in caplog.text
|
||||||
|
|
||||||
|
|
||||||
async def test_generate_backup_when_backing_up(hass: HomeAssistant) -> None:
|
async def test_async_create_backup_when_backing_up(hass: HomeAssistant) -> None:
|
||||||
"""Test generate backup."""
|
"""Test generate backup."""
|
||||||
manager = BackupManager(hass)
|
manager = BackupManager(hass)
|
||||||
manager.backing_up = True
|
manager.backing_up = True
|
||||||
with pytest.raises(HomeAssistantError, match="Backup already in progress"):
|
with pytest.raises(HomeAssistantError, match="Backup already in progress"):
|
||||||
await manager.generate_backup()
|
await manager.async_create_backup()
|
||||||
|
|
||||||
|
|
||||||
async def test_generate_backup(
|
async def test_async_create_backup(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
caplog: pytest.LogCaptureFixture,
|
caplog: pytest.LogCaptureFixture,
|
||||||
) -> None:
|
) -> None:
|
||||||
|
@ -285,7 +285,7 @@ async def test_exception_plaform_post(hass: HomeAssistant) -> None:
|
||||||
await _mock_backup_generation(manager)
|
await _mock_backup_generation(manager)
|
||||||
|
|
||||||
|
|
||||||
async def test_loading_platforms_when_running_pre_backup_actions(
|
async def test_loading_platforms_when_running_async_pre_backup_actions(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
caplog: pytest.LogCaptureFixture,
|
caplog: pytest.LogCaptureFixture,
|
||||||
) -> None:
|
) -> None:
|
||||||
|
@ -302,7 +302,7 @@ async def test_loading_platforms_when_running_pre_backup_actions(
|
||||||
async_post_backup=AsyncMock(),
|
async_post_backup=AsyncMock(),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
await manager.pre_backup_actions()
|
await manager.async_pre_backup_actions()
|
||||||
|
|
||||||
assert manager.loaded_platforms
|
assert manager.loaded_platforms
|
||||||
assert len(manager.platforms) == 1
|
assert len(manager.platforms) == 1
|
||||||
|
@ -310,7 +310,7 @@ async def test_loading_platforms_when_running_pre_backup_actions(
|
||||||
assert "Loaded 1 platforms" in caplog.text
|
assert "Loaded 1 platforms" in caplog.text
|
||||||
|
|
||||||
|
|
||||||
async def test_loading_platforms_when_running_post_backup_actions(
|
async def test_loading_platforms_when_running_async_post_backup_actions(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
caplog: pytest.LogCaptureFixture,
|
caplog: pytest.LogCaptureFixture,
|
||||||
) -> None:
|
) -> None:
|
||||||
|
@ -327,7 +327,7 @@ async def test_loading_platforms_when_running_post_backup_actions(
|
||||||
async_post_backup=AsyncMock(),
|
async_post_backup=AsyncMock(),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
await manager.post_backup_actions()
|
await manager.async_post_backup_actions()
|
||||||
|
|
||||||
assert manager.loaded_platforms
|
assert manager.loaded_platforms
|
||||||
assert len(manager.platforms) == 1
|
assert len(manager.platforms) == 1
|
||||||
|
|
|
@ -45,7 +45,7 @@ async def test_info(
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.backup.manager.BackupManager.get_backups",
|
"homeassistant.components.backup.manager.BackupManager.async_get_backups",
|
||||||
return_value={TEST_BACKUP.slug: TEST_BACKUP},
|
return_value={TEST_BACKUP.slug: TEST_BACKUP},
|
||||||
):
|
):
|
||||||
await client.send_json_auto_id({"type": "backup/info"})
|
await client.send_json_auto_id({"type": "backup/info"})
|
||||||
|
@ -72,7 +72,7 @@ async def test_remove(
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.backup.manager.BackupManager.remove_backup",
|
"homeassistant.components.backup.manager.BackupManager.async_remove_backup",
|
||||||
):
|
):
|
||||||
await client.send_json_auto_id({"type": "backup/remove", "slug": "abc123"})
|
await client.send_json_auto_id({"type": "backup/remove", "slug": "abc123"})
|
||||||
assert snapshot == await client.receive_json()
|
assert snapshot == await client.receive_json()
|
||||||
|
@ -98,7 +98,7 @@ async def test_generate(
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.backup.manager.BackupManager.generate_backup",
|
"homeassistant.components.backup.manager.BackupManager.async_create_backup",
|
||||||
return_value=TEST_BACKUP,
|
return_value=TEST_BACKUP,
|
||||||
):
|
):
|
||||||
await client.send_json_auto_id({"type": "backup/generate"})
|
await client.send_json_auto_id({"type": "backup/generate"})
|
||||||
|
@ -132,7 +132,7 @@ async def test_backup_end(
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.backup.manager.BackupManager.post_backup_actions",
|
"homeassistant.components.backup.manager.BackupManager.async_post_backup_actions",
|
||||||
):
|
):
|
||||||
await client.send_json_auto_id({"type": "backup/end"})
|
await client.send_json_auto_id({"type": "backup/end"})
|
||||||
assert snapshot == await client.receive_json()
|
assert snapshot == await client.receive_json()
|
||||||
|
@ -165,7 +165,7 @@ async def test_backup_start(
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.backup.manager.BackupManager.pre_backup_actions",
|
"homeassistant.components.backup.manager.BackupManager.async_pre_backup_actions",
|
||||||
):
|
):
|
||||||
await client.send_json_auto_id({"type": "backup/start"})
|
await client.send_json_auto_id({"type": "backup/start"})
|
||||||
assert snapshot == await client.receive_json()
|
assert snapshot == await client.receive_json()
|
||||||
|
@ -193,7 +193,7 @@ async def test_backup_end_excepion(
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.backup.manager.BackupManager.post_backup_actions",
|
"homeassistant.components.backup.manager.BackupManager.async_post_backup_actions",
|
||||||
side_effect=exception,
|
side_effect=exception,
|
||||||
):
|
):
|
||||||
await client.send_json_auto_id({"type": "backup/end"})
|
await client.send_json_auto_id({"type": "backup/end"})
|
||||||
|
@ -222,7 +222,7 @@ async def test_backup_start_excepion(
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.backup.manager.BackupManager.pre_backup_actions",
|
"homeassistant.components.backup.manager.BackupManager.async_pre_backup_actions",
|
||||||
side_effect=exception,
|
side_effect=exception,
|
||||||
):
|
):
|
||||||
await client.send_json_auto_id({"type": "backup/start"})
|
await client.send_json_auto_id({"type": "backup/start"})
|
||||||
|
|
Loading…
Add table
Reference in a new issue