From d01d161fe27d745e08899b7043eece26288e479d Mon Sep 17 00:00:00 2001 From: Erik Montnemery Date: Mon, 6 May 2024 15:10:45 +0200 Subject: [PATCH] Convert recorder history tests to use async API (#116909) --- tests/components/recorder/test_history.py | 207 +++++++++--------- .../recorder/test_history_db_schema_30.py | 157 ++++++------- .../recorder/test_history_db_schema_32.py | 162 +++++++------- .../recorder/test_history_db_schema_42.py | 207 +++++++++--------- 4 files changed, 352 insertions(+), 381 deletions(-) diff --git a/tests/components/recorder/test_history.py b/tests/components/recorder/test_history.py index ebcb0522e72..af32edbca6b 100644 --- a/tests/components/recorder/test_history.py +++ b/tests/components/recorder/test_history.py @@ -2,7 +2,6 @@ from __future__ import annotations -from collections.abc import Callable from copy import copy from datetime import datetime, timedelta import json @@ -41,12 +40,23 @@ from .common import ( assert_states_equal_without_context, async_recorder_block_till_done, async_wait_recording_done, - wait_recording_done, ) from tests.typing import RecorderInstanceGenerator +@pytest.fixture +async def mock_recorder_before_hass( + async_setup_recorder_instance: RecorderInstanceGenerator, +) -> None: + """Set up recorder.""" + + +@pytest.fixture(autouse=True) +def setup_recorder(recorder_mock: Recorder) -> recorder.Recorder: + """Set up recorder.""" + + async def _async_get_states( hass: HomeAssistant, utc_point_in_time: datetime, @@ -118,11 +128,10 @@ def _add_db_entries( ) -def test_get_full_significant_states_with_session_entity_no_matches( - hass_recorder: Callable[..., HomeAssistant], +async def test_get_full_significant_states_with_session_entity_no_matches( + hass: HomeAssistant, ) -> None: """Test getting states at a specific point in time for entities that never have been recorded.""" - hass = hass_recorder() now = dt_util.utcnow() time_before_recorder_ran = now - timedelta(days=1000) with session_scope(hass=hass, read_only=True) as session: @@ -144,11 +153,10 @@ def test_get_full_significant_states_with_session_entity_no_matches( ) -def test_significant_states_with_session_entity_minimal_response_no_matches( - hass_recorder: Callable[..., HomeAssistant], +async def test_significant_states_with_session_entity_minimal_response_no_matches( + hass: HomeAssistant, ) -> None: """Test getting states at a specific point in time for entities that never have been recorded.""" - hass = hass_recorder() now = dt_util.utcnow() time_before_recorder_ran = now - timedelta(days=1000) with session_scope(hass=hass, read_only=True) as session: @@ -176,14 +184,13 @@ def test_significant_states_with_session_entity_minimal_response_no_matches( ) -def test_significant_states_with_session_single_entity( - hass_recorder: Callable[..., HomeAssistant], +async def test_significant_states_with_session_single_entity( + hass: HomeAssistant, ) -> None: """Test get_significant_states_with_session with a single entity.""" - hass = hass_recorder() - hass.states.set("demo.id", "any", {"attr": True}) - hass.states.set("demo.id", "any2", {"attr": True}) - wait_recording_done(hass) + hass.states.async_set("demo.id", "any", {"attr": True}) + hass.states.async_set("demo.id", "any2", {"attr": True}) + await async_wait_recording_done(hass) now = dt_util.utcnow() with session_scope(hass=hass, read_only=True) as session: states = history.get_significant_states_with_session( @@ -206,17 +213,15 @@ def test_significant_states_with_session_single_entity( ({}, True, 3), ], ) -def test_state_changes_during_period( - hass_recorder: Callable[..., HomeAssistant], attributes, no_attributes, limit +async def test_state_changes_during_period( + hass: HomeAssistant, attributes, no_attributes, limit ) -> None: """Test state change during period.""" - hass = hass_recorder() entity_id = "media_player.test" def set_state(state): """Set the state.""" - hass.states.set(entity_id, state, attributes) - wait_recording_done(hass) + hass.states.async_set(entity_id, state, attributes) return hass.states.get(entity_id) start = dt_util.utcnow() @@ -238,6 +243,7 @@ def test_state_changes_during_period( freezer.move_to(end) set_state("Netflix") set_state("Plex") + await async_wait_recording_done(hass) hist = history.state_changes_during_period( hass, start, end, entity_id, no_attributes, limit=limit @@ -246,17 +252,15 @@ def test_state_changes_during_period( assert_multiple_states_equal_without_context(states[:limit], hist[entity_id]) -def test_state_changes_during_period_last_reported( - hass_recorder: Callable[..., HomeAssistant], +async def test_state_changes_during_period_last_reported( + hass: HomeAssistant, ) -> None: """Test state change during period.""" - hass = hass_recorder() entity_id = "media_player.test" def set_state(state): """Set the state.""" - hass.states.set(entity_id, state) - wait_recording_done(hass) + hass.states.async_set(entity_id, state) return hass.states.get(entity_id) start = dt_util.utcnow() @@ -275,23 +279,22 @@ def test_state_changes_during_period_last_reported( freezer.move_to(end) set_state("Netflix") + await async_wait_recording_done(hass) hist = history.state_changes_during_period(hass, start, end, entity_id) assert_multiple_states_equal_without_context(states, hist[entity_id]) -def test_state_changes_during_period_descending( - hass_recorder: Callable[..., HomeAssistant], +async def test_state_changes_during_period_descending( + hass: HomeAssistant, ) -> None: """Test state change during period descending.""" - hass = hass_recorder() entity_id = "media_player.test" def set_state(state): """Set the state.""" - hass.states.set(entity_id, state, {"any": 1}) - wait_recording_done(hass) + hass.states.async_set(entity_id, state, {"any": 1}) return hass.states.get(entity_id) start = dt_util.utcnow().replace(microsecond=0) @@ -320,6 +323,7 @@ def test_state_changes_during_period_descending( freezer.move_to(end) set_state("Netflix") set_state("Plex") + await async_wait_recording_done(hass) hist = history.state_changes_during_period( hass, start, end, entity_id, no_attributes=False, descending=False @@ -385,15 +389,13 @@ def test_state_changes_during_period_descending( ) -def test_get_last_state_changes(hass_recorder: Callable[..., HomeAssistant]) -> None: +async def test_get_last_state_changes(hass: HomeAssistant) -> None: """Test number of state changes.""" - hass = hass_recorder() entity_id = "sensor.test" def set_state(state): """Set the state.""" - hass.states.set(entity_id, state) - wait_recording_done(hass) + hass.states.async_set(entity_id, state) return hass.states.get(entity_id) start = dt_util.utcnow() - timedelta(minutes=2) @@ -409,23 +411,22 @@ def test_get_last_state_changes(hass_recorder: Callable[..., HomeAssistant]) -> freezer.move_to(point2) states.append(set_state("3")) + await async_wait_recording_done(hass) hist = history.get_last_state_changes(hass, 2, entity_id) assert_multiple_states_equal_without_context(states, hist[entity_id]) -def test_get_last_state_changes_last_reported( - hass_recorder: Callable[..., HomeAssistant], +async def test_get_last_state_changes_last_reported( + hass: HomeAssistant, ) -> None: """Test number of state changes.""" - hass = hass_recorder() entity_id = "sensor.test" def set_state(state): """Set the state.""" - hass.states.set(entity_id, state) - wait_recording_done(hass) + hass.states.async_set(entity_id, state) return hass.states.get(entity_id) start = dt_util.utcnow() - timedelta(minutes=2) @@ -441,21 +442,20 @@ def test_get_last_state_changes_last_reported( freezer.move_to(point2) states.append(set_state("2")) + await async_wait_recording_done(hass) hist = history.get_last_state_changes(hass, 2, entity_id) assert_multiple_states_equal_without_context(states, hist[entity_id]) -def test_get_last_state_change(hass_recorder: Callable[..., HomeAssistant]) -> None: +async def test_get_last_state_change(hass: HomeAssistant) -> None: """Test getting the last state change for an entity.""" - hass = hass_recorder() entity_id = "sensor.test" def set_state(state): """Set the state.""" - hass.states.set(entity_id, state) - wait_recording_done(hass) + hass.states.async_set(entity_id, state) return hass.states.get(entity_id) start = dt_util.utcnow() - timedelta(minutes=2) @@ -471,27 +471,26 @@ def test_get_last_state_change(hass_recorder: Callable[..., HomeAssistant]) -> N freezer.move_to(point2) states.append(set_state("3")) + await async_wait_recording_done(hass) hist = history.get_last_state_changes(hass, 1, entity_id) assert_multiple_states_equal_without_context(states, hist[entity_id]) -def test_ensure_state_can_be_copied( - hass_recorder: Callable[..., HomeAssistant], +async def test_ensure_state_can_be_copied( + hass: HomeAssistant, ) -> None: """Ensure a state can pass though copy(). The filter integration uses copy() on states from history. """ - hass = hass_recorder() entity_id = "sensor.test" def set_state(state): """Set the state.""" - hass.states.set(entity_id, state) - wait_recording_done(hass) + hass.states.async_set(entity_id, state) return hass.states.get(entity_id) start = dt_util.utcnow() - timedelta(minutes=2) @@ -502,6 +501,7 @@ def test_ensure_state_can_be_copied( freezer.move_to(point) set_state("2") + await async_wait_recording_done(hass) hist = history.get_last_state_changes(hass, 2, entity_id) @@ -509,21 +509,22 @@ def test_ensure_state_can_be_copied( assert_states_equal_without_context(copy(hist[entity_id][1]), hist[entity_id][1]) -def test_get_significant_states(hass_recorder: Callable[..., HomeAssistant]) -> None: +async def test_get_significant_states(hass: HomeAssistant) -> None: """Test that only significant states are returned. We should get back every thermostat change that includes an attribute change, but only the state updates for media player (attribute changes are not significant and not returned). """ - hass = hass_recorder() zero, four, states = record_states(hass) + await async_wait_recording_done(hass) + hist = history.get_significant_states(hass, zero, four, entity_ids=list(states)) assert_dict_of_states_equal_without_context_and_last_changed(states, hist) -def test_get_significant_states_minimal_response( - hass_recorder: Callable[..., HomeAssistant], +async def test_get_significant_states_minimal_response( + hass: HomeAssistant, ) -> None: """Test that only significant states are returned. @@ -534,8 +535,9 @@ def test_get_significant_states_minimal_response( includes an attribute change, but only the state updates for media player (attribute changes are not significant and not returned). """ - hass = hass_recorder() zero, four, states = record_states(hass) + await async_wait_recording_done(hass) + hist = history.get_significant_states( hass, zero, four, minimal_response=True, entity_ids=list(states) ) @@ -591,8 +593,8 @@ def test_get_significant_states_minimal_response( @pytest.mark.parametrize("time_zone", ["Europe/Berlin", "US/Hawaii", "UTC"]) -def test_get_significant_states_with_initial( - time_zone, hass_recorder: Callable[..., HomeAssistant] +async def test_get_significant_states_with_initial( + time_zone, hass: HomeAssistant ) -> None: """Test that only significant states are returned. @@ -600,9 +602,10 @@ def test_get_significant_states_with_initial( includes an attribute change, but only the state updates for media player (attribute changes are not significant and not returned). """ - hass = hass_recorder() hass.config.set_time_zone(time_zone) zero, four, states = record_states(hass) + await async_wait_recording_done(hass) + one_and_half = zero + timedelta(seconds=1.5) for entity_id in states: if entity_id == "media_player.test": @@ -621,8 +624,8 @@ def test_get_significant_states_with_initial( assert_dict_of_states_equal_without_context_and_last_changed(states, hist) -def test_get_significant_states_without_initial( - hass_recorder: Callable[..., HomeAssistant], +async def test_get_significant_states_without_initial( + hass: HomeAssistant, ) -> None: """Test that only significant states are returned. @@ -630,8 +633,9 @@ def test_get_significant_states_without_initial( includes an attribute change, but only the state updates for media player (attribute changes are not significant and not returned). """ - hass = hass_recorder() zero, four, states = record_states(hass) + await async_wait_recording_done(hass) + one = zero + timedelta(seconds=1) one_with_microsecond = zero + timedelta(seconds=1, microseconds=1) one_and_half = zero + timedelta(seconds=1.5) @@ -654,12 +658,13 @@ def test_get_significant_states_without_initial( assert_dict_of_states_equal_without_context_and_last_changed(states, hist) -def test_get_significant_states_entity_id( - hass_recorder: Callable[..., HomeAssistant], +async def test_get_significant_states_entity_id( + hass: HomeAssistant, ) -> None: """Test that only significant states are returned for one entity.""" - hass = hass_recorder() zero, four, states = record_states(hass) + await async_wait_recording_done(hass) + del states["media_player.test2"] del states["media_player.test3"] del states["thermostat.test"] @@ -671,12 +676,12 @@ def test_get_significant_states_entity_id( assert_dict_of_states_equal_without_context_and_last_changed(states, hist) -def test_get_significant_states_multiple_entity_ids( - hass_recorder: Callable[..., HomeAssistant], +async def test_get_significant_states_multiple_entity_ids( + hass: HomeAssistant, ) -> None: """Test that only significant states are returned for one entity.""" - hass = hass_recorder() zero, four, states = record_states(hass) + await async_wait_recording_done(hass) hist = history.get_significant_states( hass, @@ -693,16 +698,17 @@ def test_get_significant_states_multiple_entity_ids( ) -def test_get_significant_states_are_ordered( - hass_recorder: Callable[..., HomeAssistant], +async def test_get_significant_states_are_ordered( + hass: HomeAssistant, ) -> None: """Test order of results from get_significant_states. When entity ids are given, the results should be returned with the data in the same order. """ - hass = hass_recorder() zero, four, _states = record_states(hass) + await async_wait_recording_done(hass) + entity_ids = ["media_player.test", "media_player.test2"] hist = history.get_significant_states(hass, zero, four, entity_ids) assert list(hist.keys()) == entity_ids @@ -711,17 +717,15 @@ def test_get_significant_states_are_ordered( assert list(hist.keys()) == entity_ids -def test_get_significant_states_only( - hass_recorder: Callable[..., HomeAssistant], +async def test_get_significant_states_only( + hass: HomeAssistant, ) -> None: """Test significant states when significant_states_only is set.""" - hass = hass_recorder() entity_id = "sensor.test" def set_state(state, **kwargs): """Set the state.""" - hass.states.set(entity_id, state, **kwargs) - wait_recording_done(hass) + hass.states.async_set(entity_id, state, **kwargs) return hass.states.get(entity_id) start = dt_util.utcnow() - timedelta(minutes=4) @@ -742,6 +746,7 @@ def test_get_significant_states_only( freezer.move_to(points[2]) # everything is different states.append(set_state("412", attributes={"attribute": 54.23})) + await async_wait_recording_done(hass) hist = history.get_significant_states( hass, @@ -775,7 +780,7 @@ def test_get_significant_states_only( async def test_get_significant_states_only_minimal_response( - recorder_mock: Recorder, hass: HomeAssistant + hass: HomeAssistant, ) -> None: """Test significant states when significant_states_only is True.""" now = dt_util.utcnow() @@ -818,8 +823,7 @@ def record_states(hass) -> tuple[datetime, datetime, dict[str, list[State]]]: def set_state(entity_id, state, **kwargs): """Set the state.""" - hass.states.set(entity_id, state, **kwargs) - wait_recording_done(hass) + hass.states.async_set(entity_id, state, **kwargs) return hass.states.get(entity_id) zero = dt_util.utcnow() @@ -886,7 +890,6 @@ def record_states(hass) -> tuple[datetime, datetime, dict[str, list[State]]]: async def test_state_changes_during_period_query_during_migration_to_schema_25( - async_setup_recorder_instance: RecorderInstanceGenerator, hass: HomeAssistant, recorder_db_url: str, ) -> None: @@ -895,7 +898,7 @@ async def test_state_changes_during_period_query_during_migration_to_schema_25( # This test doesn't run on MySQL / MariaDB / Postgresql; we can't drop table state_attributes return - instance = await async_setup_recorder_instance(hass, {}) + instance = recorder.get_instance(hass) with patch.object(instance.states_meta_manager, "active", False): start = dt_util.utcnow() @@ -953,7 +956,6 @@ async def test_state_changes_during_period_query_during_migration_to_schema_25( async def test_get_states_query_during_migration_to_schema_25( - async_setup_recorder_instance: RecorderInstanceGenerator, hass: HomeAssistant, recorder_db_url: str, ) -> None: @@ -962,7 +964,7 @@ async def test_get_states_query_during_migration_to_schema_25( # This test doesn't run on MySQL / MariaDB / Postgresql; we can't drop table state_attributes return - instance = await async_setup_recorder_instance(hass, {}) + instance = recorder.get_instance(hass) start = dt_util.utcnow() point = start + timedelta(seconds=1) @@ -1004,7 +1006,6 @@ async def test_get_states_query_during_migration_to_schema_25( async def test_get_states_query_during_migration_to_schema_25_multiple_entities( - async_setup_recorder_instance: RecorderInstanceGenerator, hass: HomeAssistant, recorder_db_url: str, ) -> None: @@ -1013,7 +1014,7 @@ async def test_get_states_query_during_migration_to_schema_25_multiple_entities( # This test doesn't run on MySQL / MariaDB / Postgresql; we can't drop table state_attributes return - instance = await async_setup_recorder_instance(hass, {}) + instance = recorder.get_instance(hass) start = dt_util.utcnow() point = start + timedelta(seconds=1) @@ -1058,12 +1059,9 @@ async def test_get_states_query_during_migration_to_schema_25_multiple_entities( async def test_get_full_significant_states_handles_empty_last_changed( - async_setup_recorder_instance: RecorderInstanceGenerator, hass: HomeAssistant, ) -> None: """Test getting states when last_changed is null.""" - await async_setup_recorder_instance(hass, {}) - now = dt_util.utcnow() hass.states.async_set("sensor.one", "on", {"attr": "original"}) state0 = hass.states.get("sensor.one") @@ -1155,21 +1153,20 @@ async def test_get_full_significant_states_handles_empty_last_changed( ) -def test_state_changes_during_period_multiple_entities_single_test( - hass_recorder: Callable[..., HomeAssistant], +async def test_state_changes_during_period_multiple_entities_single_test( + hass: HomeAssistant, ) -> None: """Test state change during period with multiple entities in the same test. This test ensures the sqlalchemy query cache does not generate incorrect results. """ - hass = hass_recorder() start = dt_util.utcnow() test_entites = {f"sensor.{i}": str(i) for i in range(30)} for entity_id, value in test_entites.items(): - hass.states.set(entity_id, value) + hass.states.async_set(entity_id, value) + await async_wait_recording_done(hass) - wait_recording_done(hass) end = dt_util.utcnow() for entity_id, value in test_entites.items(): @@ -1180,11 +1177,9 @@ def test_state_changes_during_period_multiple_entities_single_test( @pytest.mark.freeze_time("2039-01-19 03:14:07.555555-00:00") async def test_get_full_significant_states_past_year_2038( - async_setup_recorder_instance: RecorderInstanceGenerator, hass: HomeAssistant, ) -> None: """Test we can store times past year 2038.""" - await async_setup_recorder_instance(hass, {}) past_2038_time = dt_util.parse_datetime("2039-01-19 03:14:07.555555-00:00") hass.states.async_set("sensor.one", "on", {"attr": "original"}) state0 = hass.states.get("sensor.one") @@ -1214,31 +1209,28 @@ async def test_get_full_significant_states_past_year_2038( assert sensor_one_states[0].last_updated == past_2038_time -def test_get_significant_states_without_entity_ids_raises( - hass_recorder: Callable[..., HomeAssistant], +async def test_get_significant_states_without_entity_ids_raises( + hass: HomeAssistant, ) -> None: """Test at least one entity id is required for get_significant_states.""" - hass = hass_recorder() now = dt_util.utcnow() with pytest.raises(ValueError, match="entity_ids must be provided"): history.get_significant_states(hass, now, None) -def test_state_changes_during_period_without_entity_ids_raises( - hass_recorder: Callable[..., HomeAssistant], +async def test_state_changes_during_period_without_entity_ids_raises( + hass: HomeAssistant, ) -> None: """Test at least one entity id is required for state_changes_during_period.""" - hass = hass_recorder() now = dt_util.utcnow() with pytest.raises(ValueError, match="entity_id must be provided"): history.state_changes_during_period(hass, now, None) -def test_get_significant_states_with_filters_raises( - hass_recorder: Callable[..., HomeAssistant], +async def test_get_significant_states_with_filters_raises( + hass: HomeAssistant, ) -> None: """Test passing filters is no longer supported.""" - hass = hass_recorder() now = dt_util.utcnow() with pytest.raises(NotImplementedError, match="Filters are no longer supported"): history.get_significant_states( @@ -1246,29 +1238,26 @@ def test_get_significant_states_with_filters_raises( ) -def test_get_significant_states_with_non_existent_entity_ids_returns_empty( - hass_recorder: Callable[..., HomeAssistant], +async def test_get_significant_states_with_non_existent_entity_ids_returns_empty( + hass: HomeAssistant, ) -> None: """Test get_significant_states returns an empty dict when entities not in the db.""" - hass = hass_recorder() now = dt_util.utcnow() assert history.get_significant_states(hass, now, None, ["nonexistent.entity"]) == {} -def test_state_changes_during_period_with_non_existent_entity_ids_returns_empty( - hass_recorder: Callable[..., HomeAssistant], +async def test_state_changes_during_period_with_non_existent_entity_ids_returns_empty( + hass: HomeAssistant, ) -> None: """Test state_changes_during_period returns an empty dict when entities not in the db.""" - hass = hass_recorder() now = dt_util.utcnow() assert ( history.state_changes_during_period(hass, now, None, "nonexistent.entity") == {} ) -def test_get_last_state_changes_with_non_existent_entity_ids_returns_empty( - hass_recorder: Callable[..., HomeAssistant], +async def test_get_last_state_changes_with_non_existent_entity_ids_returns_empty( + hass: HomeAssistant, ) -> None: """Test get_last_state_changes returns an empty dict when entities not in the db.""" - hass = hass_recorder() assert history.get_last_state_changes(hass, 1, "nonexistent.entity") == {} diff --git a/tests/components/recorder/test_history_db_schema_30.py b/tests/components/recorder/test_history_db_schema_30.py index 2d0b3398a87..e5e80b0cdb9 100644 --- a/tests/components/recorder/test_history_db_schema_30.py +++ b/tests/components/recorder/test_history_db_schema_30.py @@ -2,7 +2,6 @@ from __future__ import annotations -from collections.abc import Callable from copy import copy from datetime import datetime, timedelta import json @@ -12,7 +11,7 @@ from freezegun import freeze_time import pytest from homeassistant.components import recorder -from homeassistant.components.recorder import history +from homeassistant.components.recorder import Recorder, history from homeassistant.components.recorder.filters import Filters from homeassistant.components.recorder.models import process_timestamp from homeassistant.components.recorder.util import session_scope @@ -25,10 +24,19 @@ from .common import ( assert_multiple_states_equal_without_context, assert_multiple_states_equal_without_context_and_last_changed, assert_states_equal_without_context, + async_wait_recording_done, old_db_schema, - wait_recording_done, ) +from tests.typing import RecorderInstanceGenerator + + +@pytest.fixture +async def mock_recorder_before_hass( + async_setup_recorder_instance: RecorderInstanceGenerator, +) -> None: + """Set up recorder.""" + @pytest.fixture(autouse=True) def db_schema_30(): @@ -37,11 +45,15 @@ def db_schema_30(): yield -def test_get_full_significant_states_with_session_entity_no_matches( - hass_recorder: Callable[..., HomeAssistant], +@pytest.fixture(autouse=True) +def setup_recorder(db_schema_30, recorder_mock: Recorder) -> recorder.Recorder: + """Set up recorder.""" + + +async def test_get_full_significant_states_with_session_entity_no_matches( + hass: HomeAssistant, ) -> None: """Test getting states at a specific point in time for entities that never have been recorded.""" - hass = hass_recorder() now = dt_util.utcnow() time_before_recorder_ran = now - timedelta(days=1000) instance = recorder.get_instance(hass) @@ -67,11 +79,10 @@ def test_get_full_significant_states_with_session_entity_no_matches( ) -def test_significant_states_with_session_entity_minimal_response_no_matches( - hass_recorder: Callable[..., HomeAssistant], +async def test_significant_states_with_session_entity_minimal_response_no_matches( + hass: HomeAssistant, ) -> None: """Test getting states at a specific point in time for entities that never have been recorded.""" - hass = hass_recorder() now = dt_util.utcnow() time_before_recorder_ran = now - timedelta(days=1000) instance = recorder.get_instance(hass) @@ -112,19 +123,17 @@ def test_significant_states_with_session_entity_minimal_response_no_matches( ({}, True, 3), ], ) -def test_state_changes_during_period( - hass_recorder: Callable[..., HomeAssistant], attributes, no_attributes, limit +async def test_state_changes_during_period( + hass: HomeAssistant, attributes, no_attributes, limit ) -> None: """Test state change during period.""" - hass = hass_recorder() entity_id = "media_player.test" instance = recorder.get_instance(hass) with patch.object(instance.states_meta_manager, "active", False): def set_state(state): """Set the state.""" - hass.states.set(entity_id, state, attributes) - wait_recording_done(hass) + hass.states.async_set(entity_id, state, attributes) return hass.states.get(entity_id) start = dt_util.utcnow() @@ -146,6 +155,7 @@ def test_state_changes_during_period( freezer.move_to(end) set_state("Netflix") set_state("Plex") + await async_wait_recording_done(hass) hist = history.state_changes_during_period( hass, start, end, entity_id, no_attributes, limit=limit @@ -154,19 +164,17 @@ def test_state_changes_during_period( assert_multiple_states_equal_without_context(states[:limit], hist[entity_id]) -def test_state_changes_during_period_descending( - hass_recorder: Callable[..., HomeAssistant], +async def test_state_changes_during_period_descending( + hass: HomeAssistant, ) -> None: """Test state change during period descending.""" - hass = hass_recorder() entity_id = "media_player.test" instance = recorder.get_instance(hass) with patch.object(instance.states_meta_manager, "active", False): def set_state(state): """Set the state.""" - hass.states.set(entity_id, state, {"any": 1}) - wait_recording_done(hass) + hass.states.async_set(entity_id, state, {"any": 1}) return hass.states.get(entity_id) start = dt_util.utcnow() @@ -196,6 +204,7 @@ def test_state_changes_during_period_descending( freezer.move_to(end) set_state("Netflix") set_state("Plex") + await async_wait_recording_done(hass) hist = history.state_changes_during_period( hass, start, end, entity_id, no_attributes=False, descending=False @@ -210,17 +219,15 @@ def test_state_changes_during_period_descending( ) -def test_get_last_state_changes(hass_recorder: Callable[..., HomeAssistant]) -> None: +async def test_get_last_state_changes(hass: HomeAssistant) -> None: """Test number of state changes.""" - hass = hass_recorder() entity_id = "sensor.test" instance = recorder.get_instance(hass) with patch.object(instance.states_meta_manager, "active", False): def set_state(state): """Set the state.""" - hass.states.set(entity_id, state) - wait_recording_done(hass) + hass.states.async_set(entity_id, state) return hass.states.get(entity_id) start = dt_util.utcnow() - timedelta(minutes=2) @@ -236,29 +243,28 @@ def test_get_last_state_changes(hass_recorder: Callable[..., HomeAssistant]) -> freezer.move_to(point2) states.append(set_state("3")) + await async_wait_recording_done(hass) hist = history.get_last_state_changes(hass, 2, entity_id) assert_multiple_states_equal_without_context(states, hist[entity_id]) -def test_ensure_state_can_be_copied( - hass_recorder: Callable[..., HomeAssistant], +async def test_ensure_state_can_be_copied( + hass: HomeAssistant, ) -> None: """Ensure a state can pass though copy(). The filter integration uses copy() on states from history. """ - hass = hass_recorder() entity_id = "sensor.test" instance = recorder.get_instance(hass) with patch.object(instance.states_meta_manager, "active", False): def set_state(state): """Set the state.""" - hass.states.set(entity_id, state) - wait_recording_done(hass) + hass.states.async_set(entity_id, state) return hass.states.get(entity_id) start = dt_util.utcnow() - timedelta(minutes=2) @@ -269,6 +275,7 @@ def test_ensure_state_can_be_copied( freezer.move_to(point) set_state("2") + await async_wait_recording_done(hass) hist = history.get_last_state_changes(hass, 2, entity_id) @@ -280,24 +287,23 @@ def test_ensure_state_can_be_copied( ) -def test_get_significant_states(hass_recorder: Callable[..., HomeAssistant]) -> None: +async def test_get_significant_states(hass: HomeAssistant) -> None: """Test that only significant states are returned. We should get back every thermostat change that includes an attribute change, but only the state updates for media player (attribute changes are not significant and not returned). """ - hass = hass_recorder() instance = recorder.get_instance(hass) with patch.object(instance.states_meta_manager, "active", False): zero, four, states = record_states(hass) + await async_wait_recording_done(hass) + hist = history.get_significant_states(hass, zero, four, entity_ids=list(states)) assert_dict_of_states_equal_without_context_and_last_changed(states, hist) -def test_get_significant_states_minimal_response( - hass_recorder: Callable[..., HomeAssistant], -) -> None: +async def test_get_significant_states_minimal_response(hass: HomeAssistant) -> None: """Test that only significant states are returned. When minimal responses is set only the first and @@ -306,10 +312,11 @@ def test_get_significant_states_minimal_response( includes an attribute change, but only the state updates for media player (attribute changes are not significant and not returned). """ - hass = hass_recorder() instance = recorder.get_instance(hass) with patch.object(instance.states_meta_manager, "active", False): zero, four, states = record_states(hass) + await async_wait_recording_done(hass) + hist = history.get_significant_states( hass, zero, four, minimal_response=True, entity_ids=list(states) ) @@ -364,19 +371,18 @@ def test_get_significant_states_minimal_response( ) -def test_get_significant_states_with_initial( - hass_recorder: Callable[..., HomeAssistant], -) -> None: +async def test_get_significant_states_with_initial(hass: HomeAssistant) -> None: """Test that only significant states are returned. We should get back every thermostat change that includes an attribute change, but only the state updates for media player (attribute changes are not significant and not returned). """ - hass = hass_recorder() instance = recorder.get_instance(hass) with patch.object(instance.states_meta_manager, "active", False): zero, four, states = record_states(hass) + await async_wait_recording_done(hass) + one = zero + timedelta(seconds=1) one_with_microsecond = zero + timedelta(seconds=1, microseconds=1) one_and_half = zero + timedelta(seconds=1.5) @@ -398,19 +404,18 @@ def test_get_significant_states_with_initial( assert_dict_of_states_equal_without_context_and_last_changed(states, hist) -def test_get_significant_states_without_initial( - hass_recorder: Callable[..., HomeAssistant], -) -> None: +async def test_get_significant_states_without_initial(hass: HomeAssistant) -> None: """Test that only significant states are returned. We should get back every thermostat change that includes an attribute change, but only the state updates for media player (attribute changes are not significant and not returned). """ - hass = hass_recorder() instance = recorder.get_instance(hass) with patch.object(instance.states_meta_manager, "active", False): zero, four, states = record_states(hass) + await async_wait_recording_done(hass) + one = zero + timedelta(seconds=1) one_with_microsecond = zero + timedelta(seconds=1, microseconds=1) one_and_half = zero + timedelta(seconds=1.5) @@ -432,14 +437,13 @@ def test_get_significant_states_without_initial( assert_dict_of_states_equal_without_context_and_last_changed(states, hist) -def test_get_significant_states_entity_id( - hass_recorder: Callable[..., HomeAssistant], -) -> None: +async def test_get_significant_states_entity_id(hass: HomeAssistant) -> None: """Test that only significant states are returned for one entity.""" - hass = hass_recorder() instance = recorder.get_instance(hass) with patch.object(instance.states_meta_manager, "active", False): zero, four, states = record_states(hass) + await async_wait_recording_done(hass) + del states["media_player.test2"] del states["media_player.test3"] del states["thermostat.test"] @@ -450,14 +454,13 @@ def test_get_significant_states_entity_id( assert_dict_of_states_equal_without_context_and_last_changed(states, hist) -def test_get_significant_states_multiple_entity_ids( - hass_recorder: Callable[..., HomeAssistant], -) -> None: +async def test_get_significant_states_multiple_entity_ids(hass: HomeAssistant) -> None: """Test that only significant states are returned for one entity.""" - hass = hass_recorder() instance = recorder.get_instance(hass) with patch.object(instance.states_meta_manager, "active", False): zero, four, states = record_states(hass) + await async_wait_recording_done(hass) + del states["media_player.test2"] del states["media_player.test3"] del states["thermostat.test2"] @@ -477,19 +480,18 @@ def test_get_significant_states_multiple_entity_ids( ) -def test_get_significant_states_are_ordered( - hass_recorder: Callable[..., HomeAssistant], -) -> None: +async def test_get_significant_states_are_ordered(hass: HomeAssistant) -> None: """Test order of results from get_significant_states. When entity ids are given, the results should be returned with the data in the same order. """ - hass = hass_recorder() instance = recorder.get_instance(hass) with patch.object(instance.states_meta_manager, "active", False): zero, four, _states = record_states(hass) + await async_wait_recording_done(hass) + entity_ids = ["media_player.test", "media_player.test2"] hist = history.get_significant_states(hass, zero, four, entity_ids) assert list(hist.keys()) == entity_ids @@ -498,19 +500,15 @@ def test_get_significant_states_are_ordered( assert list(hist.keys()) == entity_ids -def test_get_significant_states_only( - hass_recorder: Callable[..., HomeAssistant], -) -> None: +async def test_get_significant_states_only(hass: HomeAssistant) -> None: """Test significant states when significant_states_only is set.""" - hass = hass_recorder() entity_id = "sensor.test" instance = recorder.get_instance(hass) with patch.object(instance.states_meta_manager, "active", False): def set_state(state, **kwargs): """Set the state.""" - hass.states.set(entity_id, state, **kwargs) - wait_recording_done(hass) + hass.states.async_set(entity_id, state, **kwargs) return hass.states.get(entity_id) start = dt_util.utcnow() - timedelta(minutes=4) @@ -531,6 +529,7 @@ def test_get_significant_states_only( freezer.move_to(points[2]) # everything is different states.append(set_state("412", attributes={"attribute": 54.23})) + await async_wait_recording_done(hass) hist = history.get_significant_states( hass, @@ -563,7 +562,9 @@ def test_get_significant_states_only( ) -def record_states(hass) -> tuple[datetime, datetime, dict[str, list[State]]]: +def record_states( + hass: HomeAssistant, +) -> tuple[datetime, datetime, dict[str, list[State]]]: """Record some test states. We inject a bunch of state updates from media player, zone and @@ -579,8 +580,7 @@ def record_states(hass) -> tuple[datetime, datetime, dict[str, list[State]]]: def set_state(entity_id, state, **kwargs): """Set the state.""" - hass.states.set(entity_id, state, **kwargs) - wait_recording_done(hass) + hass.states.async_set(entity_id, state, **kwargs) return hass.states.get(entity_id) zero = dt_util.utcnow() @@ -639,23 +639,22 @@ def record_states(hass) -> tuple[datetime, datetime, dict[str, list[State]]]: return zero, four, states -def test_state_changes_during_period_multiple_entities_single_test( - hass_recorder: Callable[..., HomeAssistant], +async def test_state_changes_during_period_multiple_entities_single_test( + hass: HomeAssistant, ) -> None: """Test state change during period with multiple entities in the same test. This test ensures the sqlalchemy query cache does not generate incorrect results. """ - hass = hass_recorder() instance = recorder.get_instance(hass) with patch.object(instance.states_meta_manager, "active", False): start = dt_util.utcnow() test_entites = {f"sensor.{i}": str(i) for i in range(30)} for entity_id, value in test_entites.items(): - hass.states.set(entity_id, value) + hass.states.async_set(entity_id, value) + await async_wait_recording_done(hass) - wait_recording_done(hass) end = dt_util.utcnow() for entity_id, value in test_entites.items(): @@ -664,31 +663,24 @@ def test_state_changes_during_period_multiple_entities_single_test( assert hist[entity_id][0].state == value -def test_get_significant_states_without_entity_ids_raises( - hass_recorder: Callable[..., HomeAssistant], -) -> None: +def test_get_significant_states_without_entity_ids_raises(hass: HomeAssistant) -> None: """Test at least one entity id is required for get_significant_states.""" - hass = hass_recorder() now = dt_util.utcnow() with pytest.raises(ValueError, match="entity_ids must be provided"): history.get_significant_states(hass, now, None) def test_state_changes_during_period_without_entity_ids_raises( - hass_recorder: Callable[..., HomeAssistant], + hass: HomeAssistant, ) -> None: """Test at least one entity id is required for state_changes_during_period.""" - hass = hass_recorder() now = dt_util.utcnow() with pytest.raises(ValueError, match="entity_id must be provided"): history.state_changes_during_period(hass, now, None) -def test_get_significant_states_with_filters_raises( - hass_recorder: Callable[..., HomeAssistant], -) -> None: +def test_get_significant_states_with_filters_raises(hass: HomeAssistant) -> None: """Test passing filters is no longer supported.""" - hass = hass_recorder() now = dt_util.utcnow() with pytest.raises(NotImplementedError, match="Filters are no longer supported"): history.get_significant_states( @@ -697,19 +689,17 @@ def test_get_significant_states_with_filters_raises( def test_get_significant_states_with_non_existent_entity_ids_returns_empty( - hass_recorder: Callable[..., HomeAssistant], + hass: HomeAssistant, ) -> None: """Test get_significant_states returns an empty dict when entities not in the db.""" - hass = hass_recorder() now = dt_util.utcnow() assert history.get_significant_states(hass, now, None, ["nonexistent.entity"]) == {} def test_state_changes_during_period_with_non_existent_entity_ids_returns_empty( - hass_recorder: Callable[..., HomeAssistant], + hass: HomeAssistant, ) -> None: """Test state_changes_during_period returns an empty dict when entities not in the db.""" - hass = hass_recorder() now = dt_util.utcnow() assert ( history.state_changes_during_period(hass, now, None, "nonexistent.entity") == {} @@ -717,8 +707,7 @@ def test_state_changes_during_period_with_non_existent_entity_ids_returns_empty( def test_get_last_state_changes_with_non_existent_entity_ids_returns_empty( - hass_recorder: Callable[..., HomeAssistant], + hass: HomeAssistant, ) -> None: """Test get_last_state_changes returns an empty dict when entities not in the db.""" - hass = hass_recorder() assert history.get_last_state_changes(hass, 1, "nonexistent.entity") == {} diff --git a/tests/components/recorder/test_history_db_schema_32.py b/tests/components/recorder/test_history_db_schema_32.py index 5acf07b0604..821dbf5e955 100644 --- a/tests/components/recorder/test_history_db_schema_32.py +++ b/tests/components/recorder/test_history_db_schema_32.py @@ -2,7 +2,6 @@ from __future__ import annotations -from collections.abc import Callable from copy import copy from datetime import datetime, timedelta import json @@ -12,7 +11,7 @@ from freezegun import freeze_time import pytest from homeassistant.components import recorder -from homeassistant.components.recorder import history +from homeassistant.components.recorder import Recorder, history from homeassistant.components.recorder.filters import Filters from homeassistant.components.recorder.models import process_timestamp from homeassistant.components.recorder.util import session_scope @@ -25,10 +24,19 @@ from .common import ( assert_multiple_states_equal_without_context, assert_multiple_states_equal_without_context_and_last_changed, assert_states_equal_without_context, + async_wait_recording_done, old_db_schema, - wait_recording_done, ) +from tests.typing import RecorderInstanceGenerator + + +@pytest.fixture +async def mock_recorder_before_hass( + async_setup_recorder_instance: RecorderInstanceGenerator, +) -> None: + """Set up recorder.""" + @pytest.fixture(autouse=True) def db_schema_32(): @@ -37,11 +45,15 @@ def db_schema_32(): yield -def test_get_full_significant_states_with_session_entity_no_matches( - hass_recorder: Callable[..., HomeAssistant], +@pytest.fixture(autouse=True) +def setup_recorder(db_schema_32, recorder_mock: Recorder) -> recorder.Recorder: + """Set up recorder.""" + + +async def test_get_full_significant_states_with_session_entity_no_matches( + hass: HomeAssistant, ) -> None: """Test getting states at a specific point in time for entities that never have been recorded.""" - hass = hass_recorder() now = dt_util.utcnow() time_before_recorder_ran = now - timedelta(days=1000) instance = recorder.get_instance(hass) @@ -67,11 +79,10 @@ def test_get_full_significant_states_with_session_entity_no_matches( ) -def test_significant_states_with_session_entity_minimal_response_no_matches( - hass_recorder: Callable[..., HomeAssistant], +async def test_significant_states_with_session_entity_minimal_response_no_matches( + hass: HomeAssistant, ) -> None: """Test getting states at a specific point in time for entities that never have been recorded.""" - hass = hass_recorder() now = dt_util.utcnow() time_before_recorder_ran = now - timedelta(days=1000) instance = recorder.get_instance(hass) @@ -112,19 +123,17 @@ def test_significant_states_with_session_entity_minimal_response_no_matches( ({}, True, 3), ], ) -def test_state_changes_during_period( - hass_recorder: Callable[..., HomeAssistant], attributes, no_attributes, limit +async def test_state_changes_during_period( + hass: HomeAssistant, attributes, no_attributes, limit ) -> None: """Test state change during period.""" - hass = hass_recorder() entity_id = "media_player.test" instance = recorder.get_instance(hass) with patch.object(instance.states_meta_manager, "active", False): def set_state(state): """Set the state.""" - hass.states.set(entity_id, state, attributes) - wait_recording_done(hass) + hass.states.async_set(entity_id, state, attributes) return hass.states.get(entity_id) start = dt_util.utcnow() @@ -146,6 +155,7 @@ def test_state_changes_during_period( freezer.move_to(end) set_state("Netflix") set_state("Plex") + await async_wait_recording_done(hass) hist = history.state_changes_during_period( hass, start, end, entity_id, no_attributes, limit=limit @@ -154,19 +164,17 @@ def test_state_changes_during_period( assert_multiple_states_equal_without_context(states[:limit], hist[entity_id]) -def test_state_changes_during_period_descending( - hass_recorder: Callable[..., HomeAssistant], +async def test_state_changes_during_period_descending( + hass: HomeAssistant, ) -> None: """Test state change during period descending.""" - hass = hass_recorder() entity_id = "media_player.test" instance = recorder.get_instance(hass) with patch.object(instance.states_meta_manager, "active", False): def set_state(state): """Set the state.""" - hass.states.set(entity_id, state, {"any": 1}) - wait_recording_done(hass) + hass.states.async_set(entity_id, state, {"any": 1}) return hass.states.get(entity_id) start = dt_util.utcnow() @@ -195,6 +203,7 @@ def test_state_changes_during_period_descending( freezer.move_to(end) set_state("Netflix") set_state("Plex") + await async_wait_recording_done(hass) hist = history.state_changes_during_period( hass, start, end, entity_id, no_attributes=False, descending=False @@ -209,17 +218,15 @@ def test_state_changes_during_period_descending( ) -def test_get_last_state_changes(hass_recorder: Callable[..., HomeAssistant]) -> None: +async def test_get_last_state_changes(hass: HomeAssistant) -> None: """Test number of state changes.""" - hass = hass_recorder() entity_id = "sensor.test" instance = recorder.get_instance(hass) with patch.object(instance.states_meta_manager, "active", False): def set_state(state): """Set the state.""" - hass.states.set(entity_id, state) - wait_recording_done(hass) + hass.states.async_set(entity_id, state) return hass.states.get(entity_id) start = dt_util.utcnow() - timedelta(minutes=2) @@ -235,29 +242,28 @@ def test_get_last_state_changes(hass_recorder: Callable[..., HomeAssistant]) -> freezer.move_to(point2) states.append(set_state("3")) + await async_wait_recording_done(hass) hist = history.get_last_state_changes(hass, 2, entity_id) assert_multiple_states_equal_without_context(states, hist[entity_id]) -def test_ensure_state_can_be_copied( - hass_recorder: Callable[..., HomeAssistant], +async def test_ensure_state_can_be_copied( + hass: HomeAssistant, ) -> None: """Ensure a state can pass though copy(). The filter integration uses copy() on states from history. """ - hass = hass_recorder() entity_id = "sensor.test" instance = recorder.get_instance(hass) with patch.object(instance.states_meta_manager, "active", False): def set_state(state): """Set the state.""" - hass.states.set(entity_id, state) - wait_recording_done(hass) + hass.states.async_set(entity_id, state) return hass.states.get(entity_id) start = dt_util.utcnow() - timedelta(minutes=2) @@ -268,6 +274,7 @@ def test_ensure_state_can_be_copied( freezer.move_to(point) set_state("2") + await async_wait_recording_done(hass) hist = history.get_last_state_changes(hass, 2, entity_id) @@ -279,23 +286,24 @@ def test_ensure_state_can_be_copied( ) -def test_get_significant_states(hass_recorder: Callable[..., HomeAssistant]) -> None: +async def test_get_significant_states(hass: HomeAssistant) -> None: """Test that only significant states are returned. We should get back every thermostat change that includes an attribute change, but only the state updates for media player (attribute changes are not significant and not returned). """ - hass = hass_recorder() instance = recorder.get_instance(hass) with patch.object(instance.states_meta_manager, "active", False): zero, four, states = record_states(hass) + await async_wait_recording_done(hass) + hist = history.get_significant_states(hass, zero, four, entity_ids=list(states)) assert_dict_of_states_equal_without_context_and_last_changed(states, hist) -def test_get_significant_states_minimal_response( - hass_recorder: Callable[..., HomeAssistant], +async def test_get_significant_states_minimal_response( + hass: HomeAssistant, ) -> None: """Test that only significant states are returned. @@ -305,10 +313,11 @@ def test_get_significant_states_minimal_response( includes an attribute change, but only the state updates for media player (attribute changes are not significant and not returned). """ - hass = hass_recorder() instance = recorder.get_instance(hass) with patch.object(instance.states_meta_manager, "active", False): zero, four, states = record_states(hass) + await async_wait_recording_done(hass) + hist = history.get_significant_states( hass, zero, four, minimal_response=True, entity_ids=list(states) ) @@ -364,8 +373,8 @@ def test_get_significant_states_minimal_response( @pytest.mark.parametrize("time_zone", ["Europe/Berlin", "US/Hawaii", "UTC"]) -def test_get_significant_states_with_initial( - time_zone, hass_recorder: Callable[..., HomeAssistant] +async def test_get_significant_states_with_initial( + time_zone, hass: HomeAssistant ) -> None: """Test that only significant states are returned. @@ -373,9 +382,10 @@ def test_get_significant_states_with_initial( includes an attribute change, but only the state updates for media player (attribute changes are not significant and not returned). """ - hass = hass_recorder() hass.config.set_time_zone(time_zone) zero, four, states = record_states(hass) + await async_wait_recording_done(hass) + one = zero + timedelta(seconds=1) one_and_half = zero + timedelta(seconds=1.5) for entity_id in states: @@ -391,8 +401,8 @@ def test_get_significant_states_with_initial( assert_dict_of_states_equal_without_context_and_last_changed(states, hist) -def test_get_significant_states_without_initial( - hass_recorder: Callable[..., HomeAssistant], +async def test_get_significant_states_without_initial( + hass: HomeAssistant, ) -> None: """Test that only significant states are returned. @@ -400,10 +410,11 @@ def test_get_significant_states_without_initial( includes an attribute change, but only the state updates for media player (attribute changes are not significant and not returned). """ - hass = hass_recorder() instance = recorder.get_instance(hass) with patch.object(instance.states_meta_manager, "active", False): zero, four, states = record_states(hass) + await async_wait_recording_done(hass) + one = zero + timedelta(seconds=1) one_with_microsecond = zero + timedelta(seconds=1, microseconds=1) one_and_half = zero + timedelta(seconds=1.5) @@ -425,14 +436,15 @@ def test_get_significant_states_without_initial( assert_dict_of_states_equal_without_context_and_last_changed(states, hist) -def test_get_significant_states_entity_id( - hass_recorder: Callable[..., HomeAssistant], +async def test_get_significant_states_entity_id( + hass: HomeAssistant, ) -> None: """Test that only significant states are returned for one entity.""" - hass = hass_recorder() instance = recorder.get_instance(hass) with patch.object(instance.states_meta_manager, "active", False): zero, four, states = record_states(hass) + await async_wait_recording_done(hass) + del states["media_player.test2"] del states["media_player.test3"] del states["thermostat.test"] @@ -443,14 +455,15 @@ def test_get_significant_states_entity_id( assert_dict_of_states_equal_without_context_and_last_changed(states, hist) -def test_get_significant_states_multiple_entity_ids( - hass_recorder: Callable[..., HomeAssistant], +async def test_get_significant_states_multiple_entity_ids( + hass: HomeAssistant, ) -> None: """Test that only significant states are returned for one entity.""" - hass = hass_recorder() instance = recorder.get_instance(hass) with patch.object(instance.states_meta_manager, "active", False): zero, four, states = record_states(hass) + await async_wait_recording_done(hass) + del states["media_player.test2"] del states["media_player.test3"] del states["thermostat.test2"] @@ -470,19 +483,19 @@ def test_get_significant_states_multiple_entity_ids( ) -def test_get_significant_states_are_ordered( - hass_recorder: Callable[..., HomeAssistant], +async def test_get_significant_states_are_ordered( + hass: HomeAssistant, ) -> None: """Test order of results from get_significant_states. When entity ids are given, the results should be returned with the data in the same order. """ - hass = hass_recorder() - instance = recorder.get_instance(hass) with patch.object(instance.states_meta_manager, "active", False): zero, four, _states = record_states(hass) + await async_wait_recording_done(hass) + entity_ids = ["media_player.test", "media_player.test2"] hist = history.get_significant_states(hass, zero, four, entity_ids) assert list(hist.keys()) == entity_ids @@ -491,19 +504,17 @@ def test_get_significant_states_are_ordered( assert list(hist.keys()) == entity_ids -def test_get_significant_states_only( - hass_recorder: Callable[..., HomeAssistant], +async def test_get_significant_states_only( + hass: HomeAssistant, ) -> None: """Test significant states when significant_states_only is set.""" - hass = hass_recorder() entity_id = "sensor.test" instance = recorder.get_instance(hass) with patch.object(instance.states_meta_manager, "active", False): def set_state(state, **kwargs): """Set the state.""" - hass.states.set(entity_id, state, **kwargs) - wait_recording_done(hass) + hass.states.async_set(entity_id, state, **kwargs) return hass.states.get(entity_id) start = dt_util.utcnow() - timedelta(minutes=4) @@ -524,6 +535,7 @@ def test_get_significant_states_only( freezer.move_to(points[2]) # everything is different states.append(set_state("412", attributes={"attribute": 54.23})) + await async_wait_recording_done(hass) hist = history.get_significant_states( hass, @@ -572,8 +584,7 @@ def record_states(hass) -> tuple[datetime, datetime, dict[str, list[State]]]: def set_state(entity_id, state, **kwargs): """Set the state.""" - hass.states.set(entity_id, state, **kwargs) - wait_recording_done(hass) + hass.states.async_set(entity_id, state, **kwargs) return hass.states.get(entity_id) zero = dt_util.utcnow() @@ -632,23 +643,22 @@ def record_states(hass) -> tuple[datetime, datetime, dict[str, list[State]]]: return zero, four, states -def test_state_changes_during_period_multiple_entities_single_test( - hass_recorder: Callable[..., HomeAssistant], +async def test_state_changes_during_period_multiple_entities_single_test( + hass: HomeAssistant, ) -> None: """Test state change during period with multiple entities in the same test. This test ensures the sqlalchemy query cache does not generate incorrect results. """ - hass = hass_recorder() instance = recorder.get_instance(hass) with patch.object(instance.states_meta_manager, "active", False): start = dt_util.utcnow() test_entites = {f"sensor.{i}": str(i) for i in range(30)} for entity_id, value in test_entites.items(): - hass.states.set(entity_id, value) + hass.states.async_set(entity_id, value) - wait_recording_done(hass) + await async_wait_recording_done(hass) end = dt_util.utcnow() for entity_id, value in test_entites.items(): @@ -657,31 +667,28 @@ def test_state_changes_during_period_multiple_entities_single_test( assert hist[entity_id][0].state == value -def test_get_significant_states_without_entity_ids_raises( - hass_recorder: Callable[..., HomeAssistant], +async def test_get_significant_states_without_entity_ids_raises( + hass: HomeAssistant, ) -> None: """Test at least one entity id is required for get_significant_states.""" - hass = hass_recorder() now = dt_util.utcnow() with pytest.raises(ValueError, match="entity_ids must be provided"): history.get_significant_states(hass, now, None) -def test_state_changes_during_period_without_entity_ids_raises( - hass_recorder: Callable[..., HomeAssistant], +async def test_state_changes_during_period_without_entity_ids_raises( + hass: HomeAssistant, ) -> None: """Test at least one entity id is required for state_changes_during_period.""" - hass = hass_recorder() now = dt_util.utcnow() with pytest.raises(ValueError, match="entity_id must be provided"): history.state_changes_during_period(hass, now, None) -def test_get_significant_states_with_filters_raises( - hass_recorder: Callable[..., HomeAssistant], +async def test_get_significant_states_with_filters_raises( + hass: HomeAssistant, ) -> None: """Test passing filters is no longer supported.""" - hass = hass_recorder() now = dt_util.utcnow() with pytest.raises(NotImplementedError, match="Filters are no longer supported"): history.get_significant_states( @@ -689,29 +696,26 @@ def test_get_significant_states_with_filters_raises( ) -def test_get_significant_states_with_non_existent_entity_ids_returns_empty( - hass_recorder: Callable[..., HomeAssistant], +async def test_get_significant_states_with_non_existent_entity_ids_returns_empty( + hass: HomeAssistant, ) -> None: """Test get_significant_states returns an empty dict when entities not in the db.""" - hass = hass_recorder() now = dt_util.utcnow() assert history.get_significant_states(hass, now, None, ["nonexistent.entity"]) == {} -def test_state_changes_during_period_with_non_existent_entity_ids_returns_empty( - hass_recorder: Callable[..., HomeAssistant], +async def test_state_changes_during_period_with_non_existent_entity_ids_returns_empty( + hass: HomeAssistant, ) -> None: """Test state_changes_during_period returns an empty dict when entities not in the db.""" - hass = hass_recorder() now = dt_util.utcnow() assert ( history.state_changes_during_period(hass, now, None, "nonexistent.entity") == {} ) -def test_get_last_state_changes_with_non_existent_entity_ids_returns_empty( - hass_recorder: Callable[..., HomeAssistant], +async def test_get_last_state_changes_with_non_existent_entity_ids_returns_empty( + hass: HomeAssistant, ) -> None: """Test get_last_state_changes returns an empty dict when entities not in the db.""" - hass = hass_recorder() assert history.get_last_state_changes(hass, 1, "nonexistent.entity") == {} diff --git a/tests/components/recorder/test_history_db_schema_42.py b/tests/components/recorder/test_history_db_schema_42.py index e342799c3a8..6ed2a683552 100644 --- a/tests/components/recorder/test_history_db_schema_42.py +++ b/tests/components/recorder/test_history_db_schema_42.py @@ -2,7 +2,6 @@ from __future__ import annotations -from collections.abc import Callable from copy import copy from datetime import datetime, timedelta import json @@ -35,13 +34,19 @@ from .common import ( async_recorder_block_till_done, async_wait_recording_done, old_db_schema, - wait_recording_done, ) from .db_schema_42 import Events, RecorderRuns, StateAttributes, States, StatesMeta from tests.typing import RecorderInstanceGenerator +@pytest.fixture +async def mock_recorder_before_hass( + async_setup_recorder_instance: RecorderInstanceGenerator, +) -> None: + """Set up recorder.""" + + @pytest.fixture(autouse=True) def db_schema_42(): """Fixture to initialize the db with the old schema 42.""" @@ -49,6 +54,11 @@ def db_schema_42(): yield +@pytest.fixture(autouse=True) +def setup_recorder(db_schema_42, recorder_mock: Recorder) -> recorder.Recorder: + """Set up recorder.""" + + async def _async_get_states( hass: HomeAssistant, utc_point_in_time: datetime, @@ -120,11 +130,10 @@ def _add_db_entries( ) -def test_get_full_significant_states_with_session_entity_no_matches( - hass_recorder: Callable[..., HomeAssistant], +async def test_get_full_significant_states_with_session_entity_no_matches( + hass: HomeAssistant, ) -> None: """Test getting states at a specific point in time for entities that never have been recorded.""" - hass = hass_recorder() now = dt_util.utcnow() time_before_recorder_ran = now - timedelta(days=1000) with session_scope(hass=hass, read_only=True) as session: @@ -146,11 +155,10 @@ def test_get_full_significant_states_with_session_entity_no_matches( ) -def test_significant_states_with_session_entity_minimal_response_no_matches( - hass_recorder: Callable[..., HomeAssistant], +async def test_significant_states_with_session_entity_minimal_response_no_matches( + hass: HomeAssistant, ) -> None: """Test getting states at a specific point in time for entities that never have been recorded.""" - hass = hass_recorder() now = dt_util.utcnow() time_before_recorder_ran = now - timedelta(days=1000) with session_scope(hass=hass, read_only=True) as session: @@ -178,14 +186,13 @@ def test_significant_states_with_session_entity_minimal_response_no_matches( ) -def test_significant_states_with_session_single_entity( - hass_recorder: Callable[..., HomeAssistant], +async def test_significant_states_with_session_single_entity( + hass: HomeAssistant, ) -> None: """Test get_significant_states_with_session with a single entity.""" - hass = hass_recorder() - hass.states.set("demo.id", "any", {"attr": True}) - hass.states.set("demo.id", "any2", {"attr": True}) - wait_recording_done(hass) + hass.states.async_set("demo.id", "any", {"attr": True}) + hass.states.async_set("demo.id", "any2", {"attr": True}) + await async_wait_recording_done(hass) now = dt_util.utcnow() with session_scope(hass=hass, read_only=True) as session: states = history.get_significant_states_with_session( @@ -208,17 +215,15 @@ def test_significant_states_with_session_single_entity( ({}, True, 3), ], ) -def test_state_changes_during_period( - hass_recorder: Callable[..., HomeAssistant], attributes, no_attributes, limit +async def test_state_changes_during_period( + hass: HomeAssistant, attributes, no_attributes, limit ) -> None: """Test state change during period.""" - hass = hass_recorder() entity_id = "media_player.test" def set_state(state): """Set the state.""" - hass.states.set(entity_id, state, attributes) - wait_recording_done(hass) + hass.states.async_set(entity_id, state, attributes) return hass.states.get(entity_id) start = dt_util.utcnow() @@ -240,6 +245,7 @@ def test_state_changes_during_period( freezer.move_to(end) set_state("Netflix") set_state("Plex") + await async_wait_recording_done(hass) hist = history.state_changes_during_period( hass, start, end, entity_id, no_attributes, limit=limit @@ -248,17 +254,15 @@ def test_state_changes_during_period( assert_multiple_states_equal_without_context(states[:limit], hist[entity_id]) -def test_state_changes_during_period_last_reported( - hass_recorder: Callable[..., HomeAssistant], +async def test_state_changes_during_period_last_reported( + hass: HomeAssistant, ) -> None: """Test state change during period.""" - hass = hass_recorder() entity_id = "media_player.test" def set_state(state): """Set the state.""" - hass.states.set(entity_id, state) - wait_recording_done(hass) + hass.states.async_set(entity_id, state) return ha.State.from_dict(hass.states.get(entity_id).as_dict()) start = dt_util.utcnow() @@ -277,23 +281,22 @@ def test_state_changes_during_period_last_reported( freezer.move_to(end) set_state("Netflix") + await async_wait_recording_done(hass) hist = history.state_changes_during_period(hass, start, end, entity_id) assert_multiple_states_equal_without_context(states, hist[entity_id]) -def test_state_changes_during_period_descending( - hass_recorder: Callable[..., HomeAssistant], +async def test_state_changes_during_period_descending( + hass: HomeAssistant, ) -> None: """Test state change during period descending.""" - hass = hass_recorder() entity_id = "media_player.test" def set_state(state): """Set the state.""" - hass.states.set(entity_id, state, {"any": 1}) - wait_recording_done(hass) + hass.states.async_set(entity_id, state, {"any": 1}) return hass.states.get(entity_id) start = dt_util.utcnow().replace(microsecond=0) @@ -322,6 +325,7 @@ def test_state_changes_during_period_descending( freezer.move_to(end) set_state("Netflix") set_state("Plex") + await async_wait_recording_done(hass) hist = history.state_changes_during_period( hass, start, end, entity_id, no_attributes=False, descending=False @@ -387,15 +391,13 @@ def test_state_changes_during_period_descending( ) -def test_get_last_state_changes(hass_recorder: Callable[..., HomeAssistant]) -> None: +async def test_get_last_state_changes(hass: HomeAssistant) -> None: """Test number of state changes.""" - hass = hass_recorder() entity_id = "sensor.test" def set_state(state): """Set the state.""" - hass.states.set(entity_id, state) - wait_recording_done(hass) + hass.states.async_set(entity_id, state) return hass.states.get(entity_id) start = dt_util.utcnow() - timedelta(minutes=2) @@ -411,23 +413,22 @@ def test_get_last_state_changes(hass_recorder: Callable[..., HomeAssistant]) -> freezer.move_to(point2) states.append(set_state("3")) + await async_wait_recording_done(hass) hist = history.get_last_state_changes(hass, 2, entity_id) assert_multiple_states_equal_without_context(states, hist[entity_id]) -def test_get_last_state_changes_last_reported( - hass_recorder: Callable[..., HomeAssistant], +async def test_get_last_state_changes_last_reported( + hass: HomeAssistant, ) -> None: """Test number of state changes.""" - hass = hass_recorder() entity_id = "sensor.test" def set_state(state): """Set the state.""" - hass.states.set(entity_id, state) - wait_recording_done(hass) + hass.states.async_set(entity_id, state) return ha.State.from_dict(hass.states.get(entity_id).as_dict()) start = dt_util.utcnow() - timedelta(minutes=2) @@ -443,21 +444,20 @@ def test_get_last_state_changes_last_reported( freezer.move_to(point2) states.append(set_state("2")) + await async_wait_recording_done(hass) hist = history.get_last_state_changes(hass, 2, entity_id) assert_multiple_states_equal_without_context(states, hist[entity_id]) -def test_get_last_state_change(hass_recorder: Callable[..., HomeAssistant]) -> None: +async def test_get_last_state_change(hass: HomeAssistant) -> None: """Test getting the last state change for an entity.""" - hass = hass_recorder() entity_id = "sensor.test" def set_state(state): """Set the state.""" - hass.states.set(entity_id, state) - wait_recording_done(hass) + hass.states.async_set(entity_id, state) return hass.states.get(entity_id) start = dt_util.utcnow() - timedelta(minutes=2) @@ -473,27 +473,26 @@ def test_get_last_state_change(hass_recorder: Callable[..., HomeAssistant]) -> N freezer.move_to(point2) states.append(set_state("3")) + await async_wait_recording_done(hass) hist = history.get_last_state_changes(hass, 1, entity_id) assert_multiple_states_equal_without_context(states, hist[entity_id]) -def test_ensure_state_can_be_copied( - hass_recorder: Callable[..., HomeAssistant], +async def test_ensure_state_can_be_copied( + hass: HomeAssistant, ) -> None: """Ensure a state can pass though copy(). The filter integration uses copy() on states from history. """ - hass = hass_recorder() entity_id = "sensor.test" def set_state(state): """Set the state.""" - hass.states.set(entity_id, state) - wait_recording_done(hass) + hass.states.async_set(entity_id, state) return hass.states.get(entity_id) start = dt_util.utcnow() - timedelta(minutes=2) @@ -504,6 +503,7 @@ def test_ensure_state_can_be_copied( freezer.move_to(point) set_state("2") + await async_wait_recording_done(hass) hist = history.get_last_state_changes(hass, 2, entity_id) @@ -511,21 +511,22 @@ def test_ensure_state_can_be_copied( assert_states_equal_without_context(copy(hist[entity_id][1]), hist[entity_id][1]) -def test_get_significant_states(hass_recorder: Callable[..., HomeAssistant]) -> None: +async def test_get_significant_states(hass: HomeAssistant) -> None: """Test that only significant states are returned. We should get back every thermostat change that includes an attribute change, but only the state updates for media player (attribute changes are not significant and not returned). """ - hass = hass_recorder() zero, four, states = record_states(hass) + await async_wait_recording_done(hass) + hist = history.get_significant_states(hass, zero, four, entity_ids=list(states)) assert_dict_of_states_equal_without_context_and_last_changed(states, hist) -def test_get_significant_states_minimal_response( - hass_recorder: Callable[..., HomeAssistant], +async def test_get_significant_states_minimal_response( + hass: HomeAssistant, ) -> None: """Test that only significant states are returned. @@ -536,8 +537,9 @@ def test_get_significant_states_minimal_response( includes an attribute change, but only the state updates for media player (attribute changes are not significant and not returned). """ - hass = hass_recorder() zero, four, states = record_states(hass) + await async_wait_recording_done(hass) + hist = history.get_significant_states( hass, zero, four, minimal_response=True, entity_ids=list(states) ) @@ -593,8 +595,8 @@ def test_get_significant_states_minimal_response( @pytest.mark.parametrize("time_zone", ["Europe/Berlin", "US/Hawaii", "UTC"]) -def test_get_significant_states_with_initial( - time_zone, hass_recorder: Callable[..., HomeAssistant] +async def test_get_significant_states_with_initial( + time_zone, hass: HomeAssistant ) -> None: """Test that only significant states are returned. @@ -602,9 +604,10 @@ def test_get_significant_states_with_initial( includes an attribute change, but only the state updates for media player (attribute changes are not significant and not returned). """ - hass = hass_recorder() hass.config.set_time_zone(time_zone) zero, four, states = record_states(hass) + await async_wait_recording_done(hass) + one_and_half = zero + timedelta(seconds=1.5) for entity_id in states: if entity_id == "media_player.test": @@ -623,8 +626,8 @@ def test_get_significant_states_with_initial( assert_dict_of_states_equal_without_context_and_last_changed(states, hist) -def test_get_significant_states_without_initial( - hass_recorder: Callable[..., HomeAssistant], +async def test_get_significant_states_without_initial( + hass: HomeAssistant, ) -> None: """Test that only significant states are returned. @@ -632,8 +635,9 @@ def test_get_significant_states_without_initial( includes an attribute change, but only the state updates for media player (attribute changes are not significant and not returned). """ - hass = hass_recorder() zero, four, states = record_states(hass) + await async_wait_recording_done(hass) + one = zero + timedelta(seconds=1) one_with_microsecond = zero + timedelta(seconds=1, microseconds=1) one_and_half = zero + timedelta(seconds=1.5) @@ -656,12 +660,13 @@ def test_get_significant_states_without_initial( assert_dict_of_states_equal_without_context_and_last_changed(states, hist) -def test_get_significant_states_entity_id( - hass_recorder: Callable[..., HomeAssistant], +async def test_get_significant_states_entity_id( + hass: HomeAssistant, ) -> None: """Test that only significant states are returned for one entity.""" - hass = hass_recorder() zero, four, states = record_states(hass) + await async_wait_recording_done(hass) + del states["media_player.test2"] del states["media_player.test3"] del states["thermostat.test"] @@ -673,12 +678,12 @@ def test_get_significant_states_entity_id( assert_dict_of_states_equal_without_context_and_last_changed(states, hist) -def test_get_significant_states_multiple_entity_ids( - hass_recorder: Callable[..., HomeAssistant], +async def test_get_significant_states_multiple_entity_ids( + hass: HomeAssistant, ) -> None: """Test that only significant states are returned for one entity.""" - hass = hass_recorder() zero, four, states = record_states(hass) + await async_wait_recording_done(hass) hist = history.get_significant_states( hass, @@ -695,16 +700,17 @@ def test_get_significant_states_multiple_entity_ids( ) -def test_get_significant_states_are_ordered( - hass_recorder: Callable[..., HomeAssistant], +async def test_get_significant_states_are_ordered( + hass: HomeAssistant, ) -> None: """Test order of results from get_significant_states. When entity ids are given, the results should be returned with the data in the same order. """ - hass = hass_recorder() zero, four, _states = record_states(hass) + await async_wait_recording_done(hass) + entity_ids = ["media_player.test", "media_player.test2"] hist = history.get_significant_states(hass, zero, four, entity_ids) assert list(hist.keys()) == entity_ids @@ -713,17 +719,15 @@ def test_get_significant_states_are_ordered( assert list(hist.keys()) == entity_ids -def test_get_significant_states_only( - hass_recorder: Callable[..., HomeAssistant], +async def test_get_significant_states_only( + hass: HomeAssistant, ) -> None: """Test significant states when significant_states_only is set.""" - hass = hass_recorder() entity_id = "sensor.test" def set_state(state, **kwargs): """Set the state.""" - hass.states.set(entity_id, state, **kwargs) - wait_recording_done(hass) + hass.states.async_set(entity_id, state, **kwargs) return hass.states.get(entity_id) start = dt_util.utcnow() - timedelta(minutes=4) @@ -744,6 +748,7 @@ def test_get_significant_states_only( freezer.move_to(points[2]) # everything is different states.append(set_state("412", attributes={"attribute": 54.23})) + await async_wait_recording_done(hass) hist = history.get_significant_states( hass, @@ -777,7 +782,7 @@ def test_get_significant_states_only( async def test_get_significant_states_only_minimal_response( - recorder_mock: Recorder, hass: HomeAssistant + hass: HomeAssistant, ) -> None: """Test significant states when significant_states_only is True.""" now = dt_util.utcnow() @@ -820,8 +825,7 @@ def record_states(hass) -> tuple[datetime, datetime, dict[str, list[State]]]: def set_state(entity_id, state, **kwargs): """Set the state.""" - hass.states.set(entity_id, state, **kwargs) - wait_recording_done(hass) + hass.states.async_set(entity_id, state, **kwargs) return hass.states.get(entity_id) zero = dt_util.utcnow() @@ -888,7 +892,6 @@ def record_states(hass) -> tuple[datetime, datetime, dict[str, list[State]]]: async def test_state_changes_during_period_query_during_migration_to_schema_25( - async_setup_recorder_instance: RecorderInstanceGenerator, hass: HomeAssistant, recorder_db_url: str, ) -> None: @@ -897,7 +900,7 @@ async def test_state_changes_during_period_query_during_migration_to_schema_25( # This test doesn't run on MySQL / MariaDB / Postgresql; we can't drop table state_attributes return - instance = await async_setup_recorder_instance(hass, {}) + instance = recorder.get_instance(hass) with patch.object(instance.states_meta_manager, "active", False): start = dt_util.utcnow() @@ -955,7 +958,6 @@ async def test_state_changes_during_period_query_during_migration_to_schema_25( async def test_get_states_query_during_migration_to_schema_25( - async_setup_recorder_instance: RecorderInstanceGenerator, hass: HomeAssistant, recorder_db_url: str, ) -> None: @@ -964,7 +966,7 @@ async def test_get_states_query_during_migration_to_schema_25( # This test doesn't run on MySQL / MariaDB / Postgresql; we can't drop table state_attributes return - instance = await async_setup_recorder_instance(hass, {}) + instance = recorder.get_instance(hass) start = dt_util.utcnow() point = start + timedelta(seconds=1) @@ -1006,7 +1008,6 @@ async def test_get_states_query_during_migration_to_schema_25( async def test_get_states_query_during_migration_to_schema_25_multiple_entities( - async_setup_recorder_instance: RecorderInstanceGenerator, hass: HomeAssistant, recorder_db_url: str, ) -> None: @@ -1015,7 +1016,7 @@ async def test_get_states_query_during_migration_to_schema_25_multiple_entities( # This test doesn't run on MySQL / MariaDB / Postgresql; we can't drop table state_attributes return - instance = await async_setup_recorder_instance(hass, {}) + instance = recorder.get_instance(hass) start = dt_util.utcnow() point = start + timedelta(seconds=1) @@ -1060,12 +1061,9 @@ async def test_get_states_query_during_migration_to_schema_25_multiple_entities( async def test_get_full_significant_states_handles_empty_last_changed( - async_setup_recorder_instance: RecorderInstanceGenerator, hass: HomeAssistant, ) -> None: """Test getting states when last_changed is null.""" - await async_setup_recorder_instance(hass, {}) - now = dt_util.utcnow() hass.states.async_set("sensor.one", "on", {"attr": "original"}) state0 = hass.states.get("sensor.one") @@ -1157,21 +1155,20 @@ async def test_get_full_significant_states_handles_empty_last_changed( ) -def test_state_changes_during_period_multiple_entities_single_test( - hass_recorder: Callable[..., HomeAssistant], +async def test_state_changes_during_period_multiple_entities_single_test( + hass: HomeAssistant, ) -> None: """Test state change during period with multiple entities in the same test. This test ensures the sqlalchemy query cache does not generate incorrect results. """ - hass = hass_recorder() start = dt_util.utcnow() test_entites = {f"sensor.{i}": str(i) for i in range(30)} for entity_id, value in test_entites.items(): - hass.states.set(entity_id, value) + hass.states.async_set(entity_id, value) - wait_recording_done(hass) + await async_wait_recording_done(hass) end = dt_util.utcnow() for entity_id, value in test_entites.items(): @@ -1182,11 +1179,9 @@ def test_state_changes_during_period_multiple_entities_single_test( @pytest.mark.freeze_time("2039-01-19 03:14:07.555555-00:00") async def test_get_full_significant_states_past_year_2038( - async_setup_recorder_instance: RecorderInstanceGenerator, hass: HomeAssistant, ) -> None: """Test we can store times past year 2038.""" - await async_setup_recorder_instance(hass, {}) past_2038_time = dt_util.parse_datetime("2039-01-19 03:14:07.555555-00:00") hass.states.async_set("sensor.one", "on", {"attr": "original"}) state0 = hass.states.get("sensor.one") @@ -1216,31 +1211,28 @@ async def test_get_full_significant_states_past_year_2038( assert sensor_one_states[0].last_updated == past_2038_time -def test_get_significant_states_without_entity_ids_raises( - hass_recorder: Callable[..., HomeAssistant], +async def test_get_significant_states_without_entity_ids_raises( + hass: HomeAssistant, ) -> None: """Test at least one entity id is required for get_significant_states.""" - hass = hass_recorder() now = dt_util.utcnow() with pytest.raises(ValueError, match="entity_ids must be provided"): history.get_significant_states(hass, now, None) -def test_state_changes_during_period_without_entity_ids_raises( - hass_recorder: Callable[..., HomeAssistant], +async def test_state_changes_during_period_without_entity_ids_raises( + hass: HomeAssistant, ) -> None: """Test at least one entity id is required for state_changes_during_period.""" - hass = hass_recorder() now = dt_util.utcnow() with pytest.raises(ValueError, match="entity_id must be provided"): history.state_changes_during_period(hass, now, None) -def test_get_significant_states_with_filters_raises( - hass_recorder: Callable[..., HomeAssistant], +async def test_get_significant_states_with_filters_raises( + hass: HomeAssistant, ) -> None: """Test passing filters is no longer supported.""" - hass = hass_recorder() now = dt_util.utcnow() with pytest.raises(NotImplementedError, match="Filters are no longer supported"): history.get_significant_states( @@ -1248,29 +1240,26 @@ def test_get_significant_states_with_filters_raises( ) -def test_get_significant_states_with_non_existent_entity_ids_returns_empty( - hass_recorder: Callable[..., HomeAssistant], +async def test_get_significant_states_with_non_existent_entity_ids_returns_empty( + hass: HomeAssistant, ) -> None: """Test get_significant_states returns an empty dict when entities not in the db.""" - hass = hass_recorder() now = dt_util.utcnow() assert history.get_significant_states(hass, now, None, ["nonexistent.entity"]) == {} -def test_state_changes_during_period_with_non_existent_entity_ids_returns_empty( - hass_recorder: Callable[..., HomeAssistant], +async def test_state_changes_during_period_with_non_existent_entity_ids_returns_empty( + hass: HomeAssistant, ) -> None: """Test state_changes_during_period returns an empty dict when entities not in the db.""" - hass = hass_recorder() now = dt_util.utcnow() assert ( history.state_changes_during_period(hass, now, None, "nonexistent.entity") == {} ) -def test_get_last_state_changes_with_non_existent_entity_ids_returns_empty( - hass_recorder: Callable[..., HomeAssistant], +async def test_get_last_state_changes_with_non_existent_entity_ids_returns_empty( + hass: HomeAssistant, ) -> None: """Test get_last_state_changes returns an empty dict when entities not in the db.""" - hass = hass_recorder() assert history.get_last_state_changes(hass, 1, "nonexistent.entity") == {}