Convert recorder history tests to use async API (#116909)
This commit is contained in:
parent
9517800da6
commit
d01d161fe2
4 changed files with 352 additions and 381 deletions
|
@ -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") == {}
|
||||
|
|
|
@ -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") == {}
|
||||
|
|
|
@ -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") == {}
|
||||
|
|
|
@ -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") == {}
|
||||
|
|
Loading…
Add table
Reference in a new issue