Convert recorder entity registry tests to use async API (#116448)

* Convert recorder entity registry tests to use async API

* Address review comment

* Make sure recorder is patch is set up before hass fixture
This commit is contained in:
Erik Montnemery 2024-05-03 14:10:58 +02:00 committed by GitHub
parent f309064a7f
commit e9b9d2d545
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 89 additions and 102 deletions

View File

@ -257,6 +257,11 @@ def assert_dict_of_states_equal_without_context_and_last_changed(
)
async def async_record_states(hass: HomeAssistant):
"""Record some test states."""
return await hass.async_add_executor_job(record_states, hass)
def record_states(hass):
"""Record some test states.

View File

@ -1,6 +1,5 @@
"""The tests for sensor recorder platform."""
from collections.abc import Callable
from unittest.mock import patch
import pytest
@ -8,23 +7,22 @@ from sqlalchemy import select
from sqlalchemy.orm import Session
from homeassistant.components import recorder
from homeassistant.components.recorder import history
from homeassistant.components.recorder import Recorder, history
from homeassistant.components.recorder.db_schema import StatesMeta
from homeassistant.components.recorder.util import session_scope
from homeassistant.core import HomeAssistant, callback
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
from homeassistant.setup import setup_component
from homeassistant.setup import async_setup_component
from homeassistant.util import dt as dt_util
from .common import (
ForceReturnConnectionToPool,
assert_dict_of_states_equal_without_context_and_last_changed,
async_record_states,
async_wait_recording_done,
record_states,
wait_recording_done,
)
from tests.common import MockEntity, MockEntityPlatform, mock_registry
from tests.common import MockEntity, MockEntityPlatform
from tests.typing import RecorderInstanceGenerator
@ -40,41 +38,44 @@ def _count_entity_id_in_states_meta(
)
def test_rename_entity_without_collision(
hass_recorder: Callable[..., HomeAssistant], caplog: pytest.LogCaptureFixture
@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 test_rename_entity_without_collision(
hass: HomeAssistant,
entity_registry: er.EntityRegistry,
caplog: pytest.LogCaptureFixture,
) -> None:
"""Test states meta is migrated when entity_id is changed."""
hass = hass_recorder()
setup_component(hass, "sensor", {})
await async_setup_component(hass, "sensor", {})
entity_reg = mock_registry(hass)
reg_entry = entity_registry.async_get_or_create(
"sensor",
"test",
"unique_0000",
suggested_object_id="test1",
)
assert reg_entry.entity_id == "sensor.test1"
await hass.async_block_till_done()
@callback
def add_entry():
reg_entry = entity_reg.async_get_or_create(
"sensor",
"test",
"unique_0000",
suggested_object_id="test1",
)
assert reg_entry.entity_id == "sensor.test1"
hass.add_job(add_entry)
hass.block_till_done()
zero, four, states = record_states(hass)
zero, four, states = await async_record_states(hass)
hist = history.get_significant_states(
hass, zero, four, list(set(states) | {"sensor.test99", "sensor.test1"})
)
assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
@callback
def rename_entry():
entity_reg.async_update_entity("sensor.test1", new_entity_id="sensor.test99")
hass.add_job(rename_entry)
wait_recording_done(hass)
entity_registry.async_update_entity("sensor.test1", new_entity_id="sensor.test99")
await async_wait_recording_done(hass)
hist = history.get_significant_states(
hass, zero, four, list(set(states) | {"sensor.test99", "sensor.test1"})
@ -82,8 +83,8 @@ def test_rename_entity_without_collision(
states["sensor.test99"] = states.pop("sensor.test1")
assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
hass.states.set("sensor.test99", "post_migrate")
wait_recording_done(hass)
hass.states.async_set("sensor.test99", "post_migrate")
await async_wait_recording_done(hass)
new_hist = history.get_significant_states(
hass,
zero,
@ -101,8 +102,8 @@ def test_rename_entity_without_collision(
async def test_rename_entity_on_mocked_platform(
async_setup_recorder_instance: RecorderInstanceGenerator,
hass: HomeAssistant,
entity_registry: er.EntityRegistry,
caplog: pytest.LogCaptureFixture,
) -> None:
"""Test states meta is migrated when entity_id is changed when using a mocked platform.
@ -111,11 +112,10 @@ async def test_rename_entity_on_mocked_platform(
sure that we do not record the entity as removed in the database
when we rename it.
"""
instance = await async_setup_recorder_instance(hass)
entity_reg = er.async_get(hass)
instance = recorder.get_instance(hass)
start = dt_util.utcnow()
reg_entry = entity_reg.async_get_or_create(
reg_entry = entity_registry.async_get_or_create(
"sensor",
"test",
"unique_0000",
@ -142,7 +142,7 @@ async def test_rename_entity_on_mocked_platform(
["sensor.test1", "sensor.test99"],
)
entity_reg.async_update_entity("sensor.test1", new_entity_id="sensor.test99")
entity_registry.async_update_entity("sensor.test1", new_entity_id="sensor.test99")
await hass.async_block_till_done()
# We have to call the remove method ourselves since we are mocking the platform
hass.states.async_remove("sensor.test1")
@ -196,47 +196,38 @@ async def test_rename_entity_on_mocked_platform(
assert "the new entity_id is already in use" not in caplog.text
def test_rename_entity_collision(
hass_recorder: Callable[..., HomeAssistant], caplog: pytest.LogCaptureFixture
async def test_rename_entity_collision(
hass: HomeAssistant,
entity_registry: er.EntityRegistry,
caplog: pytest.LogCaptureFixture,
) -> None:
"""Test states meta is not migrated when there is a collision."""
hass = hass_recorder()
setup_component(hass, "sensor", {})
await async_setup_component(hass, "sensor", {})
entity_reg = mock_registry(hass)
reg_entry = entity_registry.async_get_or_create(
"sensor",
"test",
"unique_0000",
suggested_object_id="test1",
)
assert reg_entry.entity_id == "sensor.test1"
await hass.async_block_till_done()
@callback
def add_entry():
reg_entry = entity_reg.async_get_or_create(
"sensor",
"test",
"unique_0000",
suggested_object_id="test1",
)
assert reg_entry.entity_id == "sensor.test1"
hass.add_job(add_entry)
hass.block_till_done()
zero, four, states = record_states(hass)
zero, four, states = await async_record_states(hass)
hist = history.get_significant_states(
hass, zero, four, list(set(states) | {"sensor.test99", "sensor.test1"})
)
assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
assert len(hist["sensor.test1"]) == 3
hass.states.set("sensor.test99", "collision")
hass.states.remove("sensor.test99")
hass.states.async_set("sensor.test99", "collision")
hass.states.async_remove("sensor.test99")
hass.block_till_done()
await hass.async_block_till_done()
# Rename entity sensor.test1 to sensor.test99
@callback
def rename_entry():
entity_reg.async_update_entity("sensor.test1", new_entity_id="sensor.test99")
hass.add_job(rename_entry)
wait_recording_done(hass)
entity_registry.async_update_entity("sensor.test1", new_entity_id="sensor.test99")
await async_wait_recording_done(hass)
# History is not migrated on collision
hist = history.get_significant_states(
@ -248,8 +239,8 @@ def test_rename_entity_collision(
with session_scope(hass=hass) as session:
assert _count_entity_id_in_states_meta(hass, session, "sensor.test99") == 1
hass.states.set("sensor.test99", "post_migrate")
wait_recording_done(hass)
hass.states.async_set("sensor.test99", "post_migrate")
await async_wait_recording_done(hass)
new_hist = history.get_significant_states(
hass,
zero,
@ -270,44 +261,39 @@ def test_rename_entity_collision(
assert "Blocked attempt to insert duplicated state rows" not in caplog.text
def test_rename_entity_collision_without_states_meta_safeguard(
hass_recorder: Callable[..., HomeAssistant], caplog: pytest.LogCaptureFixture
async def test_rename_entity_collision_without_states_meta_safeguard(
hass: HomeAssistant,
entity_registry: er.EntityRegistry,
caplog: pytest.LogCaptureFixture,
) -> None:
"""Test states meta is not migrated when there is a collision.
This test disables the safeguard in the states_meta_manager
and relies on the filter_unique_constraint_integrity_error safeguard.
"""
hass = hass_recorder()
setup_component(hass, "sensor", {})
await async_setup_component(hass, "sensor", {})
entity_reg = mock_registry(hass)
reg_entry = entity_registry.async_get_or_create(
"sensor",
"test",
"unique_0000",
suggested_object_id="test1",
)
assert reg_entry.entity_id == "sensor.test1"
await hass.async_block_till_done()
@callback
def add_entry():
reg_entry = entity_reg.async_get_or_create(
"sensor",
"test",
"unique_0000",
suggested_object_id="test1",
)
assert reg_entry.entity_id == "sensor.test1"
hass.add_job(add_entry)
hass.block_till_done()
zero, four, states = record_states(hass)
zero, four, states = await async_record_states(hass)
hist = history.get_significant_states(
hass, zero, four, list(set(states) | {"sensor.test99", "sensor.test1"})
)
assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
assert len(hist["sensor.test1"]) == 3
hass.states.set("sensor.test99", "collision")
hass.states.remove("sensor.test99")
hass.states.async_set("sensor.test99", "collision")
hass.states.async_remove("sensor.test99")
hass.block_till_done()
wait_recording_done(hass)
await hass.async_block_till_done()
await async_wait_recording_done(hass)
# Verify history before collision
hist = history.get_significant_states(
@ -321,14 +307,10 @@ def test_rename_entity_collision_without_states_meta_safeguard(
# so that we hit the filter_unique_constraint_integrity_error safeguard in the entity_registry
with patch.object(instance.states_meta_manager, "get", return_value=None):
# Rename entity sensor.test1 to sensor.test99
@callback
def rename_entry():
entity_reg.async_update_entity(
"sensor.test1", new_entity_id="sensor.test99"
)
hass.add_job(rename_entry)
wait_recording_done(hass)
entity_registry.async_update_entity(
"sensor.test1", new_entity_id="sensor.test99"
)
await async_wait_recording_done(hass)
# History is not migrated on collision
hist = history.get_significant_states(
@ -340,8 +322,8 @@ def test_rename_entity_collision_without_states_meta_safeguard(
with session_scope(hass=hass) as session:
assert _count_entity_id_in_states_meta(hass, session, "sensor.test99") == 1
hass.states.set("sensor.test99", "post_migrate")
wait_recording_done(hass)
hass.states.async_set("sensor.test99", "post_migrate")
await async_wait_recording_done(hass)
new_hist = history.get_significant_states(
hass,