Recorder improvements (#47739)

This commit is contained in:
Marc Mueller 2021-03-11 18:52:07 +01:00 committed by GitHub
parent af4d06b12e
commit 10848b9bdf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 207 additions and 77 deletions

View file

@ -3,19 +3,23 @@ from datetime import timedelta
import json
from homeassistant.components import recorder
from homeassistant.components.recorder.const import DATA_INSTANCE
from homeassistant.components.recorder.models import Events, RecorderRuns, States
from homeassistant.components.recorder.purge import purge_old_data
from homeassistant.components.recorder.util import session_scope
from homeassistant.helpers.typing import HomeAssistantType
from homeassistant.util import dt as dt_util
from .common import wait_recording_done
from .common import async_wait_recording_done
from .conftest import SetupRecorderInstanceT
def test_purge_old_states(hass, hass_recorder):
async def test_purge_old_states(
hass: HomeAssistantType, async_setup_recorder_instance: SetupRecorderInstanceT
):
"""Test deleting old states."""
hass = hass_recorder()
_add_test_states(hass)
instance = await async_setup_recorder_instance(hass)
await _add_test_states(hass, instance)
# make sure we start with 6 states
with session_scope(hass=hass) as session:
@ -28,7 +32,7 @@ def test_purge_old_states(hass, hass_recorder):
assert events.count() == 6
# run purge_old_data()
finished = purge_old_data(hass.data[DATA_INSTANCE], 4, repack=False)
finished = purge_old_data(instance, 4, repack=False)
assert not finished
assert states.count() == 2
@ -36,35 +40,41 @@ def test_purge_old_states(hass, hass_recorder):
assert states_after_purge[1].old_state_id == states_after_purge[0].state_id
assert states_after_purge[0].old_state_id is None
finished = purge_old_data(hass.data[DATA_INSTANCE], 4, repack=False)
finished = purge_old_data(instance, 4, repack=False)
assert finished
assert states.count() == 2
def test_purge_old_events(hass, hass_recorder):
async def test_purge_old_events(
hass: HomeAssistantType, async_setup_recorder_instance: SetupRecorderInstanceT
):
"""Test deleting old events."""
hass = hass_recorder()
_add_test_events(hass)
instance = await async_setup_recorder_instance(hass)
await _add_test_events(hass, instance)
with session_scope(hass=hass) as session:
events = session.query(Events).filter(Events.event_type.like("EVENT_TEST%"))
assert events.count() == 6
# run purge_old_data()
finished = purge_old_data(hass.data[DATA_INSTANCE], 4, repack=False)
finished = purge_old_data(instance, 4, repack=False)
assert not finished
assert events.count() == 2
# we should only have 2 events left
finished = purge_old_data(hass.data[DATA_INSTANCE], 4, repack=False)
finished = purge_old_data(instance, 4, repack=False)
assert finished
assert events.count() == 2
def test_purge_old_recorder_runs(hass, hass_recorder):
async def test_purge_old_recorder_runs(
hass: HomeAssistantType, async_setup_recorder_instance: SetupRecorderInstanceT
):
"""Test deleting old recorder runs keeps current run."""
hass = hass_recorder()
_add_test_recorder_runs(hass)
instance = await async_setup_recorder_instance(hass)
await _add_test_recorder_runs(hass, instance)
# make sure we start with 7 recorder runs
with session_scope(hass=hass) as session:
@ -72,21 +82,26 @@ def test_purge_old_recorder_runs(hass, hass_recorder):
assert recorder_runs.count() == 7
# run purge_old_data()
finished = purge_old_data(hass.data[DATA_INSTANCE], 0, repack=False)
finished = purge_old_data(instance, 0, repack=False)
assert not finished
finished = purge_old_data(hass.data[DATA_INSTANCE], 0, repack=False)
finished = purge_old_data(instance, 0, repack=False)
assert finished
assert recorder_runs.count() == 1
def test_purge_method(hass, hass_recorder, caplog):
async def test_purge_method(
hass: HomeAssistantType,
async_setup_recorder_instance: SetupRecorderInstanceT,
caplog,
):
"""Test purge method."""
hass = hass_recorder()
instance = await async_setup_recorder_instance(hass)
service_data = {"keep_days": 4}
_add_test_events(hass)
_add_test_states(hass)
_add_test_recorder_runs(hass)
await _add_test_events(hass, instance)
await _add_test_states(hass, instance)
await _add_test_recorder_runs(hass, instance)
# make sure we start with 6 states
with session_scope(hass=hass) as session:
@ -99,28 +114,26 @@ def test_purge_method(hass, hass_recorder, caplog):
recorder_runs = session.query(RecorderRuns)
assert recorder_runs.count() == 7
hass.data[DATA_INSTANCE].block_till_done()
wait_recording_done(hass)
await hass.async_block_till_done()
await async_wait_recording_done(hass, instance)
# run purge method - no service data, use defaults
hass.services.call("recorder", "purge")
hass.block_till_done()
await hass.services.async_call("recorder", "purge")
await hass.async_block_till_done()
# Small wait for recorder thread
hass.data[DATA_INSTANCE].block_till_done()
wait_recording_done(hass)
await async_wait_recording_done(hass, instance)
# only purged old events
assert states.count() == 4
assert events.count() == 4
# run purge method - correct service data
hass.services.call("recorder", "purge", service_data=service_data)
hass.block_till_done()
await hass.services.async_call("recorder", "purge", service_data=service_data)
await hass.async_block_till_done()
# Small wait for recorder thread
hass.data[DATA_INSTANCE].block_till_done()
wait_recording_done(hass)
await async_wait_recording_done(hass, instance)
# we should only have 2 states left after purging
assert states.count() == 2
@ -135,23 +148,21 @@ def test_purge_method(hass, hass_recorder, caplog):
# run purge method - correct service data, with repack
service_data["repack"] = True
hass.services.call("recorder", "purge", service_data=service_data)
hass.block_till_done()
hass.data[DATA_INSTANCE].block_till_done()
wait_recording_done(hass)
await hass.services.async_call("recorder", "purge", service_data=service_data)
await hass.async_block_till_done()
await async_wait_recording_done(hass, instance)
assert "Vacuuming SQL DB to free space" in caplog.text
def _add_test_states(hass):
async def _add_test_states(hass: HomeAssistantType, instance: recorder.Recorder):
"""Add multiple states to the db for testing."""
utcnow = dt_util.utcnow()
five_days_ago = utcnow - timedelta(days=5)
eleven_days_ago = utcnow - timedelta(days=11)
attributes = {"test_attr": 5, "test_attr_10": "nice"}
hass.block_till_done()
hass.data[DATA_INSTANCE].block_till_done()
wait_recording_done(hass)
await hass.async_block_till_done()
await async_wait_recording_done(hass, instance)
with recorder.session_scope(hass=hass) as session:
old_state_id = None
@ -191,16 +202,15 @@ def _add_test_states(hass):
old_state_id = state.state_id
def _add_test_events(hass):
async def _add_test_events(hass: HomeAssistantType, instance: recorder.Recorder):
"""Add a few events for testing."""
utcnow = dt_util.utcnow()
five_days_ago = utcnow - timedelta(days=5)
eleven_days_ago = utcnow - timedelta(days=11)
event_data = {"test_attr": 5, "test_attr_10": "nice"}
hass.block_till_done()
hass.data[DATA_INSTANCE].block_till_done()
wait_recording_done(hass)
await hass.async_block_till_done()
await async_wait_recording_done(hass, instance)
with recorder.session_scope(hass=hass) as session:
for event_id in range(6):
@ -225,15 +235,14 @@ def _add_test_events(hass):
)
def _add_test_recorder_runs(hass):
async def _add_test_recorder_runs(hass: HomeAssistantType, instance: recorder.Recorder):
"""Add a few recorder_runs for testing."""
utcnow = dt_util.utcnow()
five_days_ago = utcnow - timedelta(days=5)
eleven_days_ago = utcnow - timedelta(days=11)
hass.block_till_done()
hass.data[DATA_INSTANCE].block_till_done()
wait_recording_done(hass)
await hass.async_block_till_done()
await async_wait_recording_done(hass, instance)
with recorder.session_scope(hass=hass) as session:
for rec_id in range(6):