Fix statistic_during_period after core restart (#119323)

This commit is contained in:
Erik Montnemery 2024-06-10 21:44:55 +02:00 committed by GitHub
parent 632f136c02
commit def9d5b101
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 39 additions and 4 deletions

View file

@ -1244,7 +1244,7 @@ def _first_statistic(
table: type[StatisticsBase],
metadata_id: int,
) -> datetime | None:
"""Return the data of the oldest statistic row for a given metadata id."""
"""Return the date of the oldest statistic row for a given metadata id."""
stmt = lambda_stmt(
lambda: select(table.start_ts)
.filter(table.metadata_id == metadata_id)
@ -1256,6 +1256,23 @@ def _first_statistic(
return None
def _last_statistic(
session: Session,
table: type[StatisticsBase],
metadata_id: int,
) -> datetime | None:
"""Return the date of the newest statistic row for a given metadata id."""
stmt = lambda_stmt(
lambda: select(table.start_ts)
.filter(table.metadata_id == metadata_id)
.order_by(table.start_ts.desc())
.limit(1)
)
if stats := cast(Sequence[Row], execute_stmt_lambda_element(session, stmt)):
return dt_util.utc_from_timestamp(stats[0].start_ts)
return None
def _get_oldest_sum_statistic(
session: Session,
head_start_time: datetime | None,
@ -1486,7 +1503,11 @@ def statistic_during_period(
tail_start_time: datetime | None = None
tail_end_time: datetime | None = None
if end_time is None:
tail_start_time = now.replace(minute=0, second=0, microsecond=0)
tail_start_time = _last_statistic(session, Statistics, metadata_id)
if tail_start_time:
tail_start_time += Statistics.duration
else:
tail_start_time = now.replace(minute=0, second=0, microsecond=0)
elif tail_only:
tail_start_time = start_time
tail_end_time = end_time

View file

@ -7,6 +7,7 @@ import threading
from unittest.mock import ANY, patch
from freezegun import freeze_time
from freezegun.api import FrozenDateTimeFactory
import pytest
from homeassistant.components import recorder
@ -794,17 +795,30 @@ async def test_statistic_during_period_hole(
}
@pytest.mark.freeze_time(datetime.datetime(2022, 10, 21, 6, 31, tzinfo=datetime.UTC))
@pytest.mark.parametrize(
"frozen_time",
[
# This is the normal case, all statistics runs are available
datetime.datetime(2022, 10, 21, 6, 31, tzinfo=datetime.UTC),
# Statistic only available up until 6:25, this can happen if
# core has been shut down for an hour
datetime.datetime(2022, 10, 21, 7, 31, tzinfo=datetime.UTC),
],
)
async def test_statistic_during_period_partial_overlap(
recorder_mock: Recorder,
hass: HomeAssistant,
hass_ws_client: WebSocketGenerator,
freezer: FrozenDateTimeFactory,
frozen_time: datetime,
) -> None:
"""Test statistic_during_period."""
client = await hass_ws_client()
freezer.move_to(frozen_time)
now = dt_util.utcnow()
await async_recorder_block_till_done(hass)
client = await hass_ws_client()
zero = now
start = zero.replace(hour=0, minute=0, second=0, microsecond=0)