mirror of
https://github.com/home-assistant/core.git
synced 2025-07-15 17:27:10 +00:00
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:
parent
f309064a7f
commit
e9b9d2d545
@ -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.
|
||||
|
||||
|
@ -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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user