Convert recorder auto_repairs tests to use async API (#116927)

This commit is contained in:
Erik Montnemery 2024-05-06 15:25:48 +02:00 committed by GitHub
parent 5150557372
commit 2e945aed54
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -1,6 +1,5 @@
"""Test removing statistics duplicates.""" """Test removing statistics duplicates."""
from collections.abc import Callable
import importlib import importlib
from pathlib import Path from pathlib import Path
import sys import sys
@ -11,7 +10,7 @@ from sqlalchemy import create_engine
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from homeassistant.components import recorder from homeassistant.components import recorder
from homeassistant.components.recorder import statistics from homeassistant.components.recorder import Recorder, statistics
from homeassistant.components.recorder.auto_repairs.statistics.duplicates import ( from homeassistant.components.recorder.auto_repairs.statistics.duplicates import (
delete_statistics_duplicates, delete_statistics_duplicates,
delete_statistics_meta_duplicates, delete_statistics_meta_duplicates,
@ -21,20 +20,34 @@ from homeassistant.components.recorder.statistics import async_add_external_stat
from homeassistant.components.recorder.util import session_scope from homeassistant.components.recorder.util import session_scope
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers import recorder as recorder_helper from homeassistant.helpers import recorder as recorder_helper
from homeassistant.setup import setup_component from homeassistant.setup import async_setup_component
import homeassistant.util.dt as dt_util import homeassistant.util.dt as dt_util
from ...common import wait_recording_done from ...common import async_wait_recording_done
from tests.common import get_test_home_assistant from tests.common import async_test_home_assistant
from tests.typing import RecorderInstanceGenerator
def test_delete_duplicates_no_duplicates( @pytest.fixture
hass_recorder: Callable[..., HomeAssistant], caplog: pytest.LogCaptureFixture async def mock_recorder_before_hass(
async_setup_recorder_instance: RecorderInstanceGenerator,
) -> None:
"""Set up recorder."""
@pytest.fixture
def setup_recorder(recorder_mock: Recorder) -> None:
"""Set up recorder."""
async def test_delete_duplicates_no_duplicates(
hass: HomeAssistant,
caplog: pytest.LogCaptureFixture,
setup_recorder: None,
) -> None: ) -> None:
"""Test removal of duplicated statistics.""" """Test removal of duplicated statistics."""
hass = hass_recorder() await async_wait_recording_done(hass)
wait_recording_done(hass)
instance = recorder.get_instance(hass) instance = recorder.get_instance(hass)
with session_scope(hass=hass) as session: with session_scope(hass=hass) as session:
delete_statistics_duplicates(instance, hass, session) delete_statistics_duplicates(instance, hass, session)
@ -43,12 +56,13 @@ def test_delete_duplicates_no_duplicates(
assert "Found duplicated" not in caplog.text assert "Found duplicated" not in caplog.text
def test_duplicate_statistics_handle_integrity_error( async def test_duplicate_statistics_handle_integrity_error(
hass_recorder: Callable[..., HomeAssistant], caplog: pytest.LogCaptureFixture hass: HomeAssistant,
caplog: pytest.LogCaptureFixture,
setup_recorder: None,
) -> None: ) -> None:
"""Test the recorder does not blow up if statistics is duplicated.""" """Test the recorder does not blow up if statistics is duplicated."""
hass = hass_recorder() await async_wait_recording_done(hass)
wait_recording_done(hass)
period1 = dt_util.as_utc(dt_util.parse_datetime("2021-09-01 00:00:00")) period1 = dt_util.as_utc(dt_util.parse_datetime("2021-09-01 00:00:00"))
period2 = dt_util.as_utc(dt_util.parse_datetime("2021-09-30 23:00:00")) period2 = dt_util.as_utc(dt_util.parse_datetime("2021-09-30 23:00:00"))
@ -93,7 +107,7 @@ def test_duplicate_statistics_handle_integrity_error(
async_add_external_statistics( async_add_external_statistics(
hass, external_energy_metadata_1, external_energy_statistics_2 hass, external_energy_metadata_1, external_energy_statistics_2
) )
wait_recording_done(hass) await async_wait_recording_done(hass)
assert insert_statistics_mock.call_count == 3 assert insert_statistics_mock.call_count == 3
with session_scope(hass=hass) as session: with session_scope(hass=hass) as session:
@ -126,7 +140,7 @@ def _create_engine_28(*args, **kwargs):
return engine return engine
def test_delete_metadata_duplicates( async def test_delete_metadata_duplicates(
caplog: pytest.LogCaptureFixture, tmp_path: Path caplog: pytest.LogCaptureFixture, tmp_path: Path
) -> None: ) -> None:
"""Test removal of duplicated statistics.""" """Test removal of duplicated statistics."""
@ -164,23 +178,7 @@ def test_delete_metadata_duplicates(
"unit_of_measurement": "%", "unit_of_measurement": "%",
} }
# Create some duplicated statistics_meta with schema version 28 def add_statistics_meta(hass: HomeAssistant) -> None:
with (
patch.object(recorder, "db_schema", old_db_schema),
patch.object(
recorder.migration, "SCHEMA_VERSION", old_db_schema.SCHEMA_VERSION
),
patch(
"homeassistant.components.recorder.core.create_engine",
new=_create_engine_28,
),
get_test_home_assistant() as hass,
):
recorder_helper.async_initialize_recorder(hass)
setup_component(hass, "recorder", {"recorder": {"db_url": dburl}})
wait_recording_done(hass)
wait_recording_done(hass)
with session_scope(hass=hass) as session: with session_scope(hass=hass) as session:
session.add( session.add(
recorder.db_schema.StatisticsMeta.from_meta(external_energy_metadata_1) recorder.db_schema.StatisticsMeta.from_meta(external_energy_metadata_1)
@ -192,8 +190,33 @@ def test_delete_metadata_duplicates(
recorder.db_schema.StatisticsMeta.from_meta(external_co2_metadata) recorder.db_schema.StatisticsMeta.from_meta(external_co2_metadata)
) )
with session_scope(hass=hass) as session: def get_statistics_meta(hass: HomeAssistant) -> list:
tmp = session.query(recorder.db_schema.StatisticsMeta).all() with session_scope(hass=hass, read_only=True) as session:
return list(session.query(recorder.db_schema.StatisticsMeta).all())
# Create some duplicated statistics_meta with schema version 28
with (
patch.object(recorder, "db_schema", old_db_schema),
patch.object(
recorder.migration, "SCHEMA_VERSION", old_db_schema.SCHEMA_VERSION
),
patch(
"homeassistant.components.recorder.core.create_engine",
new=_create_engine_28,
),
):
async with async_test_home_assistant() as hass:
recorder_helper.async_initialize_recorder(hass)
await async_setup_component(
hass, "recorder", {"recorder": {"db_url": dburl}}
)
await async_wait_recording_done(hass)
await async_wait_recording_done(hass)
instance = recorder.get_instance(hass)
await instance.async_add_executor_job(add_statistics_meta, hass)
tmp = await instance.async_add_executor_job(get_statistics_meta, hass)
assert len(tmp) == 3 assert len(tmp) == 3
assert tmp[0].id == 1 assert tmp[0].id == 1
assert tmp[0].statistic_id == "test:total_energy_import_tariff_1" assert tmp[0].statistic_id == "test:total_energy_import_tariff_1"
@ -202,29 +225,29 @@ def test_delete_metadata_duplicates(
assert tmp[2].id == 3 assert tmp[2].id == 3
assert tmp[2].statistic_id == "test:fossil_percentage" assert tmp[2].statistic_id == "test:fossil_percentage"
hass.stop() await hass.async_stop()
# Test that the duplicates are removed during migration from schema 28 # Test that the duplicates are removed during migration from schema 28
with get_test_home_assistant() as hass: async with async_test_home_assistant() as hass:
recorder_helper.async_initialize_recorder(hass) recorder_helper.async_initialize_recorder(hass)
setup_component(hass, "recorder", {"recorder": {"db_url": dburl}}) await async_setup_component(hass, "recorder", {"recorder": {"db_url": dburl}})
hass.start() await hass.async_start()
wait_recording_done(hass) await async_wait_recording_done(hass)
wait_recording_done(hass) await async_wait_recording_done(hass)
assert "Deleted 1 duplicated statistics_meta rows" in caplog.text assert "Deleted 1 duplicated statistics_meta rows" in caplog.text
with session_scope(hass=hass) as session: instance = recorder.get_instance(hass)
tmp = session.query(recorder.db_schema.StatisticsMeta).all() tmp = await instance.async_add_executor_job(get_statistics_meta, hass)
assert len(tmp) == 2 assert len(tmp) == 2
assert tmp[0].id == 2 assert tmp[0].id == 2
assert tmp[0].statistic_id == "test:total_energy_import_tariff_1" assert tmp[0].statistic_id == "test:total_energy_import_tariff_1"
assert tmp[1].id == 3 assert tmp[1].id == 3
assert tmp[1].statistic_id == "test:fossil_percentage" assert tmp[1].statistic_id == "test:fossil_percentage"
hass.stop() await hass.async_stop()
def test_delete_metadata_duplicates_many( async def test_delete_metadata_duplicates_many(
caplog: pytest.LogCaptureFixture, tmp_path: Path caplog: pytest.LogCaptureFixture, tmp_path: Path
) -> None: ) -> None:
"""Test removal of duplicated statistics.""" """Test removal of duplicated statistics."""
@ -262,23 +285,7 @@ def test_delete_metadata_duplicates_many(
"unit_of_measurement": "%", "unit_of_measurement": "%",
} }
# Create some duplicated statistics with schema version 28 def add_statistics_meta(hass: HomeAssistant) -> None:
with (
patch.object(recorder, "db_schema", old_db_schema),
patch.object(
recorder.migration, "SCHEMA_VERSION", old_db_schema.SCHEMA_VERSION
),
patch(
"homeassistant.components.recorder.core.create_engine",
new=_create_engine_28,
),
get_test_home_assistant() as hass,
):
recorder_helper.async_initialize_recorder(hass)
setup_component(hass, "recorder", {"recorder": {"db_url": dburl}})
wait_recording_done(hass)
wait_recording_done(hass)
with session_scope(hass=hass) as session: with session_scope(hass=hass) as session:
session.add( session.add(
recorder.db_schema.StatisticsMeta.from_meta(external_energy_metadata_1) recorder.db_schema.StatisticsMeta.from_meta(external_energy_metadata_1)
@ -302,36 +309,61 @@ def test_delete_metadata_duplicates_many(
recorder.db_schema.StatisticsMeta.from_meta(external_co2_metadata) recorder.db_schema.StatisticsMeta.from_meta(external_co2_metadata)
) )
hass.stop() def get_statistics_meta(hass: HomeAssistant) -> list:
with session_scope(hass=hass, read_only=True) as session:
return list(session.query(recorder.db_schema.StatisticsMeta).all())
# Create some duplicated statistics with schema version 28
with (
patch.object(recorder, "db_schema", old_db_schema),
patch.object(
recorder.migration, "SCHEMA_VERSION", old_db_schema.SCHEMA_VERSION
),
patch(
"homeassistant.components.recorder.core.create_engine",
new=_create_engine_28,
),
):
async with async_test_home_assistant() as hass:
recorder_helper.async_initialize_recorder(hass)
await async_setup_component(
hass, "recorder", {"recorder": {"db_url": dburl}}
)
await async_wait_recording_done(hass)
await async_wait_recording_done(hass)
instance = recorder.get_instance(hass)
await instance.async_add_executor_job(add_statistics_meta, hass)
await hass.async_stop()
# Test that the duplicates are removed during migration from schema 28 # Test that the duplicates are removed during migration from schema 28
with get_test_home_assistant() as hass: async with async_test_home_assistant() as hass:
recorder_helper.async_initialize_recorder(hass) recorder_helper.async_initialize_recorder(hass)
setup_component(hass, "recorder", {"recorder": {"db_url": dburl}}) await async_setup_component(hass, "recorder", {"recorder": {"db_url": dburl}})
hass.start() await hass.async_start()
wait_recording_done(hass) await async_wait_recording_done(hass)
wait_recording_done(hass) await async_wait_recording_done(hass)
assert "Deleted 1102 duplicated statistics_meta rows" in caplog.text assert "Deleted 1102 duplicated statistics_meta rows" in caplog.text
with session_scope(hass=hass) as session: instance = recorder.get_instance(hass)
tmp = session.query(recorder.db_schema.StatisticsMeta).all() tmp = await instance.async_add_executor_job(get_statistics_meta, hass)
assert len(tmp) == 3 assert len(tmp) == 3
assert tmp[0].id == 1101 assert tmp[0].id == 1101
assert tmp[0].statistic_id == "test:total_energy_import_tariff_1" assert tmp[0].statistic_id == "test:total_energy_import_tariff_1"
assert tmp[1].id == 1103 assert tmp[1].id == 1103
assert tmp[1].statistic_id == "test:total_energy_import_tariff_2" assert tmp[1].statistic_id == "test:total_energy_import_tariff_2"
assert tmp[2].id == 1105 assert tmp[2].id == 1105
assert tmp[2].statistic_id == "test:fossil_percentage" assert tmp[2].statistic_id == "test:fossil_percentage"
hass.stop() await hass.async_stop()
def test_delete_metadata_duplicates_no_duplicates( async def test_delete_metadata_duplicates_no_duplicates(
hass_recorder: Callable[..., HomeAssistant], caplog: pytest.LogCaptureFixture hass: HomeAssistant, caplog: pytest.LogCaptureFixture, setup_recorder: None
) -> None: ) -> None:
"""Test removal of duplicated statistics.""" """Test removal of duplicated statistics."""
hass = hass_recorder() await async_wait_recording_done(hass)
wait_recording_done(hass)
with session_scope(hass=hass) as session: with session_scope(hass=hass) as session:
instance = recorder.get_instance(hass) instance = recorder.get_instance(hass)
delete_statistics_meta_duplicates(instance, session) delete_statistics_meta_duplicates(instance, session)