Add test of recorder platform with statistics support (#122754)

* Add test of recorder platform with statistics support

* Remove excessive line breaks
This commit is contained in:
Erik Montnemery 2024-07-29 11:57:53 +02:00 committed by GitHub
parent 1879db9f8f
commit 8a84addc54
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -1,7 +1,8 @@
"""The tests for sensor recorder platform.""" """The tests for sensor recorder platform."""
from datetime import timedelta from datetime import timedelta
from unittest.mock import patch from typing import Any
from unittest.mock import ANY, Mock, patch
import pytest import pytest
from sqlalchemy import select from sqlalchemy import select
@ -15,11 +16,13 @@ from homeassistant.components.recorder.models import (
) )
from homeassistant.components.recorder.statistics import ( from homeassistant.components.recorder.statistics import (
STATISTIC_UNIT_TO_UNIT_CONVERTER, STATISTIC_UNIT_TO_UNIT_CONVERTER,
PlatformCompiledStatistics,
_generate_max_mean_min_statistic_in_sub_period_stmt, _generate_max_mean_min_statistic_in_sub_period_stmt,
_generate_statistics_at_time_stmt, _generate_statistics_at_time_stmt,
_generate_statistics_during_period_stmt, _generate_statistics_during_period_stmt,
async_add_external_statistics, async_add_external_statistics,
async_import_statistics, async_import_statistics,
async_list_statistic_ids,
get_last_short_term_statistics, get_last_short_term_statistics,
get_last_statistics, get_last_statistics,
get_latest_short_term_statistics_with_session, get_latest_short_term_statistics_with_session,
@ -27,6 +30,7 @@ from homeassistant.components.recorder.statistics import (
get_metadata_with_session, get_metadata_with_session,
get_short_term_statistics_run_cache, get_short_term_statistics_run_cache,
list_statistic_ids, list_statistic_ids,
validate_statistics,
) )
from homeassistant.components.recorder.table_managers.statistics_meta import ( from homeassistant.components.recorder.table_managers.statistics_meta import (
_generate_get_metadata_stmt, _generate_get_metadata_stmt,
@ -42,12 +46,14 @@ import homeassistant.util.dt as dt_util
from .common import ( from .common import (
assert_dict_of_states_equal_without_context_and_last_changed, assert_dict_of_states_equal_without_context_and_last_changed,
async_record_states, async_record_states,
async_recorder_block_till_done,
async_wait_recording_done, async_wait_recording_done,
do_adhoc_statistics, do_adhoc_statistics,
get_start_time, get_start_time,
statistics_during_period, statistics_during_period,
) )
from tests.common import MockPlatform, mock_platform
from tests.typing import RecorderInstanceGenerator, WebSocketGenerator from tests.typing import RecorderInstanceGenerator, WebSocketGenerator
@ -63,6 +69,15 @@ def setup_recorder(recorder_mock: Recorder) -> None:
"""Set up recorder.""" """Set up recorder."""
async def _setup_mock_domain(
hass: HomeAssistant,
platform: Any | None = None, # There's no RecorderPlatform class yet
) -> None:
"""Set up a mock domain."""
mock_platform(hass, "some_domain.recorder", platform or MockPlatform())
assert await async_setup_component(hass, "some_domain", {})
def test_converters_align_with_sensor() -> None: def test_converters_align_with_sensor() -> None:
"""Ensure STATISTIC_UNIT_TO_UNIT_CONVERTER is aligned with UNIT_CONVERTERS.""" """Ensure STATISTIC_UNIT_TO_UNIT_CONVERTER is aligned with UNIT_CONVERTERS."""
for converter in UNIT_CONVERTERS.values(): for converter in UNIT_CONVERTERS.values():
@ -2473,3 +2488,151 @@ async def test_change_with_none(
types={"change"}, types={"change"},
) )
assert stats == {} assert stats == {}
async def test_recorder_platform_with_statistics(
hass: HomeAssistant,
setup_recorder: None,
caplog: pytest.LogCaptureFixture,
) -> None:
"""Test recorder platform."""
instance = recorder.get_instance(hass)
recorder_data = hass.data["recorder"]
assert not recorder_data.recorder_platforms
def _mock_compile_statistics(*args: Any) -> PlatformCompiledStatistics:
return PlatformCompiledStatistics([], {})
def _mock_list_statistic_ids(*args: Any, **kwargs: Any) -> dict:
return {}
def _mock_validate_statistics(*args: Any) -> dict:
return {}
recorder_platform = Mock(
compile_statistics=Mock(wraps=_mock_compile_statistics),
list_statistic_ids=Mock(wraps=_mock_list_statistic_ids),
validate_statistics=Mock(wraps=_mock_validate_statistics),
)
await _setup_mock_domain(hass, recorder_platform)
# Wait for the sensor recorder platform to be added
await async_recorder_block_till_done(hass)
assert recorder_data.recorder_platforms == {"some_domain": recorder_platform}
recorder_platform.compile_statistics.assert_not_called()
recorder_platform.list_statistic_ids.assert_not_called()
recorder_platform.validate_statistics.assert_not_called()
# Test compile statistics
zero = get_start_time(dt_util.utcnow())
do_adhoc_statistics(hass, start=zero)
await async_wait_recording_done(hass)
recorder_platform.compile_statistics.assert_called_once_with(
hass, ANY, zero, zero + timedelta(minutes=5)
)
recorder_platform.list_statistic_ids.assert_not_called()
recorder_platform.validate_statistics.assert_not_called()
# Test list statistic IDs
await async_list_statistic_ids(hass)
recorder_platform.compile_statistics.assert_called_once()
recorder_platform.list_statistic_ids.assert_called_once_with(
hass, statistic_ids=None, statistic_type=None
)
recorder_platform.validate_statistics.assert_not_called()
# Test validate statistics
await instance.async_add_executor_job(
validate_statistics,
hass,
)
recorder_platform.compile_statistics.assert_called_once()
recorder_platform.list_statistic_ids.assert_called_once()
recorder_platform.validate_statistics.assert_called_once_with(hass)
async def test_recorder_platform_without_statistics(
hass: HomeAssistant,
setup_recorder: None,
caplog: pytest.LogCaptureFixture,
) -> None:
"""Test recorder platform."""
recorder_data = hass.data["recorder"]
assert recorder_data.recorder_platforms == {}
await _setup_mock_domain(hass)
# Wait for the sensor recorder platform to be added
await async_recorder_block_till_done(hass)
assert recorder_data.recorder_platforms == {}
@pytest.mark.parametrize(
"supported_methods",
[
("compile_statistics",),
("list_statistic_ids",),
("validate_statistics",),
],
)
async def test_recorder_platform_with_partial_statistics_support(
hass: HomeAssistant,
setup_recorder: None,
caplog: pytest.LogCaptureFixture,
supported_methods: tuple[str, ...],
) -> None:
"""Test recorder platform."""
instance = recorder.get_instance(hass)
recorder_data = hass.data["recorder"]
assert not recorder_data.recorder_platforms
def _mock_compile_statistics(*args: Any) -> PlatformCompiledStatistics:
return PlatformCompiledStatistics([], {})
def _mock_list_statistic_ids(*args: Any, **kwargs: Any) -> dict:
return {}
def _mock_validate_statistics(*args: Any) -> dict:
return {}
mock_impl = {
"compile_statistics": _mock_compile_statistics,
"list_statistic_ids": _mock_list_statistic_ids,
"validate_statistics": _mock_validate_statistics,
}
kwargs = {meth: Mock(wraps=mock_impl[meth]) for meth in supported_methods}
recorder_platform = Mock(
spec=supported_methods,
**kwargs,
)
await _setup_mock_domain(hass, recorder_platform)
# Wait for the sensor recorder platform to be added
await async_recorder_block_till_done(hass)
assert recorder_data.recorder_platforms == {"some_domain": recorder_platform}
for meth in supported_methods:
getattr(recorder_platform, meth).assert_not_called()
# Test compile statistics
zero = get_start_time(dt_util.utcnow())
do_adhoc_statistics(hass, start=zero)
await async_wait_recording_done(hass)
# Test list statistic IDs
await async_list_statistic_ids(hass)
# Test validate statistics
await instance.async_add_executor_job(
validate_statistics,
hass,
)
for meth in supported_methods:
getattr(recorder_platform, meth).assert_called_once()