1
0
mirror of https://github.com/home-assistant/supervisor.git synced 2025-12-24 12:29:08 +00:00

Report stage with error in jobs (#5784)

* Report stage with error in jobs

* Copy doesn't lose track of the successful copies

* Add stage to errors in api output test

* revert unneessary change to import

* Add tests for a bit more coverage of copy_additional_locations
This commit is contained in:
Mike Degatano
2025-03-27 10:07:06 -04:00
committed by GitHub
parent 92cadb4c55
commit 9222a3c9c0
6 changed files with 214 additions and 30 deletions

View File

@@ -394,7 +394,11 @@ async def test_api_backup_errors(
assert job["child_jobs"][1]["child_jobs"][0]["name"] == "backup_addon_save"
assert job["child_jobs"][1]["child_jobs"][0]["reference"] == "local_ssh"
assert job["child_jobs"][1]["child_jobs"][0]["errors"] == [
{"type": "BackupError", "message": "Can't create backup for local_ssh"}
{
"type": "BackupError",
"message": "Can't create backup for local_ssh",
"stage": None,
}
]
assert job["child_jobs"][2]["name"] == "backup_store_folders"
assert job["child_jobs"][2]["reference"] == slug
@@ -425,11 +429,21 @@ async def test_api_backup_errors(
assert job["name"] == f"backup_manager_{backup_type}_backup"
assert job["done"] is True
assert job["errors"] == (
err := [{"type": "HomeAssistantBackupError", "message": "Backup error"}]
)
assert job["errors"] == [
{
"type": "HomeAssistantBackupError",
"message": "Backup error",
"stage": "home_assistant",
}
]
assert job["child_jobs"][0]["name"] == "backup_store_homeassistant"
assert job["child_jobs"][0]["errors"] == err
assert job["child_jobs"][0]["errors"] == [
{
"type": "HomeAssistantBackupError",
"message": "Backup error",
"stage": None,
}
]
assert len(job["child_jobs"]) == 1
@@ -625,13 +639,20 @@ async def test_upload_download(
@pytest.mark.usefixtures("path_extern", "tmp_supervisor_data")
@pytest.mark.parametrize(
("backup_type", "inputs"), [("full", {}), ("partial", {"folders": ["ssl"]})]
("backup_type", "inputs", "locations"),
[
("full", {}, [None, ".cloud_backup"]),
("full", {}, [".cloud_backup", None]),
("partial", {"folders": ["ssl"]}, [None, ".cloud_backup"]),
("partial", {"folders": ["ssl"]}, [".cloud_backup", None]),
],
)
async def test_backup_to_multiple_locations(
api_client: TestClient,
coresys: CoreSys,
backup_type: str,
inputs: dict[str, Any],
locations: list[str | None],
):
"""Test making a backup to multiple locations."""
await coresys.core.set_state(CoreState.RUNNING)
@@ -639,8 +660,7 @@ async def test_backup_to_multiple_locations(
resp = await api_client.post(
f"/backups/new/{backup_type}",
json={"name": "Multiple locations test", "location": [None, ".cloud_backup"]}
| inputs,
json={"name": "Multiple locations test", "location": locations} | inputs,
)
assert resp.status == 200
result = await resp.json()
@@ -658,6 +678,56 @@ async def test_backup_to_multiple_locations(
assert coresys.backups.get(slug).location is None
@pytest.mark.usefixtures("path_extern", "tmp_supervisor_data")
@pytest.mark.parametrize(
("backup_type", "inputs"), [("full", {}), ("partial", {"folders": ["ssl"]})]
)
async def test_backup_to_multiple_locations_error_on_copy(
api_client: TestClient,
coresys: CoreSys,
backup_type: str,
inputs: dict[str, Any],
):
"""Test making a backup to multiple locations that fails during copy stage."""
await coresys.core.set_state(CoreState.RUNNING)
coresys.hardware.disk.get_disk_free_space = lambda x: 5000
with patch("supervisor.backups.manager.copy", side_effect=OSError):
resp = await api_client.post(
f"/backups/new/{backup_type}",
json={
"name": "Multiple locations test",
"location": [None, ".cloud_backup"],
}
| inputs,
)
assert resp.status == 200
result = await resp.json()
assert result["result"] == "ok"
slug = result["data"]["slug"]
orig_backup = coresys.config.path_backup / f"{slug}.tar"
assert await coresys.run_in_executor(orig_backup.exists)
assert coresys.backups.get(slug).all_locations == {
None: {"path": orig_backup, "protected": False, "size_bytes": 10240},
}
assert coresys.backups.get(slug).location is None
resp = await api_client.get("/jobs/info")
assert resp.status == 200
result = await resp.json()
assert result["data"]["jobs"][0]["name"] == f"backup_manager_{backup_type}_backup"
assert result["data"]["jobs"][0]["reference"] == slug
assert result["data"]["jobs"][0]["done"] is True
assert result["data"]["jobs"][0]["errors"] == [
{
"type": "BackupError",
"message": "Could not copy backup to .cloud_backup due to: ",
"stage": "copy_additional_locations",
}
]
@pytest.mark.parametrize(
("backup_type", "inputs"), [("full", {}), ("partial", {"folders": ["ssl"]})]
)