From a1e6f8c2ec7c27fb6ee7123e18dcbfa5ab01dc52 Mon Sep 17 00:00:00 2001 From: Erik Montnemery Date: Thu, 4 Jul 2024 17:39:13 +0200 Subject: [PATCH] Drop use of async_setup_recorder_instance fixture in recorder migration tests (#121196) --- .../recorder/test_migration_from_schema_32.py | 130 +++++++++--------- ..._migration_run_time_migrations_remember.py | 48 ++++--- 2 files changed, 91 insertions(+), 87 deletions(-) diff --git a/tests/components/recorder/test_migration_from_schema_32.py b/tests/components/recorder/test_migration_from_schema_32.py index ec307632826..91358388614 100644 --- a/tests/components/recorder/test_migration_from_schema_32.py +++ b/tests/components/recorder/test_migration_from_schema_32.py @@ -1,6 +1,5 @@ """The tests for the recorder filter matching the EntityFilter component.""" -from collections.abc import AsyncGenerator import datetime import importlib import sys @@ -60,6 +59,13 @@ CREATE_ENGINE_TARGET = "homeassistant.components.recorder.core.create_engine" SCHEMA_MODULE = "tests.components.recorder.db_schema_32" +@pytest.fixture +async def mock_recorder_before_hass( + async_test_recorder: RecorderInstanceGenerator, +) -> None: + """Set up recorder.""" + + async def _async_wait_migration_done(hass: HomeAssistant) -> None: """Wait for the migration to be done.""" await recorder.get_instance(hass).async_block_till_done() @@ -116,21 +122,11 @@ def db_schema_32(): yield -@pytest.fixture(name="legacy_recorder_mock") -async def legacy_recorder_mock_fixture( - recorder_mock: Recorder, -) -> AsyncGenerator[Recorder]: - """Fixture for legacy recorder mock.""" - with patch.object(recorder_mock.states_meta_manager, "active", False): - yield recorder_mock - - @pytest.mark.parametrize("enable_migrate_context_ids", [True]) async def test_migrate_events_context_ids( - async_setup_recorder_instance: RecorderInstanceGenerator, hass: HomeAssistant + hass: HomeAssistant, recorder_mock: Recorder ) -> None: """Test we can migrate old uuid context ids and ulid context ids to binary format.""" - instance = await async_setup_recorder_instance(hass) await async_wait_recording_done(hass) importlib.import_module(SCHEMA_MODULE) old_db_schema = sys.modules[SCHEMA_MODULE] @@ -224,7 +220,7 @@ async def test_migrate_events_context_ids( ) ) - await instance.async_add_executor_job(_insert_events) + await recorder_mock.async_add_executor_job(_insert_events) await async_wait_recording_done(hass) now = dt_util.utcnow() @@ -233,7 +229,7 @@ async def test_migrate_events_context_ids( with freeze_time(now): # This is a threadsafe way to add a task to the recorder - instance.queue_task(EventsContextIDMigrationTask()) + recorder_mock.queue_task(EventsContextIDMigrationTask()) await _async_wait_migration_done(hass) def _object_as_dict(obj): @@ -260,7 +256,7 @@ async def test_migrate_events_context_ids( assert len(events) == 6 return {event.event_type: _object_as_dict(event) for event in events} - events_by_type = await instance.async_add_executor_job(_fetch_migrated_events) + events_by_type = await recorder_mock.async_add_executor_job(_fetch_migrated_events) old_uuid_context_id_event = events_by_type["old_uuid_context_id_event"] assert old_uuid_context_id_event["context_id"] is None @@ -331,7 +327,9 @@ async def test_migrate_events_context_ids( event_with_garbage_context_id_no_time_fired_ts["context_parent_id_bin"] is None ) - migration_changes = await instance.async_add_executor_job(_get_migration_id, hass) + migration_changes = await recorder_mock.async_add_executor_job( + _get_migration_id, hass + ) assert ( migration_changes[migration.EventsContextIDMigration.migration_id] == migration.EventsContextIDMigration.migration_version @@ -340,10 +338,9 @@ async def test_migrate_events_context_ids( @pytest.mark.parametrize("enable_migrate_context_ids", [True]) async def test_migrate_states_context_ids( - async_setup_recorder_instance: RecorderInstanceGenerator, hass: HomeAssistant + hass: HomeAssistant, recorder_mock: Recorder ) -> None: """Test we can migrate old uuid context ids and ulid context ids to binary format.""" - instance = await async_setup_recorder_instance(hass) await async_wait_recording_done(hass) importlib.import_module(SCHEMA_MODULE) old_db_schema = sys.modules[SCHEMA_MODULE] @@ -419,10 +416,10 @@ async def test_migrate_states_context_ids( ) ) - await instance.async_add_executor_job(_insert_states) + await recorder_mock.async_add_executor_job(_insert_states) await async_wait_recording_done(hass) - instance.queue_task(StatesContextIDMigrationTask()) + recorder_mock.queue_task(StatesContextIDMigrationTask()) await _async_wait_migration_done(hass) def _object_as_dict(obj): @@ -449,7 +446,9 @@ async def test_migrate_states_context_ids( assert len(events) == 6 return {state.entity_id: _object_as_dict(state) for state in events} - states_by_entity_id = await instance.async_add_executor_job(_fetch_migrated_states) + states_by_entity_id = await recorder_mock.async_add_executor_job( + _fetch_migrated_states + ) old_uuid_context_id = states_by_entity_id["state.old_uuid_context_id"] assert old_uuid_context_id["context_id"] is None @@ -524,7 +523,9 @@ async def test_migrate_states_context_ids( == b"\n\xe2\x97\x99\xeeNOE\x81\x16\xf5\x82\xd7\xd3\xeee" ) - migration_changes = await instance.async_add_executor_job(_get_migration_id, hass) + migration_changes = await recorder_mock.async_add_executor_job( + _get_migration_id, hass + ) assert ( migration_changes[migration.StatesContextIDMigration.migration_id] == migration.StatesContextIDMigration.migration_version @@ -533,10 +534,9 @@ async def test_migrate_states_context_ids( @pytest.mark.parametrize("enable_migrate_event_type_ids", [True]) async def test_migrate_event_type_ids( - async_setup_recorder_instance: RecorderInstanceGenerator, hass: HomeAssistant + hass: HomeAssistant, recorder_mock: Recorder ) -> None: """Test we can migrate event_types to the EventTypes table.""" - instance = await async_setup_recorder_instance(hass) await async_wait_recording_done(hass) importlib.import_module(SCHEMA_MODULE) old_db_schema = sys.modules[SCHEMA_MODULE] @@ -563,11 +563,11 @@ async def test_migrate_event_type_ids( ) ) - await instance.async_add_executor_job(_insert_events) + await recorder_mock.async_add_executor_job(_insert_events) await async_wait_recording_done(hass) # This is a threadsafe way to add a task to the recorder - instance.queue_task(EventTypeIDMigrationTask()) + recorder_mock.queue_task(EventTypeIDMigrationTask()) await _async_wait_migration_done(hass) def _fetch_migrated_events(): @@ -599,21 +599,23 @@ async def test_migrate_event_type_ids( ) return result - events_by_type = await instance.async_add_executor_job(_fetch_migrated_events) + events_by_type = await recorder_mock.async_add_executor_job(_fetch_migrated_events) assert len(events_by_type["event_type_one"]) == 2 assert len(events_by_type["event_type_two"]) == 1 def _get_many(): with session_scope(hass=hass, read_only=True) as session: - return instance.event_type_manager.get_many( + return recorder_mock.event_type_manager.get_many( ("event_type_one", "event_type_two"), session ) - mapped = await instance.async_add_executor_job(_get_many) + mapped = await recorder_mock.async_add_executor_job(_get_many) assert mapped["event_type_one"] is not None assert mapped["event_type_two"] is not None - migration_changes = await instance.async_add_executor_job(_get_migration_id, hass) + migration_changes = await recorder_mock.async_add_executor_job( + _get_migration_id, hass + ) assert ( migration_changes[migration.EventTypeIDMigration.migration_id] == migration.EventTypeIDMigration.migration_version @@ -621,11 +623,8 @@ async def test_migrate_event_type_ids( @pytest.mark.parametrize("enable_migrate_entity_ids", [True]) -async def test_migrate_entity_ids( - async_setup_recorder_instance: RecorderInstanceGenerator, hass: HomeAssistant -) -> None: +async def test_migrate_entity_ids(hass: HomeAssistant, recorder_mock: Recorder) -> None: """Test we can migrate entity_ids to the StatesMeta table.""" - instance = await async_setup_recorder_instance(hass) await async_wait_recording_done(hass) importlib.import_module(SCHEMA_MODULE) old_db_schema = sys.modules[SCHEMA_MODULE] @@ -652,11 +651,11 @@ async def test_migrate_entity_ids( ) ) - await instance.async_add_executor_job(_insert_states) + await recorder_mock.async_add_executor_job(_insert_states) await _async_wait_migration_done(hass) # This is a threadsafe way to add a task to the recorder - instance.queue_task(EntityIDMigrationTask()) + recorder_mock.queue_task(EntityIDMigrationTask()) await _async_wait_migration_done(hass) def _fetch_migrated_states(): @@ -683,11 +682,15 @@ async def test_migrate_entity_ids( ) return result - states_by_entity_id = await instance.async_add_executor_job(_fetch_migrated_states) + states_by_entity_id = await recorder_mock.async_add_executor_job( + _fetch_migrated_states + ) assert len(states_by_entity_id["sensor.two"]) == 2 assert len(states_by_entity_id["sensor.one"]) == 1 - migration_changes = await instance.async_add_executor_job(_get_migration_id, hass) + migration_changes = await recorder_mock.async_add_executor_job( + _get_migration_id, hass + ) assert ( migration_changes[migration.EntityIDMigration.migration_id] == migration.EntityIDMigration.migration_version @@ -696,10 +699,9 @@ async def test_migrate_entity_ids( @pytest.mark.parametrize("enable_migrate_entity_ids", [True]) async def test_post_migrate_entity_ids( - async_setup_recorder_instance: RecorderInstanceGenerator, hass: HomeAssistant + hass: HomeAssistant, recorder_mock: Recorder ) -> None: """Test we can migrate entity_ids to the StatesMeta table.""" - instance = await async_setup_recorder_instance(hass) await async_wait_recording_done(hass) importlib.import_module(SCHEMA_MODULE) old_db_schema = sys.modules[SCHEMA_MODULE] @@ -726,11 +728,11 @@ async def test_post_migrate_entity_ids( ) ) - await instance.async_add_executor_job(_insert_events) + await recorder_mock.async_add_executor_job(_insert_events) await _async_wait_migration_done(hass) # This is a threadsafe way to add a task to the recorder - instance.queue_task(EntityIDPostMigrationTask()) + recorder_mock.queue_task(EntityIDPostMigrationTask()) await _async_wait_migration_done(hass) def _fetch_migrated_states(): @@ -742,7 +744,7 @@ async def test_post_migrate_entity_ids( assert len(states) == 3 return {state.state: state.entity_id for state in states} - states_by_state = await instance.async_add_executor_job(_fetch_migrated_states) + states_by_state = await recorder_mock.async_add_executor_job(_fetch_migrated_states) assert states_by_state["one_1"] is None assert states_by_state["two_2"] is None assert states_by_state["two_1"] is None @@ -750,10 +752,9 @@ async def test_post_migrate_entity_ids( @pytest.mark.parametrize("enable_migrate_entity_ids", [True]) async def test_migrate_null_entity_ids( - async_setup_recorder_instance: RecorderInstanceGenerator, hass: HomeAssistant + hass: HomeAssistant, recorder_mock: Recorder ) -> None: """Test we can migrate entity_ids to the StatesMeta table.""" - instance = await async_setup_recorder_instance(hass) await async_wait_recording_done(hass) importlib.import_module(SCHEMA_MODULE) old_db_schema = sys.modules[SCHEMA_MODULE] @@ -783,11 +784,11 @@ async def test_migrate_null_entity_ids( ), ) - await instance.async_add_executor_job(_insert_states) + await recorder_mock.async_add_executor_job(_insert_states) await _async_wait_migration_done(hass) # This is a threadsafe way to add a task to the recorder - instance.queue_task(EntityIDMigrationTask()) + recorder_mock.queue_task(EntityIDMigrationTask()) await _async_wait_migration_done(hass) def _fetch_migrated_states(): @@ -814,7 +815,9 @@ async def test_migrate_null_entity_ids( ) return result - states_by_entity_id = await instance.async_add_executor_job(_fetch_migrated_states) + states_by_entity_id = await recorder_mock.async_add_executor_job( + _fetch_migrated_states + ) assert len(states_by_entity_id[migration._EMPTY_ENTITY_ID]) == 1000 assert len(states_by_entity_id["sensor.one"]) == 2 @@ -822,7 +825,7 @@ async def test_migrate_null_entity_ids( with session_scope(hass=hass, read_only=True) as session: return dict(execute_stmt_lambda_element(session, get_migration_changes())) - migration_changes = await instance.async_add_executor_job(_get_migration_id) + migration_changes = await recorder_mock.async_add_executor_job(_get_migration_id) assert ( migration_changes[migration.EntityIDMigration.migration_id] == migration.EntityIDMigration.migration_version @@ -831,10 +834,9 @@ async def test_migrate_null_entity_ids( @pytest.mark.parametrize("enable_migrate_event_type_ids", [True]) async def test_migrate_null_event_type_ids( - async_setup_recorder_instance: RecorderInstanceGenerator, hass: HomeAssistant + hass: HomeAssistant, recorder_mock: Recorder ) -> None: """Test we can migrate event_types to the EventTypes table when the event_type is NULL.""" - instance = await async_setup_recorder_instance(hass) await async_wait_recording_done(hass) importlib.import_module(SCHEMA_MODULE) old_db_schema = sys.modules[SCHEMA_MODULE] @@ -864,11 +866,11 @@ async def test_migrate_null_event_type_ids( ), ) - await instance.async_add_executor_job(_insert_events) + await recorder_mock.async_add_executor_job(_insert_events) await _async_wait_migration_done(hass) # This is a threadsafe way to add a task to the recorder - instance.queue_task(EventTypeIDMigrationTask()) + recorder_mock.queue_task(EventTypeIDMigrationTask()) await _async_wait_migration_done(hass) def _fetch_migrated_events(): @@ -900,7 +902,7 @@ async def test_migrate_null_event_type_ids( ) return result - events_by_type = await instance.async_add_executor_job(_fetch_migrated_events) + events_by_type = await recorder_mock.async_add_executor_job(_fetch_migrated_events) assert len(events_by_type["event_type_one"]) == 2 assert len(events_by_type[migration._EMPTY_EVENT_TYPE]) == 1000 @@ -908,7 +910,7 @@ async def test_migrate_null_event_type_ids( with session_scope(hass=hass, read_only=True) as session: return dict(execute_stmt_lambda_element(session, get_migration_changes())) - migration_changes = await instance.async_add_executor_job(_get_migration_id) + migration_changes = await recorder_mock.async_add_executor_job(_get_migration_id) assert ( migration_changes[migration.EventTypeIDMigration.migration_id] == migration.EventTypeIDMigration.migration_version @@ -916,11 +918,9 @@ async def test_migrate_null_event_type_ids( async def test_stats_timestamp_conversion_is_reentrant( - async_setup_recorder_instance: RecorderInstanceGenerator, - hass: HomeAssistant, + hass: HomeAssistant, recorder_mock: Recorder ) -> None: """Test stats migration is reentrant.""" - instance = await async_setup_recorder_instance(hass) await async_wait_recording_done(hass) await async_attach_db_engine(hass) importlib.import_module(SCHEMA_MODULE) @@ -932,7 +932,7 @@ async def test_stats_timestamp_conversion_is_reentrant( def _do_migration(): migration._migrate_statistics_columns_to_timestamp_removing_duplicates( - hass, instance, instance.get_session, instance.engine + hass, recorder_mock, recorder_mock.get_session, recorder_mock.engine ) def _insert_fake_metadata(): @@ -1070,11 +1070,9 @@ async def test_stats_timestamp_conversion_is_reentrant( async def test_stats_timestamp_with_one_by_one( - async_setup_recorder_instance: RecorderInstanceGenerator, - hass: HomeAssistant, + hass: HomeAssistant, recorder_mock: Recorder ) -> None: """Test stats migration with one by one.""" - instance = await async_setup_recorder_instance(hass) await async_wait_recording_done(hass) await async_attach_db_engine(hass) importlib.import_module(SCHEMA_MODULE) @@ -1091,7 +1089,7 @@ async def test_stats_timestamp_with_one_by_one( side_effect=IntegrityError("test", "test", "test"), ): migration._migrate_statistics_columns_to_timestamp_removing_duplicates( - hass, instance, instance.get_session, instance.engine + hass, recorder_mock, recorder_mock.get_session, recorder_mock.engine ) def _insert_fake_metadata(): @@ -1291,11 +1289,9 @@ async def test_stats_timestamp_with_one_by_one( async def test_stats_timestamp_with_one_by_one_removes_duplicates( - async_setup_recorder_instance: RecorderInstanceGenerator, - hass: HomeAssistant, + hass: HomeAssistant, recorder_mock: Recorder ) -> None: """Test stats migration with one by one removes duplicates.""" - instance = await async_setup_recorder_instance(hass) await async_wait_recording_done(hass) await async_attach_db_engine(hass) importlib.import_module(SCHEMA_MODULE) @@ -1319,7 +1315,7 @@ async def test_stats_timestamp_with_one_by_one_removes_duplicates( ), ): migration._migrate_statistics_columns_to_timestamp_removing_duplicates( - hass, instance, instance.get_session, instance.engine + hass, recorder_mock, recorder_mock.get_session, recorder_mock.engine ) def _insert_fake_metadata(): diff --git a/tests/components/recorder/test_migration_run_time_migrations_remember.py b/tests/components/recorder/test_migration_run_time_migrations_remember.py index 5ef8a4b32e9..ec81711c215 100644 --- a/tests/components/recorder/test_migration_run_time_migrations_remember.py +++ b/tests/components/recorder/test_migration_run_time_migrations_remember.py @@ -28,6 +28,13 @@ CREATE_ENGINE_TARGET = "homeassistant.components.recorder.core.create_engine" SCHEMA_MODULE = "tests.components.recorder.db_schema_32" +@pytest.fixture +async def mock_recorder_before_hass( + async_test_recorder: RecorderInstanceGenerator, +) -> None: + """Set up recorder.""" + + async def _async_wait_migration_done(hass: HomeAssistant) -> None: """Wait for the migration to be done.""" await recorder.get_instance(hass).async_block_till_done() @@ -65,7 +72,7 @@ def _create_engine_test(*args, **kwargs): @pytest.mark.parametrize("persistent_database", [True]) @pytest.mark.usefixtures("hass_storage") # Prevent test hass from writing to storage async def test_migration_changes_prevent_trying_to_migrate_again( - async_setup_recorder_instance: RecorderInstanceGenerator, + async_test_recorder: RecorderInstanceGenerator, ) -> None: """Test that we do not try to migrate when migration_changes indicate its already migrated. @@ -76,9 +83,7 @@ async def test_migration_changes_prevent_trying_to_migrate_again( 3. With current schema to verify we do not have to query to see if the migration is done """ - config = { - recorder.CONF_COMMIT_INTERVAL: 1, - } + config = {recorder.CONF_COMMIT_INTERVAL: 1} importlib.import_module(SCHEMA_MODULE) old_db_schema = sys.modules[SCHEMA_MODULE] @@ -97,8 +102,10 @@ async def test_migration_changes_prevent_trying_to_migrate_again( patch.object(migration.EntityIDMigration, "task", core.RecorderTask), patch(CREATE_ENGINE_TARGET, new=_create_engine_test), ): - async with async_test_home_assistant() as hass: - await async_setup_recorder_instance(hass, config) + async with ( + async_test_home_assistant() as hass, + async_test_recorder(hass, config), + ): await hass.async_block_till_done() await async_wait_recording_done(hass) await _async_wait_migration_done(hass) @@ -107,8 +114,7 @@ async def test_migration_changes_prevent_trying_to_migrate_again( await hass.async_stop() # Now start again with current db schema - async with async_test_home_assistant() as hass: - await async_setup_recorder_instance(hass, config) + async with async_test_home_assistant() as hass, async_test_recorder(hass, config): await hass.async_block_till_done() await async_wait_recording_done(hass) await _async_wait_migration_done(hass) @@ -132,19 +138,21 @@ async def test_migration_changes_prevent_trying_to_migrate_again( original_queue_task(self, task) # Finally verify we did not call needs_migrate_query on StatesContextIDMigration - async with async_test_home_assistant() as hass: - with ( - patch( - "homeassistant.components.recorder.core.Recorder.queue_task", - _queue_task, - ), - patch.object( - migration.StatesContextIDMigration, - "needs_migrate_query", - side_effect=RuntimeError("Should not be called"), - ), + with ( + patch( + "homeassistant.components.recorder.core.Recorder.queue_task", + _queue_task, + ), + patch.object( + migration.StatesContextIDMigration, + "needs_migrate_query", + side_effect=RuntimeError("Should not be called"), + ), + ): + async with ( + async_test_home_assistant() as hass, + async_test_recorder(hass, config), ): - await async_setup_recorder_instance(hass, config) await hass.async_block_till_done() await async_wait_recording_done(hass) await _async_wait_migration_done(hass)