Adapt LLM integration migration tests to single config entry devices (#178442)

This commit is contained in:
Erik Montnemery
2026-08-07 15:24:49 +02:00
committed by GitHub
parent e73975f158
commit ea676a9abd
4 changed files with 66 additions and 118 deletions
+11 -20
View File
@@ -237,8 +237,8 @@ async def test_migration_from_v1_to_v2(
assert migrated_entity.unique_id == subentry.subentry_id
# Check device migration
assert not device_registry.async_get_device_by_identifier(
(DOMAIN, mock_config_entry.entry_id), mock_config_entry.entry_id
assert not device_registry.async_get_devices(
identifiers={(DOMAIN, mock_config_entry.entry_id)}
)
assert (
migrated_device := device_registry.async_get_device_by_identifier(
@@ -436,11 +436,11 @@ async def test_migration_from_v1_disabled(
assert subentry.data == options
assert "Claude" in subentry.title
assert not device_registry.async_get_device_by_identifier(
(DOMAIN, mock_config_entry.entry_id), mock_config_entry.entry_id
assert not device_registry.async_get_devices(
identifiers={(DOMAIN, mock_config_entry.entry_id)}
)
assert not device_registry.async_get_device_by_identifier(
(DOMAIN, mock_config_entry_2.entry_id), mock_config_entry_2.entry_id
assert not device_registry.async_get_devices(
identifiers={(DOMAIN, mock_config_entry_2.entry_id)}
)
for idx, subentry in enumerate(conversation_subentries):
@@ -667,12 +667,7 @@ async def test_migration_from_v2_1_to_v2_2(
device_registry: dr.DeviceRegistry,
entity_registry: er.EntityRegistry,
) -> None:
"""Test migration from version 2.1 to version 2.2.
This tests we clean up the broken migration in Home Assistant Core
2025.7.0b0-2025.7.0b1:
- Fix device registry (Fixed in Home Assistant Core 2025.7.0b2)
"""
"""Test migration from version 2.1 to version 2.2."""
# Create a v2.1 config entry with 2 subentries, devices and entities
options = {
"recommended": True,
@@ -715,10 +710,6 @@ async def test_migration_from_v2_1_to_v2_2(
model="Claude",
entry_type=dr.DeviceEntryType.SERVICE,
)
device_1 = device_registry.async_update_device(
device_1.id, add_config_entry_id="mock_entry_id", add_config_subentry_id=None
)
assert device_1.config_entries_subentries == {"mock_entry_id": {"mock_id_1"}}
entity_registry.async_get_or_create(
"conversation",
DOMAIN,
@@ -778,8 +769,8 @@ async def test_migration_from_v2_1_to_v2_2(
assert entity.config_subentry_id == subentry.subentry_id
assert entity.config_entry_id == entry.entry_id
assert not device_registry.async_get_device_by_identifier(
(DOMAIN, mock_config_entry.entry_id), mock_config_entry.entry_id
assert not device_registry.async_get_devices(
identifiers={(DOMAIN, mock_config_entry.entry_id)}
)
assert (
device := device_registry.async_get_device_by_identifier(
@@ -799,8 +790,8 @@ async def test_migration_from_v2_1_to_v2_2(
assert entity.unique_id == subentry.subentry_id
assert entity.config_subentry_id == subentry.subentry_id
assert entity.config_entry_id == entry.entry_id
assert not device_registry.async_get_device_by_identifier(
(DOMAIN, mock_config_entry.entry_id), mock_config_entry.entry_id
assert not device_registry.async_get_devices(
identifiers={(DOMAIN, mock_config_entry.entry_id)}
)
assert (
device := device_registry.async_get_device_by_identifier(
@@ -191,12 +191,12 @@ async def test_migration_from_v1(
assert entity.config_subentry_id == subentry.subentry_id
assert entity.config_entry_id == entry.entry_id
assert not device_registry.async_get_device(
assert not device_registry.async_get_devices(
identifiers={(DOMAIN, mock_config_entry.entry_id)}
)
assert (
device := device_registry.async_get_device(
identifiers={(DOMAIN, subentry.subentry_id)}
device := device_registry.async_get_device_by_identifier(
(DOMAIN, subentry.subentry_id), mock_config_entry.entry_id
)
)
assert device.identifiers == {(DOMAIN, subentry.subentry_id)}
@@ -214,12 +214,12 @@ async def test_migration_from_v1(
assert entity.unique_id == subentry.subentry_id
assert entity.config_subentry_id == subentry.subentry_id
assert entity.config_entry_id == entry.entry_id
assert not device_registry.async_get_device(
assert not device_registry.async_get_devices(
identifiers={(DOMAIN, mock_config_entry_2.entry_id)}
)
assert (
device := device_registry.async_get_device(
identifiers={(DOMAIN, subentry.subentry_id)}
device := device_registry.async_get_device_by_identifier(
(DOMAIN, subentry.subentry_id), mock_config_entry.entry_id
)
)
assert device.identifiers == {(DOMAIN, subentry.subentry_id)}
@@ -448,10 +448,10 @@ async def test_migration_from_v1_disabled(
assert stt_subentries[0].data == RECOMMENDED_STT_OPTIONS
assert stt_subentries[0].title == DEFAULT_STT_NAME
assert not device_registry.async_get_device(
assert not device_registry.async_get_devices(
identifiers={(DOMAIN, mock_config_entry.entry_id)}
)
assert not device_registry.async_get_device(
assert not device_registry.async_get_devices(
identifiers={(DOMAIN, mock_config_entry_2.entry_id)}
)
@@ -464,8 +464,9 @@ async def test_migration_from_v1_disabled(
assert entity.disabled_by is subentry_data["entity_disabled_by"]
assert (
device := device_registry.async_get_device(
identifiers={(DOMAIN, subentry.subentry_id)}
device := device_registry.async_get_device_by_identifier(
(DOMAIN, subentry.subentry_id),
mock_config_entries[main_config_entry].entry_id,
)
)
assert device.identifiers == {(DOMAIN, subentry.subentry_id)}
@@ -577,8 +578,8 @@ async def test_migration_from_v1_with_multiple_keys(
assert subentry.data == RECOMMENDED_STT_OPTIONS
assert subentry.title == DEFAULT_STT_NAME
dev = device_registry.async_get_device(
identifiers={(DOMAIN, list(entry.subentries.values())[0].subentry_id)}
dev = device_registry.async_get_device_by_identifier(
(DOMAIN, list(entry.subentries.values())[0].subentry_id), entry.entry_id
)
assert dev is not None
assert dev.config_entries == {entry.entry_id}
@@ -709,12 +710,12 @@ async def test_migration_from_v1_with_same_keys(
assert entity.config_subentry_id == subentry.subentry_id
assert entity.config_entry_id == entry.entry_id
assert not device_registry.async_get_device(
assert not device_registry.async_get_devices(
identifiers={(DOMAIN, mock_config_entry.entry_id)}
)
assert (
device := device_registry.async_get_device(
identifiers={(DOMAIN, subentry.subentry_id)}
device := device_registry.async_get_device_by_identifier(
(DOMAIN, subentry.subentry_id), mock_config_entry.entry_id
)
)
assert device.identifiers == {(DOMAIN, subentry.subentry_id)}
@@ -732,12 +733,12 @@ async def test_migration_from_v1_with_same_keys(
assert entity.unique_id == subentry.subentry_id
assert entity.config_subentry_id == subentry.subentry_id
assert entity.config_entry_id == entry.entry_id
assert not device_registry.async_get_device(
assert not device_registry.async_get_devices(
identifiers={(DOMAIN, mock_config_entry_2.entry_id)}
)
assert (
device := device_registry.async_get_device(
identifiers={(DOMAIN, subentry.subentry_id)}
device := device_registry.async_get_device_by_identifier(
(DOMAIN, subentry.subentry_id), mock_config_entry.entry_id
)
)
assert device.identifiers == {(DOMAIN, subentry.subentry_id)}
@@ -749,19 +750,14 @@ async def test_migration_from_v1_with_same_keys(
@pytest.mark.parametrize(
("device_changes", "extra_subentries", "expected_device_subentries"),
"extra_subentries",
[
# Scenario where we have a v2.1 config entry migrated by HA Core 2025.7.0b0:
# Wrong device registry, no TTS subentry
(
{"add_config_entry_id": "mock_entry_id", "add_config_subentry_id": None},
[],
{"mock_entry_id": {"mock_id_1"}},
),
# Scenario where we have a v2.1 config entry migrated by HA Core 2025.7.0b1:
# Wrong device registry, TTS subentry created
(
{"add_config_entry_id": "mock_entry_id", "add_config_subentry_id": None},
# no TTS subentry
pytest.param([], id="without_tts_subentry"),
# Scenario where we have a v2.1 config entry migrated by HA Core 2025.7.0b1
# or later: TTS subentry created
pytest.param(
[
ConfigSubentryData(
data=RECOMMENDED_TTS_OPTIONS,
@@ -771,22 +767,7 @@ async def test_migration_from_v1_with_same_keys(
unique_id=None,
)
],
{"mock_entry_id": {"mock_id_1"}},
),
# Scenario where we have a v2.1 config entry migrated by HA Core 2025.7.0b2
# or later: Correct device registry, TTS subentry created
(
{},
[
ConfigSubentryData(
data=RECOMMENDED_TTS_OPTIONS,
subentry_id="mock_id_3",
subentry_type="tts",
title=DEFAULT_TTS_NAME,
unique_id=None,
)
],
{"mock_entry_id": {"mock_id_1"}},
id="with_tts_subentry",
),
],
)
@@ -794,15 +775,11 @@ async def test_migration_from_v2_1(
hass: HomeAssistant,
device_registry: dr.DeviceRegistry,
entity_registry: er.EntityRegistry,
device_changes: dict[str, str],
extra_subentries: list[ConfigSubentryData],
expected_device_subentries: dict[str, set[str | None]],
) -> None:
"""Test migration from version 2.1.
This tests we clean up the broken migration in Home Assistant Core
2025.7.0b0-2025.7.0b1 and add AI Task and STT subentries:
- Fix device registry (Fixed in Home Assistant Core 2025.7.0b2)
This tests we add TTS, AI Task and STT subentries:
- Add TTS subentry (Added in Home Assistant Core 2025.7.0b1)
- Add AI Task subentry (Added in version 2.3)
- Add STT subentry (Added in version 2.3)
@@ -850,8 +827,6 @@ async def test_migration_from_v2_1(
model="Generative AI",
entry_type=dr.DeviceEntryType.SERVICE,
)
device_1 = device_registry.async_update_device(device_1.id, **device_changes)
assert device_1.config_entries_subentries == expected_device_subentries
entity_registry.async_get_or_create(
"conversation",
DOMAIN,
@@ -939,12 +914,12 @@ async def test_migration_from_v2_1(
assert entity.config_subentry_id == subentry.subentry_id
assert entity.config_entry_id == entry.entry_id
assert not device_registry.async_get_device(
assert not device_registry.async_get_devices(
identifiers={(DOMAIN, mock_config_entry.entry_id)}
)
assert (
device := device_registry.async_get_device(
identifiers={(DOMAIN, subentry.subentry_id)}
device := device_registry.async_get_device_by_identifier(
(DOMAIN, subentry.subentry_id), mock_config_entry.entry_id
)
)
assert device.identifiers == {(DOMAIN, subentry.subentry_id)}
@@ -962,12 +937,12 @@ async def test_migration_from_v2_1(
assert entity.unique_id == subentry.subentry_id
assert entity.config_subentry_id == subentry.subentry_id
assert entity.config_entry_id == entry.entry_id
assert not device_registry.async_get_device(
assert not device_registry.async_get_devices(
identifiers={(DOMAIN, mock_config_entry.entry_id)}
)
assert (
device := device_registry.async_get_device(
identifiers={(DOMAIN, subentry.subentry_id)}
device := device_registry.async_get_device_by_identifier(
(DOMAIN, subentry.subentry_id), mock_config_entry.entry_id
)
)
assert device.identifiers == {(DOMAIN, subentry.subentry_id)}
+11 -20
View File
@@ -239,8 +239,8 @@ async def test_migration_from_v1(
assert migrated_entity.unique_id == subentry.subentry_id
# Check device migration
assert not device_registry.async_get_device_by_identifier(
(DOMAIN, mock_config_entry.entry_id), mock_config_entry.entry_id
assert not device_registry.async_get_devices(
identifiers={(DOMAIN, mock_config_entry.entry_id)}
)
assert (
migrated_device := device_registry.async_get_device_by_identifier(
@@ -652,11 +652,11 @@ async def test_migration_from_v1_disabled(
assert ai_task_subentries[0].data == {"model": "llama3.2:latest"}
assert ai_task_subentries[0].title == "Ollama AI Task"
assert not device_registry.async_get_device_by_identifier(
(DOMAIN, mock_config_entry.entry_id), mock_config_entry.entry_id
assert not device_registry.async_get_devices(
identifiers={(DOMAIN, mock_config_entry.entry_id)}
)
assert not device_registry.async_get_device_by_identifier(
(DOMAIN, mock_config_entry_2.entry_id), mock_config_entry_2.entry_id
assert not device_registry.async_get_devices(
identifiers={(DOMAIN, mock_config_entry_2.entry_id)}
)
for idx, subentry in enumerate(conversation_subentries):
@@ -689,12 +689,7 @@ async def test_migration_from_v2_1(
device_registry: dr.DeviceRegistry,
entity_registry: er.EntityRegistry,
) -> None:
"""Test migration from version 2.1.
This tests we clean up the broken migration in Home Assistant Core
2025.7.0b0-2025.7.0b1:
- Fix device registry (Fixed in Home Assistant Core 2025.7.0b2)
"""
"""Test migration from version 2.1."""
# Create a v2.1 config entry with 2 subentries, devices and entities
mock_config_entry = MockConfigEntry(
domain=DOMAIN,
@@ -731,10 +726,6 @@ async def test_migration_from_v2_1(
model="Ollama",
entry_type=dr.DeviceEntryType.SERVICE,
)
device_1 = device_registry.async_update_device(
device_1.id, add_config_entry_id="mock_entry_id", add_config_subentry_id=None
)
assert device_1.config_entries_subentries == {"mock_entry_id": {"mock_id_1"}}
entity_registry.async_get_or_create(
"conversation",
DOMAIN,
@@ -800,8 +791,8 @@ async def test_migration_from_v2_1(
assert entity.config_subentry_id == subentry.subentry_id
assert entity.config_entry_id == entry.entry_id
assert not device_registry.async_get_device_by_identifier(
(DOMAIN, mock_config_entry.entry_id), mock_config_entry.entry_id
assert not device_registry.async_get_devices(
identifiers={(DOMAIN, mock_config_entry.entry_id)}
)
assert (
device := device_registry.async_get_device_by_identifier(
@@ -821,8 +812,8 @@ async def test_migration_from_v2_1(
assert entity.unique_id == subentry.subentry_id
assert entity.config_subentry_id == subentry.subentry_id
assert entity.config_entry_id == entry.entry_id
assert not device_registry.async_get_device_by_identifier(
(DOMAIN, mock_config_entry.entry_id), mock_config_entry.entry_id
assert not device_registry.async_get_devices(
identifiers={(DOMAIN, mock_config_entry.entry_id)}
)
assert (
device := device_registry.async_get_device_by_identifier(
@@ -736,8 +736,8 @@ async def test_migration_from_v1(
assert migrated_entity.unique_id == subentry.subentry_id
# Check device migration
assert not device_registry.async_get_device_by_identifier(
(DOMAIN, mock_config_entry.entry_id), mock_config_entry.entry_id
assert not device_registry.async_get_devices(
identifiers={(DOMAIN, mock_config_entry.entry_id)}
)
assert (
migrated_device := device_registry.async_get_device_by_identifier(
@@ -1192,11 +1192,11 @@ async def test_migration_from_v1_disabled(
assert tts_subentries[0].data == RECOMMENDED_TTS_OPTIONS
assert tts_subentries[0].title == DEFAULT_TTS_NAME
assert not device_registry.async_get_device_by_identifier(
(DOMAIN, mock_config_entry.entry_id), mock_config_entry.entry_id
assert not device_registry.async_get_devices(
identifiers={(DOMAIN, mock_config_entry.entry_id)}
)
assert not device_registry.async_get_device_by_identifier(
(DOMAIN, mock_config_entry_2.entry_id), mock_config_entry_2.entry_id
assert not device_registry.async_get_devices(
identifiers={(DOMAIN, mock_config_entry_2.entry_id)}
)
for idx, subentry in enumerate(conversation_subentries):
@@ -1229,12 +1229,7 @@ async def test_migration_from_v2_1(
device_registry: dr.DeviceRegistry,
entity_registry: er.EntityRegistry,
) -> None:
"""Test migration from version 2.1.
This tests we clean up the broken migration in Home Assistant Core
2025.7.0b0-2025.7.0b1:
- Fix device registry (Fixed in Home Assistant Core 2025.7.0b2)
"""
"""Test migration from version 2.1."""
# Create a v2.1 config entry with 2 subentries, devices and entities
options = {
"recommended": True,
@@ -1277,10 +1272,6 @@ async def test_migration_from_v2_1(
model="ChatGPT",
entry_type=dr.DeviceEntryType.SERVICE,
)
device_1 = device_registry.async_update_device(
device_1.id, add_config_entry_id="mock_entry_id", add_config_subentry_id=None
)
assert device_1.config_entries_subentries == {"mock_entry_id": {"mock_id_1"}}
entity_registry.async_get_or_create(
"conversation",
DOMAIN,
@@ -1362,8 +1353,8 @@ async def test_migration_from_v2_1(
assert entity.config_subentry_id == subentry.subentry_id
assert entity.config_entry_id == entry.entry_id
assert not device_registry.async_get_device_by_identifier(
(DOMAIN, mock_config_entry.entry_id), mock_config_entry.entry_id
assert not device_registry.async_get_devices(
identifiers={(DOMAIN, mock_config_entry.entry_id)}
)
assert (
device := device_registry.async_get_device_by_identifier(
@@ -1383,8 +1374,8 @@ async def test_migration_from_v2_1(
assert entity.unique_id == subentry.subentry_id
assert entity.config_subentry_id == subentry.subentry_id
assert entity.config_entry_id == entry.entry_id
assert not device_registry.async_get_device_by_identifier(
(DOMAIN, mock_config_entry.entry_id), mock_config_entry.entry_id
assert not device_registry.async_get_devices(
identifiers={(DOMAIN, mock_config_entry.entry_id)}
)
assert (
device := device_registry.async_get_device_by_identifier(