mirror of
https://github.com/home-assistant/core.git
synced 2025-08-08 07:05:07 +02:00
coverage
This commit is contained in:
@@ -239,7 +239,7 @@ class Events(Base):
|
|||||||
"""Return string representation of instance for debugging."""
|
"""Return string representation of instance for debugging."""
|
||||||
return (
|
return (
|
||||||
"<recorder.Events("
|
"<recorder.Events("
|
||||||
f"id={self.event_id}, type='{self.event_type}', "
|
f"id={self.event_id}, event_type_id='{self.event_type_id}', "
|
||||||
f"origin_idx='{self.origin_idx}', time_fired='{self._time_fired_isotime}'"
|
f"origin_idx='{self.origin_idx}', time_fired='{self._time_fired_isotime}'"
|
||||||
f", data_id={self.data_id})>"
|
f", data_id={self.data_id})>"
|
||||||
)
|
)
|
||||||
|
@@ -571,10 +571,10 @@ def _purge_old_recorder_runs(
|
|||||||
def _purge_old_event_types(instance: Recorder, session: Session) -> None:
|
def _purge_old_event_types(instance: Recorder, session: Session) -> None:
|
||||||
"""Purge all old event types."""
|
"""Purge all old event types."""
|
||||||
# Event types is small, no need to batch run it
|
# Event types is small, no need to batch run it
|
||||||
purged_event_types = set()
|
purge_event_types = set()
|
||||||
event_type_ids = set()
|
event_type_ids = set()
|
||||||
for event_type_id, event_type in session.execute(find_event_types_to_purge()):
|
for event_type_id, event_type in session.execute(find_event_types_to_purge()):
|
||||||
purged_event_types.add(event_type)
|
purge_event_types.add(event_type)
|
||||||
event_type_ids.add(event_type_id)
|
event_type_ids.add(event_type_id)
|
||||||
|
|
||||||
if not event_type_ids:
|
if not event_type_ids:
|
||||||
@@ -584,7 +584,7 @@ def _purge_old_event_types(instance: Recorder, session: Session) -> None:
|
|||||||
_LOGGER.debug("Deleted %s event types", deleted_rows)
|
_LOGGER.debug("Deleted %s event types", deleted_rows)
|
||||||
|
|
||||||
# Evict any entries in the event_type cache referring to a purged state
|
# Evict any entries in the event_type cache referring to a purged state
|
||||||
instance.event_type_manager.evict_purged(purged_event_types)
|
instance.event_type_manager.evict_purged(purge_event_types)
|
||||||
|
|
||||||
|
|
||||||
def _purge_filtered_data(instance: Recorder, session: Session) -> bool:
|
def _purge_filtered_data(instance: Recorder, session: Session) -> bool:
|
||||||
|
@@ -743,9 +743,9 @@ def find_event_types_to_purge() -> StatementLambdaElement:
|
|||||||
lambda: select(EventTypes.event_type_id, EventTypes.event_type).where(
|
lambda: select(EventTypes.event_type_id, EventTypes.event_type).where(
|
||||||
EventTypes.event_type_id
|
EventTypes.event_type_id
|
||||||
== (
|
== (
|
||||||
select(
|
select(distinct(EventTypes.event_type_id).label("unused_event_type_id"))
|
||||||
distinct(Events.event_type_id).label("unused_event_type_id")
|
.filter(EventTypes.event_type_id.not_in(select(Events.event_type_id)))
|
||||||
).filter(Events.event_type_id.not_in(select(EventTypes.event_type_id)))
|
.subquery()
|
||||||
).c.unused_event_type_id
|
).c.unused_event_type_id
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@@ -16,6 +16,7 @@ from homeassistant.components.recorder.const import (
|
|||||||
from homeassistant.components.recorder.db_schema import (
|
from homeassistant.components.recorder.db_schema import (
|
||||||
EventData,
|
EventData,
|
||||||
Events,
|
Events,
|
||||||
|
EventTypes,
|
||||||
RecorderRuns,
|
RecorderRuns,
|
||||||
StateAttributes,
|
StateAttributes,
|
||||||
States,
|
States,
|
||||||
@@ -31,6 +32,7 @@ from homeassistant.components.recorder.tasks import PurgeTask
|
|||||||
from homeassistant.components.recorder.util import session_scope
|
from homeassistant.components.recorder.util import session_scope
|
||||||
from homeassistant.const import EVENT_STATE_CHANGED, EVENT_THEMES_UPDATED, STATE_ON
|
from homeassistant.const import EVENT_STATE_CHANGED, EVENT_THEMES_UPDATED, STATE_ON
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.helpers.json import json_dumps
|
||||||
from homeassistant.helpers.typing import ConfigType
|
from homeassistant.helpers.typing import ConfigType
|
||||||
from homeassistant.util import dt as dt_util
|
from homeassistant.util import dt as dt_util
|
||||||
|
|
||||||
@@ -1684,3 +1686,113 @@ async def test_purge_can_mix_legacy_and_new_format(
|
|||||||
# does not prevent future purges. Its ignored.
|
# does not prevent future purges. Its ignored.
|
||||||
assert states_with_event_id.count() == 0
|
assert states_with_event_id.count() == 0
|
||||||
assert states_without_event_id.count() == 1
|
assert states_without_event_id.count() == 1
|
||||||
|
|
||||||
|
|
||||||
|
async def test_purge_old_events_purges_the_event_type_ids(
|
||||||
|
async_setup_recorder_instance: RecorderInstanceGenerator, hass: HomeAssistant
|
||||||
|
) -> None:
|
||||||
|
"""Test deleting old events purges event type ids."""
|
||||||
|
instance = await async_setup_recorder_instance(hass)
|
||||||
|
assert instance.event_type_manager.active is True
|
||||||
|
|
||||||
|
utcnow = dt_util.utcnow()
|
||||||
|
five_days_ago = utcnow - timedelta(days=5)
|
||||||
|
eleven_days_ago = utcnow - timedelta(days=11)
|
||||||
|
far_past = utcnow - timedelta(days=1000)
|
||||||
|
event_data = {"test_attr": 5, "test_attr_10": "nice"}
|
||||||
|
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
await async_wait_recording_done(hass)
|
||||||
|
|
||||||
|
def _insert_events():
|
||||||
|
with session_scope(hass=hass) as session:
|
||||||
|
event_type_test_auto_purge = EventTypes(event_type="EVENT_TEST_AUTOPURGE")
|
||||||
|
event_type_test_purge = EventTypes(event_type="EVENT_TEST_PURGE")
|
||||||
|
event_type_test = EventTypes(event_type="EVENT_TEST")
|
||||||
|
event_type_unused = EventTypes(event_type="EVENT_TEST_UNUSED")
|
||||||
|
session.add_all(
|
||||||
|
(
|
||||||
|
event_type_test_auto_purge,
|
||||||
|
event_type_test_purge,
|
||||||
|
event_type_test,
|
||||||
|
event_type_unused,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
session.flush()
|
||||||
|
for _ in range(5):
|
||||||
|
for event_id in range(6):
|
||||||
|
if event_id < 2:
|
||||||
|
timestamp = eleven_days_ago
|
||||||
|
event_type = event_type_test_auto_purge
|
||||||
|
elif event_id < 4:
|
||||||
|
timestamp = five_days_ago
|
||||||
|
event_type = event_type_test_purge
|
||||||
|
else:
|
||||||
|
timestamp = utcnow
|
||||||
|
event_type = event_type_test
|
||||||
|
|
||||||
|
session.add(
|
||||||
|
Events(
|
||||||
|
event_type=None,
|
||||||
|
event_type_id=event_type.event_type_id,
|
||||||
|
event_data=json_dumps(event_data),
|
||||||
|
origin="LOCAL",
|
||||||
|
time_fired_ts=dt_util.utc_to_timestamp(timestamp),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return instance.event_type_manager.get_many(
|
||||||
|
[
|
||||||
|
"EVENT_TEST_AUTOPURGE",
|
||||||
|
"EVENT_TEST_PURGE",
|
||||||
|
"EVENT_TEST",
|
||||||
|
"EVENT_TEST_UNUSED",
|
||||||
|
],
|
||||||
|
session,
|
||||||
|
)
|
||||||
|
|
||||||
|
event_type_to_id = await instance.async_add_executor_job(_insert_events)
|
||||||
|
test_event_type_ids = event_type_to_id.values()
|
||||||
|
with session_scope(hass=hass) as session:
|
||||||
|
events = session.query(Events).where(
|
||||||
|
Events.event_type_id.in_(test_event_type_ids)
|
||||||
|
)
|
||||||
|
event_types = session.query(EventTypes).where(
|
||||||
|
EventTypes.event_type_id.in_(test_event_type_ids)
|
||||||
|
)
|
||||||
|
|
||||||
|
assert events.count() == 30
|
||||||
|
assert event_types.count() == 4
|
||||||
|
|
||||||
|
# run purge_old_data()
|
||||||
|
finished = purge_old_data(
|
||||||
|
instance,
|
||||||
|
far_past,
|
||||||
|
repack=False,
|
||||||
|
)
|
||||||
|
assert finished
|
||||||
|
assert events.count() == 30
|
||||||
|
# We should remove the unused event type
|
||||||
|
assert event_types.count() == 3
|
||||||
|
|
||||||
|
assert "EVENT_TEST_UNUSED" not in instance.event_type_manager._id_map
|
||||||
|
|
||||||
|
# we should only have 10 events left since
|
||||||
|
# only one event type was recorded now
|
||||||
|
finished = purge_old_data(
|
||||||
|
instance,
|
||||||
|
utcnow,
|
||||||
|
repack=False,
|
||||||
|
)
|
||||||
|
assert finished
|
||||||
|
assert events.count() == 10
|
||||||
|
assert event_types.count() == 1
|
||||||
|
|
||||||
|
# Purge everything
|
||||||
|
finished = purge_old_data(
|
||||||
|
instance,
|
||||||
|
utcnow + timedelta(seconds=1),
|
||||||
|
repack=False,
|
||||||
|
)
|
||||||
|
assert finished
|
||||||
|
assert events.count() == 0
|
||||||
|
assert event_types.count() == 0
|
||||||
|
Reference in New Issue
Block a user