Create repair for configured unavailable backup agents (#137382)

* Create repair for configured not loaded agents

* Rework to repair issue

* Extract logic to config function

* Update test

* Handle empty agend ids config update

* Address review comment

* Update tests

* Address comment
This commit is contained in:
Martin Hjelmare
2025-02-25 16:27:56 +01:00
committed by GitHub
parent f607b95c00
commit 27f7085b61
5 changed files with 262 additions and 3 deletions

View File

@@ -27,6 +27,7 @@ from homeassistant.components.backup.manager import (
)
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import issue_registry as ir
from homeassistant.helpers.backup import async_initialize_backup
from homeassistant.setup import async_setup_component
@@ -34,7 +35,9 @@ from .common import (
LOCAL_AGENT_ID,
TEST_BACKUP_ABC123,
TEST_BACKUP_DEF456,
mock_backup_agent,
setup_backup_integration,
setup_backup_platform,
)
from tests.common import async_fire_time_changed, async_mock_service
@@ -3244,6 +3247,185 @@ async def test_config_retention_days_logic(
await hass.async_block_till_done()
async def test_configured_agents_unavailable_repair(
hass: HomeAssistant,
hass_ws_client: WebSocketGenerator,
issue_registry: ir.IssueRegistry,
hass_storage: dict[str, Any],
) -> None:
"""Test creating and deleting repair issue for configured unavailable agents."""
issue_id = "automatic_backup_agents_unavailable_test.agent"
ws_client = await hass_ws_client(hass)
hass_storage.update(
{
"backup": {
"data": {
"backups": [],
"config": {
"agents": {},
"automatic_backups_configured": True,
"create_backup": {
"agent_ids": ["test.agent"],
"include_addons": None,
"include_all_addons": False,
"include_database": False,
"include_folders": None,
"name": None,
"password": None,
},
"retention": {"copies": None, "days": None},
"last_attempted_automatic_backup": None,
"last_completed_automatic_backup": None,
"schedule": {
"days": ["mon"],
"recurrence": "custom_days",
"state": "never",
"time": None,
},
},
},
"key": DOMAIN,
"version": store.STORAGE_VERSION,
"minor_version": store.STORAGE_VERSION_MINOR,
},
}
)
await setup_backup_integration(hass)
get_agents_mock = AsyncMock(return_value=[mock_backup_agent("agent")])
register_listener_mock = Mock()
await setup_backup_platform(
hass,
domain="test",
platform=Mock(
async_get_backup_agents=get_agents_mock,
async_register_backup_agents_listener=register_listener_mock,
),
)
await hass.async_block_till_done()
reload_backup_agents = register_listener_mock.call_args[1]["listener"]
await ws_client.send_json_auto_id({"type": "backup/agents/info"})
resp = await ws_client.receive_json()
assert resp["result"]["agents"] == [
{"agent_id": "backup.local", "name": "local"},
{"agent_id": "test.agent", "name": "agent"},
]
assert not issue_registry.async_get_issue(domain=DOMAIN, issue_id=issue_id)
# Reload the agents with no agents returned.
get_agents_mock.return_value = []
reload_backup_agents()
await hass.async_block_till_done()
await ws_client.send_json_auto_id({"type": "backup/agents/info"})
resp = await ws_client.receive_json()
assert resp["result"]["agents"] == [
{"agent_id": "backup.local", "name": "local"},
]
assert issue_registry.async_get_issue(domain=DOMAIN, issue_id=issue_id)
await ws_client.send_json_auto_id({"type": "backup/config/info"})
result = await ws_client.receive_json()
assert result["result"]["config"]["create_backup"]["agent_ids"] == ["test.agent"]
# Update the automatic backup configuration removing the unavailable agent.
await ws_client.send_json_auto_id(
{
"type": "backup/config/update",
"create_backup": {"agent_ids": ["backup.local"]},
}
)
result = await ws_client.receive_json()
assert not issue_registry.async_get_issue(domain=DOMAIN, issue_id=issue_id)
await ws_client.send_json_auto_id({"type": "backup/config/info"})
result = await ws_client.receive_json()
assert result["result"]["config"]["create_backup"]["agent_ids"] == ["backup.local"]
# Reload the agents with one agent returned
# but not configured for automatic backups.
get_agents_mock.return_value = [mock_backup_agent("agent")]
reload_backup_agents()
await hass.async_block_till_done()
await ws_client.send_json_auto_id({"type": "backup/agents/info"})
resp = await ws_client.receive_json()
assert resp["result"]["agents"] == [
{"agent_id": "backup.local", "name": "local"},
{"agent_id": "test.agent", "name": "agent"},
]
assert not issue_registry.async_get_issue(domain=DOMAIN, issue_id=issue_id)
await ws_client.send_json_auto_id({"type": "backup/config/info"})
result = await ws_client.receive_json()
assert result["result"]["config"]["create_backup"]["agent_ids"] == ["backup.local"]
# Update the automatic backup configuration and configure the test agent.
await ws_client.send_json_auto_id(
{
"type": "backup/config/update",
"create_backup": {"agent_ids": ["backup.local", "test.agent"]},
}
)
result = await ws_client.receive_json()
assert not issue_registry.async_get_issue(domain=DOMAIN, issue_id=issue_id)
await ws_client.send_json_auto_id({"type": "backup/config/info"})
result = await ws_client.receive_json()
assert result["result"]["config"]["create_backup"]["agent_ids"] == [
"backup.local",
"test.agent",
]
# Reload the agents with no agents returned again.
get_agents_mock.return_value = []
reload_backup_agents()
await hass.async_block_till_done()
await ws_client.send_json_auto_id({"type": "backup/agents/info"})
resp = await ws_client.receive_json()
assert resp["result"]["agents"] == [
{"agent_id": "backup.local", "name": "local"},
]
assert issue_registry.async_get_issue(domain=DOMAIN, issue_id=issue_id)
await ws_client.send_json_auto_id({"type": "backup/config/info"})
result = await ws_client.receive_json()
assert result["result"]["config"]["create_backup"]["agent_ids"] == [
"backup.local",
"test.agent",
]
# Update the automatic backup configuration removing all agents.
await ws_client.send_json_auto_id(
{
"type": "backup/config/update",
"create_backup": {"agent_ids": []},
}
)
result = await ws_client.receive_json()
assert not issue_registry.async_get_issue(domain=DOMAIN, issue_id=issue_id)
await ws_client.send_json_auto_id({"type": "backup/config/info"})
result = await ws_client.receive_json()
assert result["result"]["config"]["create_backup"]["agent_ids"] == []
async def test_subscribe_event(
hass: HomeAssistant,
hass_ws_client: WebSocketGenerator,