mirror of
https://github.com/home-assistant/core.git
synced 2025-04-23 16:57:53 +00:00
Ensure restore state is not written after the stop event (#49329)
If everything lined up, the states could be written while Home Assistant is shutting down after the stop event because the interval tracker was not canceled on the stop event.
This commit is contained in:
parent
41ed1f818c
commit
f96a6e878f
@ -177,10 +177,18 @@ class RestoreStateData:
|
||||
self.hass.async_create_task(_async_dump_states())
|
||||
|
||||
# Dump states periodically
|
||||
async_track_time_interval(self.hass, _async_dump_states, STATE_DUMP_INTERVAL)
|
||||
cancel_interval = async_track_time_interval(
|
||||
self.hass, _async_dump_states, STATE_DUMP_INTERVAL
|
||||
)
|
||||
|
||||
async def _async_dump_states_at_stop(*_: Any) -> None:
|
||||
cancel_interval()
|
||||
await self.async_dump_states()
|
||||
|
||||
# Dump states when stopping hass
|
||||
self.hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, _async_dump_states)
|
||||
self.hass.bus.async_listen_once(
|
||||
EVENT_HOMEASSISTANT_STOP, _async_dump_states_at_stop
|
||||
)
|
||||
|
||||
@callback
|
||||
def async_restore_entity_added(self, entity_id: str) -> None:
|
||||
|
@ -1,8 +1,8 @@
|
||||
"""The tests for the Restore component."""
|
||||
from datetime import datetime
|
||||
from datetime import datetime, timedelta
|
||||
from unittest.mock import patch
|
||||
|
||||
from homeassistant.const import EVENT_HOMEASSISTANT_START
|
||||
from homeassistant.const import EVENT_HOMEASSISTANT_START, EVENT_HOMEASSISTANT_STOP
|
||||
from homeassistant.core import CoreState, State
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
from homeassistant.helpers.entity import Entity
|
||||
@ -15,6 +15,8 @@ from homeassistant.helpers.restore_state import (
|
||||
)
|
||||
from homeassistant.util import dt as dt_util
|
||||
|
||||
from tests.common import async_fire_time_changed
|
||||
|
||||
|
||||
async def test_caching_data(hass):
|
||||
"""Test that we cache data."""
|
||||
@ -50,6 +52,52 @@ async def test_caching_data(hass):
|
||||
assert mock_write_data.called
|
||||
|
||||
|
||||
async def test_periodic_write(hass):
|
||||
"""Test that we write periodiclly but not after stop."""
|
||||
data = await RestoreStateData.async_get_instance(hass)
|
||||
await hass.async_block_till_done()
|
||||
await data.store.async_save([])
|
||||
|
||||
# Emulate a fresh load
|
||||
hass.data[DATA_RESTORE_STATE_TASK] = None
|
||||
|
||||
entity = RestoreEntity()
|
||||
entity.hass = hass
|
||||
entity.entity_id = "input_boolean.b1"
|
||||
|
||||
with patch(
|
||||
"homeassistant.helpers.restore_state.Store.async_save"
|
||||
) as mock_write_data:
|
||||
await entity.async_get_last_state()
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert mock_write_data.called
|
||||
|
||||
with patch(
|
||||
"homeassistant.helpers.restore_state.Store.async_save"
|
||||
) as mock_write_data:
|
||||
async_fire_time_changed(hass, dt_util.utcnow() + timedelta(minutes=15))
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert mock_write_data.called
|
||||
|
||||
with patch(
|
||||
"homeassistant.helpers.restore_state.Store.async_save"
|
||||
) as mock_write_data:
|
||||
hass.bus.async_fire(EVENT_HOMEASSISTANT_STOP)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert mock_write_data.called
|
||||
|
||||
with patch(
|
||||
"homeassistant.helpers.restore_state.Store.async_save"
|
||||
) as mock_write_data:
|
||||
async_fire_time_changed(hass, dt_util.utcnow() + timedelta(minutes=30))
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert not mock_write_data.called
|
||||
|
||||
|
||||
async def test_hass_starting(hass):
|
||||
"""Test that we cache data."""
|
||||
hass.state = CoreState.starting
|
||||
|
Loading…
x
Reference in New Issue
Block a user