Add agent delete backup (#130921)

* Add backup agent delete backup

* Remove agents delete websocket command

* Update docstring

Co-authored-by: Erik Montnemery <erik@montnemery.com>

---------

Co-authored-by: Erik Montnemery <erik@montnemery.com>
This commit is contained in:
Martin Hjelmare
2024-11-19 08:43:13 +01:00
committed by GitHub
parent 3cd69c32ec
commit 1a3a089cdd
8 changed files with 94 additions and 6 deletions

View File

@@ -55,6 +55,17 @@ class BackupAgent(abc.ABC):
:param metadata: Metadata about the backup that should be uploaded.
"""
@abc.abstractmethod
async def async_delete_backup(
self,
backup_id: str,
**kwargs: Any,
) -> None:
"""Delete a backup file.
:param backup_id: The ID of the backup that was returned in async_list_backups.
"""
@abc.abstractmethod
async def async_list_backups(self, **kwargs: Any) -> list[BaseBackup]:
"""List backups."""

View File

@@ -124,8 +124,8 @@ class CoreLocalBackupAgent(LocalBackupAgent):
"""Return the local path to a backup."""
return self._backup_dir / f"{backup_id}.tar"
async def async_remove_backup(self, backup_id: str, **kwargs: Any) -> None:
"""Remove a backup."""
async def async_delete_backup(self, backup_id: str, **kwargs: Any) -> None:
"""Delete a backup file."""
if await self.async_get_backup(backup_id) is None:
return

View File

@@ -356,9 +356,7 @@ class BackupManager(BaseBackupManager[Backup]):
async def async_remove_backup(self, backup_id: str, **kwargs: Any) -> None:
"""Remove a backup."""
for agent in self.backup_agents.values():
if not hasattr(agent, "async_remove_backup"):
continue
await agent.async_remove_backup(backup_id)
await agent.async_delete_backup(backup_id)
async def async_receive_backup(
self,

View File

@@ -43,6 +43,7 @@ class KitchenSinkBackupAgent(BackupAgent):
async def async_download_backup(
self,
backup_id: str,
*,
path: Path,
**kwargs: Any,
) -> None:
@@ -68,6 +69,17 @@ class KitchenSinkBackupAgent(BackupAgent):
)
)
async def async_delete_backup(
self,
backup_id: str,
**kwargs: Any,
) -> None:
"""Delete a backup file."""
self._uploads = [
upload for upload in self._uploads if upload.backup_id != backup_id
]
LOGGER.info("Deleted backup %s", backup_id)
async def async_list_backups(self, **kwargs: Any) -> list[BaseBackup]:
"""List synced backups."""
return self._uploads

View File

@@ -99,6 +99,13 @@ class BackupAgentTest(BackupAgent):
"""Return a backup."""
return self._backups.get(backup_id)
async def async_delete_backup(
self,
backup_id: str,
**kwargs: Any,
) -> None:
"""Delete a backup file."""
async def setup_backup_integration(
hass: HomeAssistant,

View File

@@ -1227,6 +1227,14 @@
'type': 'result',
})
# ---
# name: test_remove_agents_delete
dict({
'id': 1,
'result': None,
'success': True,
'type': 'result',
})
# ---
# name: test_restore_local_agent[with_hassio-backups0]
dict({
'error': dict({

View File

@@ -2,7 +2,7 @@
from pathlib import Path
from typing import Any
from unittest.mock import ANY, patch
from unittest.mock import ANY, call, patch
from freezegun.api import FrozenDateTimeFactory
import pytest
@@ -224,6 +224,30 @@ async def test_remove(
assert await client.receive_json() == snapshot
async def test_remove_agents_delete(
hass: HomeAssistant,
hass_ws_client: WebSocketGenerator,
snapshot: SnapshotAssertion,
) -> None:
"""Test removing a backup file with a mock agent."""
await setup_backup_integration(hass)
hass.data[DATA_MANAGER].backup_agents = {"domain.test": BackupAgentTest("test")}
client = await hass_ws_client(hass)
await hass.async_block_till_done()
with patch.object(BackupAgentTest, "async_delete_backup") as delete_mock:
await client.send_json_auto_id(
{
"type": "backup/remove",
"backup_id": "abc123",
}
)
assert await client.receive_json() == snapshot
assert delete_mock.call_args == call("abc123")
@pytest.mark.parametrize(
"data",
[

View File

@@ -152,3 +152,31 @@ async def test_agents_upload(
"protected": test_backup.protected,
"size": 0.0,
}
async def test_agents_delete(
hass: HomeAssistant,
hass_ws_client: WebSocketGenerator,
caplog: pytest.LogCaptureFixture,
) -> None:
"""Test backup agents delete."""
client = await hass_ws_client(hass)
backup_id = "abc123"
await client.send_json_auto_id(
{
"type": "backup/remove",
"backup_id": backup_id,
}
)
response = await client.receive_json()
assert response["success"]
assert f"Deleted backup {backup_id}" in caplog.text
await client.send_json_auto_id({"type": "backup/agents/list_backups"})
response = await client.receive_json()
assert response["success"]
backup_list = response["result"]
assert not backup_list