Fix recorder setup hanging if non live schema migration fails (#122207)
This commit is contained in:
parent
d1d2ce1270
commit
153b69c971
3 changed files with 37 additions and 7 deletions
|
@ -773,6 +773,7 @@ class Recorder(threading.Thread):
|
|||
"Database Migration Failed",
|
||||
"recorder_database_migration",
|
||||
)
|
||||
self.hass.add_job(self._async_startup_failed)
|
||||
return
|
||||
|
||||
if not database_was_ready:
|
||||
|
|
|
@ -200,8 +200,14 @@ async def test_database_migration_encounters_corruption(
|
|||
assert move_away.called
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("live_migration", "expected_setup_result"), [(True, True), (False, False)]
|
||||
)
|
||||
async def test_database_migration_encounters_corruption_not_sqlite(
|
||||
hass: HomeAssistant, async_setup_recorder_instance: RecorderInstanceGenerator
|
||||
hass: HomeAssistant,
|
||||
async_setup_recorder_instance: RecorderInstanceGenerator,
|
||||
live_migration: bool,
|
||||
expected_setup_result: bool,
|
||||
) -> None:
|
||||
"""Test we fail on database error when we cannot recover."""
|
||||
assert recorder.util.async_migration_in_progress(hass) is False
|
||||
|
@ -226,8 +232,14 @@ async def test_database_migration_encounters_corruption_not_sqlite(
|
|||
"homeassistant.components.persistent_notification.dismiss",
|
||||
side_effect=pn.dismiss,
|
||||
) as mock_dismiss,
|
||||
patch(
|
||||
"homeassistant.components.recorder.core.migration.live_migration",
|
||||
return_value=live_migration,
|
||||
),
|
||||
):
|
||||
await async_setup_recorder_instance(hass, wait_recorder=False)
|
||||
await async_setup_recorder_instance(
|
||||
hass, wait_recorder=False, expected_setup_result=expected_setup_result
|
||||
)
|
||||
hass.states.async_set("my.entity", "on", {})
|
||||
hass.states.async_set("my.entity", "off", {})
|
||||
await hass.async_block_till_done()
|
||||
|
|
|
@ -1394,6 +1394,8 @@ async def _async_init_recorder_component(
|
|||
hass: HomeAssistant,
|
||||
add_config: dict[str, Any] | None = None,
|
||||
db_url: str | None = None,
|
||||
*,
|
||||
expected_setup_result: bool,
|
||||
) -> None:
|
||||
"""Initialize the recorder asynchronously."""
|
||||
# pylint: disable-next=import-outside-toplevel
|
||||
|
@ -1408,10 +1410,13 @@ async def _async_init_recorder_component(
|
|||
with patch("homeassistant.components.recorder.ALLOW_IN_MEMORY_DB", True):
|
||||
if recorder.DOMAIN not in hass.data:
|
||||
recorder_helper.async_initialize_recorder(hass)
|
||||
assert await async_setup_component(
|
||||
hass, recorder.DOMAIN, {recorder.DOMAIN: config}
|
||||
setup_task = asyncio.ensure_future(
|
||||
async_setup_component(hass, recorder.DOMAIN, {recorder.DOMAIN: config})
|
||||
)
|
||||
assert recorder.DOMAIN in hass.config.components
|
||||
# Wait for recorder integration to setup
|
||||
setup_result = await setup_task
|
||||
assert setup_result == expected_setup_result
|
||||
assert (recorder.DOMAIN in hass.config.components) == expected_setup_result
|
||||
_LOGGER.info(
|
||||
"Test recorder successfully started, database location: %s",
|
||||
config[recorder.CONF_DB_URL],
|
||||
|
@ -1527,10 +1532,16 @@ async def async_test_recorder(
|
|||
hass: HomeAssistant,
|
||||
config: ConfigType | None = None,
|
||||
*,
|
||||
expected_setup_result: bool = True,
|
||||
wait_recorder: bool = True,
|
||||
) -> AsyncGenerator[recorder.Recorder]:
|
||||
"""Setup and return recorder instance.""" # noqa: D401
|
||||
await _async_init_recorder_component(hass, config, recorder_db_url)
|
||||
await _async_init_recorder_component(
|
||||
hass,
|
||||
config,
|
||||
recorder_db_url,
|
||||
expected_setup_result=expected_setup_result,
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
instance = hass.data[recorder.DATA_INSTANCE]
|
||||
# The recorder's worker is not started until Home Assistant is running
|
||||
|
@ -1557,12 +1568,18 @@ async def async_setup_recorder_instance(
|
|||
hass: HomeAssistant,
|
||||
config: ConfigType | None = None,
|
||||
*,
|
||||
expected_setup_result: bool = True,
|
||||
wait_recorder: bool = True,
|
||||
) -> AsyncGenerator[recorder.Recorder]:
|
||||
"""Set up and return recorder instance."""
|
||||
|
||||
return await stack.enter_async_context(
|
||||
async_test_recorder(hass, config, wait_recorder=wait_recorder)
|
||||
async_test_recorder(
|
||||
hass,
|
||||
config,
|
||||
expected_setup_result=expected_setup_result,
|
||||
wait_recorder=wait_recorder,
|
||||
)
|
||||
)
|
||||
|
||||
yield async_setup_recorder
|
||||
|
|
Loading…
Add table
Reference in a new issue