Prepare backup store to read version 2 (#136149)

This commit is contained in:
Erik Montnemery 2025-01-21 14:37:44 +01:00 committed by GitHub
parent 5b49ba563e
commit a2cbaef264
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 234 additions and 35 deletions

View File

@ -102,7 +102,7 @@ class BackupConfigData:
schedule=BackupSchedule( schedule=BackupSchedule(
days=days, days=days,
recurrence=ScheduleRecurrence(data["schedule"]["recurrence"]), recurrence=ScheduleRecurrence(data["schedule"]["recurrence"]),
state=ScheduleState(data["schedule"]["state"]), state=ScheduleState(data["schedule"].get("state", ScheduleState.NEVER)),
time=time, time=time,
), ),
) )

View File

@ -57,7 +57,9 @@ class _BackupStore(Store[StoredBackupData]):
data["config"]["schedule"]["days"] = [state] data["config"]["schedule"]["days"] = [state]
data["config"]["schedule"]["recurrence"] = "custom_days" data["config"]["schedule"]["recurrence"] = "custom_days"
if old_major_version > 1: # Note: We allow reading data with major version 2.
# Reject if major version is higher than 2.
if old_major_version > 2:
raise NotImplementedError raise NotImplementedError
return data return data

View File

@ -1,5 +1,5 @@
# serializer version: 1 # serializer version: 1
# name: test_store_migration # name: test_store_migration[store_data0]
dict({ dict({
'data': dict({ 'data': dict({
'backups': list([ 'backups': list([
@ -41,3 +41,131 @@
'version': 1, 'version': 1,
}) })
# --- # ---
# name: test_store_migration[store_data0].1
dict({
'data': dict({
'backups': list([
dict({
'backup_id': 'abc123',
'failed_agent_ids': list([
'test.remote',
]),
}),
]),
'config': dict({
'create_backup': dict({
'agent_ids': list([
'test-agent',
]),
'include_addons': None,
'include_all_addons': False,
'include_database': True,
'include_folders': None,
'name': None,
'password': None,
}),
'last_attempted_automatic_backup': None,
'last_completed_automatic_backup': None,
'retention': dict({
'copies': None,
'days': None,
}),
'schedule': dict({
'days': list([
]),
'recurrence': 'never',
'state': 'never',
'time': None,
}),
}),
}),
'key': 'backup',
'minor_version': 2,
'version': 1,
})
# ---
# name: test_store_migration[store_data1]
dict({
'data': dict({
'backups': list([
dict({
'backup_id': 'abc123',
'failed_agent_ids': list([
'test.remote',
]),
}),
]),
'config': dict({
'create_backup': dict({
'agent_ids': list([
]),
'include_addons': None,
'include_all_addons': False,
'include_database': True,
'include_folders': None,
'name': None,
'password': None,
}),
'last_attempted_automatic_backup': None,
'last_completed_automatic_backup': None,
'retention': dict({
'copies': None,
'days': None,
}),
'schedule': dict({
'days': list([
]),
'recurrence': 'never',
'time': None,
}),
'something_from_the_future': 'value',
}),
}),
'key': 'backup',
'minor_version': 2,
'version': 1,
})
# ---
# name: test_store_migration[store_data1].1
dict({
'data': dict({
'backups': list([
dict({
'backup_id': 'abc123',
'failed_agent_ids': list([
'test.remote',
]),
}),
]),
'config': dict({
'create_backup': dict({
'agent_ids': list([
'test-agent',
]),
'include_addons': None,
'include_all_addons': False,
'include_database': True,
'include_folders': None,
'name': None,
'password': None,
}),
'last_attempted_automatic_backup': None,
'last_completed_automatic_backup': None,
'retention': dict({
'copies': None,
'days': None,
}),
'schedule': dict({
'days': list([
]),
'recurrence': 'never',
'state': 'never',
'time': None,
}),
}),
}),
'key': 'backup',
'minor_version': 2,
'version': 1,
})
# ---

View File

@ -1,7 +1,10 @@
"""Tests for the Backup integration.""" """Tests for the Backup integration."""
from collections.abc import Generator
from typing import Any from typing import Any
from unittest.mock import patch
import pytest
from syrupy import SnapshotAssertion from syrupy import SnapshotAssertion
from homeassistant.components.backup.const import DOMAIN from homeassistant.components.backup.const import DOMAIN
@ -9,46 +12,112 @@ from homeassistant.core import HomeAssistant
from .common import setup_backup_integration from .common import setup_backup_integration
from tests.typing import WebSocketGenerator
@pytest.fixture(autouse=True)
def mock_delay_save() -> Generator[None]:
"""Mock the delay save constant."""
with patch("homeassistant.components.backup.store.STORE_DELAY_SAVE", 0):
yield
@pytest.mark.parametrize(
"store_data",
[
{
"data": {
"backups": [
{
"backup_id": "abc123",
"failed_agent_ids": ["test.remote"],
}
],
"config": {
"create_backup": {
"agent_ids": [],
"include_addons": None,
"include_all_addons": False,
"include_database": True,
"include_folders": None,
"name": None,
"password": None,
},
"last_attempted_automatic_backup": None,
"last_completed_automatic_backup": None,
"retention": {
"copies": None,
"days": None,
},
"schedule": {
"state": "never",
},
},
},
"key": DOMAIN,
"version": 1,
},
{
"data": {
"backups": [
{
"backup_id": "abc123",
"failed_agent_ids": ["test.remote"],
}
],
"config": {
"create_backup": {
"agent_ids": [],
"include_addons": None,
"include_all_addons": False,
"include_database": True,
"include_folders": None,
"name": None,
"password": None,
},
"last_attempted_automatic_backup": None,
"last_completed_automatic_backup": None,
"retention": {
"copies": None,
"days": None,
},
"schedule": {
"days": [],
"recurrence": "never",
"time": None,
},
"something_from_the_future": "value",
},
},
"key": DOMAIN,
"version": 2,
},
],
)
async def test_store_migration( async def test_store_migration(
hass: HomeAssistant, hass: HomeAssistant,
hass_storage: dict[str, Any], hass_storage: dict[str, Any],
hass_ws_client: WebSocketGenerator,
snapshot: SnapshotAssertion, snapshot: SnapshotAssertion,
store_data: dict[str, Any],
) -> None: ) -> None:
"""Test migrating the backup store.""" """Test migrating the backup store."""
hass_storage[DOMAIN] = { hass_storage[DOMAIN] = store_data
"data": {
"backups": [
{
"backup_id": "abc123",
"failed_agent_ids": ["test.remote"],
}
],
"config": {
"create_backup": {
"agent_ids": [],
"include_addons": None,
"include_all_addons": False,
"include_database": True,
"include_folders": None,
"name": None,
"password": None,
},
"last_attempted_automatic_backup": None,
"last_completed_automatic_backup": None,
"retention": {
"copies": None,
"days": None,
},
"schedule": {
"state": "never",
},
},
},
"key": DOMAIN,
"version": 1,
}
await setup_backup_integration(hass) await setup_backup_integration(hass)
await hass.async_block_till_done() await hass.async_block_till_done()
# Check migrated data
assert hass_storage[DOMAIN] == snapshot
# Update settings, then check saved data
client = await hass_ws_client(hass)
await client.send_json_auto_id(
{
"type": "backup/config/update",
"create_backup": {"agent_ids": ["test-agent"]},
}
)
result = await client.receive_json()
assert result["success"]
await hass.async_block_till_done()
assert hass_storage[DOMAIN] == snapshot assert hass_storage[DOMAIN] == snapshot