supervisor/tests/api/test_backups.py
Mike Degatano 44daffc65b
Add freeze/thaw apis for external snapshots (#4538)
* Add freeze/thaw apis for external backups

* Error when thaw called before freeze

* Timeout must be > 0
2023-09-09 10:54:19 +02:00

170 lines
5.2 KiB
Python

"""Test backups API."""
import asyncio
from pathlib import Path, PurePath
from unittest.mock import AsyncMock, patch
from aiohttp.test_utils import TestClient
from awesomeversion import AwesomeVersion
import pytest
from supervisor.backups.backup import Backup
from supervisor.const import CoreState
from supervisor.coresys import CoreSys
from supervisor.mounts.mount import Mount
async def test_info(api_client, coresys: CoreSys, mock_full_backup: Backup):
"""Test info endpoint."""
resp = await api_client.get("/backups/info")
result = await resp.json()
assert result["data"]["days_until_stale"] == 30
assert len(result["data"]["backups"]) == 1
assert result["data"]["backups"][0]["slug"] == "test"
assert result["data"]["backups"][0]["content"]["homeassistant"] is True
assert len(result["data"]["backups"][0]["content"]["addons"]) == 1
assert result["data"]["backups"][0]["content"]["addons"][0] == "local_ssh"
async def test_list(api_client, coresys: CoreSys, mock_full_backup: Backup):
"""Test list endpoint."""
resp = await api_client.get("/backups")
result = await resp.json()
assert len(result["data"]["backups"]) == 1
assert result["data"]["backups"][0]["slug"] == "test"
assert result["data"]["backups"][0]["content"]["homeassistant"] is True
assert len(result["data"]["backups"][0]["content"]["addons"]) == 1
assert result["data"]["backups"][0]["content"]["addons"][0] == "local_ssh"
async def test_options(api_client, coresys: CoreSys):
"""Test options endpoint."""
assert coresys.backups.days_until_stale == 30
with patch.object(type(coresys.backups), "save_data") as save_data:
await api_client.post(
"/backups/options",
json={
"days_until_stale": 10,
},
)
save_data.assert_called_once()
assert coresys.backups.days_until_stale == 10
@pytest.mark.parametrize(
"location,backup_dir",
[("backup_test", PurePath("mounts", "backup_test")), (None, PurePath("backup"))],
)
async def test_backup_to_location(
api_client: TestClient,
coresys: CoreSys,
location: str | None,
backup_dir: PurePath,
tmp_supervisor_data: Path,
path_extern,
mount_propagation,
):
"""Test making a backup to a specific location with default mount."""
await coresys.mounts.load()
(coresys.config.path_mounts / "backup_test").mkdir()
mount = Mount.from_dict(
coresys,
{
"name": "backup_test",
"type": "cifs",
"usage": "backup",
"server": "backup.local",
"share": "backups",
},
)
await coresys.mounts.create_mount(mount)
coresys.mounts.default_backup_mount = mount
coresys.core.state = CoreState.RUNNING
coresys.hardware.disk.get_disk_free_space = lambda x: 5000
resp = await api_client.post(
"/backups/new/full",
json={
"name": "Mount test",
"location": location,
},
)
result = await resp.json()
assert result["result"] == "ok"
slug = result["data"]["slug"]
assert (tmp_supervisor_data / backup_dir / f"{slug}.tar").exists()
resp = await api_client.get(f"/backups/{slug}/info")
result = await resp.json()
assert result["result"] == "ok"
assert result["data"]["location"] == location
async def test_backup_to_default(
api_client: TestClient,
coresys: CoreSys,
tmp_supervisor_data,
path_extern,
mount_propagation,
):
"""Test making backup to default mount."""
await coresys.mounts.load()
(mount_dir := coresys.config.path_mounts / "backup_test").mkdir()
mount = Mount.from_dict(
coresys,
{
"name": "backup_test",
"type": "cifs",
"usage": "backup",
"server": "backup.local",
"share": "backups",
},
)
await coresys.mounts.create_mount(mount)
coresys.mounts.default_backup_mount = mount
coresys.core.state = CoreState.RUNNING
coresys.hardware.disk.get_disk_free_space = lambda x: 5000
resp = await api_client.post(
"/backups/new/full",
json={"name": "Mount test"},
)
result = await resp.json()
assert result["result"] == "ok"
slug = result["data"]["slug"]
assert (mount_dir / f"{slug}.tar").exists()
async def test_api_freeze_thaw(
api_client: TestClient,
coresys: CoreSys,
ha_ws_client: AsyncMock,
tmp_supervisor_data,
path_extern,
):
"""Test manual freeze and thaw for external backup via API."""
coresys.core.state = CoreState.RUNNING
coresys.hardware.disk.get_disk_free_space = lambda x: 5000
ha_ws_client.ha_version = AwesomeVersion("2022.1.0")
await api_client.post("/backups/freeze")
assert coresys.core.state == CoreState.FREEZE
await asyncio.sleep(0)
assert any(
call.args[0] == {"type": "backup/start"}
for call in ha_ws_client.async_send_command.call_args_list
)
ha_ws_client.async_send_command.reset_mock()
await api_client.post("/backups/thaw")
assert coresys.core.state == CoreState.RUNNING
await asyncio.sleep(0)
assert any(
call.args[0] == {"type": "backup/end"}
for call in ha_ws_client.async_send_command.call_args_list
)