Convert history tests to use async API (#116447)

* Convert history tests to use async API

* Add new fixture to help patch recorder

* Modify

* Modify

* Update tests/conftest.py

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>

* Rename fixture

---------

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
pull/116663/head^2
Erik Montnemery 2024-05-03 08:14:46 +02:00 committed by GitHub
parent 897794f53b
commit 27fcf72275
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 209 additions and 163 deletions

View File

@ -3,15 +3,24 @@
import pytest
from homeassistant.components import history
from homeassistant.components.recorder import Recorder
from homeassistant.const import CONF_DOMAINS, CONF_ENTITIES, CONF_EXCLUDE, CONF_INCLUDE
from homeassistant.setup import setup_component
from homeassistant.core import HomeAssistant
from homeassistant.setup import async_setup_component
from tests.typing import RecorderInstanceGenerator
@pytest.fixture
def hass_history(hass_recorder):
"""Home Assistant fixture with history."""
hass = hass_recorder()
async def mock_recorder_before_hass(
async_setup_recorder_instance: RecorderInstanceGenerator,
) -> None:
"""Set up recorder."""
@pytest.fixture
async def hass_history(hass: HomeAssistant, recorder_mock: Recorder) -> None:
"""Home Assistant fixture with history."""
config = history.CONFIG_SCHEMA(
{
history.DOMAIN: {
@ -26,6 +35,4 @@ def hass_history(hass_recorder):
}
}
)
assert setup_component(hass, history.DOMAIN, config)
return hass
assert await async_setup_component(hass, history.DOMAIN, config)

View File

@ -24,7 +24,6 @@ from tests.components.recorder.common import (
assert_multiple_states_equal_without_context_and_last_changed,
assert_states_equal_without_context,
async_wait_recording_done,
wait_recording_done,
)
from tests.typing import ClientSessionGenerator
@ -39,25 +38,26 @@ def listeners_without_writes(listeners: dict[str, int]) -> dict[str, int]:
@pytest.mark.usefixtures("hass_history")
def test_setup() -> None:
async def test_setup() -> None:
"""Test setup method of history."""
# Verification occurs in the fixture
def test_get_significant_states(hass_history) -> None:
async def test_get_significant_states(hass: HomeAssistant, hass_history) -> 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_history
zero, four, states = record_states(hass)
zero, four, states = await async_record_states(hass)
hist = 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_history) -> None:
async def test_get_significant_states_minimal_response(
hass: HomeAssistant, hass_history
) -> None:
"""Test that only significant states are returned.
When minimal responses is set only the first and
@ -67,8 +67,7 @@ def test_get_significant_states_minimal_response(hass_history) -> None:
includes an attribute change, but only the state updates for
media player (attribute changes are not significant and not returned).
"""
hass = hass_history
zero, four, states = record_states(hass)
zero, four, states = await async_record_states(hass)
hist = get_significant_states(
hass, zero, four, minimal_response=True, entity_ids=list(states)
)
@ -122,15 +121,16 @@ def test_get_significant_states_minimal_response(hass_history) -> None:
)
def test_get_significant_states_with_initial(hass_history) -> None:
async def test_get_significant_states_with_initial(
hass: HomeAssistant, hass_history
) -> 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_history
zero, four, states = record_states(hass)
zero, four, states = await async_record_states(hass)
one_and_half = zero + timedelta(seconds=1.5)
for entity_id in states:
if entity_id == "media_player.test":
@ -149,15 +149,16 @@ def test_get_significant_states_with_initial(hass_history) -> None:
assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
def test_get_significant_states_without_initial(hass_history) -> None:
async def test_get_significant_states_without_initial(
hass: HomeAssistant, hass_history
) -> 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_history
zero, four, states = record_states(hass)
zero, four, states = await async_record_states(hass)
one = zero + timedelta(seconds=1)
one_with_microsecond = zero + timedelta(seconds=1, microseconds=1)
one_and_half = zero + timedelta(seconds=1.5)
@ -179,10 +180,11 @@ def test_get_significant_states_without_initial(hass_history) -> None:
assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
def test_get_significant_states_entity_id(hass_history) -> None:
async def test_get_significant_states_entity_id(
hass: HomeAssistant, hass_history
) -> None:
"""Test that only significant states are returned for one entity."""
hass = hass_history
zero, four, states = record_states(hass)
zero, four, states = await async_record_states(hass)
del states["media_player.test2"]
del states["media_player.test3"]
del states["thermostat.test"]
@ -193,10 +195,11 @@ def test_get_significant_states_entity_id(hass_history) -> None:
assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
def test_get_significant_states_multiple_entity_ids(hass_history) -> None:
async def test_get_significant_states_multiple_entity_ids(
hass: HomeAssistant, hass_history
) -> None:
"""Test that only significant states are returned for one entity."""
hass = hass_history
zero, four, states = record_states(hass)
zero, four, states = await async_record_states(hass)
del states["media_player.test2"]
del states["media_player.test3"]
del states["thermostat.test2"]
@ -211,14 +214,15 @@ def test_get_significant_states_multiple_entity_ids(hass_history) -> None:
assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
def test_get_significant_states_are_ordered(hass_history) -> None:
async def test_get_significant_states_are_ordered(
hass: HomeAssistant, hass_history
) -> 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_history
zero, four, _states = record_states(hass)
zero, four, _states = await async_record_states(hass)
entity_ids = ["media_player.test", "media_player.test2"]
hist = get_significant_states(hass, zero, four, entity_ids)
assert list(hist.keys()) == entity_ids
@ -227,15 +231,14 @@ def test_get_significant_states_are_ordered(hass_history) -> None:
assert list(hist.keys()) == entity_ids
def test_get_significant_states_only(hass_history) -> None:
async def test_get_significant_states_only(hass: HomeAssistant, hass_history) -> None:
"""Test significant states when significant_states_only is set."""
hass = hass_history
entity_id = "sensor.test"
def set_state(state, **kwargs):
async 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)
await async_wait_recording_done(hass)
return hass.states.get(entity_id)
start = dt_util.utcnow() - timedelta(minutes=4)
@ -243,19 +246,19 @@ def test_get_significant_states_only(hass_history) -> None:
states = []
with freeze_time(start) as freezer:
set_state("123", attributes={"attribute": 10.64})
await set_state("123", attributes={"attribute": 10.64})
freezer.move_to(points[0])
# Attributes are different, state not
states.append(set_state("123", attributes={"attribute": 21.42}))
states.append(await set_state("123", attributes={"attribute": 21.42}))
freezer.move_to(points[1])
# state is different, attributes not
states.append(set_state("32", attributes={"attribute": 21.42}))
states.append(await set_state("32", attributes={"attribute": 21.42}))
freezer.move_to(points[2])
# everything is different
states.append(set_state("412", attributes={"attribute": 54.23}))
states.append(await set_state("412", attributes={"attribute": 54.23}))
hist = get_significant_states(
hass,
@ -288,13 +291,13 @@ def test_get_significant_states_only(hass_history) -> None:
)
def check_significant_states(hass, zero, four, states, config):
async def check_significant_states(hass, zero, four, states, config):
"""Check if significant states are retrieved."""
hist = get_significant_states(hass, zero, four)
assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
def record_states(hass):
async def async_record_states(hass):
"""Record some test states.
We inject a bunch of state updates from media player, zone and
@ -308,10 +311,10 @@ def record_states(hass):
zone = "zone.home"
script_c = "script.can_cancel_this_one"
def set_state(entity_id, state, **kwargs):
async 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)
await async_wait_recording_done(hass)
return hass.states.get(entity_id)
zero = dt_util.utcnow()
@ -323,55 +326,63 @@ def record_states(hass):
states = {therm: [], therm2: [], mp: [], mp2: [], mp3: [], script_c: []}
with freeze_time(one) as freezer:
states[mp].append(
set_state(mp, "idle", attributes={"media_title": str(sentinel.mt1)})
await set_state(mp, "idle", attributes={"media_title": str(sentinel.mt1)})
)
states[mp2].append(
set_state(mp2, "YouTube", attributes={"media_title": str(sentinel.mt2)})
await set_state(
mp2, "YouTube", attributes={"media_title": str(sentinel.mt2)}
)
)
states[mp3].append(
set_state(mp3, "idle", attributes={"media_title": str(sentinel.mt1)})
await set_state(mp3, "idle", attributes={"media_title": str(sentinel.mt1)})
)
states[therm].append(
set_state(therm, 20, attributes={"current_temperature": 19.5})
await set_state(therm, 20, attributes={"current_temperature": 19.5})
)
freezer.move_to(one + timedelta(microseconds=1))
states[mp].append(
set_state(mp, "YouTube", attributes={"media_title": str(sentinel.mt2)})
await set_state(
mp, "YouTube", attributes={"media_title": str(sentinel.mt2)}
)
)
freezer.move_to(two)
# This state will be skipped only different in time
set_state(mp, "YouTube", attributes={"media_title": str(sentinel.mt3)})
await set_state(mp, "YouTube", attributes={"media_title": str(sentinel.mt3)})
# This state will be skipped because domain is excluded
set_state(zone, "zoning")
await set_state(zone, "zoning")
states[script_c].append(
set_state(script_c, "off", attributes={"can_cancel": True})
await set_state(script_c, "off", attributes={"can_cancel": True})
)
states[therm].append(
set_state(therm, 21, attributes={"current_temperature": 19.8})
await set_state(therm, 21, attributes={"current_temperature": 19.8})
)
states[therm2].append(
set_state(therm2, 20, attributes={"current_temperature": 19})
await set_state(therm2, 20, attributes={"current_temperature": 19})
)
freezer.move_to(three)
states[mp].append(
set_state(mp, "Netflix", attributes={"media_title": str(sentinel.mt4)})
await set_state(
mp, "Netflix", attributes={"media_title": str(sentinel.mt4)}
)
)
states[mp3].append(
set_state(mp3, "Netflix", attributes={"media_title": str(sentinel.mt3)})
await set_state(
mp3, "Netflix", attributes={"media_title": str(sentinel.mt3)}
)
)
# Attributes changed even though state is the same
states[therm].append(
set_state(therm, 21, attributes={"current_temperature": 20})
await set_state(therm, 21, attributes={"current_temperature": 20})
)
return zero, four, states
async def test_fetch_period_api(
recorder_mock: Recorder, hass: HomeAssistant, hass_client: ClientSessionGenerator
hass: HomeAssistant, recorder_mock: Recorder, hass_client: ClientSessionGenerator
) -> None:
"""Test the fetch period view for history."""
await async_setup_component(hass, "history", {})
@ -383,8 +394,8 @@ async def test_fetch_period_api(
async def test_fetch_period_api_with_use_include_order(
recorder_mock: Recorder,
hass: HomeAssistant,
recorder_mock: Recorder,
hass_client: ClientSessionGenerator,
caplog: pytest.LogCaptureFixture,
) -> None:
@ -402,7 +413,7 @@ async def test_fetch_period_api_with_use_include_order(
async def test_fetch_period_api_with_minimal_response(
recorder_mock: Recorder, hass: HomeAssistant, hass_client: ClientSessionGenerator
hass: HomeAssistant, recorder_mock: Recorder, hass_client: ClientSessionGenerator
) -> None:
"""Test the fetch period view for history with minimal_response."""
now = dt_util.utcnow()
@ -444,7 +455,7 @@ async def test_fetch_period_api_with_minimal_response(
async def test_fetch_period_api_with_no_timestamp(
recorder_mock: Recorder, hass: HomeAssistant, hass_client: ClientSessionGenerator
hass: HomeAssistant, recorder_mock: Recorder, hass_client: ClientSessionGenerator
) -> None:
"""Test the fetch period view for history with no timestamp."""
await async_setup_component(hass, "history", {})
@ -454,8 +465,8 @@ async def test_fetch_period_api_with_no_timestamp(
async def test_fetch_period_api_with_include_order(
recorder_mock: Recorder,
hass: HomeAssistant,
recorder_mock: Recorder,
hass_client: ClientSessionGenerator,
caplog: pytest.LogCaptureFixture,
) -> None:
@ -482,7 +493,7 @@ async def test_fetch_period_api_with_include_order(
async def test_entity_ids_limit_via_api(
recorder_mock: Recorder, hass: HomeAssistant, hass_client: ClientSessionGenerator
hass: HomeAssistant, recorder_mock: Recorder, hass_client: ClientSessionGenerator
) -> None:
"""Test limiting history to entity_ids."""
await async_setup_component(
@ -508,7 +519,7 @@ async def test_entity_ids_limit_via_api(
async def test_entity_ids_limit_via_api_with_skip_initial_state(
recorder_mock: Recorder, hass: HomeAssistant, hass_client: ClientSessionGenerator
hass: HomeAssistant, recorder_mock: Recorder, hass_client: ClientSessionGenerator
) -> None:
"""Test limiting history to entity_ids with skip_initial_state."""
await async_setup_component(
@ -542,7 +553,7 @@ async def test_entity_ids_limit_via_api_with_skip_initial_state(
async def test_fetch_period_api_before_history_started(
recorder_mock: Recorder, hass: HomeAssistant, hass_client: ClientSessionGenerator
hass: HomeAssistant, recorder_mock: Recorder, hass_client: ClientSessionGenerator
) -> None:
"""Test the fetch period view for history for the far past."""
await async_setup_component(
@ -563,7 +574,7 @@ async def test_fetch_period_api_before_history_started(
async def test_fetch_period_api_far_future(
recorder_mock: Recorder, hass: HomeAssistant, hass_client: ClientSessionGenerator
hass: HomeAssistant, recorder_mock: Recorder, hass_client: ClientSessionGenerator
) -> None:
"""Test the fetch period view for history for the far future."""
await async_setup_component(
@ -584,7 +595,7 @@ async def test_fetch_period_api_far_future(
async def test_fetch_period_api_with_invalid_datetime(
recorder_mock: Recorder, hass: HomeAssistant, hass_client: ClientSessionGenerator
hass: HomeAssistant, recorder_mock: Recorder, hass_client: ClientSessionGenerator
) -> None:
"""Test the fetch period view for history with an invalid date time."""
await async_setup_component(
@ -603,7 +614,7 @@ async def test_fetch_period_api_with_invalid_datetime(
async def test_fetch_period_api_invalid_end_time(
recorder_mock: Recorder, hass: HomeAssistant, hass_client: ClientSessionGenerator
hass: HomeAssistant, recorder_mock: Recorder, hass_client: ClientSessionGenerator
) -> None:
"""Test the fetch period view for history with an invalid end time."""
await async_setup_component(
@ -625,7 +636,7 @@ async def test_fetch_period_api_invalid_end_time(
async def test_entity_ids_limit_via_api_with_end_time(
recorder_mock: Recorder, hass: HomeAssistant, hass_client: ClientSessionGenerator
hass: HomeAssistant, recorder_mock: Recorder, hass_client: ClientSessionGenerator
) -> None:
"""Test limiting history to entity_ids with end_time."""
await async_setup_component(
@ -671,7 +682,7 @@ async def test_entity_ids_limit_via_api_with_end_time(
async def test_fetch_period_api_with_no_entity_ids(
recorder_mock: Recorder, hass: HomeAssistant, hass_client: ClientSessionGenerator
hass: HomeAssistant, recorder_mock: Recorder, hass_client: ClientSessionGenerator
) -> None:
"""Test the fetch period view for history with minimal_response."""
await async_setup_component(hass, "history", {})
@ -724,13 +735,13 @@ async def test_fetch_period_api_with_no_entity_ids(
],
)
async def test_history_with_invalid_entity_ids(
hass: HomeAssistant,
recorder_mock: Recorder,
hass_client: ClientSessionGenerator,
filter_entity_id,
status_code,
response_contains1,
response_contains2,
recorder_mock: Recorder,
hass: HomeAssistant,
hass_client: ClientSessionGenerator,
) -> None:
"""Test sending valid and invalid entity_ids to the API."""
await async_setup_component(

View File

@ -27,7 +27,6 @@ from tests.components.recorder.common import (
async_recorder_block_till_done,
async_wait_recording_done,
old_db_schema,
wait_recording_done,
)
from tests.typing import ClientSessionGenerator, WebSocketGenerator
@ -40,33 +39,34 @@ def db_schema_30():
@pytest.fixture
def legacy_hass_history(hass_history):
def legacy_hass_history(hass: HomeAssistant, hass_history):
"""Home Assistant fixture to use legacy history recording."""
instance = recorder.get_instance(hass_history)
instance = recorder.get_instance(hass)
with patch.object(instance.states_meta_manager, "active", False):
yield hass_history
yield
@pytest.mark.usefixtures("legacy_hass_history")
def test_setup() -> None:
async def test_setup() -> None:
"""Test setup method of history."""
# Verification occurs in the fixture
def test_get_significant_states(legacy_hass_history) -> None:
async def test_get_significant_states(hass: HomeAssistant, legacy_hass_history) -> 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 = legacy_hass_history
zero, four, states = record_states(hass)
zero, four, states = await async_record_states(hass)
hist = 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(legacy_hass_history) -> None:
async def test_get_significant_states_minimal_response(
hass: HomeAssistant, legacy_hass_history
) -> None:
"""Test that only significant states are returned.
When minimal responses is set only the first and
@ -76,8 +76,7 @@ def test_get_significant_states_minimal_response(legacy_hass_history) -> None:
includes an attribute change, but only the state updates for
media player (attribute changes are not significant and not returned).
"""
hass = legacy_hass_history
zero, four, states = record_states(hass)
zero, four, states = await async_record_states(hass)
hist = get_significant_states(
hass, zero, four, minimal_response=True, entity_ids=list(states)
)
@ -132,15 +131,16 @@ def test_get_significant_states_minimal_response(legacy_hass_history) -> None:
)
def test_get_significant_states_with_initial(legacy_hass_history) -> None:
async def test_get_significant_states_with_initial(
hass: HomeAssistant, legacy_hass_history
) -> 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 = legacy_hass_history
zero, four, states = record_states(hass)
zero, four, states = await async_record_states(hass)
one = zero + timedelta(seconds=1)
one_with_microsecond = zero + timedelta(seconds=1, microseconds=1)
one_and_half = zero + timedelta(seconds=1.5)
@ -162,15 +162,16 @@ def test_get_significant_states_with_initial(legacy_hass_history) -> None:
assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
def test_get_significant_states_without_initial(legacy_hass_history) -> None:
async def test_get_significant_states_without_initial(
hass: HomeAssistant, legacy_hass_history
) -> 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 = legacy_hass_history
zero, four, states = record_states(hass)
zero, four, states = await async_record_states(hass)
one = zero + timedelta(seconds=1)
one_with_microsecond = zero + timedelta(seconds=1, microseconds=1)
one_and_half = zero + timedelta(seconds=1.5)
@ -193,13 +194,13 @@ def test_get_significant_states_without_initial(legacy_hass_history) -> None:
assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
def test_get_significant_states_entity_id(hass_history) -> None:
async def test_get_significant_states_entity_id(
hass: HomeAssistant, hass_history
) -> None:
"""Test that only significant states are returned for one entity."""
hass = hass_history
instance = recorder.get_instance(hass)
with patch.object(instance.states_meta_manager, "active", False):
zero, four, states = record_states(hass)
zero, four, states = await async_record_states(hass)
del states["media_player.test2"]
del states["media_player.test3"]
del states["thermostat.test"]
@ -210,10 +211,11 @@ def test_get_significant_states_entity_id(hass_history) -> None:
assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
def test_get_significant_states_multiple_entity_ids(legacy_hass_history) -> None:
async def test_get_significant_states_multiple_entity_ids(
hass: HomeAssistant, legacy_hass_history
) -> None:
"""Test that only significant states are returned for one entity."""
hass = legacy_hass_history
zero, four, states = record_states(hass)
zero, four, states = await async_record_states(hass)
del states["media_player.test2"]
del states["media_player.test3"]
del states["thermostat.test2"]
@ -228,14 +230,15 @@ def test_get_significant_states_multiple_entity_ids(legacy_hass_history) -> None
assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
def test_get_significant_states_are_ordered(legacy_hass_history) -> None:
async def test_get_significant_states_are_ordered(
hass: HomeAssistant, legacy_hass_history
) -> 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 = legacy_hass_history
zero, four, _states = record_states(hass)
zero, four, _states = await async_record_states(hass)
entity_ids = ["media_player.test", "media_player.test2"]
hist = get_significant_states(hass, zero, four, entity_ids)
assert list(hist.keys()) == entity_ids
@ -244,15 +247,16 @@ def test_get_significant_states_are_ordered(legacy_hass_history) -> None:
assert list(hist.keys()) == entity_ids
def test_get_significant_states_only(legacy_hass_history) -> None:
async def test_get_significant_states_only(
hass: HomeAssistant, legacy_hass_history
) -> None:
"""Test significant states when significant_states_only is set."""
hass = legacy_hass_history
entity_id = "sensor.test"
def set_state(state, **kwargs):
async 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)
await async_wait_recording_done(hass)
return hass.states.get(entity_id)
start = dt_util.utcnow() - timedelta(minutes=4)
@ -260,19 +264,19 @@ def test_get_significant_states_only(legacy_hass_history) -> None:
states = []
with freeze_time(start) as freezer:
set_state("123", attributes={"attribute": 10.64})
await set_state("123", attributes={"attribute": 10.64})
freezer.move_to(points[0])
# Attributes are different, state not
states.append(set_state("123", attributes={"attribute": 21.42}))
states.append(await set_state("123", attributes={"attribute": 21.42}))
freezer.move_to(points[1])
# state is different, attributes not
states.append(set_state("32", attributes={"attribute": 21.42}))
states.append(await set_state("32", attributes={"attribute": 21.42}))
freezer.move_to(points[2])
# everything is different
states.append(set_state("412", attributes={"attribute": 54.23}))
states.append(await set_state("412", attributes={"attribute": 54.23}))
hist = get_significant_states(
hass,
@ -311,7 +315,7 @@ def check_significant_states(hass, zero, four, states, config):
assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
def record_states(hass):
async def async_record_states(hass):
"""Record some test states.
We inject a bunch of state updates from media player, zone and
@ -325,10 +329,10 @@ def record_states(hass):
zone = "zone.home"
script_c = "script.can_cancel_this_one"
def set_state(entity_id, state, **kwargs):
async def async_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)
await async_wait_recording_done(hass)
return hass.states.get(entity_id)
zero = dt_util.utcnow()
@ -340,55 +344,69 @@ def record_states(hass):
states = {therm: [], therm2: [], mp: [], mp2: [], mp3: [], script_c: []}
with freeze_time(one) as freezer:
states[mp].append(
set_state(mp, "idle", attributes={"media_title": str(sentinel.mt1)})
await async_set_state(
mp, "idle", attributes={"media_title": str(sentinel.mt1)}
)
)
states[mp2].append(
set_state(mp2, "YouTube", attributes={"media_title": str(sentinel.mt2)})
await async_set_state(
mp2, "YouTube", attributes={"media_title": str(sentinel.mt2)}
)
)
states[mp3].append(
set_state(mp3, "idle", attributes={"media_title": str(sentinel.mt1)})
await async_set_state(
mp3, "idle", attributes={"media_title": str(sentinel.mt1)}
)
)
states[therm].append(
set_state(therm, 20, attributes={"current_temperature": 19.5})
await async_set_state(therm, 20, attributes={"current_temperature": 19.5})
)
freezer.move_to(one + timedelta(microseconds=1))
states[mp].append(
set_state(mp, "YouTube", attributes={"media_title": str(sentinel.mt2)})
await async_set_state(
mp, "YouTube", attributes={"media_title": str(sentinel.mt2)}
)
)
freezer.move_to(two)
# This state will be skipped only different in time
set_state(mp, "YouTube", attributes={"media_title": str(sentinel.mt3)})
await async_set_state(
mp, "YouTube", attributes={"media_title": str(sentinel.mt3)}
)
# This state will be skipped because domain is excluded
set_state(zone, "zoning")
await async_set_state(zone, "zoning")
states[script_c].append(
set_state(script_c, "off", attributes={"can_cancel": True})
await async_set_state(script_c, "off", attributes={"can_cancel": True})
)
states[therm].append(
set_state(therm, 21, attributes={"current_temperature": 19.8})
await async_set_state(therm, 21, attributes={"current_temperature": 19.8})
)
states[therm2].append(
set_state(therm2, 20, attributes={"current_temperature": 19})
await async_set_state(therm2, 20, attributes={"current_temperature": 19})
)
freezer.move_to(three)
states[mp].append(
set_state(mp, "Netflix", attributes={"media_title": str(sentinel.mt4)})
await async_set_state(
mp, "Netflix", attributes={"media_title": str(sentinel.mt4)}
)
)
states[mp3].append(
set_state(mp3, "Netflix", attributes={"media_title": str(sentinel.mt3)})
await async_set_state(
mp3, "Netflix", attributes={"media_title": str(sentinel.mt3)}
)
)
# Attributes changed even though state is the same
states[therm].append(
set_state(therm, 21, attributes={"current_temperature": 20})
await async_set_state(therm, 21, attributes={"current_temperature": 20})
)
return zero, four, states
async def test_fetch_period_api(
recorder_mock: Recorder, hass: HomeAssistant, hass_client: ClientSessionGenerator
hass: HomeAssistant, recorder_mock: Recorder, hass_client: ClientSessionGenerator
) -> None:
"""Test the fetch period view for history."""
await async_setup_component(hass, "history", {})
@ -402,7 +420,7 @@ async def test_fetch_period_api(
async def test_fetch_period_api_with_minimal_response(
recorder_mock: Recorder, hass: HomeAssistant, hass_client: ClientSessionGenerator
hass: HomeAssistant, recorder_mock: Recorder, hass_client: ClientSessionGenerator
) -> None:
"""Test the fetch period view for history with minimal_response."""
now = dt_util.utcnow()
@ -445,7 +463,7 @@ async def test_fetch_period_api_with_minimal_response(
async def test_fetch_period_api_with_no_timestamp(
recorder_mock: Recorder, hass: HomeAssistant, hass_client: ClientSessionGenerator
hass: HomeAssistant, recorder_mock: Recorder, hass_client: ClientSessionGenerator
) -> None:
"""Test the fetch period view for history with no timestamp."""
await async_setup_component(hass, "history", {})
@ -457,7 +475,7 @@ async def test_fetch_period_api_with_no_timestamp(
async def test_fetch_period_api_with_include_order(
recorder_mock: Recorder, hass: HomeAssistant, hass_client: ClientSessionGenerator
hass: HomeAssistant, recorder_mock: Recorder, hass_client: ClientSessionGenerator
) -> None:
"""Test the fetch period view for history."""
await async_setup_component(
@ -481,7 +499,7 @@ async def test_fetch_period_api_with_include_order(
async def test_entity_ids_limit_via_api(
recorder_mock: Recorder, hass: HomeAssistant, hass_client: ClientSessionGenerator
hass: HomeAssistant, recorder_mock: Recorder, hass_client: ClientSessionGenerator
) -> None:
"""Test limiting history to entity_ids."""
await async_setup_component(
@ -509,7 +527,7 @@ async def test_entity_ids_limit_via_api(
async def test_entity_ids_limit_via_api_with_skip_initial_state(
recorder_mock: Recorder, hass: HomeAssistant, hass_client: ClientSessionGenerator
hass: HomeAssistant, recorder_mock: Recorder, hass_client: ClientSessionGenerator
) -> None:
"""Test limiting history to entity_ids with skip_initial_state."""
await async_setup_component(
@ -545,7 +563,7 @@ async def test_entity_ids_limit_via_api_with_skip_initial_state(
async def test_history_during_period(
recorder_mock: Recorder, hass: HomeAssistant, hass_ws_client: WebSocketGenerator
hass: HomeAssistant, recorder_mock: Recorder, hass_ws_client: WebSocketGenerator
) -> None:
"""Test history_during_period."""
now = dt_util.utcnow()
@ -693,7 +711,7 @@ async def test_history_during_period(
async def test_history_during_period_impossible_conditions(
recorder_mock: Recorder, hass: HomeAssistant, hass_ws_client: WebSocketGenerator
hass: HomeAssistant, recorder_mock: Recorder, hass_ws_client: WebSocketGenerator
) -> None:
"""Test history_during_period returns when condition cannot be true."""
await async_setup_component(hass, "history", {})
@ -757,10 +775,10 @@ async def test_history_during_period_impossible_conditions(
"time_zone", ["UTC", "Europe/Berlin", "America/Chicago", "US/Hawaii"]
)
async def test_history_during_period_significant_domain(
time_zone,
recorder_mock: Recorder,
hass: HomeAssistant,
recorder_mock: Recorder,
hass_ws_client: WebSocketGenerator,
time_zone,
) -> None:
"""Test history_during_period with climate domain."""
hass.config.set_time_zone(time_zone)
@ -941,7 +959,7 @@ async def test_history_during_period_significant_domain(
async def test_history_during_period_bad_start_time(
recorder_mock: Recorder, hass: HomeAssistant, hass_ws_client: WebSocketGenerator
hass: HomeAssistant, recorder_mock: Recorder, hass_ws_client: WebSocketGenerator
) -> None:
"""Test history_during_period bad state time."""
await async_setup_component(
@ -966,7 +984,7 @@ async def test_history_during_period_bad_start_time(
async def test_history_during_period_bad_end_time(
recorder_mock: Recorder, hass: HomeAssistant, hass_ws_client: WebSocketGenerator
hass: HomeAssistant, recorder_mock: Recorder, hass_ws_client: WebSocketGenerator
) -> None:
"""Test history_during_period bad end time."""
now = dt_util.utcnow()

View File

@ -39,7 +39,7 @@ def test_setup() -> None:
async def test_history_during_period(
recorder_mock: Recorder, hass: HomeAssistant, hass_ws_client: WebSocketGenerator
hass: HomeAssistant, recorder_mock: Recorder, hass_ws_client: WebSocketGenerator
) -> None:
"""Test history_during_period."""
now = dt_util.utcnow()
@ -173,7 +173,7 @@ async def test_history_during_period(
async def test_history_during_period_impossible_conditions(
recorder_mock: Recorder, hass: HomeAssistant, hass_ws_client: WebSocketGenerator
hass: HomeAssistant, recorder_mock: Recorder, hass_ws_client: WebSocketGenerator
) -> None:
"""Test history_during_period returns when condition cannot be true."""
await async_setup_component(hass, "history", {})
@ -235,10 +235,10 @@ async def test_history_during_period_impossible_conditions(
"time_zone", ["UTC", "Europe/Berlin", "America/Chicago", "US/Hawaii"]
)
async def test_history_during_period_significant_domain(
time_zone,
recorder_mock: Recorder,
hass: HomeAssistant,
recorder_mock: Recorder,
hass_ws_client: WebSocketGenerator,
time_zone,
) -> None:
"""Test history_during_period with climate domain."""
hass.config.set_time_zone(time_zone)
@ -403,7 +403,7 @@ async def test_history_during_period_significant_domain(
async def test_history_during_period_bad_start_time(
recorder_mock: Recorder, hass: HomeAssistant, hass_ws_client: WebSocketGenerator
hass: HomeAssistant, recorder_mock: Recorder, hass_ws_client: WebSocketGenerator
) -> None:
"""Test history_during_period bad state time."""
await async_setup_component(
@ -427,7 +427,7 @@ async def test_history_during_period_bad_start_time(
async def test_history_during_period_bad_end_time(
recorder_mock: Recorder, hass: HomeAssistant, hass_ws_client: WebSocketGenerator
hass: HomeAssistant, recorder_mock: Recorder, hass_ws_client: WebSocketGenerator
) -> None:
"""Test history_during_period bad end time."""
now = dt_util.utcnow()
@ -454,7 +454,7 @@ async def test_history_during_period_bad_end_time(
async def test_history_stream_historical_only(
recorder_mock: Recorder, hass: HomeAssistant, hass_ws_client: WebSocketGenerator
hass: HomeAssistant, recorder_mock: Recorder, hass_ws_client: WebSocketGenerator
) -> None:
"""Test history stream."""
now = dt_util.utcnow()
@ -525,7 +525,7 @@ async def test_history_stream_historical_only(
async def test_history_stream_significant_domain_historical_only(
recorder_mock: Recorder, hass: HomeAssistant, hass_ws_client: WebSocketGenerator
hass: HomeAssistant, recorder_mock: Recorder, hass_ws_client: WebSocketGenerator
) -> None:
"""Test the stream with climate domain with historical states only."""
now = dt_util.utcnow()
@ -726,7 +726,7 @@ async def test_history_stream_significant_domain_historical_only(
async def test_history_stream_bad_start_time(
recorder_mock: Recorder, hass: HomeAssistant, hass_ws_client: WebSocketGenerator
hass: HomeAssistant, recorder_mock: Recorder, hass_ws_client: WebSocketGenerator
) -> None:
"""Test history stream bad state time."""
await async_setup_component(
@ -750,7 +750,7 @@ async def test_history_stream_bad_start_time(
async def test_history_stream_end_time_before_start_time(
recorder_mock: Recorder, hass: HomeAssistant, hass_ws_client: WebSocketGenerator
hass: HomeAssistant, recorder_mock: Recorder, hass_ws_client: WebSocketGenerator
) -> None:
"""Test history stream with an end_time before the start_time."""
end_time = dt_util.utcnow() - timedelta(seconds=2)
@ -778,7 +778,7 @@ async def test_history_stream_end_time_before_start_time(
async def test_history_stream_bad_end_time(
recorder_mock: Recorder, hass: HomeAssistant, hass_ws_client: WebSocketGenerator
hass: HomeAssistant, recorder_mock: Recorder, hass_ws_client: WebSocketGenerator
) -> None:
"""Test history stream bad end time."""
now = dt_util.utcnow()
@ -805,7 +805,7 @@ async def test_history_stream_bad_end_time(
async def test_history_stream_live_no_attributes_minimal_response(
recorder_mock: Recorder, hass: HomeAssistant, hass_ws_client: WebSocketGenerator
hass: HomeAssistant, recorder_mock: Recorder, hass_ws_client: WebSocketGenerator
) -> None:
"""Test history stream with history and live data and no_attributes and minimal_response."""
now = dt_util.utcnow()
@ -882,7 +882,7 @@ async def test_history_stream_live_no_attributes_minimal_response(
async def test_history_stream_live(
recorder_mock: Recorder, hass: HomeAssistant, hass_ws_client: WebSocketGenerator
hass: HomeAssistant, recorder_mock: Recorder, hass_ws_client: WebSocketGenerator
) -> None:
"""Test history stream with history and live data."""
now = dt_util.utcnow()
@ -985,7 +985,7 @@ async def test_history_stream_live(
async def test_history_stream_live_minimal_response(
recorder_mock: Recorder, hass: HomeAssistant, hass_ws_client: WebSocketGenerator
hass: HomeAssistant, recorder_mock: Recorder, hass_ws_client: WebSocketGenerator
) -> None:
"""Test history stream with history and live data and minimal_response."""
now = dt_util.utcnow()
@ -1082,7 +1082,7 @@ async def test_history_stream_live_minimal_response(
async def test_history_stream_live_no_attributes(
recorder_mock: Recorder, hass: HomeAssistant, hass_ws_client: WebSocketGenerator
hass: HomeAssistant, recorder_mock: Recorder, hass_ws_client: WebSocketGenerator
) -> None:
"""Test history stream with history and live data and no_attributes."""
now = dt_util.utcnow()
@ -1163,7 +1163,7 @@ async def test_history_stream_live_no_attributes(
async def test_history_stream_live_no_attributes_minimal_response_specific_entities(
recorder_mock: Recorder, hass: HomeAssistant, hass_ws_client: WebSocketGenerator
hass: HomeAssistant, recorder_mock: Recorder, hass_ws_client: WebSocketGenerator
) -> None:
"""Test history stream with history and live data and no_attributes and minimal_response with specific entities."""
now = dt_util.utcnow()
@ -1241,7 +1241,7 @@ async def test_history_stream_live_no_attributes_minimal_response_specific_entit
async def test_history_stream_live_with_future_end_time(
recorder_mock: Recorder, hass: HomeAssistant, hass_ws_client: WebSocketGenerator
hass: HomeAssistant, recorder_mock: Recorder, hass_ws_client: WebSocketGenerator
) -> None:
"""Test history stream with history and live data with future end time."""
now = dt_util.utcnow()
@ -1334,8 +1334,8 @@ async def test_history_stream_live_with_future_end_time(
@pytest.mark.parametrize("include_start_time_state", [True, False])
async def test_history_stream_before_history_starts(
recorder_mock: Recorder,
hass: HomeAssistant,
recorder_mock: Recorder,
hass_ws_client: WebSocketGenerator,
include_start_time_state,
) -> None:
@ -1385,7 +1385,7 @@ async def test_history_stream_before_history_starts(
async def test_history_stream_for_entity_with_no_possible_changes(
recorder_mock: Recorder, hass: HomeAssistant, hass_ws_client: WebSocketGenerator
hass: HomeAssistant, recorder_mock: Recorder, hass_ws_client: WebSocketGenerator
) -> None:
"""Test history stream for future with no possible changes where end time is less than or equal to now."""
await async_setup_component(
@ -1436,7 +1436,7 @@ async def test_history_stream_for_entity_with_no_possible_changes(
async def test_overflow_queue(
recorder_mock: Recorder, hass: HomeAssistant, hass_ws_client: WebSocketGenerator
hass: HomeAssistant, recorder_mock: Recorder, hass_ws_client: WebSocketGenerator
) -> None:
"""Test overflowing the history stream queue."""
now = dt_util.utcnow()
@ -1513,7 +1513,7 @@ async def test_overflow_queue(
async def test_history_during_period_for_invalid_entity_ids(
recorder_mock: Recorder, hass: HomeAssistant, hass_ws_client: WebSocketGenerator
hass: HomeAssistant, recorder_mock: Recorder, hass_ws_client: WebSocketGenerator
) -> None:
"""Test history_during_period for valid and invalid entity ids."""
now = dt_util.utcnow()
@ -1656,7 +1656,7 @@ async def test_history_during_period_for_invalid_entity_ids(
async def test_history_stream_for_invalid_entity_ids(
recorder_mock: Recorder, hass: HomeAssistant, hass_ws_client: WebSocketGenerator
hass: HomeAssistant, recorder_mock: Recorder, hass_ws_client: WebSocketGenerator
) -> None:
"""Test history stream for invalid and valid entity ids."""
@ -1824,7 +1824,7 @@ async def test_history_stream_for_invalid_entity_ids(
async def test_history_stream_historical_only_with_start_time_state_past(
recorder_mock: Recorder, hass: HomeAssistant, hass_ws_client: WebSocketGenerator
hass: HomeAssistant, recorder_mock: Recorder, hass_ws_client: WebSocketGenerator
) -> None:
"""Test history stream."""
await async_setup_component(

View File

@ -24,7 +24,7 @@ def db_schema_32():
async def test_history_during_period(
recorder_mock: Recorder, hass: HomeAssistant, hass_ws_client: WebSocketGenerator
hass: HomeAssistant, recorder_mock: Recorder, hass_ws_client: WebSocketGenerator
) -> None:
"""Test history_during_period."""
now = dt_util.utcnow()

View File

@ -198,7 +198,7 @@ async def test_shutdown_closes_connections(
hass.set_state(CoreState.not_running)
instance = get_instance(hass)
instance = recorder.get_instance(hass)
await instance.async_db_ready
await hass.async_block_till_done()
pool = instance.engine.pool

View File

@ -526,6 +526,7 @@ async def hass(
load_registries: bool,
hass_storage: dict[str, Any],
request: pytest.FixtureRequest,
mock_recorder_before_hass: None,
) -> AsyncGenerator[HomeAssistant, None]:
"""Create a test instance of Home Assistant."""
@ -1577,6 +1578,15 @@ async def recorder_mock(
return await async_setup_recorder_instance(hass, recorder_config)
@pytest.fixture
def mock_recorder_before_hass() -> None:
"""Mock the recorder.
Override or parametrize this fixture with a fixture that mocks the recorder,
in the tests that need to test the recorder.
"""
@pytest.fixture(name="enable_bluetooth")
async def mock_enable_bluetooth(
hass: HomeAssistant,