Fail recorder.backup.async_pre_backup if Home Assistant is not running (#139491)

Fail recorder.backup.async_pre_backup if hass is not running
pull/139859/head
Erik Montnemery 2025-02-28 11:44:16 +01:00 committed by Bram Kragten
parent 6de878ffe4
commit fdb4c0a81f
2 changed files with 40 additions and 2 deletions

View File

@ -2,7 +2,7 @@
from logging import getLogger
from homeassistant.core import HomeAssistant
from homeassistant.core import CoreState, HomeAssistant
from homeassistant.exceptions import HomeAssistantError
from .util import async_migration_in_progress, get_instance
@ -14,6 +14,8 @@ async def async_pre_backup(hass: HomeAssistant) -> None:
"""Perform operations before a backup starts."""
_LOGGER.info("Backup start notification, locking database for writes")
instance = get_instance(hass)
if hass.state is not CoreState.running:
raise HomeAssistantError("Home Assistant is not running")
if async_migration_in_progress(hass):
raise HomeAssistantError("Database migration in progress")
await instance.lock_database()

View File

@ -1,12 +1,13 @@
"""Test backup platform for the Recorder integration."""
from contextlib import AbstractContextManager, nullcontext as does_not_raise
from unittest.mock import patch
import pytest
from homeassistant.components.recorder import Recorder
from homeassistant.components.recorder.backup import async_post_backup, async_pre_backup
from homeassistant.core import HomeAssistant
from homeassistant.core import CoreState, HomeAssistant
from homeassistant.exceptions import HomeAssistantError
@ -19,6 +20,41 @@ async def test_async_pre_backup(recorder_mock: Recorder, hass: HomeAssistant) ->
assert lock_mock.called
RAISES_HASS_NOT_RUNNING = pytest.raises(
HomeAssistantError, match="Home Assistant is not running"
)
@pytest.mark.parametrize(
("core_state", "expected_result", "lock_calls"),
[
(CoreState.final_write, RAISES_HASS_NOT_RUNNING, 0),
(CoreState.not_running, RAISES_HASS_NOT_RUNNING, 0),
(CoreState.running, does_not_raise(), 1),
(CoreState.starting, RAISES_HASS_NOT_RUNNING, 0),
(CoreState.stopped, RAISES_HASS_NOT_RUNNING, 0),
(CoreState.stopping, RAISES_HASS_NOT_RUNNING, 0),
],
)
async def test_async_pre_backup_core_state(
recorder_mock: Recorder,
hass: HomeAssistant,
core_state: CoreState,
expected_result: AbstractContextManager,
lock_calls: int,
) -> None:
"""Test pre backup in different core states."""
hass.set_state(core_state)
with ( # pylint: disable=confusing-with-statement
patch(
"homeassistant.components.recorder.core.Recorder.lock_database"
) as lock_mock,
expected_result,
):
await async_pre_backup(hass)
assert len(lock_mock.mock_calls) == lock_calls
async def test_async_pre_backup_with_timeout(
recorder_mock: Recorder, hass: HomeAssistant
) -> None: