diff --git a/tests/common.py b/tests/common.py index 6a3bf3bb89a..d86aaaa3ab8 100644 --- a/tests/common.py +++ b/tests/common.py @@ -3,7 +3,7 @@ from __future__ import annotations import asyncio from collections import OrderedDict -from collections.abc import Awaitable, Collection +from collections.abc import Awaitable, Callable, Collection from contextlib import contextmanager from datetime import datetime, timedelta import functools as ft @@ -896,6 +896,9 @@ def assert_setup_component(count, domain=None): ), f"setup_component failed, expected {count} got {res_len}: {res}" +SetupRecorderInstanceT = Callable[..., Awaitable[recorder.Recorder]] + + def init_recorder_component(hass, add_config=None): """Initialize the recorder.""" config = dict(add_config) if add_config else {} diff --git a/tests/components/automation/test_recorder.py b/tests/components/automation/test_recorder.py index 3070452d345..ac80aabca8c 100644 --- a/tests/components/automation/test_recorder.py +++ b/tests/components/automation/test_recorder.py @@ -17,7 +17,7 @@ from homeassistant.const import ATTR_ENTITY_ID, ATTR_FRIENDLY_NAME from homeassistant.core import State from homeassistant.setup import async_setup_component -from tests.common import async_init_recorder_component, async_mock_service +from tests.common import async_mock_service from tests.components.recorder.common import async_wait_recording_done_without_instance @@ -27,10 +27,8 @@ def calls(hass): return async_mock_service(hass, "test", "automation") -async def test_exclude_attributes(hass, calls): +async def test_exclude_attributes(hass, recorder_mock, calls): """Test automation registered attributes to be excluded.""" - await async_init_recorder_component(hass) - await hass.async_block_till_done() assert await async_setup_component( hass, automation.DOMAIN, diff --git a/tests/components/camera/test_recorder.py b/tests/components/camera/test_recorder.py index 76654a2dd9c..86f20280fc0 100644 --- a/tests/components/camera/test_recorder.py +++ b/tests/components/camera/test_recorder.py @@ -16,13 +16,12 @@ from homeassistant.core import State from homeassistant.setup import async_setup_component from homeassistant.util import dt as dt_util -from tests.common import async_fire_time_changed, async_init_recorder_component +from tests.common import async_fire_time_changed from tests.components.recorder.common import async_wait_recording_done_without_instance -async def test_exclude_attributes(hass): +async def test_exclude_attributes(hass, recorder_mock): """Test camera registered attributes to be excluded.""" - await async_init_recorder_component(hass) await async_setup_component( hass, camera.DOMAIN, {camera.DOMAIN: {"platform": "demo"}} ) diff --git a/tests/components/climate/test_recorder.py b/tests/components/climate/test_recorder.py index f1642fca240..42fcd9498a8 100644 --- a/tests/components/climate/test_recorder.py +++ b/tests/components/climate/test_recorder.py @@ -22,13 +22,12 @@ from homeassistant.core import State from homeassistant.setup import async_setup_component from homeassistant.util import dt as dt_util -from tests.common import async_fire_time_changed, async_init_recorder_component +from tests.common import async_fire_time_changed from tests.components.recorder.common import async_wait_recording_done_without_instance -async def test_exclude_attributes(hass): +async def test_exclude_attributes(hass, recorder_mock): """Test climate registered attributes to be excluded.""" - await async_init_recorder_component(hass) await async_setup_component( hass, climate.DOMAIN, {climate.DOMAIN: {"platform": "demo"}} ) diff --git a/tests/components/energy/test_sensor.py b/tests/components/energy/test_sensor.py index 57074c2bfde..1ba87455a83 100644 --- a/tests/components/energy/test_sensor.py +++ b/tests/components/energy/test_sensor.py @@ -25,7 +25,6 @@ from homeassistant.const import ( from homeassistant.setup import async_setup_component import homeassistant.util.dt as dt_util -from tests.common import async_init_recorder_component from tests.components.recorder.common import async_wait_recording_done_without_instance @@ -113,7 +112,6 @@ async def test_cost_sensor_price_entity_total_increasing( ATTR_STATE_CLASS: SensorStateClass.TOTAL_INCREASING, } - await async_init_recorder_component(hass) energy_data = data.EnergyManager.default_preferences() energy_data["energy_sources"].append( { @@ -318,7 +316,6 @@ async def test_cost_sensor_price_entity_total( ATTR_STATE_CLASS: energy_state_class, } - await async_init_recorder_component(hass) energy_data = data.EnergyManager.default_preferences() energy_data["energy_sources"].append( { @@ -525,7 +522,6 @@ async def test_cost_sensor_price_entity_total_no_reset( ATTR_STATE_CLASS: energy_state_class, } - await async_init_recorder_component(hass) energy_data = data.EnergyManager.default_preferences() energy_data["energy_sources"].append( { diff --git a/tests/components/energy/test_validate.py b/tests/components/energy/test_validate.py index 78a61b1bf69..37ebe4147c5 100644 --- a/tests/components/energy/test_validate.py +++ b/tests/components/energy/test_validate.py @@ -6,8 +6,6 @@ import pytest from homeassistant.components.energy import async_get_manager, validate from homeassistant.setup import async_setup_component -from tests.common import async_init_recorder_component - @pytest.fixture def mock_is_entity_recorded(): @@ -44,9 +42,8 @@ def mock_get_metadata(): @pytest.fixture(autouse=True) -async def mock_energy_manager(hass): +async def mock_energy_manager(hass, recorder_mock): """Set up energy.""" - await async_init_recorder_component(hass) assert await async_setup_component(hass, "energy", {"energy": {}}) manager = await async_get_manager(hass) manager.data = manager.default_preferences() diff --git a/tests/components/fan/test_recorder.py b/tests/components/fan/test_recorder.py index 360e03d2491..078072350af 100644 --- a/tests/components/fan/test_recorder.py +++ b/tests/components/fan/test_recorder.py @@ -12,13 +12,12 @@ from homeassistant.core import State from homeassistant.setup import async_setup_component from homeassistant.util import dt as dt_util -from tests.common import async_fire_time_changed, async_init_recorder_component +from tests.common import async_fire_time_changed from tests.components.recorder.common import async_wait_recording_done_without_instance -async def test_exclude_attributes(hass): +async def test_exclude_attributes(hass, recorder_mock): """Test fan registered attributes to be excluded.""" - await async_init_recorder_component(hass) await async_setup_component(hass, fan.DOMAIN, {fan.DOMAIN: {"platform": "demo"}}) await hass.async_block_till_done() async_fire_time_changed(hass, dt_util.utcnow() + timedelta(minutes=5)) diff --git a/tests/components/filter/test_sensor.py b/tests/components/filter/test_sensor.py index b044b2c08fa..e6c42d370e6 100644 --- a/tests/components/filter/test_sensor.py +++ b/tests/components/filter/test_sensor.py @@ -2,7 +2,7 @@ from datetime import timedelta from unittest.mock import patch -from pytest import fixture +import pytest from homeassistant import config as hass_config from homeassistant.components.filter.sensor import ( @@ -30,14 +30,10 @@ from homeassistant.helpers import entity_registry as er from homeassistant.setup import async_setup_component import homeassistant.util.dt as dt_util -from tests.common import ( - assert_setup_component, - async_init_recorder_component, - get_fixture_path, -) +from tests.common import assert_setup_component, get_fixture_path -@fixture +@pytest.fixture def values(): """Fixture for a list of test States.""" values = [] @@ -63,7 +59,7 @@ async def test_setup_fail(hass): await hass.async_block_till_done() -async def test_chain(hass, values): +async def test_chain(hass, recorder_mock, values): """Test if filter chaining works.""" config = { "sensor": { @@ -77,7 +73,6 @@ async def test_chain(hass, values): ], } } - await async_init_recorder_component(hass) with assert_setup_component(1, "sensor"): assert await async_setup_component(hass, "sensor", config) @@ -91,8 +86,9 @@ async def test_chain(hass, values): assert state.state == "18.05" -async def test_chain_history(hass, values, missing=False): - """Test if filter chaining works.""" +@pytest.mark.parametrize("missing", (True, False)) +async def test_chain_history(hass, recorder_mock, values, missing): + """Test if filter chaining works, when a source is and isn't recorded.""" config = { "sensor": { "platform": "filter", @@ -105,7 +101,6 @@ async def test_chain_history(hass, values, missing=False): ], }, } - await async_init_recorder_component(hass) t_0 = dt_util.utcnow() - timedelta(minutes=1) t_1 = dt_util.utcnow() - timedelta(minutes=2) @@ -146,9 +141,8 @@ async def test_chain_history(hass, values, missing=False): assert state.state == "17.05" -async def test_source_state_none(hass, values): +async def test_source_state_none(hass, recorder_mock, values): """Test is source sensor state is null and sets state to STATE_UNKNOWN.""" - await async_init_recorder_component(hass) config = { "sensor": [ @@ -207,12 +201,7 @@ async def test_source_state_none(hass, values): assert state.state == STATE_UNKNOWN -async def test_chain_history_missing(hass, values): - """Test if filter chaining works when recorder is enabled but the source is not recorded.""" - await test_chain_history(hass, values, missing=True) - - -async def test_history_time(hass): +async def test_history_time(hass, recorder_mock): """Test loading from history based on a time window.""" config = { "sensor": { @@ -222,7 +211,6 @@ async def test_history_time(hass): "filters": [{"filter": "time_throttle", "window_size": "00:01"}], }, } - await async_init_recorder_component(hass) t_0 = dt_util.utcnow() - timedelta(minutes=1) t_1 = dt_util.utcnow() - timedelta(minutes=2) @@ -251,7 +239,7 @@ async def test_history_time(hass): assert state.state == "18.0" -async def test_setup(hass): +async def test_setup(hass, recorder_mock): """Test if filter attributes are inherited.""" config = { "sensor": { @@ -265,8 +253,6 @@ async def test_setup(hass): } } - await async_init_recorder_component(hass) - with assert_setup_component(1, "sensor"): assert await async_setup_component(hass, "sensor", config) await hass.async_block_till_done() @@ -294,7 +280,7 @@ async def test_setup(hass): assert entity_id == "sensor.test" -async def test_invalid_state(hass): +async def test_invalid_state(hass, recorder_mock): """Test if filter attributes are inherited.""" config = { "sensor": { @@ -307,8 +293,6 @@ async def test_invalid_state(hass): } } - await async_init_recorder_component(hass) - with assert_setup_component(1, "sensor"): assert await async_setup_component(hass, "sensor", config) await hass.async_block_till_done() @@ -326,7 +310,7 @@ async def test_invalid_state(hass): assert state.state == STATE_UNAVAILABLE -async def test_timestamp_state(hass): +async def test_timestamp_state(hass, recorder_mock): """Test if filter state is a datetime.""" config = { "sensor": { @@ -339,8 +323,6 @@ async def test_timestamp_state(hass): } } - await async_init_recorder_component(hass) - with assert_setup_component(1, "sensor"): assert await async_setup_component(hass, "sensor", config) await hass.async_block_till_done() @@ -487,10 +469,8 @@ def test_time_sma(values): assert filtered.state == 21.5 -async def test_reload(hass): +async def test_reload(hass, recorder_mock): """Verify we can reload filter sensors.""" - await async_init_recorder_component(hass) - hass.states.async_set("sensor.test_monitored", 12345) await async_setup_component( hass, diff --git a/tests/components/history/test_init.py b/tests/components/history/test_init.py index f9fb7b49fb0..e75afedcfe6 100644 --- a/tests/components/history/test_init.py +++ b/tests/components/history/test_init.py @@ -17,7 +17,7 @@ from homeassistant.setup import async_setup_component import homeassistant.util.dt as dt_util from homeassistant.util.unit_system import IMPERIAL_SYSTEM, METRIC_SYSTEM -from tests.common import async_init_recorder_component, init_recorder_component +from tests.common import init_recorder_component from tests.components.recorder.common import ( async_wait_recording_done_without_instance, trigger_db_commit, @@ -606,9 +606,8 @@ async def test_fetch_period_api_with_use_include_order(hass, hass_client): assert response.status == HTTPStatus.OK -async def test_fetch_period_api_with_minimal_response(hass, hass_client): +async def test_fetch_period_api_with_minimal_response(hass, recorder_mock, hass_client): """Test the fetch period view for history with minimal_response.""" - await async_init_recorder_component(hass) now = dt_util.utcnow() await async_setup_component(hass, "history", {}) diff --git a/tests/components/history_stats/test_sensor.py b/tests/components/history_stats/test_sensor.py index 5afc036cd8a..4b89591345d 100644 --- a/tests/components/history_stats/test_sensor.py +++ b/tests/components/history_stats/test_sensor.py @@ -19,7 +19,6 @@ import homeassistant.util.dt as dt_util from tests.common import ( async_fire_time_changed, - async_init_recorder_component, get_fixture_path, get_test_home_assistant, init_recorder_component, @@ -225,10 +224,8 @@ class TestHistoryStatsSensor(unittest.TestCase): self.hass.start() -async def test_reload(hass): +async def test_reload(hass, recorder_mock): """Verify we can reload history_stats sensors.""" - await async_init_recorder_component(hass) - hass.state = ha.CoreState.not_running hass.states.async_set("binary_sensor.test_id", "on") @@ -270,10 +267,8 @@ async def test_reload(hass): assert hass.states.get("sensor.second_test") -async def test_measure_multiple(hass): +async def test_measure_multiple(hass, recorder_mock): """Test the history statistics sensor measure for multiple .""" - await async_init_recorder_component(hass) - start_time = dt_util.utcnow() - timedelta(minutes=60) t0 = start_time + timedelta(minutes=20) t1 = t0 + timedelta(minutes=10) @@ -354,10 +349,8 @@ async def test_measure_multiple(hass): assert hass.states.get("sensor.sensor4").state == "50.0" -async def async_test_measure(hass): +async def async_test_measure(hass, recorder_mock): """Test the history statistics sensor measure.""" - await async_init_recorder_component(hass) - start_time = dt_util.utcnow() - timedelta(minutes=60) t0 = start_time + timedelta(minutes=20) t1 = t0 + timedelta(minutes=10) @@ -435,10 +428,8 @@ async def async_test_measure(hass): assert hass.states.get("sensor.sensor4").state == "50.0" -async def test_async_on_entire_period(hass): +async def test_async_on_entire_period(hass, recorder_mock): """Test the history statistics sensor measuring as on the entire period.""" - await async_init_recorder_component(hass) - start_time = dt_util.utcnow() - timedelta(minutes=60) t0 = start_time + timedelta(minutes=20) t1 = t0 + timedelta(minutes=10) @@ -517,10 +508,8 @@ async def test_async_on_entire_period(hass): assert hass.states.get("sensor.on_sensor4").state == "100.0" -async def test_async_off_entire_period(hass): +async def test_async_off_entire_period(hass, recorder_mock): """Test the history statistics sensor measuring as off the entire period.""" - await async_init_recorder_component(hass) - start_time = dt_util.utcnow() - timedelta(minutes=60) t0 = start_time + timedelta(minutes=20) t1 = t0 + timedelta(minutes=10) @@ -601,10 +590,9 @@ async def test_async_off_entire_period(hass): async def test_async_start_from_history_and_switch_to_watching_state_changes_single( hass, + recorder_mock, ): """Test we startup from history and switch to watching state changes.""" - await async_init_recorder_component(hass) - hass.config.set_time_zone("UTC") utcnow = dt_util.utcnow() start_time = utcnow.replace(hour=0, minute=0, second=0, microsecond=0) @@ -693,10 +681,9 @@ async def test_async_start_from_history_and_switch_to_watching_state_changes_sin async def test_async_start_from_history_and_switch_to_watching_state_changes_single_expanding_window( hass, + recorder_mock, ): """Test we startup from history and switch to watching state changes with an expanding end time.""" - await async_init_recorder_component(hass) - hass.config.set_time_zone("UTC") utcnow = dt_util.utcnow() start_time = utcnow.replace(hour=0, minute=0, second=0, microsecond=0) @@ -785,10 +772,9 @@ async def test_async_start_from_history_and_switch_to_watching_state_changes_sin async def test_async_start_from_history_and_switch_to_watching_state_changes_multiple( hass, + recorder_mock, ): """Test we startup from history and switch to watching state changes.""" - await async_init_recorder_component(hass) - hass.config.set_time_zone("UTC") utcnow = dt_util.utcnow() start_time = utcnow.replace(hour=0, minute=0, second=0, microsecond=0) @@ -920,13 +906,11 @@ async def test_async_start_from_history_and_switch_to_watching_state_changes_mul assert hass.states.get("sensor.sensor4").state == "87.5" -async def test_does_not_work_into_the_future(hass): +async def test_does_not_work_into_the_future(hass, recorder_mock): """Test history cannot tell the future. Verifies we do not regress https://github.com/home-assistant/core/pull/20589 """ - await async_init_recorder_component(hass) - hass.config.set_time_zone("UTC") utcnow = dt_util.utcnow() start_time = utcnow.replace(hour=0, minute=0, second=0, microsecond=0) diff --git a/tests/components/humidifier/test_recorder.py b/tests/components/humidifier/test_recorder.py index c7505574b98..70b61e21b70 100644 --- a/tests/components/humidifier/test_recorder.py +++ b/tests/components/humidifier/test_recorder.py @@ -16,13 +16,12 @@ from homeassistant.core import State from homeassistant.setup import async_setup_component from homeassistant.util import dt as dt_util -from tests.common import async_fire_time_changed, async_init_recorder_component +from tests.common import async_fire_time_changed from tests.components.recorder.common import async_wait_recording_done_without_instance -async def test_exclude_attributes(hass): +async def test_exclude_attributes(hass, recorder_mock): """Test humidifier registered attributes to be excluded.""" - await async_init_recorder_component(hass) await async_setup_component( hass, humidifier.DOMAIN, {humidifier.DOMAIN: {"platform": "demo"}} ) diff --git a/tests/components/input_boolean/test_recorder.py b/tests/components/input_boolean/test_recorder.py index 5bbbaa25c29..6fc8c80dcb3 100644 --- a/tests/components/input_boolean/test_recorder.py +++ b/tests/components/input_boolean/test_recorder.py @@ -11,15 +11,14 @@ from homeassistant.core import HomeAssistant, State from homeassistant.setup import async_setup_component from homeassistant.util import dt as dt_util -from tests.common import async_fire_time_changed, async_init_recorder_component +from tests.common import async_fire_time_changed from tests.components.recorder.common import async_wait_recording_done_without_instance async def test_exclude_attributes( - hass: HomeAssistant, enable_custom_integrations: None + hass: HomeAssistant, recorder_mock, enable_custom_integrations: None ): """Test attributes to be excluded.""" - await async_init_recorder_component(hass) assert await async_setup_component(hass, DOMAIN, {DOMAIN: {"test": {}}}) state = hass.states.get("input_boolean.test") diff --git a/tests/components/input_button/test_recorder.py b/tests/components/input_button/test_recorder.py index bd1ffa43b69..9d7ea175122 100644 --- a/tests/components/input_button/test_recorder.py +++ b/tests/components/input_button/test_recorder.py @@ -11,15 +11,14 @@ from homeassistant.core import HomeAssistant, State from homeassistant.setup import async_setup_component from homeassistant.util import dt as dt_util -from tests.common import async_fire_time_changed, async_init_recorder_component +from tests.common import async_fire_time_changed from tests.components.recorder.common import async_wait_recording_done_without_instance async def test_exclude_attributes( - hass: HomeAssistant, enable_custom_integrations: None + hass: HomeAssistant, recorder_mock, enable_custom_integrations: None ): """Test attributes to be excluded.""" - await async_init_recorder_component(hass) assert await async_setup_component(hass, DOMAIN, {DOMAIN: {"test": {}}}) state = hass.states.get("input_button.test") diff --git a/tests/components/input_datetime/test_recorder.py b/tests/components/input_datetime/test_recorder.py index ee42c4042b2..bfa6cdf6d1a 100644 --- a/tests/components/input_datetime/test_recorder.py +++ b/tests/components/input_datetime/test_recorder.py @@ -11,15 +11,14 @@ from homeassistant.core import HomeAssistant, State from homeassistant.setup import async_setup_component from homeassistant.util import dt as dt_util -from tests.common import async_fire_time_changed, async_init_recorder_component +from tests.common import async_fire_time_changed from tests.components.recorder.common import async_wait_recording_done_without_instance async def test_exclude_attributes( - hass: HomeAssistant, enable_custom_integrations: None + hass: HomeAssistant, recorder_mock, enable_custom_integrations: None ): """Test attributes to be excluded.""" - await async_init_recorder_component(hass) assert await async_setup_component( hass, DOMAIN, {DOMAIN: {"test": {CONF_HAS_TIME: True}}} ) diff --git a/tests/components/input_number/test_recorder.py b/tests/components/input_number/test_recorder.py index 337cb915f54..44024771fbb 100644 --- a/tests/components/input_number/test_recorder.py +++ b/tests/components/input_number/test_recorder.py @@ -17,15 +17,14 @@ from homeassistant.core import HomeAssistant, State from homeassistant.setup import async_setup_component from homeassistant.util import dt as dt_util -from tests.common import async_fire_time_changed, async_init_recorder_component +from tests.common import async_fire_time_changed from tests.components.recorder.common import async_wait_recording_done_without_instance async def test_exclude_attributes( - hass: HomeAssistant, enable_custom_integrations: None + hass: HomeAssistant, recorder_mock, enable_custom_integrations: None ): """Test attributes to be excluded.""" - await async_init_recorder_component(hass) assert await async_setup_component( hass, DOMAIN, {DOMAIN: {"test": {"min": 0, "max": 100}}} ) diff --git a/tests/components/input_select/test_recorder.py b/tests/components/input_select/test_recorder.py index f68dad44eb7..351a0a739cd 100644 --- a/tests/components/input_select/test_recorder.py +++ b/tests/components/input_select/test_recorder.py @@ -11,15 +11,14 @@ from homeassistant.core import HomeAssistant, State from homeassistant.setup import async_setup_component from homeassistant.util import dt as dt_util -from tests.common import async_fire_time_changed, async_init_recorder_component +from tests.common import async_fire_time_changed from tests.components.recorder.common import async_wait_recording_done_without_instance async def test_exclude_attributes( - hass: HomeAssistant, enable_custom_integrations: None + hass: HomeAssistant, recorder_mock, enable_custom_integrations: None ): """Test attributes to be excluded.""" - await async_init_recorder_component(hass) assert await async_setup_component( hass, DOMAIN, diff --git a/tests/components/input_text/test_recorder.py b/tests/components/input_text/test_recorder.py index bef74c5e9d2..7ec8463bb6b 100644 --- a/tests/components/input_text/test_recorder.py +++ b/tests/components/input_text/test_recorder.py @@ -18,15 +18,14 @@ from homeassistant.core import HomeAssistant, State from homeassistant.setup import async_setup_component from homeassistant.util import dt as dt_util -from tests.common import async_fire_time_changed, async_init_recorder_component +from tests.common import async_fire_time_changed from tests.components.recorder.common import async_wait_recording_done_without_instance async def test_exclude_attributes( - hass: HomeAssistant, enable_custom_integrations: None + hass: HomeAssistant, recorder_mock, enable_custom_integrations: None ): """Test attributes to be excluded.""" - await async_init_recorder_component(hass) assert await async_setup_component(hass, DOMAIN, {DOMAIN: {"test": {}}}) state = hass.states.get("input_text.test") diff --git a/tests/components/light/test_recorder.py b/tests/components/light/test_recorder.py index b8e35788562..6133f61abf7 100644 --- a/tests/components/light/test_recorder.py +++ b/tests/components/light/test_recorder.py @@ -17,13 +17,12 @@ from homeassistant.core import State from homeassistant.setup import async_setup_component from homeassistant.util import dt as dt_util -from tests.common import async_fire_time_changed, async_init_recorder_component +from tests.common import async_fire_time_changed from tests.components.recorder.common import async_wait_recording_done_without_instance -async def test_exclude_attributes(hass): +async def test_exclude_attributes(hass, recorder_mock): """Test light registered attributes to be excluded.""" - await async_init_recorder_component(hass) await async_setup_component( hass, light.DOMAIN, {light.DOMAIN: {"platform": "demo"}} ) diff --git a/tests/components/logbook/test_init.py b/tests/components/logbook/test_init.py index 998efc1c167..1cfc90bbb6c 100644 --- a/tests/components/logbook/test_init.py +++ b/tests/components/logbook/test_init.py @@ -38,11 +38,7 @@ from homeassistant.helpers.json import JSONEncoder from homeassistant.setup import async_setup_component import homeassistant.util.dt as dt_util -from tests.common import ( - async_capture_events, - async_init_recorder_component, - mock_platform, -) +from tests.common import async_capture_events, mock_platform from tests.components.recorder.common import ( async_trigger_db_commit, async_wait_recording_done_without_instance, @@ -53,9 +49,8 @@ EMPTY_CONFIG = logbook.CONFIG_SCHEMA({logbook.DOMAIN: {}}) @pytest.fixture -async def hass_(hass): +async def hass_(hass, recorder_mock): """Set up things to be run when tests are started.""" - await async_init_recorder_component(hass) # Force an in memory DB assert await async_setup_component(hass, logbook.DOMAIN, EMPTY_CONFIG) return hass @@ -310,9 +305,8 @@ def create_state_changed_event_from_old_new( return logbook.LazyEventPartialState(row) -async def test_logbook_view(hass, hass_client): +async def test_logbook_view(hass, hass_client, recorder_mock): """Test the logbook view.""" - await async_init_recorder_component(hass) await async_setup_component(hass, "logbook", {}) await hass.async_add_executor_job(hass.data[recorder.DATA_INSTANCE].block_till_done) client = await hass_client() @@ -320,9 +314,8 @@ async def test_logbook_view(hass, hass_client): assert response.status == HTTPStatus.OK -async def test_logbook_view_period_entity(hass, hass_client, set_utc): +async def test_logbook_view_period_entity(hass, hass_client, recorder_mock, set_utc): """Test the logbook view with period and entity.""" - await async_init_recorder_component(hass) await async_setup_component(hass, "logbook", {}) await hass.async_add_executor_job(hass.data[recorder.DATA_INSTANCE].block_till_done) @@ -404,9 +397,8 @@ async def test_logbook_view_period_entity(hass, hass_client, set_utc): assert response_json[0]["entity_id"] == entity_id_test -async def test_logbook_describe_event(hass, hass_client): +async def test_logbook_describe_event(hass, hass_client, recorder_mock): """Test teaching logbook about a new event.""" - await async_init_recorder_component(hass) def _describe(event): """Describe an event.""" @@ -446,7 +438,7 @@ async def test_logbook_describe_event(hass, hass_client): assert event["domain"] == "test_domain" -async def test_exclude_described_event(hass, hass_client): +async def test_exclude_described_event(hass, hass_client, recorder_mock): """Test exclusions of events that are described by another integration.""" name = "My Automation Rule" entity_id = "automation.excluded_rule" @@ -473,7 +465,6 @@ async def test_exclude_described_event(hass, hass_client): Mock(async_describe_events=async_describe_events), ) - await async_init_recorder_component(hass) assert await async_setup_component( hass, logbook.DOMAIN, @@ -515,9 +506,8 @@ async def test_exclude_described_event(hass, hass_client): assert event["entity_id"] == "automation.included_rule" -async def test_logbook_view_end_time_entity(hass, hass_client): +async def test_logbook_view_end_time_entity(hass, hass_client, recorder_mock): """Test the logbook view with end_time and entity.""" - await async_init_recorder_component(hass) await async_setup_component(hass, "logbook", {}) await hass.async_add_executor_job(hass.data[recorder.DATA_INSTANCE].block_till_done) @@ -573,9 +563,8 @@ async def test_logbook_view_end_time_entity(hass, hass_client): assert response_json[0]["entity_id"] == entity_id_test -async def test_logbook_entity_filter_with_automations(hass, hass_client): +async def test_logbook_entity_filter_with_automations(hass, hass_client, recorder_mock): """Test the logbook view with end_time and entity with automations and scripts.""" - await async_init_recorder_component(hass) await async_setup_component(hass, "logbook", {}) await async_setup_component(hass, "automation", {}) await async_setup_component(hass, "script", {}) @@ -648,9 +637,10 @@ async def test_logbook_entity_filter_with_automations(hass, hass_client): assert json_dict[0]["entity_id"] == entity_id_second -async def test_logbook_entity_no_longer_in_state_machine(hass, hass_client): +async def test_logbook_entity_no_longer_in_state_machine( + hass, hass_client, recorder_mock +): """Test the logbook view with an entity that hass been removed from the state machine.""" - await async_init_recorder_component(hass) await async_setup_component(hass, "logbook", {}) await async_setup_component(hass, "automation", {}) await async_setup_component(hass, "script", {}) @@ -686,9 +676,10 @@ async def test_logbook_entity_no_longer_in_state_machine(hass, hass_client): assert json_dict[0]["name"] == "Alarm Control Panel" -async def test_filter_continuous_sensor_values(hass, hass_client, set_utc): +async def test_filter_continuous_sensor_values( + hass, hass_client, recorder_mock, set_utc +): """Test remove continuous sensor events from logbook.""" - await async_init_recorder_component(hass) await async_setup_component(hass, "logbook", {}) await hass.async_add_executor_job(hass.data[recorder.DATA_INSTANCE].block_till_done) @@ -722,9 +713,8 @@ async def test_filter_continuous_sensor_values(hass, hass_client, set_utc): assert response_json[1]["entity_id"] == entity_id_third -async def test_exclude_new_entities(hass, hass_client, set_utc): +async def test_exclude_new_entities(hass, hass_client, recorder_mock, set_utc): """Test if events are excluded on first update.""" - await async_init_recorder_component(hass) await async_setup_component(hass, "logbook", {}) await hass.async_add_executor_job(hass.data[recorder.DATA_INSTANCE].block_till_done) @@ -757,9 +747,8 @@ async def test_exclude_new_entities(hass, hass_client, set_utc): assert response_json[1]["message"] == "started" -async def test_exclude_removed_entities(hass, hass_client, set_utc): +async def test_exclude_removed_entities(hass, hass_client, recorder_mock, set_utc): """Test if events are excluded on last update.""" - await async_init_recorder_component(hass) await async_setup_component(hass, "logbook", {}) await hass.async_add_executor_job(hass.data[recorder.DATA_INSTANCE].block_till_done) @@ -799,9 +788,8 @@ async def test_exclude_removed_entities(hass, hass_client, set_utc): assert response_json[2]["entity_id"] == entity_id2 -async def test_exclude_attribute_changes(hass, hass_client, set_utc): +async def test_exclude_attribute_changes(hass, hass_client, recorder_mock, set_utc): """Test if events of attribute changes are filtered.""" - await async_init_recorder_component(hass) await async_setup_component(hass, "logbook", {}) await hass.async_add_executor_job(hass.data[recorder.DATA_INSTANCE].block_till_done) @@ -837,9 +825,8 @@ async def test_exclude_attribute_changes(hass, hass_client, set_utc): assert response_json[2]["entity_id"] == "light.kitchen" -async def test_logbook_entity_context_id(hass, hass_client): +async def test_logbook_entity_context_id(hass, recorder_mock, hass_client): """Test the logbook view with end_time and entity with automations and scripts.""" - await async_init_recorder_component(hass) await async_setup_component(hass, "logbook", {}) await async_setup_component(hass, "automation", {}) await async_setup_component(hass, "script", {}) @@ -989,9 +976,8 @@ async def test_logbook_entity_context_id(hass, hass_client): assert json_dict[7]["context_user_id"] == "9400facee45711eaa9308bfd3d19e474" -async def test_logbook_entity_context_parent_id(hass, hass_client): +async def test_logbook_entity_context_parent_id(hass, hass_client, recorder_mock): """Test the logbook view links events via context parent_id.""" - await async_init_recorder_component(hass) await async_setup_component(hass, "logbook", {}) await async_setup_component(hass, "automation", {}) await async_setup_component(hass, "script", {}) @@ -1170,9 +1156,8 @@ async def test_logbook_entity_context_parent_id(hass, hass_client): assert json_dict[8]["context_user_id"] == "485cacf93ef84d25a99ced3126b921d2" -async def test_logbook_context_from_template(hass, hass_client): +async def test_logbook_context_from_template(hass, hass_client, recorder_mock): """Test the logbook view with end_time and entity with automations and scripts.""" - await async_init_recorder_component(hass) await async_setup_component(hass, "logbook", {}) assert await async_setup_component( hass, @@ -1256,9 +1241,8 @@ async def test_logbook_context_from_template(hass, hass_client): assert json_dict[5]["context_user_id"] == "9400facee45711eaa9308bfd3d19e474" -async def test_logbook_entity_matches_only(hass, hass_client): +async def test_logbook_entity_matches_only(hass, hass_client, recorder_mock): """Test the logbook view with a single entity and entity_matches_only.""" - await async_init_recorder_component(hass) await async_setup_component(hass, "logbook", {}) assert await async_setup_component( hass, @@ -1330,9 +1314,10 @@ async def test_logbook_entity_matches_only(hass, hass_client): assert json_dict[1]["context_user_id"] == "9400facee45711eaa9308bfd3d19e474" -async def test_custom_log_entry_discoverable_via_entity_matches_only(hass, hass_client): +async def test_custom_log_entry_discoverable_via_entity_matches_only( + hass, hass_client, recorder_mock +): """Test if a custom log entry is later discoverable via entity_matches_only.""" - await async_init_recorder_component(hass) await async_setup_component(hass, "logbook", {}) await hass.async_add_executor_job(hass.data[recorder.DATA_INSTANCE].block_till_done) @@ -1369,9 +1354,8 @@ async def test_custom_log_entry_discoverable_via_entity_matches_only(hass, hass_ assert json_dict[0]["entity_id"] == "switch.test_switch" -async def test_logbook_entity_matches_only_multiple(hass, hass_client): +async def test_logbook_entity_matches_only_multiple(hass, hass_client, recorder_mock): """Test the logbook view with a multiple entities and entity_matches_only.""" - await async_init_recorder_component(hass) await async_setup_component(hass, "logbook", {}) assert await async_setup_component( hass, @@ -1453,9 +1437,8 @@ async def test_logbook_entity_matches_only_multiple(hass, hass_client): assert json_dict[3]["context_user_id"] == "9400facee45711eaa9308bfd3d19e474" -async def test_logbook_invalid_entity(hass, hass_client): +async def test_logbook_invalid_entity(hass, hass_client, recorder_mock): """Test the logbook view with requesting an invalid entity.""" - await async_init_recorder_component(hass) await async_setup_component(hass, "logbook", {}) await hass.async_block_till_done() client = await hass_client() @@ -1472,9 +1455,8 @@ async def test_logbook_invalid_entity(hass, hass_client): assert response.status == HTTPStatus.INTERNAL_SERVER_ERROR -async def test_icon_and_state(hass, hass_client): +async def test_icon_and_state(hass, hass_client, recorder_mock): """Test to ensure state and custom icons are returned.""" - await async_init_recorder_component(hass) await async_setup_component(hass, "logbook", {}) await hass.async_add_executor_job(hass.data[recorder.DATA_INSTANCE].block_till_done) @@ -1510,7 +1492,7 @@ async def test_icon_and_state(hass, hass_client): assert response_json[2]["state"] == STATE_OFF -async def test_exclude_events_domain(hass, hass_client): +async def test_exclude_events_domain(hass, hass_client, recorder_mock): """Test if events are filtered if domain is excluded in config.""" entity_id = "switch.bla" entity_id2 = "sensor.blu" @@ -1521,7 +1503,6 @@ async def test_exclude_events_domain(hass, hass_client): logbook.DOMAIN: {CONF_EXCLUDE: {CONF_DOMAINS: ["switch", "alexa"]}}, } ) - await async_init_recorder_component(hass) await async_setup_component(hass, "logbook", config) await hass.async_add_executor_job(hass.data[recorder.DATA_INSTANCE].block_till_done) @@ -1544,7 +1525,7 @@ async def test_exclude_events_domain(hass, hass_client): _assert_entry(entries[1], name="blu", entity_id=entity_id2) -async def test_exclude_events_domain_glob(hass, hass_client): +async def test_exclude_events_domain_glob(hass, hass_client, recorder_mock): """Test if events are filtered if domain or glob is excluded in config.""" entity_id = "switch.bla" entity_id2 = "sensor.blu" @@ -1561,7 +1542,6 @@ async def test_exclude_events_domain_glob(hass, hass_client): }, } ) - await async_init_recorder_component(hass) await async_setup_component(hass, "logbook", config) await hass.async_add_executor_job(hass.data[recorder.DATA_INSTANCE].block_till_done) @@ -1585,7 +1565,7 @@ async def test_exclude_events_domain_glob(hass, hass_client): _assert_entry(entries[1], name="blu", entity_id=entity_id2) -async def test_include_events_entity(hass, hass_client): +async def test_include_events_entity(hass, hass_client, recorder_mock): """Test if events are filtered if entity is included in config.""" entity_id = "sensor.bla" entity_id2 = "sensor.blu" @@ -1601,7 +1581,6 @@ async def test_include_events_entity(hass, hass_client): }, } ) - await async_init_recorder_component(hass) await async_setup_component(hass, "logbook", config) await hass.async_add_executor_job(hass.data[recorder.DATA_INSTANCE].block_till_done) @@ -1623,7 +1602,7 @@ async def test_include_events_entity(hass, hass_client): _assert_entry(entries[1], name="blu", entity_id=entity_id2) -async def test_exclude_events_entity(hass, hass_client): +async def test_exclude_events_entity(hass, hass_client, recorder_mock): """Test if events are filtered if entity is excluded in config.""" entity_id = "sensor.bla" entity_id2 = "sensor.blu" @@ -1634,7 +1613,6 @@ async def test_exclude_events_entity(hass, hass_client): logbook.DOMAIN: {CONF_EXCLUDE: {CONF_ENTITIES: [entity_id]}}, } ) - await async_init_recorder_component(hass) await async_setup_component(hass, "logbook", config) await hass.async_add_executor_job(hass.data[recorder.DATA_INSTANCE].block_till_done) @@ -1655,7 +1633,7 @@ async def test_exclude_events_entity(hass, hass_client): _assert_entry(entries[1], name="blu", entity_id=entity_id2) -async def test_include_events_domain(hass, hass_client): +async def test_include_events_domain(hass, hass_client, recorder_mock): """Test if events are filtered if domain is included in config.""" assert await async_setup_component(hass, "alexa", {}) entity_id = "switch.bla" @@ -1668,7 +1646,6 @@ async def test_include_events_domain(hass, hass_client): }, } ) - await async_init_recorder_component(hass) await async_setup_component(hass, "logbook", config) await hass.async_add_executor_job(hass.data[recorder.DATA_INSTANCE].block_till_done) @@ -1695,7 +1672,7 @@ async def test_include_events_domain(hass, hass_client): _assert_entry(entries[2], name="blu", entity_id=entity_id2) -async def test_include_events_domain_glob(hass, hass_client): +async def test_include_events_domain_glob(hass, hass_client, recorder_mock): """Test if events are filtered if domain or glob is included in config.""" assert await async_setup_component(hass, "alexa", {}) entity_id = "switch.bla" @@ -1712,7 +1689,6 @@ async def test_include_events_domain_glob(hass, hass_client): }, } ) - await async_init_recorder_component(hass) await async_setup_component(hass, "logbook", config) await hass.async_add_executor_job(hass.data[recorder.DATA_INSTANCE].block_till_done) @@ -1742,7 +1718,7 @@ async def test_include_events_domain_glob(hass, hass_client): _assert_entry(entries[3], name="included", entity_id=entity_id3) -async def test_include_exclude_events(hass, hass_client): +async def test_include_exclude_events(hass, hass_client, recorder_mock): """Test if events are filtered if include and exclude is configured.""" entity_id = "switch.bla" entity_id2 = "sensor.blu" @@ -1764,7 +1740,6 @@ async def test_include_exclude_events(hass, hass_client): }, } ) - await async_init_recorder_component(hass) await async_setup_component(hass, "logbook", config) await hass.async_add_executor_job(hass.data[recorder.DATA_INSTANCE].block_till_done) @@ -1793,7 +1768,9 @@ async def test_include_exclude_events(hass, hass_client): _assert_entry(entries[2], name="keep", entity_id=entity_id4) -async def test_include_exclude_events_with_glob_filters(hass, hass_client): +async def test_include_exclude_events_with_glob_filters( + hass, hass_client, recorder_mock +): """Test if events are filtered if include and exclude is configured.""" entity_id = "switch.bla" entity_id2 = "sensor.blu" @@ -1818,7 +1795,6 @@ async def test_include_exclude_events_with_glob_filters(hass, hass_client): }, } ) - await async_init_recorder_component(hass) await async_setup_component(hass, "logbook", config) await hass.async_add_executor_job(hass.data[recorder.DATA_INSTANCE].block_till_done) @@ -1851,7 +1827,7 @@ async def test_include_exclude_events_with_glob_filters(hass, hass_client): _assert_entry(entries[2], name="included", entity_id=entity_id4) -async def test_empty_config(hass, hass_client): +async def test_empty_config(hass, hass_client, recorder_mock): """Test we can handle an empty entity filter.""" entity_id = "sensor.blu" @@ -1861,7 +1837,6 @@ async def test_empty_config(hass, hass_client): logbook.DOMAIN: {}, } ) - await async_init_recorder_component(hass) await async_setup_component(hass, "logbook", config) await hass.async_add_executor_job(hass.data[recorder.DATA_INSTANCE].block_till_done) @@ -1881,9 +1856,8 @@ async def test_empty_config(hass, hass_client): _assert_entry(entries[1], name="blu", entity_id=entity_id) -async def test_context_filter(hass, hass_client): +async def test_context_filter(hass, hass_client, recorder_mock): """Test we can filter by context.""" - await async_init_recorder_component(hass) assert await async_setup_component(hass, "logbook", {}) await hass.async_add_executor_job(hass.data[recorder.DATA_INSTANCE].block_till_done) diff --git a/tests/components/media_player/test_recorder.py b/tests/components/media_player/test_recorder.py index df1c7cc8da0..dd1119efd52 100644 --- a/tests/components/media_player/test_recorder.py +++ b/tests/components/media_player/test_recorder.py @@ -18,13 +18,12 @@ from homeassistant.core import State from homeassistant.setup import async_setup_component from homeassistant.util import dt as dt_util -from tests.common import async_fire_time_changed, async_init_recorder_component +from tests.common import async_fire_time_changed from tests.components.recorder.common import async_wait_recording_done_without_instance -async def test_exclude_attributes(hass): +async def test_exclude_attributes(hass, recorder_mock): """Test media_player registered attributes to be excluded.""" - await async_init_recorder_component(hass) await async_setup_component( hass, media_player.DOMAIN, {media_player.DOMAIN: {"platform": "demo"}} ) diff --git a/tests/components/number/test_recorder.py b/tests/components/number/test_recorder.py index 26eca4eb4da..3123614fe14 100644 --- a/tests/components/number/test_recorder.py +++ b/tests/components/number/test_recorder.py @@ -12,13 +12,12 @@ from homeassistant.core import State from homeassistant.setup import async_setup_component from homeassistant.util import dt as dt_util -from tests.common import async_fire_time_changed, async_init_recorder_component +from tests.common import async_fire_time_changed from tests.components.recorder.common import async_wait_recording_done_without_instance -async def test_exclude_attributes(hass): +async def test_exclude_attributes(hass, recorder_mock): """Test number registered attributes to be excluded.""" - await async_init_recorder_component(hass) await async_setup_component( hass, number.DOMAIN, {number.DOMAIN: {"platform": "demo"}} ) diff --git a/tests/components/plant/test_init.py b/tests/components/plant/test_init.py index 602f368abcd..3c278532811 100644 --- a/tests/components/plant/test_init.py +++ b/tests/components/plant/test_init.py @@ -13,7 +13,6 @@ from homeassistant.const import ( from homeassistant.core import State from homeassistant.setup import async_setup_component -from tests.common import async_init_recorder_component from tests.components.recorder.common import async_wait_recording_done_without_instance GOOD_DATA = { @@ -145,13 +144,12 @@ async def test_state_problem_if_unavailable(hass): assert state.attributes[plant.READING_MOISTURE] == STATE_UNAVAILABLE -async def test_load_from_db(hass): +async def test_load_from_db(hass, recorder_mock): """Test bootstrapping the brightness history from the database. This test can should only be executed if the loading of the history is enabled via plant.ENABLE_LOAD_HISTORY. """ - await async_init_recorder_component(hass) plant_name = "wise_plant" for value in [20, 30, 10]: diff --git a/tests/components/recorder/conftest.py b/tests/components/recorder/conftest.py deleted file mode 100644 index b23bfee48d3..00000000000 --- a/tests/components/recorder/conftest.py +++ /dev/null @@ -1,48 +0,0 @@ -"""Common test tools.""" -from __future__ import annotations - -from collections.abc import AsyncGenerator, Awaitable, Callable -from typing import cast -from unittest.mock import patch - -import pytest - -from homeassistant.components import recorder -from homeassistant.components.recorder import Recorder -from homeassistant.components.recorder.const import DATA_INSTANCE -from homeassistant.core import HomeAssistant -from homeassistant.helpers.typing import ConfigType - -from .common import async_recorder_block_till_done - -from tests.common import async_init_recorder_component - -SetupRecorderInstanceT = Callable[..., Awaitable[Recorder]] - - -@pytest.fixture -async def async_setup_recorder_instance( - enable_statistics, -) -> AsyncGenerator[SetupRecorderInstanceT, None]: - """Yield callable to setup recorder instance.""" - - async def async_setup_recorder( - hass: HomeAssistant, config: ConfigType | None = None - ) -> Recorder: - """Setup and return recorder instance.""" # noqa: D401 - stats = ( - recorder.Recorder.async_periodic_statistics if enable_statistics else None - ) - with patch( - "homeassistant.components.recorder.Recorder.async_periodic_statistics", - side_effect=stats, - autospec=True, - ): - await async_init_recorder_component(hass, config) - await hass.async_block_till_done() - instance = cast(Recorder, hass.data[DATA_INSTANCE]) - await async_recorder_block_till_done(hass, instance) - assert isinstance(instance, Recorder) - return instance - - yield async_setup_recorder diff --git a/tests/components/recorder/test_backup.py b/tests/components/recorder/test_backup.py index 4667691add8..d7c5a55b56a 100644 --- a/tests/components/recorder/test_backup.py +++ b/tests/components/recorder/test_backup.py @@ -9,13 +9,9 @@ from homeassistant.components.recorder.backup import async_post_backup, async_pr from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from tests.common import async_init_recorder_component - -async def test_async_pre_backup(hass: HomeAssistant) -> None: +async def test_async_pre_backup(hass: HomeAssistant, recorder_mock) -> None: """Test pre backup.""" - await async_init_recorder_component(hass) - with patch( "homeassistant.components.recorder.backup.Recorder.lock_database" ) as lock_mock: @@ -23,10 +19,10 @@ async def test_async_pre_backup(hass: HomeAssistant) -> None: assert lock_mock.called -async def test_async_pre_backup_with_timeout(hass: HomeAssistant) -> None: +async def test_async_pre_backup_with_timeout( + hass: HomeAssistant, recorder_mock +) -> None: """Test pre backup with timeout.""" - await async_init_recorder_component(hass) - with patch( "homeassistant.components.recorder.backup.Recorder.lock_database", side_effect=TimeoutError(), @@ -35,10 +31,10 @@ async def test_async_pre_backup_with_timeout(hass: HomeAssistant) -> None: assert lock_mock.called -async def test_async_pre_backup_with_migration(hass: HomeAssistant) -> None: +async def test_async_pre_backup_with_migration( + hass: HomeAssistant, recorder_mock +) -> None: """Test pre backup with migration.""" - await async_init_recorder_component(hass) - with patch( "homeassistant.components.recorder.backup.async_migration_in_progress", return_value=True, @@ -46,10 +42,8 @@ async def test_async_pre_backup_with_migration(hass: HomeAssistant) -> None: await async_pre_backup(hass) -async def test_async_post_backup(hass: HomeAssistant) -> None: +async def test_async_post_backup(hass: HomeAssistant, recorder_mock) -> None: """Test post backup.""" - await async_init_recorder_component(hass) - with patch( "homeassistant.components.recorder.backup.Recorder.unlock_database" ) as unlock_mock: @@ -57,10 +51,8 @@ async def test_async_post_backup(hass: HomeAssistant) -> None: assert unlock_mock.called -async def test_async_post_backup_failure(hass: HomeAssistant) -> None: +async def test_async_post_backup_failure(hass: HomeAssistant, recorder_mock) -> None: """Test post backup failure.""" - await async_init_recorder_component(hass) - with patch( "homeassistant.components.recorder.backup.Recorder.unlock_database", return_value=False, diff --git a/tests/components/recorder/test_history.py b/tests/components/recorder/test_history.py index 6e917a5b77d..e70d15e730c 100644 --- a/tests/components/recorder/test_history.py +++ b/tests/components/recorder/test_history.py @@ -20,9 +20,7 @@ import homeassistant.core as ha from homeassistant.helpers.json import JSONEncoder import homeassistant.util.dt as dt_util -from .conftest import SetupRecorderInstanceT - -from tests.common import mock_state_change_event +from tests.common import SetupRecorderInstanceT, mock_state_change_event from tests.components.recorder.common import wait_recording_done diff --git a/tests/components/recorder/test_init.py b/tests/components/recorder/test_init.py index a4bc1bbacaf..09099f93f69 100644 --- a/tests/components/recorder/test_init.py +++ b/tests/components/recorder/test_init.py @@ -57,9 +57,9 @@ from .common import ( corrupt_db_file, wait_recording_done, ) -from .conftest import SetupRecorderInstanceT from tests.common import ( + SetupRecorderInstanceT, async_fire_time_changed, async_init_recorder_component, fire_time_changed, @@ -113,12 +113,11 @@ async def test_shutdown_before_startup_finishes(hass, tmp_path): assert run_info.end is not None -async def test_shutdown_closes_connections(hass): +async def test_shutdown_closes_connections(hass, recorder_mock): """Test shutdown closes connections.""" hass.state = CoreState.not_running - await async_init_recorder_component(hass) instance = get_instance(hass) await instance.async_db_ready await hass.async_block_till_done() diff --git a/tests/components/recorder/test_purge.py b/tests/components/recorder/test_purge.py index 0194cb0c57c..ae49e3905d2 100644 --- a/tests/components/recorder/test_purge.py +++ b/tests/components/recorder/test_purge.py @@ -31,7 +31,8 @@ from .common import ( async_wait_recording_done, async_wait_recording_done_without_instance, ) -from .conftest import SetupRecorderInstanceT + +from tests.common import SetupRecorderInstanceT async def test_purge_old_states( diff --git a/tests/components/recorder/test_statistics.py b/tests/components/recorder/test_statistics.py index ccdbcc4f74d..818db57b382 100644 --- a/tests/components/recorder/test_statistics.py +++ b/tests/components/recorder/test_statistics.py @@ -37,11 +37,7 @@ import homeassistant.util.dt as dt_util from .common import async_wait_recording_done_without_instance -from tests.common import ( - async_init_recorder_component, - get_test_home_assistant, - mock_registry, -) +from tests.common import get_test_home_assistant, mock_registry from tests.components.recorder.common import wait_recording_done ORIG_TZ = dt_util.DEFAULT_TIME_ZONE @@ -357,10 +353,9 @@ def test_statistics_duplicated(hass_recorder, caplog): caplog.clear() -async def test_external_statistics(hass, hass_ws_client, caplog): +async def test_external_statistics(hass, hass_ws_client, recorder_mock, caplog): """Test inserting external statistics.""" client = await hass_ws_client() - await async_init_recorder_component(hass) assert "Compiling statistics for" not in caplog.text assert "Statistics already compiled" not in caplog.text diff --git a/tests/components/recorder/test_websocket_api.py b/tests/components/recorder/test_websocket_api.py index 612593f71f9..2193045387d 100644 --- a/tests/components/recorder/test_websocket_api.py +++ b/tests/components/recorder/test_websocket_api.py @@ -20,11 +20,7 @@ from .common import ( trigger_db_commit, ) -from tests.common import ( - async_fire_time_changed, - async_init_recorder_component, - init_recorder_component, -) +from tests.common import async_fire_time_changed, init_recorder_component POWER_SENSOR_ATTRIBUTES = { "device_class": "power", @@ -48,7 +44,7 @@ GAS_SENSOR_ATTRIBUTES = { } -async def test_validate_statistics(hass, hass_ws_client): +async def test_validate_statistics(hass, hass_ws_client, recorder_mock): """Test validate_statistics can be called.""" id = 1 @@ -66,12 +62,11 @@ async def test_validate_statistics(hass, hass_ws_client): assert response["result"] == expected_result # No statistics, no state - empty response - await hass.async_add_executor_job(init_recorder_component, hass) client = await hass_ws_client() await assert_validation_result(client, {}) -async def test_clear_statistics(hass, hass_ws_client): +async def test_clear_statistics(hass, hass_ws_client, recorder_mock): """Test removing statistics.""" now = dt_util.utcnow() @@ -81,7 +76,6 @@ async def test_clear_statistics(hass, hass_ws_client): value = 10000 hass.config.units = units - await hass.async_add_executor_job(init_recorder_component, hass) await async_setup_component(hass, "history", {}) await async_setup_component(hass, "sensor", {}) await hass.async_add_executor_job(hass.data[DATA_INSTANCE].block_till_done) @@ -200,7 +194,9 @@ async def test_clear_statistics(hass, hass_ws_client): @pytest.mark.parametrize("new_unit", ["dogs", None]) -async def test_update_statistics_metadata(hass, hass_ws_client, new_unit): +async def test_update_statistics_metadata( + hass, hass_ws_client, recorder_mock, new_unit +): """Test removing statistics.""" now = dt_util.utcnow() @@ -209,7 +205,6 @@ async def test_update_statistics_metadata(hass, hass_ws_client, new_unit): state = 10 hass.config.units = units - await hass.async_add_executor_job(init_recorder_component, hass) await async_setup_component(hass, "history", {}) await async_setup_component(hass, "sensor", {}) await hass.async_add_executor_job(hass.data[DATA_INSTANCE].block_till_done) @@ -265,10 +260,9 @@ async def test_update_statistics_metadata(hass, hass_ws_client, new_unit): ] -async def test_recorder_info(hass, hass_ws_client): +async def test_recorder_info(hass, hass_ws_client, recorder_mock): """Test getting recorder status.""" client = await hass_ws_client() - await async_init_recorder_component(hass) # Ensure there are no queued events await async_wait_recording_done_without_instance(hass) @@ -387,10 +381,11 @@ async def test_backup_start_no_recorder( assert response["error"]["code"] == "unknown_command" -async def test_backup_start_timeout(hass, hass_ws_client, hass_supervisor_access_token): +async def test_backup_start_timeout( + hass, hass_ws_client, hass_supervisor_access_token, recorder_mock +): """Test getting backup start when recorder is not present.""" client = await hass_ws_client(hass, hass_supervisor_access_token) - await async_init_recorder_component(hass) # Ensure there are no queued events await async_wait_recording_done_without_instance(hass) @@ -405,10 +400,11 @@ async def test_backup_start_timeout(hass, hass_ws_client, hass_supervisor_access await client.send_json({"id": 2, "type": "backup/end"}) -async def test_backup_end(hass, hass_ws_client, hass_supervisor_access_token): +async def test_backup_end( + hass, hass_ws_client, hass_supervisor_access_token, recorder_mock +): """Test backup start.""" client = await hass_ws_client(hass, hass_supervisor_access_token) - await async_init_recorder_component(hass) # Ensure there are no queued events await async_wait_recording_done_without_instance(hass) @@ -423,11 +419,10 @@ async def test_backup_end(hass, hass_ws_client, hass_supervisor_access_token): async def test_backup_end_without_start( - hass, hass_ws_client, hass_supervisor_access_token + hass, hass_ws_client, hass_supervisor_access_token, recorder_mock ): """Test backup start.""" client = await hass_ws_client(hass, hass_supervisor_access_token) - await async_init_recorder_component(hass) # Ensure there are no queued events await async_wait_recording_done_without_instance(hass) @@ -445,7 +440,9 @@ async def test_backup_end_without_start( (METRIC_SYSTEM, ENERGY_SENSOR_ATTRIBUTES, "kWh"), ], ) -async def test_get_statistics_metadata(hass, hass_ws_client, units, attributes, unit): +async def test_get_statistics_metadata( + hass, hass_ws_client, recorder_mock, units, attributes, unit +): """Test get_statistics_metadata.""" now = dt_util.utcnow() @@ -453,7 +450,6 @@ async def test_get_statistics_metadata(hass, hass_ws_client, units, attributes, await hass.async_add_executor_job(init_recorder_component, hass) await async_setup_component(hass, "history", {"history": {}}) await async_setup_component(hass, "sensor", {}) - await async_init_recorder_component(hass) await hass.async_add_executor_job(hass.data[recorder.DATA_INSTANCE].block_till_done) client = await hass_ws_client() diff --git a/tests/components/script/test_recorder.py b/tests/components/script/test_recorder.py index c9a4f97491e..79f83b6c482 100644 --- a/tests/components/script/test_recorder.py +++ b/tests/components/script/test_recorder.py @@ -17,7 +17,7 @@ from homeassistant.const import ATTR_FRIENDLY_NAME from homeassistant.core import Context, State, callback from homeassistant.setup import async_setup_component -from tests.common import async_init_recorder_component, async_mock_service +from tests.common import async_mock_service from tests.components.recorder.common import async_wait_recording_done_without_instance @@ -27,9 +27,8 @@ def calls(hass): return async_mock_service(hass, "test", "automation") -async def test_exclude_attributes(hass, calls): +async def test_exclude_attributes(hass, recorder_mock, calls): """Test automation registered attributes to be excluded.""" - await async_init_recorder_component(hass) await hass.async_block_till_done() calls = [] context = Context() diff --git a/tests/components/select/test_recorder.py b/tests/components/select/test_recorder.py index f6366045338..76a32db3f9f 100644 --- a/tests/components/select/test_recorder.py +++ b/tests/components/select/test_recorder.py @@ -12,13 +12,12 @@ from homeassistant.core import State from homeassistant.setup import async_setup_component from homeassistant.util import dt as dt_util -from tests.common import async_fire_time_changed, async_init_recorder_component +from tests.common import async_fire_time_changed from tests.components.recorder.common import async_wait_recording_done_without_instance -async def test_exclude_attributes(hass): +async def test_exclude_attributes(hass, recorder_mock): """Test select registered attributes to be excluded.""" - await async_init_recorder_component(hass) await async_setup_component( hass, select.DOMAIN, {select.DOMAIN: {"platform": "demo"}} ) diff --git a/tests/components/sensor/test_recorder.py b/tests/components/sensor/test_recorder.py index 343f2678299..a56f440acb3 100644 --- a/tests/components/sensor/test_recorder.py +++ b/tests/components/sensor/test_recorder.py @@ -27,11 +27,7 @@ from homeassistant.setup import setup_component import homeassistant.util.dt as dt_util from homeassistant.util.unit_system import IMPERIAL_SYSTEM, METRIC_SYSTEM -from tests.common import ( - async_init_recorder_component, - async_setup_component, - init_recorder_component, -) +from tests.common import async_setup_component, init_recorder_component from tests.components.recorder.common import ( async_wait_recording_done_without_instance, wait_recording_done, @@ -347,6 +343,7 @@ def test_compile_hourly_statistics_unsupported(hass_recorder, caplog, attributes async def test_compile_hourly_sum_statistics_amount( hass, hass_ws_client, + recorder_mock, caplog, units, state_class, @@ -361,7 +358,6 @@ async def test_compile_hourly_sum_statistics_amount( period1_end = period2 = period0 + timedelta(minutes=10) period2_end = period0 + timedelta(minutes=15) client = await hass_ws_client() - await async_init_recorder_component(hass) hass.config.units = units recorder = hass.data[DATA_INSTANCE] await async_setup_component(hass, "sensor", {}) diff --git a/tests/components/siren/test_recorder.py b/tests/components/siren/test_recorder.py index 89d770fbfb3..db3ab5f1d3d 100644 --- a/tests/components/siren/test_recorder.py +++ b/tests/components/siren/test_recorder.py @@ -12,13 +12,12 @@ from homeassistant.core import State from homeassistant.setup import async_setup_component from homeassistant.util import dt as dt_util -from tests.common import async_fire_time_changed, async_init_recorder_component +from tests.common import async_fire_time_changed from tests.components.recorder.common import async_wait_recording_done_without_instance -async def test_exclude_attributes(hass): +async def test_exclude_attributes(hass, recorder_mock): """Test siren registered attributes to be excluded.""" - await async_init_recorder_component(hass) await async_setup_component( hass, siren.DOMAIN, {siren.DOMAIN: {"platform": "demo"}} ) diff --git a/tests/components/statistics/test_sensor.py b/tests/components/statistics/test_sensor.py index e2e6c7dfd5d..1f714446fd5 100644 --- a/tests/components/statistics/test_sensor.py +++ b/tests/components/statistics/test_sensor.py @@ -23,11 +23,7 @@ from homeassistant.helpers import entity_registry as er from homeassistant.setup import async_setup_component from homeassistant.util import dt as dt_util -from tests.common import ( - async_fire_time_changed, - async_init_recorder_component, - get_fixture_path, -) +from tests.common import async_fire_time_changed, get_fixture_path from tests.components.recorder.common import async_wait_recording_done_without_instance VALUES_BINARY = ["on", "off", "on", "off", "on", "off", "on", "off", "on"] @@ -906,10 +902,9 @@ async def test_invalid_state_characteristic(hass: HomeAssistant): assert state is None -async def test_initialize_from_database(hass: HomeAssistant): +async def test_initialize_from_database(hass: HomeAssistant, recorder_mock): """Test initializing the statistics from the recorder database.""" # enable and pre-fill the recorder - await async_init_recorder_component(hass) await hass.async_block_till_done() await async_wait_recording_done_without_instance(hass) @@ -946,7 +941,7 @@ async def test_initialize_from_database(hass: HomeAssistant): assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == TEMP_CELSIUS -async def test_initialize_from_database_with_maxage(hass: HomeAssistant): +async def test_initialize_from_database_with_maxage(hass: HomeAssistant, recorder_mock): """Test initializing the statistics from the database.""" now = dt_util.utcnow() mock_data = { @@ -962,7 +957,6 @@ async def test_initialize_from_database_with_maxage(hass: HomeAssistant): return # enable and pre-fill the recorder - await async_init_recorder_component(hass) await hass.async_block_till_done() await async_wait_recording_done_without_instance(hass) @@ -1007,9 +1001,8 @@ async def test_initialize_from_database_with_maxage(hass: HomeAssistant): ) + timedelta(hours=1) -async def test_reload(hass: HomeAssistant): +async def test_reload(hass: HomeAssistant, recorder_mock): """Verify we can reload statistics sensors.""" - await async_init_recorder_component(hass) await async_setup_component( hass, diff --git a/tests/components/sun/test_recorder.py b/tests/components/sun/test_recorder.py index 08e68fc7555..fc1664d340b 100644 --- a/tests/components/sun/test_recorder.py +++ b/tests/components/sun/test_recorder.py @@ -22,13 +22,12 @@ from homeassistant.core import State from homeassistant.setup import async_setup_component from homeassistant.util import dt as dt_util -from tests.common import async_fire_time_changed, async_init_recorder_component +from tests.common import async_fire_time_changed from tests.components.recorder.common import async_wait_recording_done_without_instance -async def test_exclude_attributes(hass): +async def test_exclude_attributes(hass, recorder_mock): """Test sun attributes to be excluded.""" - await async_init_recorder_component(hass) await async_setup_component(hass, DOMAIN, {}) await hass.async_block_till_done() async_fire_time_changed(hass, dt_util.utcnow() + timedelta(minutes=5)) diff --git a/tests/components/tibber/test_config_flow.py b/tests/components/tibber/test_config_flow.py index 198ff8ccfc4..1d42c9826e9 100644 --- a/tests/components/tibber/test_config_flow.py +++ b/tests/components/tibber/test_config_flow.py @@ -7,8 +7,6 @@ from homeassistant import config_entries from homeassistant.components.tibber.const import DOMAIN from homeassistant.const import CONF_ACCESS_TOKEN -from tests.common import async_init_recorder_component - @pytest.fixture(name="tibber_setup", autouse=True) def tibber_setup_fixture(): @@ -17,10 +15,8 @@ def tibber_setup_fixture(): yield -async def test_show_config_form(hass): +async def test_show_config_form(hass, recorder_mock): """Test show configuration form.""" - await async_init_recorder_component(hass) - result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_USER} ) @@ -29,10 +25,8 @@ async def test_show_config_form(hass): assert result["step_id"] == "user" -async def test_create_entry(hass): +async def test_create_entry(hass, recorder_mock): """Test create entry from user input.""" - await async_init_recorder_component(hass) - test_data = { CONF_ACCESS_TOKEN: "valid", } @@ -55,10 +49,8 @@ async def test_create_entry(hass): assert result["data"] == test_data -async def test_flow_entry_already_exists(hass, config_entry): +async def test_flow_entry_already_exists(hass, recorder_mock, config_entry): """Test user input for config_entry that already exists.""" - await async_init_recorder_component(hass) - test_data = { CONF_ACCESS_TOKEN: "valid", } diff --git a/tests/components/tibber/test_diagnostics.py b/tests/components/tibber/test_diagnostics.py index 706f86b63ac..c9210412820 100644 --- a/tests/components/tibber/test_diagnostics.py +++ b/tests/components/tibber/test_diagnostics.py @@ -5,14 +5,11 @@ from homeassistant.setup import async_setup_component from .test_common import mock_get_homes -from tests.common import async_init_recorder_component from tests.components.diagnostics import get_diagnostics_for_config_entry -async def test_entry_diagnostics(hass, hass_client, config_entry): +async def test_entry_diagnostics(hass, hass_client, recorder_mock, config_entry): """Test config entry diagnostics.""" - await async_init_recorder_component(hass) - with patch( "tibber.Tibber.update_info", return_value=None, diff --git a/tests/components/tibber/test_statistics.py b/tests/components/tibber/test_statistics.py index 7fbc0327910..8b8ad24d6b7 100644 --- a/tests/components/tibber/test_statistics.py +++ b/tests/components/tibber/test_statistics.py @@ -7,14 +7,11 @@ from homeassistant.util import dt as dt_util from .test_common import CONSUMPTION_DATA_1, mock_get_homes -from tests.common import async_init_recorder_component from tests.components.recorder.common import async_wait_recording_done_without_instance -async def test_async_setup_entry(hass): +async def test_async_setup_entry(hass, recorder_mock): """Test setup Tibber.""" - await async_init_recorder_component(hass) - tibber_connection = AsyncMock() tibber_connection.name = "tibber" tibber_connection.fetch_consumption_data_active_homes.return_value = None diff --git a/tests/components/update/test_recorder.py b/tests/components/update/test_recorder.py index 9e1767c190c..db31a5d5926 100644 --- a/tests/components/update/test_recorder.py +++ b/tests/components/update/test_recorder.py @@ -16,15 +16,14 @@ from homeassistant.core import HomeAssistant, State from homeassistant.setup import async_setup_component from homeassistant.util import dt as dt_util -from tests.common import async_fire_time_changed, async_init_recorder_component +from tests.common import async_fire_time_changed from tests.components.recorder.common import async_wait_recording_done_without_instance async def test_exclude_attributes( - hass: HomeAssistant, enable_custom_integrations: None + hass: HomeAssistant, recorder_mock, enable_custom_integrations: None ): """Test update attributes to be excluded.""" - await async_init_recorder_component(hass) platform = getattr(hass.components, f"test.{DOMAIN}") platform.init() assert await async_setup_component(hass, DOMAIN, {DOMAIN: {CONF_PLATFORM: "test"}}) diff --git a/tests/components/vacuum/test_recorder.py b/tests/components/vacuum/test_recorder.py index 0717c149d19..dc8744fedc1 100644 --- a/tests/components/vacuum/test_recorder.py +++ b/tests/components/vacuum/test_recorder.py @@ -12,13 +12,12 @@ from homeassistant.core import State from homeassistant.setup import async_setup_component from homeassistant.util import dt as dt_util -from tests.common import async_fire_time_changed, async_init_recorder_component +from tests.common import async_fire_time_changed from tests.components.recorder.common import async_wait_recording_done_without_instance -async def test_exclude_attributes(hass): +async def test_exclude_attributes(hass, recorder_mock): """Test vacuum registered attributes to be excluded.""" - await async_init_recorder_component(hass) await async_setup_component( hass, vacuum.DOMAIN, {vacuum.DOMAIN: {"platform": "demo"}} ) diff --git a/tests/components/water_heater/test_recorder.py b/tests/components/water_heater/test_recorder.py index b7e7fc4bb10..199a7785638 100644 --- a/tests/components/water_heater/test_recorder.py +++ b/tests/components/water_heater/test_recorder.py @@ -16,13 +16,12 @@ from homeassistant.core import State from homeassistant.setup import async_setup_component from homeassistant.util import dt as dt_util -from tests.common import async_fire_time_changed, async_init_recorder_component +from tests.common import async_fire_time_changed from tests.components.recorder.common import async_wait_recording_done_without_instance -async def test_exclude_attributes(hass): +async def test_exclude_attributes(hass, recorder_mock): """Test water_heater registered attributes to be excluded.""" - await async_init_recorder_component(hass) await async_setup_component( hass, water_heater.DOMAIN, {water_heater.DOMAIN: {"platform": "demo"}} ) diff --git a/tests/components/weather/test_recorder.py b/tests/components/weather/test_recorder.py index ed902df1385..19cd88bb0f2 100644 --- a/tests/components/weather/test_recorder.py +++ b/tests/components/weather/test_recorder.py @@ -11,13 +11,12 @@ from homeassistant.setup import async_setup_component from homeassistant.util import dt as dt_util from homeassistant.util.unit_system import METRIC_SYSTEM -from tests.common import async_fire_time_changed, async_init_recorder_component +from tests.common import async_fire_time_changed from tests.components.recorder.common import async_wait_recording_done_without_instance -async def test_exclude_attributes(hass: HomeAssistant) -> None: +async def test_exclude_attributes(hass: HomeAssistant, recorder_mock) -> None: """Test weather attributes to be excluded.""" - await async_init_recorder_component(hass) await async_setup_component(hass, DOMAIN, {DOMAIN: {"platform": "demo"}}) hass.config.units = METRIC_SYSTEM await hass.async_block_till_done() diff --git a/tests/conftest.py b/tests/conftest.py index e0b6d118999..53b6b877eda 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,5 +1,8 @@ """Set up some common test helper things.""" +from __future__ import annotations + import asyncio +from collections.abc import AsyncGenerator import functools import logging import socket @@ -26,7 +29,9 @@ from homeassistant.components.websocket_api.auth import ( ) from homeassistant.components.websocket_api.http import URL from homeassistant.const import HASSIO_USER_NAME +from homeassistant.core import CoreState, HomeAssistant from homeassistant.helpers import config_entry_oauth2_flow +from homeassistant.helpers.typing import ConfigType from homeassistant.setup import async_setup_component from homeassistant.util import dt as dt_util, location @@ -39,6 +44,7 @@ from tests.common import ( # noqa: E402, isort:skip INSTANCES, MockConfigEntry, MockUser, + SetupRecorderInstanceT, async_fire_mqtt_message, async_init_recorder_component, async_test_home_assistant, @@ -47,7 +53,9 @@ from tests.common import ( # noqa: E402, isort:skip mock_storage as mock_storage, ) from tests.test_util.aiohttp import mock_aiohttp_client # noqa: E402, isort:skip - +from tests.components.recorder.common import ( # noqa: E402, isort:skip + async_recorder_block_till_done, +) logging.basicConfig(level=logging.DEBUG) logging.getLogger("sqlalchemy.engine").setLevel(logging.INFO) @@ -680,28 +688,38 @@ def enable_statistics(): def enable_nightly_purge(): """Fixture to control enabling of recorder's nightly purge job. - To enable nightly purgin, tests can be marked with: + To enable nightly purging, tests can be marked with: @pytest.mark.parametrize("enable_nightly_purge", [True]) """ return False +@pytest.fixture +def recorder_config(): + """Fixture to override recorder config. + + To override the config, tests can be marked with: + @pytest.mark.parametrize("recorder_config", [{...}]) + """ + return None + + @pytest.fixture def hass_recorder(enable_nightly_purge, enable_statistics, hass_storage): """Home Assistant fixture with in-memory recorder.""" original_tz = dt_util.DEFAULT_TIME_ZONE hass = get_test_home_assistant() - stats = recorder.Recorder.async_periodic_statistics if enable_statistics else None nightly = recorder.Recorder.async_nightly_tasks if enable_nightly_purge else None + stats = recorder.Recorder.async_periodic_statistics if enable_statistics else None with patch( - "homeassistant.components.recorder.Recorder.async_periodic_statistics", - side_effect=stats, - autospec=True, - ), patch( "homeassistant.components.recorder.Recorder.async_nightly_tasks", side_effect=nightly, autospec=True, + ), patch( + "homeassistant.components.recorder.Recorder.async_periodic_statistics", + side_effect=stats, + autospec=True, ): def setup_recorder(config=None): @@ -720,25 +738,45 @@ def hass_recorder(enable_nightly_purge, enable_statistics, hass_storage): @pytest.fixture -async def recorder_mock(enable_nightly_purge, enable_statistics, hass): - """Fixture with in-memory recorder.""" - stats = recorder.Recorder.async_periodic_statistics if enable_statistics else None - nightly = recorder.Recorder.async_nightly_tasks if enable_nightly_purge else None - with patch( - "homeassistant.components.recorder.Recorder.async_periodic_statistics", - side_effect=stats, - autospec=True, - ), patch( - "homeassistant.components.recorder.Recorder.async_nightly_tasks", - side_effect=nightly, - autospec=True, - ): - await async_init_recorder_component(hass) - await hass.async_start() - await hass.async_block_till_done() - await hass.async_add_executor_job( - hass.data[recorder.DATA_INSTANCE].block_till_done +async def async_setup_recorder_instance( + enable_nightly_purge, enable_statistics +) -> AsyncGenerator[SetupRecorderInstanceT, None]: + """Yield callable to setup recorder instance.""" + + async def async_setup_recorder( + hass: HomeAssistant, config: ConfigType | None = None + ) -> recorder.Recorder: + """Setup and return recorder instance.""" # noqa: D401 + nightly = ( + recorder.Recorder.async_nightly_tasks if enable_nightly_purge else None ) + stats = ( + recorder.Recorder.async_periodic_statistics if enable_statistics else None + ) + with patch( + "homeassistant.components.recorder.Recorder.async_nightly_tasks", + side_effect=nightly, + autospec=True, + ), patch( + "homeassistant.components.recorder.Recorder.async_periodic_statistics", + side_effect=stats, + autospec=True, + ): + await async_init_recorder_component(hass, config) + await hass.async_block_till_done() + instance = hass.data[recorder.DATA_INSTANCE] + # The recorder's worker is not started until Home Assistant is running + if hass.state == CoreState.running: + await async_recorder_block_till_done(hass, instance) + return instance + + return async_setup_recorder + + +@pytest.fixture +async def recorder_mock(recorder_config, async_setup_recorder_instance, hass): + """Fixture with in-memory recorder.""" + await async_setup_recorder_instance(hass, recorder_config) @pytest.fixture