Ensure recorder purge tests can handle multiple purge cycle (#47956)

Since a purge can generate another purge task, we now wait for
three recorder queue completions by default.
This commit is contained in:
J. Nick Koston 2021-03-15 08:19:19 -10:00 committed by GitHub
parent 9e05aa2d1f
commit 28c80c1133
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 39 additions and 14 deletions

View File

@ -8,6 +8,8 @@ from homeassistant.util import dt as dt_util
from tests.common import async_fire_time_changed, fire_time_changed from tests.common import async_fire_time_changed, fire_time_changed
DEFAULT_PURGE_TASKS = 3
def wait_recording_done(hass: HomeAssistantType) -> None: def wait_recording_done(hass: HomeAssistantType) -> None:
"""Block till recording is done.""" """Block till recording is done."""
@ -42,6 +44,22 @@ async def async_wait_recording_done(
await hass.async_block_till_done() await hass.async_block_till_done()
async def async_wait_purge_done(
hass: HomeAssistantType, instance: recorder.Recorder, max: int = None
) -> None:
"""Wait for max number of purge events.
Because a purge may insert another PurgeTask into
the queue after the WaitTask finishes, we need up to
a maximum number of WaitTasks that we will put into the
queue.
"""
if not max:
max = DEFAULT_PURGE_TASKS
for _ in range(max + 1):
await async_wait_recording_done(hass, instance)
@ha.callback @ha.callback
def async_trigger_db_commit(hass: HomeAssistantType) -> None: def async_trigger_db_commit(hass: HomeAssistantType) -> None:
"""Fore the recorder to commit. Async friendly.""" """Fore the recorder to commit. Async friendly."""

View File

@ -12,7 +12,11 @@ from homeassistant.const import EVENT_STATE_CHANGED
from homeassistant.helpers.typing import ConfigType, HomeAssistantType from homeassistant.helpers.typing import ConfigType, HomeAssistantType
from homeassistant.util import dt as dt_util from homeassistant.util import dt as dt_util
from .common import async_recorder_block_till_done, async_wait_recording_done from .common import (
async_recorder_block_till_done,
async_wait_purge_done,
async_wait_recording_done,
)
from .conftest import SetupRecorderInstanceT from .conftest import SetupRecorderInstanceT
@ -120,12 +124,15 @@ async def test_purge_method(
assert recorder_runs.count() == 7 assert recorder_runs.count() == 7
runs_before_purge = recorder_runs.all() runs_before_purge = recorder_runs.all()
await hass.async_block_till_done()
await async_wait_purge_done(hass, instance)
# run purge method - no service data, use defaults # run purge method - no service data, use defaults
await hass.services.async_call("recorder", "purge") await hass.services.async_call("recorder", "purge")
await hass.async_block_till_done() await hass.async_block_till_done()
# Small wait for recorder thread # Small wait for recorder thread
await async_wait_recording_done(hass, instance) await async_wait_purge_done(hass, instance)
# only purged old events # only purged old events
assert states.count() == 4 assert states.count() == 4
@ -136,7 +143,7 @@ async def test_purge_method(
await hass.async_block_till_done() await hass.async_block_till_done()
# Small wait for recorder thread # Small wait for recorder thread
await async_wait_recording_done(hass, instance) await async_wait_purge_done(hass, instance)
# we should only have 2 states left after purging # we should only have 2 states left after purging
assert states.count() == 2 assert states.count() == 2
@ -156,7 +163,7 @@ async def test_purge_method(
service_data["repack"] = True service_data["repack"] = True
await hass.services.async_call("recorder", "purge", service_data=service_data) await hass.services.async_call("recorder", "purge", service_data=service_data)
await hass.async_block_till_done() await hass.async_block_till_done()
await async_wait_recording_done(hass, instance) await async_wait_purge_done(hass, instance)
assert "Vacuuming SQL DB to free space" in caplog.text assert "Vacuuming SQL DB to free space" in caplog.text
@ -192,7 +199,7 @@ async def test_purge_edge_case(
) )
instance = await async_setup_recorder_instance(hass, None) instance = await async_setup_recorder_instance(hass, None)
await async_wait_recording_done(hass, instance) await async_wait_purge_done(hass, instance)
service_data = {"keep_days": 2} service_data = {"keep_days": 2}
timestamp = dt_util.utcnow() - timedelta(days=2, minutes=1) timestamp = dt_util.utcnow() - timedelta(days=2, minutes=1)
@ -211,7 +218,7 @@ async def test_purge_edge_case(
await hass.async_block_till_done() await hass.async_block_till_done()
await async_recorder_block_till_done(hass, instance) await async_recorder_block_till_done(hass, instance)
await async_wait_recording_done(hass, instance) await async_wait_purge_done(hass, instance)
assert states.count() == 0 assert states.count() == 0
assert events.count() == 0 assert events.count() == 0
@ -329,7 +336,7 @@ async def test_purge_filtered_states(
await hass.async_block_till_done() await hass.async_block_till_done()
await async_recorder_block_till_done(hass, instance) await async_recorder_block_till_done(hass, instance)
await async_wait_recording_done(hass, instance) await async_wait_purge_done(hass, instance)
assert states.count() == 74 assert states.count() == 74
assert events_state_changed.count() == 70 assert events_state_changed.count() == 70
@ -343,10 +350,10 @@ async def test_purge_filtered_states(
await hass.async_block_till_done() await hass.async_block_till_done()
await async_recorder_block_till_done(hass, instance) await async_recorder_block_till_done(hass, instance)
await async_wait_recording_done(hass, instance) await async_wait_purge_done(hass, instance)
await async_recorder_block_till_done(hass, instance) await async_recorder_block_till_done(hass, instance)
await async_wait_recording_done(hass, instance) await async_wait_purge_done(hass, instance)
assert states.count() == 13 assert states.count() == 13
assert events_state_changed.count() == 10 assert events_state_changed.count() == 10
@ -419,7 +426,7 @@ async def test_purge_filtered_events(
await hass.async_block_till_done() await hass.async_block_till_done()
await async_recorder_block_till_done(hass, instance) await async_recorder_block_till_done(hass, instance)
await async_wait_recording_done(hass, instance) await async_wait_purge_done(hass, instance)
assert events_purge.count() == 60 assert events_purge.count() == 60
assert events_keep.count() == 10 assert events_keep.count() == 10
@ -433,10 +440,10 @@ async def test_purge_filtered_events(
await hass.async_block_till_done() await hass.async_block_till_done()
await async_recorder_block_till_done(hass, instance) await async_recorder_block_till_done(hass, instance)
await async_wait_recording_done(hass, instance) await async_wait_purge_done(hass, instance)
await async_recorder_block_till_done(hass, instance) await async_recorder_block_till_done(hass, instance)
await async_wait_recording_done(hass, instance) await async_wait_purge_done(hass, instance)
assert events_purge.count() == 0 assert events_purge.count() == 0
assert events_keep.count() == 10 assert events_keep.count() == 10
@ -534,10 +541,10 @@ async def test_purge_filtered_events_state_changed(
await hass.async_block_till_done() await hass.async_block_till_done()
await async_recorder_block_till_done(hass, instance) await async_recorder_block_till_done(hass, instance)
await async_wait_recording_done(hass, instance) await async_wait_purge_done(hass, instance)
await async_recorder_block_till_done(hass, instance) await async_recorder_block_till_done(hass, instance)
await async_wait_recording_done(hass, instance) await async_wait_purge_done(hass, instance)
assert events_keep.count() == 10 assert events_keep.count() == 10
assert events_purge.count() == 0 assert events_purge.count() == 0