1
0
mirror of https://github.com/home-assistant/supervisor.git synced 2026-05-08 08:58:31 +01:00

Add background option to backup APIs (#4802)

* Add background option to backup APIs

* Fix decorator tests

* Working error handling, initial test cases

* Change to schedule_job and always return job id

* Add tests

* Reorder call at/later args

* Validation errors return immediately in background

* None is invalid option for background

* Must pop the background option from body
This commit is contained in:
Mike Degatano
2024-01-22 12:09:15 -05:00
committed by GitHub
parent d3efd4c24b
commit 480b383782
24 changed files with 1079 additions and 239 deletions
+26 -17
View File
@@ -2,6 +2,7 @@
import asyncio
import errno
from functools import partial
from pathlib import Path
from shutil import rmtree
from unittest.mock import ANY, AsyncMock, MagicMock, Mock, PropertyMock, patch
@@ -23,7 +24,6 @@ from supervisor.docker.const import ContainerState
from supervisor.docker.homeassistant import DockerHomeAssistant
from supervisor.docker.monitor import DockerContainerStateEvent
from supervisor.exceptions import (
AddonsError,
BackupError,
BackupInvalidError,
BackupJobError,
@@ -53,9 +53,9 @@ async def test_do_backup_full(coresys: CoreSys, backup_mock, install_addon_ssh):
backup_instance: MagicMock = await manager.do_backup_full()
# Check Backup has been created without password
assert backup_instance.new.call_args[0][3] == BackupType.FULL
assert backup_instance.new.call_args[0][4] is None
assert backup_instance.new.call_args[0][5] is True
assert backup_instance.new.call_args[0][2] == BackupType.FULL
assert backup_instance.new.call_args[0][3] is None
assert backup_instance.new.call_args[0][4] is True
backup_instance.store_homeassistant.assert_called_once()
backup_instance.store_repositories.assert_called_once()
@@ -83,9 +83,9 @@ async def test_do_backup_full_uncompressed(
backup_instance: MagicMock = await manager.do_backup_full(compressed=False)
# Check Backup has been created without password
assert backup_instance.new.call_args[0][3] == BackupType.FULL
assert backup_instance.new.call_args[0][4] is None
assert backup_instance.new.call_args[0][5] is False
assert backup_instance.new.call_args[0][2] == BackupType.FULL
assert backup_instance.new.call_args[0][3] is None
assert backup_instance.new.call_args[0][4] is False
backup_instance.store_homeassistant.assert_called_once()
backup_instance.store_repositories.assert_called_once()
@@ -114,9 +114,9 @@ async def test_do_backup_partial_minimal(
backup_instance: MagicMock = await manager.do_backup_partial(homeassistant=False)
# Check Backup has been created without password
assert backup_instance.new.call_args[0][3] == BackupType.PARTIAL
assert backup_instance.new.call_args[0][4] is None
assert backup_instance.new.call_args[0][5] is True
assert backup_instance.new.call_args[0][2] == BackupType.PARTIAL
assert backup_instance.new.call_args[0][3] is None
assert backup_instance.new.call_args[0][4] is True
backup_instance.store_homeassistant.assert_not_called()
backup_instance.store_repositories.assert_called_once()
@@ -144,9 +144,9 @@ async def test_do_backup_partial_minimal_uncompressed(
)
# Check Backup has been created without password
assert backup_instance.new.call_args[0][3] == BackupType.PARTIAL
assert backup_instance.new.call_args[0][4] is None
assert backup_instance.new.call_args[0][5] is False
assert backup_instance.new.call_args[0][2] == BackupType.PARTIAL
assert backup_instance.new.call_args[0][3] is None
assert backup_instance.new.call_args[0][4] is False
backup_instance.store_homeassistant.assert_not_called()
backup_instance.store_repositories.assert_called_once()
@@ -176,9 +176,9 @@ async def test_do_backup_partial_maximal(
)
# Check Backup has been created without password
assert backup_instance.new.call_args[0][3] == BackupType.PARTIAL
assert backup_instance.new.call_args[0][4] is None
assert backup_instance.new.call_args[0][5] is True
assert backup_instance.new.call_args[0][2] == BackupType.PARTIAL
assert backup_instance.new.call_args[0][3] is None
assert backup_instance.new.call_args[0][4] is True
backup_instance.store_homeassistant.assert_called_once()
backup_instance.store_repositories.assert_called_once()
@@ -206,6 +206,10 @@ async def test_do_restore_full(coresys: CoreSys, full_backup_mock, install_addon
manager = BackupManager(coresys)
backup_instance = full_backup_mock.return_value
backup_instance.sys_addons = coresys.addons
backup_instance.remove_delta_addons = partial(
Backup.remove_delta_addons, backup_instance
)
assert await manager.do_restore_full(backup_instance)
backup_instance.restore_homeassistant.assert_called_once()
@@ -235,6 +239,10 @@ async def test_do_restore_full_different_addon(
backup_instance = full_backup_mock.return_value
backup_instance.addon_list = ["differentslug"]
backup_instance.sys_addons = coresys.addons
backup_instance.remove_delta_addons = partial(
Backup.remove_delta_addons, backup_instance
)
assert await manager.do_restore_full(backup_instance)
backup_instance.restore_homeassistant.assert_called_once()
@@ -371,7 +379,7 @@ async def test_backup_error(
coresys.core.state = CoreState.RUNNING
coresys.hardware.disk.get_disk_free_space = lambda x: 5000
backup_mock.return_value.store_addons.side_effect = (err := AddonsError())
backup_mock.return_value.store_folders.side_effect = (err := OSError())
await coresys.backups.do_backup_full()
capture_exception.assert_called_once_with(err)
@@ -937,6 +945,7 @@ def _make_backup_message_for_assert(
"stage": stage,
"done": done,
"parent_id": None,
"errors": [],
},
},
}