Log warning if via_device reference not exists when creating or updating a device registry entry ()

pull/131795/head
Jan Bouwhuis 2024-11-28 08:27:24 +01:00 committed by GitHub
parent 4257277086
commit d26c7a0536
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 58 additions and 3 deletions
homeassistant/helpers

View File

@ -38,6 +38,7 @@ from .deprecation import (
check_if_deprecated_constant,
dir_with_deprecated_constants,
)
from .frame import ReportBehavior, report_usage
from .json import JSON_DUMP, find_paths_unserializable_data, json_bytes, json_fragment
from .registry import BaseRegistry, BaseRegistryItems, RegistryIndexType
from .singleton import singleton
@ -821,7 +822,15 @@ class DeviceRegistry(BaseRegistry[dict[str, list[dict[str, Any]]]]):
name = default_name
if via_device is not None and via_device is not UNDEFINED:
via = self.async_get_device(identifiers={via_device})
if (via := self.async_get_device(identifiers={via_device})) is None:
report_usage(
"calls `device_registry.async_get_or_create` referencing a "
f"non existing `via_device` {via_device}, "
f"with device info: {device_info}",
core_behavior=ReportBehavior.LOG,
breaks_in_ha_version="2025.12.0",
)
via_device_id: str | UndefinedType = via.id if via else UNDEFINED
else:
via_device_id = UNDEFINED

View File

@ -1482,7 +1482,9 @@ async def test_removing_area_id(
async def test_specifying_via_device_create(
hass: HomeAssistant, device_registry: dr.DeviceRegistry
hass: HomeAssistant,
device_registry: dr.DeviceRegistry,
caplog: pytest.LogCaptureFixture,
) -> None:
"""Test specifying a via_device and removal of the hub device."""
config_entry_1 = MockConfigEntry()
@ -1513,9 +1515,32 @@ async def test_specifying_via_device_create(
light = device_registry.async_get_device(identifiers={("hue", "456")})
assert light.via_device_id is None
# A device with a non existing via_device reference should create
light_via_nonexisting_parent_device = device_registry.async_get_or_create(
config_entry_id=config_entry_2.entry_id,
connections=set(),
identifiers={("hue", "789")},
manufacturer="manufacturer",
model="light",
via_device=("hue", "non_existing_123"),
)
assert {
"calls `device_registry.async_get_or_create` "
"referencing a non existing `via_device` "
'("hue","non_existing_123")' in caplog.text
}
assert light_via_nonexisting_parent_device is not None
assert light_via_nonexisting_parent_device.via_device_id is None
nonexisting_parent_device = device_registry.async_get_device(
identifiers={("hue", "non_existing_123")}
)
assert nonexisting_parent_device is None
async def test_specifying_via_device_update(
hass: HomeAssistant, device_registry: dr.DeviceRegistry
hass: HomeAssistant,
device_registry: dr.DeviceRegistry,
caplog: pytest.LogCaptureFixture,
) -> None:
"""Test specifying a via_device and updating."""
config_entry_1 = MockConfigEntry()
@ -1529,6 +1554,7 @@ async def test_specifying_via_device_update(
identifiers={("hue", "456")},
manufacturer="manufacturer",
model="light",
name="Light",
via_device=("hue", "0123"),
)
@ -1552,6 +1578,26 @@ async def test_specifying_via_device_update(
)
assert light.via_device_id == via.id
assert light.name == "Light"
# Try updating with a non existing via device
light = device_registry.async_get_or_create(
config_entry_id=config_entry_2.entry_id,
connections=set(),
identifiers={("hue", "456")},
manufacturer="manufacturer",
model="light",
name="New light",
via_device=("hue", "non_existing_abc"),
)
assert {
"calls `device_registry.async_get_or_create` "
"referencing a non existing `via_device` "
'("hue","non_existing_123")' in caplog.text
}
# Assert the name was updated correctly
assert light.via_device_id == via.id
assert light.name == "New light"
async def test_loading_saving_data(