Use setup_backup_integration test helper in backup tests (#138362)

This commit is contained in:
Erik Montnemery 2025-02-12 09:49:01 +01:00 committed by GitHub
parent 2033dbdd90
commit 6ef1178a35
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 158 additions and 441 deletions

View File

@ -20,7 +20,7 @@ from homeassistant.components.backup.const import DATA_MANAGER
from homeassistant.core import HomeAssistant
from homeassistant.setup import async_setup_component
from tests.common import MockPlatform, mock_platform
from tests.common import mock_platform
LOCAL_AGENT_ID = f"{DOMAIN}.local"
@ -138,15 +138,15 @@ async def setup_backup_integration(
raise ValueError(f"Invalid agent_id: {agent}")
name = agent.partition(".")[2]
remote_agents_dict[agent] = mock_backup_agent(name, backups.get(agent))
platform = Mock(
async_get_backup_agents=AsyncMock(
return_value=list(remote_agents_dict.values())
),
spec_set=BackupAgentPlatformProtocol,
)
if remote_agents:
platform = Mock(
async_get_backup_agents=AsyncMock(
return_value=list(remote_agents_dict.values())
),
spec_set=BackupAgentPlatformProtocol,
)
await setup_backup_platform(hass, domain=TEST_DOMAIN, platform=platform)
mock_platform(hass, f"{TEST_DOMAIN}.backup", platform or MockPlatform())
assert await async_setup_component(hass, TEST_DOMAIN, {})
assert await async_setup_component(hass, DOMAIN, {})
await hass.async_block_till_done()

View File

@ -16,12 +16,12 @@
'result': dict({
'agents': list([
dict({
'agent_id': 'backup.local',
'name': 'local',
'agent_id': 'test.remote',
'name': 'remote',
}),
dict({
'agent_id': 'test.test',
'name': 'test',
'agent_id': 'backup.local',
'name': 'local',
}),
]),
}),
@ -3457,7 +3457,7 @@
'id': 1,
'result': dict({
'agent_errors': dict({
'domain.test': 'The backup agent is unreachable.',
'test.remote': 'The backup agent is unreachable.',
}),
}),
'success': True,
@ -3480,7 +3480,7 @@
}),
]),
'agents': dict({
'domain.test': dict({
'test.remote': dict({
'protected': False,
'size': 0,
}),
@ -3520,7 +3520,7 @@
'id': 1,
'result': dict({
'agent_errors': dict({
'domain.test': 'The backup agent is unreachable.',
'test.remote': 'The backup agent is unreachable.',
}),
}),
'success': True,
@ -3543,7 +3543,7 @@
}),
]),
'agents': dict({
'domain.test': dict({
'test.remote': dict({
'protected': False,
'size': 0,
}),
@ -3606,7 +3606,7 @@
}),
]),
'agents': dict({
'domain.test': dict({
'test.remote': dict({
'protected': False,
'size': 0,
}),
@ -3668,7 +3668,7 @@
}),
]),
'agents': dict({
'domain.test': dict({
'test.remote': dict({
'protected': False,
'size': 0,
}),
@ -3708,7 +3708,7 @@
'id': 1,
'result': dict({
'agent_errors': dict({
'domain.test': 'Boom!',
'test.remote': 'Boom!',
}),
}),
'success': True,
@ -3731,7 +3731,7 @@
}),
]),
'agents': dict({
'domain.test': dict({
'test.remote': dict({
'protected': False,
'size': 0,
}),
@ -3771,7 +3771,7 @@
'id': 1,
'result': dict({
'agent_errors': dict({
'domain.test': 'Boom!',
'test.remote': 'Boom!',
}),
}),
'success': True,
@ -3794,7 +3794,7 @@
}),
]),
'agents': dict({
'domain.test': dict({
'test.remote': dict({
'protected': False,
'size': 0,
}),
@ -3992,7 +3992,7 @@
'id': 1,
'result': dict({
'agent_errors': dict({
'domain.test': 'The backup agent is unreachable.',
'test.remote': 'The backup agent is unreachable.',
}),
'backup': dict({
'addons': list([
@ -4036,7 +4036,7 @@
'id': 1,
'result': dict({
'agent_errors': dict({
'domain.test': 'Oops',
'test.remote': 'Oops',
}),
'backup': dict({
'addons': list([
@ -4080,7 +4080,7 @@
'id': 1,
'result': dict({
'agent_errors': dict({
'domain.test': 'Boom!',
'test.remote': 'Boom!',
}),
'backup': dict({
'addons': list([
@ -4584,7 +4584,7 @@
'id': 1,
'result': dict({
'agent_errors': dict({
'domain.test': 'The backup agent is unreachable.',
'test.remote': 'The backup agent is unreachable.',
}),
'backups': list([
dict({
@ -4636,7 +4636,7 @@
'id': 1,
'result': dict({
'agent_errors': dict({
'domain.test': 'Oops',
'test.remote': 'Oops',
}),
'backups': list([
dict({
@ -4688,7 +4688,7 @@
'id': 1,
'result': dict({
'agent_errors': dict({
'domain.test': 'Boom!',
'test.remote': 'Boom!',
}),
'backups': list([
dict({

View File

@ -18,19 +18,28 @@ from homeassistant.components.backup import (
BackupNotFound,
Folder,
)
from homeassistant.components.backup.const import DATA_MANAGER, DOMAIN
from homeassistant.components.backup.const import DOMAIN
from homeassistant.core import HomeAssistant
from .common import (
TEST_BACKUP_ABC123,
aiter_from_iter,
mock_backup_agent,
setup_backup_integration,
)
from .common import TEST_BACKUP_ABC123, aiter_from_iter, setup_backup_integration
from tests.common import MockUser, get_fixture_path
from tests.typing import ClientSessionGenerator
PROTECTED_BACKUP = AgentBackup(
addons=[AddonInfo(name="Test", slug="test", version="1.0.0")],
backup_id="c0cb53bd",
database_included=True,
date="1970-01-01T00:00:00Z",
extra_metadata={},
folders=[Folder.MEDIA, Folder.SHARE],
homeassistant_included=True,
homeassistant_version="2024.12.0",
name="Test",
protected=True,
size=13,
)
async def test_downloading_local_backup(
hass: HomeAssistant,
@ -115,32 +124,15 @@ async def test_downloading_remote_encrypted_backup(
) -> None:
"""Test downloading a local backup file."""
backup_path = get_fixture_path("test_backups/c0cb53bd.tar", DOMAIN)
await setup_backup_integration(hass)
mock_agent = mock_backup_agent(
"test",
[
AgentBackup(
addons=[AddonInfo(name="Test", slug="test", version="1.0.0")],
backup_id="c0cb53bd",
database_included=True,
date="1970-01-01T00:00:00Z",
extra_metadata={},
folders=[Folder.MEDIA, Folder.SHARE],
homeassistant_included=True,
homeassistant_version="2024.12.0",
name="Test",
protected=True,
size=13,
)
],
mock_agents = await setup_backup_integration(
hass, remote_agents=["test.test"], backups={"test.test": [PROTECTED_BACKUP]}
)
hass.data[DATA_MANAGER].backup_agents["domain.test"] = mock_agent
async def download_backup(backup_id: str, **kwargs: Any) -> AsyncIterator[bytes]:
return aiter_from_iter((backup_path.read_bytes(),))
mock_agent.async_download_backup.side_effect = download_backup
await _test_downloading_encrypted_backup(hass_client, "domain.test")
mock_agents["test.test"].async_download_backup.side_effect = download_backup
await _test_downloading_encrypted_backup(hass_client, "test.test")
@pytest.mark.parametrize(
@ -157,31 +149,14 @@ async def test_downloading_remote_encrypted_backup_with_error(
status: int,
) -> None:
"""Test downloading a local backup file."""
await setup_backup_integration(hass)
mock_agent = mock_backup_agent(
"test",
[
AgentBackup(
addons=[AddonInfo(name="Test", slug="test", version="1.0.0")],
backup_id="abc123",
database_included=True,
date="1970-01-01T00:00:00Z",
extra_metadata={},
folders=[Folder.MEDIA, Folder.SHARE],
homeassistant_included=True,
homeassistant_version="2024.12.0",
name="Test",
protected=True,
size=13,
)
],
mock_agents = await setup_backup_integration(
hass, remote_agents=["test.test"], backups={"test.test": [PROTECTED_BACKUP]}
)
hass.data[DATA_MANAGER].backup_agents["domain.test"] = mock_agent
mock_agent.async_download_backup.side_effect = error
mock_agents["test.test"].async_download_backup.side_effect = error
client = await hass_client()
resp = await client.get(
"/api/backup/download/abc123?agent_id=domain.test&password=blah"
f"/api/backup/download/{PROTECTED_BACKUP.backup_id}?agent_id=test.test&password=blah"
)
assert resp.status == status

View File

@ -27,11 +27,9 @@ import pytest
from homeassistant.components.backup import (
DOMAIN,
AgentBackup,
BackupAgentPlatformProtocol,
BackupReaderWriterError,
Folder,
LocalBackupAgent,
backup as local_backup_platform,
)
from homeassistant.components.backup.agent import BackupAgentError
from homeassistant.components.backup.const import DATA_MANAGER
@ -50,7 +48,6 @@ from homeassistant.components.backup.util import password_to_key
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import issue_registry as ir
from homeassistant.setup import async_setup_component
from .common import (
LOCAL_AGENT_ID,
@ -59,6 +56,7 @@ from .common import (
TEST_BACKUP_PATH_ABC123,
TEST_BACKUP_PATH_DEF456,
mock_backup_agent,
setup_backup_integration,
setup_backup_platform,
)
@ -110,8 +108,7 @@ async def test_create_backup_service(
mocked_tarfile: Mock,
) -> None:
"""Test create backup service."""
assert await async_setup_component(hass, DOMAIN, {})
await hass.async_block_till_done()
await setup_backup_integration(hass)
new_backup = NewBackup(backup_job_id="time-123")
backup_task = AsyncMock(
@ -307,8 +304,7 @@ async def test_async_create_backup(
expected_writer_kwargs: dict[str, Any],
) -> None:
"""Test create backup."""
assert await async_setup_component(hass, DOMAIN, {})
await hass.async_block_till_done()
await setup_backup_integration(hass)
manager = hass.data[DATA_MANAGER]
new_backup = NewBackup(backup_job_id="time-123")
@ -336,8 +332,7 @@ async def test_create_backup_when_busy(
hass_ws_client: WebSocketGenerator,
) -> None:
"""Test generate backup with busy manager."""
assert await async_setup_component(hass, DOMAIN, {})
await hass.async_block_till_done()
await setup_backup_integration(hass)
ws_client = await hass_ws_client(hass)
await ws_client.send_json_auto_id(
@ -385,8 +380,7 @@ async def test_create_backup_wrong_parameters(
expected_error: str,
) -> None:
"""Test create backup with wrong parameters."""
assert await async_setup_component(hass, DOMAIN, {})
await hass.async_block_till_done()
await setup_backup_integration(hass)
ws_client = await hass_ws_client(hass)
@ -523,23 +517,7 @@ async def test_initiate_backup(
temp_file_unlink_call_count: int,
) -> None:
"""Test generate backup."""
local_agent = local_backup_platform.CoreLocalBackupAgent(hass)
remote_agent = mock_backup_agent("remote")
with patch(
"homeassistant.components.backup.backup.async_get_backup_agents"
) as core_get_backup_agents:
core_get_backup_agents.return_value = [local_agent]
await async_setup_component(hass, DOMAIN, {})
await hass.async_block_till_done()
await setup_backup_platform(
hass,
domain="test",
platform=Mock(
async_get_backup_agents=AsyncMock(return_value=[remote_agent]),
spec_set=BackupAgentPlatformProtocol,
),
)
await setup_backup_integration(hass, remote_agents=["test.remote"])
ws_client = await hass_ws_client(hass)
freezer.move_to("2025-01-30 13:42:12.345678")
@ -693,7 +671,6 @@ async def test_initiate_backup_with_agent_error(
) -> None:
"""Test agent upload error during backup generation."""
agent_ids = [LOCAL_AGENT_ID, "test.remote"]
local_agent = local_backup_platform.CoreLocalBackupAgent(hass)
backup_1 = replace(TEST_BACKUP_ABC123, backup_id="backup1") # matching instance id
backup_2 = replace(TEST_BACKUP_DEF456, backup_id="backup2") # other instance id
backup_3 = replace(TEST_BACKUP_ABC123, backup_id="backup3") # matching instance id
@ -771,22 +748,12 @@ async def test_initiate_backup_with_agent_error(
"with_automatic_settings": True,
},
]
remote_agent = mock_backup_agent("remote", backups=[backup_1, backup_2, backup_3])
with patch(
"homeassistant.components.backup.backup.async_get_backup_agents"
) as core_get_backup_agents:
core_get_backup_agents.return_value = [local_agent]
await async_setup_component(hass, DOMAIN, {})
await hass.async_block_till_done()
await setup_backup_platform(
hass,
domain="test",
platform=Mock(
async_get_backup_agents=AsyncMock(return_value=[remote_agent]),
spec_set=BackupAgentPlatformProtocol,
),
)
mock_agents = await setup_backup_integration(
hass,
remote_agents=["test.remote"],
backups={"test.remote": [backup_1, backup_2, backup_3]},
)
ws_client = await hass_ws_client(hass)
@ -821,17 +788,8 @@ async def test_initiate_backup_with_agent_error(
result = await ws_client.receive_json()
assert result["success"] is True
delete_backup = AsyncMock()
with (
patch("pathlib.Path.open", mock_open(read_data=b"test")),
patch.object(
remote_agent,
"async_upload_backup",
side_effect=exception,
),
patch.object(remote_agent, "async_delete_backup", delete_backup),
):
mock_agents["test.remote"].async_upload_backup.side_effect = exception
with patch("pathlib.Path.open", mock_open(read_data=b"test")):
await ws_client.send_json_auto_id(
{"type": "backup/generate", "agent_ids": agent_ids}
)
@ -922,7 +880,7 @@ async def test_initiate_backup_with_agent_error(
]
# one of the two matching backups with the remote agent should have been deleted
assert delete_backup.call_count == 1
assert mock_agents["test.remote"].async_delete_backup.call_count == 1
@pytest.mark.usefixtures("mock_backup_generation")
@ -946,8 +904,7 @@ async def test_create_backup_success_clears_issue(
issues_after_create_backup: set[tuple[str, str]],
) -> None:
"""Test backup issue is cleared after backup is created."""
await async_setup_component(hass, DOMAIN, {})
await hass.async_block_till_done()
await setup_backup_integration(hass)
# Create a backup issue
ir.async_create_issue(
@ -996,7 +953,7 @@ async def delayed_boom(*args, **kwargs) -> tuple[NewBackup, Any]:
"automatic_agents",
"create_backup_command",
"create_backup_side_effect",
"agent_upload_side_effect",
"upload_side_effect",
"create_backup_result",
"issues_after_create_backup",
),
@ -1115,26 +1072,12 @@ async def test_create_backup_failure_raises_issue(
automatic_agents: list[str],
create_backup_command: dict[str, Any],
create_backup_side_effect: Exception | None,
agent_upload_side_effect: Exception | None,
upload_side_effect: Exception | None,
create_backup_result: bool,
issues_after_create_backup: dict[tuple[str, str], dict[str, Any]],
) -> None:
"""Test backup issue is cleared after backup is created."""
remote_agent = mock_backup_agent("remote")
await async_setup_component(hass, DOMAIN, {})
await hass.async_block_till_done()
await setup_backup_platform(
hass,
domain="test",
platform=Mock(
async_get_backup_agents=AsyncMock(return_value=[remote_agent]),
spec_set=BackupAgentPlatformProtocol,
),
)
await async_setup_component(hass, DOMAIN, {})
await hass.async_block_till_done()
mock_agents = await setup_backup_integration(hass, remote_agents=["test.remote"])
ws_client = await hass_ws_client(hass)
@ -1149,13 +1092,11 @@ async def test_create_backup_failure_raises_issue(
result = await ws_client.receive_json()
assert result["success"] is True
with patch.object(
remote_agent, "async_upload_backup", side_effect=agent_upload_side_effect
):
await ws_client.send_json_auto_id(create_backup_command)
result = await ws_client.receive_json()
assert result["success"] == create_backup_result
await hass.async_block_till_done()
mock_agents["test.remote"].async_upload_backup.side_effect = upload_side_effect
await ws_client.send_json_auto_id(create_backup_command)
result = await ws_client.receive_json()
assert result["success"] == create_backup_result
await hass.async_block_till_done()
issue_registry = ir.async_get(hass)
assert set(issue_registry.issues) == set(issues_after_create_backup)
@ -1179,23 +1120,7 @@ async def test_initiate_backup_non_agent_upload_error(
) -> None:
"""Test an unknown or writer upload error during backup generation."""
agent_ids = [LOCAL_AGENT_ID, "test.remote"]
local_agent = local_backup_platform.CoreLocalBackupAgent(hass)
remote_agent = mock_backup_agent("remote")
with patch(
"homeassistant.components.backup.backup.async_get_backup_agents"
) as core_get_backup_agents:
core_get_backup_agents.return_value = [local_agent]
await async_setup_component(hass, DOMAIN, {})
await hass.async_block_till_done()
await setup_backup_platform(
hass,
domain="test",
platform=Mock(
async_get_backup_agents=AsyncMock(return_value=[remote_agent]),
spec_set=BackupAgentPlatformProtocol,
),
)
mock_agents = await setup_backup_integration(hass, remote_agents=["test.remote"])
ws_client = await hass_ws_client(hass)
@ -1224,14 +1149,8 @@ async def test_initiate_backup_non_agent_upload_error(
result = await ws_client.receive_json()
assert result["success"] is True
with (
patch("pathlib.Path.open", mock_open(read_data=b"test")),
patch.object(
remote_agent,
"async_upload_backup",
side_effect=exception,
),
):
mock_agents["test.remote"].async_upload_backup.side_effect = exception
with patch("pathlib.Path.open", mock_open(read_data=b"test")):
await ws_client.send_json_auto_id(
{"type": "backup/generate", "agent_ids": agent_ids}
)
@ -1297,23 +1216,8 @@ async def test_initiate_backup_with_task_error(
backup_task.set_exception(exception)
create_backup.return_value = (NewBackup(backup_job_id="abc123"), backup_task)
agent_ids = [LOCAL_AGENT_ID, "test.remote"]
local_agent = local_backup_platform.CoreLocalBackupAgent(hass)
remote_agent = mock_backup_agent("remote")
with patch(
"homeassistant.components.backup.backup.async_get_backup_agents"
) as core_get_backup_agents:
core_get_backup_agents.return_value = [local_agent]
await async_setup_component(hass, DOMAIN, {})
await hass.async_block_till_done()
await setup_backup_platform(
hass,
domain="test",
platform=Mock(
async_get_backup_agents=AsyncMock(return_value=[remote_agent]),
spec_set=BackupAgentPlatformProtocol,
),
)
await setup_backup_integration(hass, remote_agents=["test.remote"])
ws_client = await hass_ws_client(hass)
@ -1408,23 +1312,8 @@ async def test_initiate_backup_file_error(
) -> None:
"""Test file error during generate backup."""
agent_ids = ["test.remote"]
local_agent = local_backup_platform.CoreLocalBackupAgent(hass)
remote_agent = mock_backup_agent("remote")
with patch(
"homeassistant.components.backup.backup.async_get_backup_agents"
) as core_get_backup_agents:
core_get_backup_agents.return_value = [local_agent]
await async_setup_component(hass, DOMAIN, {})
await hass.async_block_till_done()
await setup_backup_platform(
hass,
domain="test",
platform=Mock(
async_get_backup_agents=AsyncMock(return_value=[remote_agent]),
spec_set=BackupAgentPlatformProtocol,
),
)
await setup_backup_integration(hass, remote_agents=["test.remote"])
ws_client = await hass_ws_client(hass)
@ -1533,7 +1422,7 @@ async def test_loading_platform_with_listener(
) -> None:
"""Test loading a backup agent platform which can be listened to."""
ws_client = await hass_ws_client(hass)
assert await async_setup_component(hass, DOMAIN, {})
await setup_backup_integration(hass)
manager = hass.data[DATA_MANAGER]
get_agents_mock = AsyncMock(return_value=[agent_creator("remote1")])
@ -1593,8 +1482,7 @@ async def test_not_loading_bad_platforms(
domain="test",
platform=platform_mock,
)
assert await async_setup_component(hass, DOMAIN, {})
await hass.async_block_till_done()
await setup_backup_integration(hass)
assert platform_mock.mock_calls == []
@ -1615,8 +1503,7 @@ async def test_exception_platform_pre(hass: HomeAssistant) -> None:
async_get_backup_agents=AsyncMock(return_value=[remote_agent]),
),
)
assert await async_setup_component(hass, DOMAIN, {})
await hass.async_block_till_done()
await setup_backup_integration(hass)
with pytest.raises(BackupManagerError) as err:
await hass.services.async_call(
@ -1645,8 +1532,7 @@ async def test_exception_platform_post(hass: HomeAssistant) -> None:
async_get_backup_agents=AsyncMock(return_value=[remote_agent]),
),
)
assert await async_setup_component(hass, DOMAIN, {})
await hass.async_block_till_done()
await setup_backup_integration(hass)
with pytest.raises(BackupManagerError) as err:
await hass.services.async_call(
@ -1710,17 +1596,7 @@ async def test_receive_backup(
temp_file_unlink_call_count: int,
) -> None:
"""Test receive backup and upload to the local and a remote agent."""
remote_agent = mock_backup_agent("remote")
await setup_backup_platform(
hass,
domain="test",
platform=Mock(
async_get_backup_agents=AsyncMock(return_value=[remote_agent]),
spec_set=BackupAgentPlatformProtocol,
),
)
assert await async_setup_component(hass, DOMAIN, {})
await hass.async_block_till_done()
mock_agents = await setup_backup_integration(hass, remote_agents=["test.remote"])
client = await hass_client()
upload_data = "test"
@ -1750,6 +1626,7 @@ async def test_receive_backup(
assert move_mock.call_count == move_call_count
for index, name in enumerate(move_path_names):
assert move_mock.call_args_list[index].args[1].name == name
remote_agent = mock_agents["test.remote"]
for backup_id, (backup, expected_backup_data) in remote_agent_backups.items():
assert await remote_agent.async_get_backup(backup_id) == backup
backup_data = bytearray()
@ -1770,8 +1647,7 @@ async def test_receive_backup_busy_manager(
new_backup = NewBackup(backup_job_id="time-123")
backup_task: asyncio.Future[WrittenBackup] = asyncio.Future()
create_backup.return_value = (new_backup, backup_task)
assert await async_setup_component(hass, DOMAIN, {})
await hass.async_block_till_done()
await setup_backup_integration(hass)
client = await hass_client()
ws_client = await hass_ws_client(hass)
@ -1833,7 +1709,6 @@ async def test_receive_backup_agent_error(
exception: Exception,
) -> None:
"""Test upload error during backup receive."""
local_agent = local_backup_platform.CoreLocalBackupAgent(hass)
backup_1 = replace(TEST_BACKUP_ABC123, backup_id="backup1") # matching instance id
backup_2 = replace(TEST_BACKUP_DEF456, backup_id="backup2") # other instance id
backup_3 = replace(TEST_BACKUP_ABC123, backup_id="backup3") # matching instance id
@ -1911,22 +1786,12 @@ async def test_receive_backup_agent_error(
"with_automatic_settings": True,
},
]
remote_agent = mock_backup_agent("remote", backups=[backup_1, backup_2, backup_3])
with patch(
"homeassistant.components.backup.backup.async_get_backup_agents"
) as core_get_backup_agents:
core_get_backup_agents.return_value = [local_agent]
await async_setup_component(hass, DOMAIN, {})
await hass.async_block_till_done()
await setup_backup_platform(
hass,
domain="test",
platform=Mock(
async_get_backup_agents=AsyncMock(return_value=[remote_agent]),
spec_set=BackupAgentPlatformProtocol,
),
)
mock_agents = await setup_backup_integration(
hass,
remote_agents=["test.remote"],
backups={"test.remote": [backup_1, backup_2, backup_3]},
)
client = await hass_client()
ws_client = await hass_ws_client(hass)
@ -1962,13 +1827,11 @@ async def test_receive_backup_agent_error(
result = await ws_client.receive_json()
assert result["success"] is True
delete_backup = AsyncMock()
upload_data = "test"
open_mock = mock_open(read_data=upload_data.encode(encoding="utf-8"))
mock_agents["test.remote"].async_upload_backup.side_effect = exception
with (
patch.object(remote_agent, "async_delete_backup", delete_backup),
patch.object(remote_agent, "async_upload_backup", side_effect=exception),
patch("pathlib.Path.open", open_mock),
patch("shutil.move") as move_mock,
patch(
@ -2050,7 +1913,7 @@ async def test_receive_backup_agent_error(
assert open_mock.call_count == 1
assert move_mock.call_count == 0
assert unlink_mock.call_count == 1
assert delete_backup.call_count == 0
assert mock_agents["test.remote"].async_delete_backup.call_count == 0
@pytest.mark.usefixtures("mock_backup_generation")
@ -2064,23 +1927,7 @@ async def test_receive_backup_non_agent_upload_error(
exception: Exception,
) -> None:
"""Test non agent upload error during backup receive."""
local_agent = local_backup_platform.CoreLocalBackupAgent(hass)
remote_agent = mock_backup_agent("remote")
with patch(
"homeassistant.components.backup.backup.async_get_backup_agents"
) as core_get_backup_agents:
core_get_backup_agents.return_value = [local_agent]
await async_setup_component(hass, DOMAIN, {})
await hass.async_block_till_done()
await setup_backup_platform(
hass,
domain="test",
platform=Mock(
async_get_backup_agents=AsyncMock(return_value=[remote_agent]),
spec_set=BackupAgentPlatformProtocol,
),
)
mock_agents = await setup_backup_integration(hass, remote_agents=["test.remote"])
client = await hass_client()
ws_client = await hass_ws_client(hass)
@ -2113,8 +1960,8 @@ async def test_receive_backup_non_agent_upload_error(
upload_data = "test"
open_mock = mock_open(read_data=upload_data.encode(encoding="utf-8"))
mock_agents["test.remote"].async_upload_backup.side_effect = exception
with (
patch.object(remote_agent, "async_upload_backup", side_effect=exception),
patch("pathlib.Path.open", open_mock),
patch("shutil.move") as move_mock,
patch(
@ -2192,22 +2039,7 @@ async def test_receive_backup_file_write_error(
close_exception: Exception | None,
) -> None:
"""Test file write error during backup receive."""
local_agent = local_backup_platform.CoreLocalBackupAgent(hass)
remote_agent = mock_backup_agent("remote")
with patch(
"homeassistant.components.backup.backup.async_get_backup_agents"
) as core_get_backup_agents:
core_get_backup_agents.return_value = [local_agent]
await async_setup_component(hass, DOMAIN, {})
await hass.async_block_till_done()
await setup_backup_platform(
hass,
domain="test",
platform=Mock(
async_get_backup_agents=AsyncMock(return_value=[remote_agent]),
spec_set=BackupAgentPlatformProtocol,
),
)
await setup_backup_integration(hass, remote_agents=["test.remote"])
client = await hass_client()
ws_client = await hass_ws_client(hass)
@ -2303,22 +2135,7 @@ async def test_receive_backup_read_tar_error(
exception: Exception,
) -> None:
"""Test read tar error during backup receive."""
local_agent = local_backup_platform.CoreLocalBackupAgent(hass)
remote_agent = mock_backup_agent("remote")
with patch(
"homeassistant.components.backup.backup.async_get_backup_agents"
) as core_get_backup_agents:
core_get_backup_agents.return_value = [local_agent]
await async_setup_component(hass, DOMAIN, {})
await hass.async_block_till_done()
await setup_backup_platform(
hass,
domain="test",
platform=Mock(
async_get_backup_agents=AsyncMock(return_value=[remote_agent]),
spec_set=BackupAgentPlatformProtocol,
),
)
await setup_backup_integration(hass, remote_agents=["test.remote"])
client = await hass_client()
ws_client = await hass_ws_client(hass)
@ -2483,23 +2300,7 @@ async def test_receive_backup_file_read_error(
response_status: int,
) -> None:
"""Test file read error during backup receive."""
local_agent = local_backup_platform.CoreLocalBackupAgent(hass)
remote_agent = mock_backup_agent("remote")
with patch(
"homeassistant.components.backup.backup.async_get_backup_agents"
) as core_get_backup_agents:
core_get_backup_agents.return_value = [local_agent]
await async_setup_component(hass, DOMAIN, {})
await hass.async_block_till_done()
await setup_backup_platform(
hass,
domain="test",
platform=Mock(
async_get_backup_agents=AsyncMock(return_value=[remote_agent]),
spec_set=BackupAgentPlatformProtocol,
),
)
await setup_backup_integration(hass, remote_agents=["test.remote"])
client = await hass_client()
ws_client = await hass_ws_client(hass)
@ -2655,16 +2456,10 @@ async def test_restore_backup(
) -> None:
"""Test restore backup."""
password = password_param.get("password")
remote_agent = mock_backup_agent("remote", backups=[TEST_BACKUP_ABC123])
await async_setup_component(hass, DOMAIN, {})
await hass.async_block_till_done()
await setup_backup_platform(
await setup_backup_integration(
hass,
domain="test",
platform=Mock(
async_get_backup_agents=AsyncMock(return_value=[remote_agent]),
spec_set=BackupAgentPlatformProtocol,
),
remote_agents=["test.remote"],
backups={"test.remote": [TEST_BACKUP_ABC123]},
)
ws_client = await hass_ws_client(hass)
@ -2685,13 +2480,11 @@ async def test_restore_backup(
patch(
"homeassistant.components.backup.manager.validate_password"
) as validate_password_mock,
patch.object(remote_agent, "async_download_backup") as download_mock,
patch(
"homeassistant.components.backup.backup.read_backup",
side_effect=mock_read_backup,
),
):
download_mock.return_value.__aiter__.return_value = iter((b"backup data",))
await ws_client.send_json_auto_id(
{
"type": "backup/restore",
@ -2762,16 +2555,10 @@ async def test_restore_backup_wrong_password(
) -> None:
"""Test restore backup wrong password."""
password = "hunter2"
remote_agent = mock_backup_agent("remote", backups=[TEST_BACKUP_ABC123])
await async_setup_component(hass, DOMAIN, {})
await hass.async_block_till_done()
await setup_backup_platform(
await setup_backup_integration(
hass,
domain="test",
platform=Mock(
async_get_backup_agents=AsyncMock(return_value=[remote_agent]),
spec_set=BackupAgentPlatformProtocol,
),
remote_agents=["test.remote"],
backups={"test.remote": [TEST_BACKUP_ABC123]},
)
ws_client = await hass_ws_client(hass)
@ -2792,13 +2579,11 @@ async def test_restore_backup_wrong_password(
patch(
"homeassistant.components.backup.manager.validate_password"
) as validate_password_mock,
patch.object(remote_agent, "async_download_backup") as download_mock,
patch(
"homeassistant.components.backup.backup.read_backup",
side_effect=mock_read_backup,
),
):
download_mock.return_value.__aiter__.return_value = iter((b"backup data",))
validate_password_mock.return_value = False
await ws_client.send_json_auto_id(
{
@ -2872,8 +2657,7 @@ async def test_restore_backup_wrong_parameters(
expected_reason: str,
) -> None:
"""Test restore backup wrong parameters."""
await async_setup_component(hass, DOMAIN, {})
await hass.async_block_till_done()
await setup_backup_integration(hass)
ws_client = await hass_ws_client(hass)
@ -2937,8 +2721,7 @@ async def test_restore_backup_when_busy(
hass_ws_client: WebSocketGenerator,
) -> None:
"""Test restore backup with busy manager."""
assert await async_setup_component(hass, DOMAIN, {})
await hass.async_block_till_done()
await setup_backup_integration(hass)
ws_client = await hass_ws_client(hass)
await ws_client.send_json_auto_id(
@ -2989,16 +2772,10 @@ async def test_restore_backup_agent_error(
expected_reason: str,
) -> None:
"""Test restore backup with agent error."""
remote_agent = mock_backup_agent("remote", backups=[TEST_BACKUP_ABC123])
await async_setup_component(hass, DOMAIN, {})
await hass.async_block_till_done()
await setup_backup_platform(
mock_agents = await setup_backup_integration(
hass,
domain="test",
platform=Mock(
async_get_backup_agents=AsyncMock(return_value=[remote_agent]),
spec_set=BackupAgentPlatformProtocol,
),
remote_agents=["test.remote"],
backups={"test.remote": [TEST_BACKUP_ABC123]},
)
ws_client = await hass_ws_client(hass)
@ -3010,19 +2787,17 @@ async def test_restore_backup_agent_error(
result = await ws_client.receive_json()
assert result["success"] is True
mock_agents["test.remote"].async_download_backup.side_effect = exception
with (
patch("pathlib.Path.open"),
patch("pathlib.Path.write_text") as mocked_write_text,
patch("homeassistant.core.ServiceRegistry.async_call") as mocked_service_call,
patch.object(
remote_agent, "async_download_backup", side_effect=exception
) as download_mock,
):
await ws_client.send_json_auto_id(
{
"type": "backup/restore",
"backup_id": TEST_BACKUP_ABC123.backup_id,
"agent_id": remote_agent.agent_id,
"agent_id": "test.remote",
}
)
@ -3050,7 +2825,7 @@ async def test_restore_backup_agent_error(
assert result["error"]["code"] == error_code
assert result["error"]["message"] == error_message
assert download_mock.call_count == 1
assert mock_agents["test.remote"].async_download_backup.call_count == 1
assert mocked_write_text.call_count == 0
assert mocked_service_call.call_count == 0
@ -3129,16 +2904,10 @@ async def test_restore_backup_file_error(
validate_password_call_count: int,
) -> None:
"""Test restore backup with file error."""
remote_agent = mock_backup_agent("remote", backups=[TEST_BACKUP_ABC123])
await async_setup_component(hass, DOMAIN, {})
await hass.async_block_till_done()
await setup_backup_platform(
mock_agents = await setup_backup_integration(
hass,
domain="test",
platform=Mock(
async_get_backup_agents=AsyncMock(return_value=[remote_agent]),
spec_set=BackupAgentPlatformProtocol,
),
remote_agents=["test.remote"],
backups={"test.remote": [TEST_BACKUP_ABC123]},
)
ws_client = await hass_ws_client(hass)
@ -3164,14 +2933,12 @@ async def test_restore_backup_file_error(
patch(
"homeassistant.components.backup.manager.validate_password"
) as validate_password_mock,
patch.object(remote_agent, "async_download_backup") as download_mock,
):
download_mock.return_value.__aiter__.return_value = iter((b"backup data",))
await ws_client.send_json_auto_id(
{
"type": "backup/restore",
"backup_id": TEST_BACKUP_ABC123.backup_id,
"agent_id": remote_agent.agent_id,
"agent_id": "test.remote",
}
)
@ -3199,7 +2966,7 @@ async def test_restore_backup_file_error(
assert result["error"]["code"] == "unknown_error"
assert result["error"]["message"] == "Unknown error"
assert download_mock.call_count == 1
assert mock_agents["test.remote"].async_download_backup.call_count == 1
assert validate_password_mock.call_count == validate_password_call_count
assert open_mock.call_count == open_call_count
assert open_mock.return_value.write.call_count == write_call_count
@ -3346,23 +3113,7 @@ async def test_initiate_backup_per_agent_encryption(
inner_tar_key: bytes | None,
) -> None:
"""Test generate backup where encryption is selectively set on agents."""
local_agent = local_backup_platform.CoreLocalBackupAgent(hass)
remote_agent = mock_backup_agent("remote")
with patch(
"homeassistant.components.backup.backup.async_get_backup_agents"
) as core_get_backup_agents:
core_get_backup_agents.return_value = [local_agent]
await async_setup_component(hass, DOMAIN, {})
await hass.async_block_till_done()
await setup_backup_platform(
hass,
domain="test",
platform=Mock(
async_get_backup_agents=AsyncMock(return_value=[remote_agent]),
spec_set=BackupAgentPlatformProtocol,
),
)
await setup_backup_integration(hass, remote_agents=["test.remote"])
ws_client = await hass_ws_client(hass)
@ -3512,8 +3263,7 @@ async def test_restore_progress_after_restart(
with patch(
"pathlib.Path.read_bytes", return_value=json.dumps(restore_result).encode()
):
await async_setup_component(hass, DOMAIN, {})
await hass.async_block_till_done()
await setup_backup_integration(hass)
ws_client = await hass_ws_client(hass)
await ws_client.send_json_auto_id({"type": "backup/info"})
@ -3539,8 +3289,7 @@ async def test_restore_progress_after_restart_fail_to_remove(
"""Test restore backup progress after restart when failing to remove result file."""
with patch("pathlib.Path.unlink", side_effect=OSError("Boom!")):
await async_setup_component(hass, DOMAIN, {})
await hass.async_block_till_done()
await setup_backup_integration(hass)
ws_client = await hass_ws_client(hass)
await ws_client.send_json_auto_id({"type": "backup/info"})

View File

@ -11,7 +11,6 @@ from syrupy import SnapshotAssertion
from homeassistant.components.backup import (
AgentBackup,
BackupAgentError,
BackupAgentPlatformProtocol,
BackupNotFound,
BackupReaderWriterError,
Folder,
@ -28,15 +27,12 @@ from homeassistant.components.backup.manager import (
)
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
from homeassistant.setup import async_setup_component
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
@ -150,12 +146,13 @@ async def test_info_with_errors(
snapshot: SnapshotAssertion,
) -> None:
"""Test getting backup info with one unavailable agent."""
await setup_backup_integration(
hass, with_hassio=False, backups={LOCAL_AGENT_ID: [TEST_BACKUP_ABC123]}
mock_agents = await setup_backup_integration(
hass,
with_hassio=False,
backups={LOCAL_AGENT_ID: [TEST_BACKUP_ABC123]},
remote_agents=["test.remote"],
)
mock_agent = mock_backup_agent("test")
mock_agent.async_list_backups.side_effect = side_effect
hass.data[DATA_MANAGER].backup_agents["domain.test"] = mock_agent
mock_agents["test.remote"].async_list_backups.side_effect = side_effect
client = await hass_ws_client(hass)
await hass.async_block_till_done()
@ -213,12 +210,13 @@ async def test_details_with_errors(
snapshot: SnapshotAssertion,
) -> None:
"""Test getting backup info with one unavailable agent."""
await setup_backup_integration(
hass, with_hassio=False, backups={LOCAL_AGENT_ID: [TEST_BACKUP_ABC123]}
mock_agents = await setup_backup_integration(
hass,
with_hassio=False,
backups={LOCAL_AGENT_ID: [TEST_BACKUP_ABC123]},
remote_agents=["test.remote"],
)
mock_agent = mock_backup_agent("test")
mock_agent.async_get_backup.side_effect = side_effect
hass.data[DATA_MANAGER].backup_agents["domain.test"] = mock_agent
mock_agents["test.remote"].async_get_backup.side_effect = side_effect
client = await hass_ws_client(hass)
await hass.async_block_till_done()
@ -304,12 +302,16 @@ async def test_delete_with_errors(
"version": store.STORAGE_VERSION,
"minor_version": store.STORAGE_VERSION_MINOR,
}
await setup_backup_integration(
hass, with_hassio=False, backups={LOCAL_AGENT_ID: [TEST_BACKUP_ABC123]}
mock_agents = await setup_backup_integration(
hass,
with_hassio=False,
backups={
LOCAL_AGENT_ID: [TEST_BACKUP_ABC123],
"test.remote": [TEST_BACKUP_ABC123],
},
remote_agents=["test.remote"],
)
mock_agent = mock_backup_agent("test", [TEST_BACKUP_ABC123])
mock_agent.async_delete_backup.side_effect = side_effect
hass.data[DATA_MANAGER].backup_agents["domain.test"] = mock_agent
mock_agents["test.remote"].async_delete_backup.side_effect = side_effect
client = await hass_ws_client(hass)
await hass.async_block_till_done()
@ -327,9 +329,9 @@ async def test_agent_delete_backup(
snapshot: SnapshotAssertion,
) -> None:
"""Test deleting a backup file with a mock agent."""
await setup_backup_integration(hass)
mock_agent = mock_backup_agent("test")
hass.data[DATA_MANAGER].backup_agents = {"domain.test": mock_agent}
mock_agents = await setup_backup_integration(
hass, with_hassio=False, remote_agents=["test.remote"]
)
client = await hass_ws_client(hass)
await hass.async_block_till_done()
@ -342,7 +344,7 @@ async def test_agent_delete_backup(
)
assert await client.receive_json() == snapshot
assert mock_agent.async_delete_backup.call_args == call("abc123")
assert mock_agents["test.remote"].async_delete_backup.call_args == call("abc123")
@pytest.mark.parametrize(
@ -589,17 +591,9 @@ async def test_generate_with_default_settings_calls_create(
client = await hass_ws_client(hass)
await hass.config.async_set_time_zone("Europe/Amsterdam")
freezer.move_to("2024-11-13T12:01:00+01:00")
remote_agent = mock_backup_agent("remote")
await setup_backup_platform(
hass,
domain="test",
platform=Mock(
async_get_backup_agents=AsyncMock(return_value=[remote_agent]),
spec_set=BackupAgentPlatformProtocol,
),
mock_agents = await setup_backup_integration(
hass, with_hassio=False, remote_agents=["test.remote"]
)
await async_setup_component(hass, DOMAIN, {})
await hass.async_block_till_done()
await client.send_json_auto_id(
{"type": "backup/config/update", "create_backup": create_backup_settings}
@ -624,15 +618,13 @@ async def test_generate_with_default_settings_calls_create(
is None
)
with patch.object(remote_agent, "async_upload_backup", side_effect=side_effect):
await client.send_json_auto_id(
{"type": "backup/generate_with_automatic_settings"}
)
result = await client.receive_json()
assert result["success"]
assert result["result"] == {"backup_job_id": "abc123"}
mock_agents["test.remote"].async_upload_backup.side_effect = side_effect
await client.send_json_auto_id({"type": "backup/generate_with_automatic_settings"})
result = await client.receive_json()
assert result["success"]
assert result["result"] == {"backup_job_id": "abc123"}
await hass.async_block_till_done()
await hass.async_block_till_done()
create_backup.assert_called_once_with(**expected_call_params)
@ -893,8 +885,9 @@ async def test_agents_info(
snapshot: SnapshotAssertion,
) -> None:
"""Test getting backup agents info."""
await setup_backup_integration(hass, with_hassio=False)
hass.data[DATA_MANAGER].backup_agents["domain.test"] = mock_backup_agent("test")
await setup_backup_integration(
hass, with_hassio=False, remote_agents=["test.remote"]
)
client = await hass_ws_client(hass)
await hass.async_block_till_done()