hass-core/tests/components/homekit/test_iidmanager.py

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

193 lines
7.3 KiB
Python
Raw Normal View History

"""Tests for the HomeKit IID manager."""
from typing import Any
from uuid import UUID
from homeassistant.components.homekit.const import DOMAIN
from homeassistant.components.homekit.iidmanager import (
AccessoryIIDStorage,
get_iid_storage_filename_for_entry_id,
)
from homeassistant.core import HomeAssistant
2023-02-17 19:13:48 +01:00
from homeassistant.util.json import json_loads
from homeassistant.util.uuid import random_uuid_hex
from tests.common import MockConfigEntry, load_fixture
async def test_iid_generation_and_restore(
hass: HomeAssistant, iid_storage, hass_storage: dict[str, Any]
) -> None:
"""Test generating iids and restoring them from storage."""
entry = MockConfigEntry(domain=DOMAIN)
iid_storage = AccessoryIIDStorage(hass, entry.entry_id)
await iid_storage.async_initialize()
random_service_uuid = UUID(random_uuid_hex())
random_characteristic_uuid = UUID(random_uuid_hex())
iid1 = iid_storage.get_or_allocate_iid(
1, random_service_uuid, None, random_characteristic_uuid, None
)
iid2 = iid_storage.get_or_allocate_iid(
1, random_service_uuid, None, random_characteristic_uuid, None
)
assert iid1 == iid2
service_only_iid1 = iid_storage.get_or_allocate_iid(
1, random_service_uuid, None, None, None
)
service_only_iid2 = iid_storage.get_or_allocate_iid(
1, random_service_uuid, None, None, None
)
assert service_only_iid1 == service_only_iid2
assert service_only_iid1 != iid1
service_only_iid_with_unique_id1 = iid_storage.get_or_allocate_iid(
1, random_service_uuid, "any", None, None
)
service_only_iid_with_unique_id2 = iid_storage.get_or_allocate_iid(
1, random_service_uuid, "any", None, None
)
assert service_only_iid_with_unique_id1 == service_only_iid_with_unique_id2
assert service_only_iid_with_unique_id1 != service_only_iid1
unique_char_iid1 = iid_storage.get_or_allocate_iid(
1, random_service_uuid, None, random_characteristic_uuid, "any"
)
unique_char_iid2 = iid_storage.get_or_allocate_iid(
1, random_service_uuid, None, random_characteristic_uuid, "any"
)
assert unique_char_iid1 == unique_char_iid2
assert unique_char_iid1 != iid1
unique_service_unique_char_iid1 = iid_storage.get_or_allocate_iid(
1, random_service_uuid, "any", random_characteristic_uuid, "any"
)
unique_service_unique_char_iid2 = iid_storage.get_or_allocate_iid(
1, random_service_uuid, "any", random_characteristic_uuid, "any"
)
assert unique_service_unique_char_iid1 == unique_service_unique_char_iid2
assert unique_service_unique_char_iid1 != iid1
unique_service_unique_char_new_aid_iid1 = iid_storage.get_or_allocate_iid(
2, random_service_uuid, "any", random_characteristic_uuid, "any"
)
unique_service_unique_char_new_aid_iid2 = iid_storage.get_or_allocate_iid(
2, random_service_uuid, "any", random_characteristic_uuid, "any"
)
assert (
unique_service_unique_char_new_aid_iid1
== unique_service_unique_char_new_aid_iid2
)
await iid_storage.async_save()
iid_storage2 = AccessoryIIDStorage(hass, entry.entry_id)
await iid_storage2.async_initialize()
iid3 = iid_storage2.get_or_allocate_iid(
1, random_service_uuid, None, random_characteristic_uuid, None
)
assert iid3 == iid1
async def test_iid_storage_filename(
hass: HomeAssistant, iid_storage, hass_storage: dict[str, Any]
) -> None:
"""Test iid storage uses the expected filename."""
entry = MockConfigEntry(domain=DOMAIN)
iid_storage = AccessoryIIDStorage(hass, entry.entry_id)
await iid_storage.async_initialize()
assert iid_storage.store.path.endswith(
get_iid_storage_filename_for_entry_id(entry.entry_id)
)
async def test_iid_migration_to_v2(
hass: HomeAssistant, iid_storage, hass_storage: dict[str, Any]
) -> None:
"""Test iid storage migration."""
v1_iids = json_loads(load_fixture("iids_v1", DOMAIN))
v2_iids = json_loads(load_fixture("iids_v2", DOMAIN))
hass_storage["homekit.v1.iids"] = v1_iids
hass_storage["homekit.v2.iids"] = v2_iids
iid_storage_v2 = AccessoryIIDStorage(hass, "v1")
await iid_storage_v2.async_initialize()
iid_storage_v1 = AccessoryIIDStorage(hass, "v2")
await iid_storage_v1.async_initialize()
assert iid_storage_v1.allocations == iid_storage_v2.allocations
assert iid_storage_v1.allocated_iids == iid_storage_v2.allocated_iids
assert len(iid_storage_v2.allocations) == 12
for allocations in iid_storage_v2.allocations.values():
assert allocations["3E___"] == 1
async def test_iid_migration_to_v2_with_underscore(
hass: HomeAssistant, iid_storage, hass_storage: dict[str, Any]
) -> None:
"""Test iid storage migration with underscore."""
v1_iids = json_loads(load_fixture("iids_v1_with_underscore", DOMAIN))
v2_iids = json_loads(load_fixture("iids_v2_with_underscore", DOMAIN))
hass_storage["homekit.v1_with_underscore.iids"] = v1_iids
hass_storage["homekit.v2_with_underscore.iids"] = v2_iids
iid_storage_v2 = AccessoryIIDStorage(hass, "v1_with_underscore")
await iid_storage_v2.async_initialize()
iid_storage_v1 = AccessoryIIDStorage(hass, "v2_with_underscore")
await iid_storage_v1.async_initialize()
assert iid_storage_v1.allocations == iid_storage_v2.allocations
assert iid_storage_v1.allocated_iids == iid_storage_v2.allocated_iids
assert len(iid_storage_v2.allocations) == 2
for allocations in iid_storage_v2.allocations.values():
assert allocations["3E___"] == 1
async def test_iid_generation_and_restore_v2(
hass: HomeAssistant, iid_storage, hass_storage: dict[str, Any]
) -> None:
"""Test generating iids and restoring them from storage."""
entry = MockConfigEntry(domain=DOMAIN)
iid_storage = AccessoryIIDStorage(hass, entry.entry_id)
await iid_storage.async_initialize()
not_accessory_info_service_iid = iid_storage.get_or_allocate_iid(
1, "000000AA-0000-1000-8000-0026BB765291", None, None, None
)
assert not_accessory_info_service_iid == 2
assert iid_storage.allocated_iids == {"1": [1, 2]}
not_accessory_info_service_iid_2 = iid_storage.get_or_allocate_iid(
1, "000000BB-0000-1000-8000-0026BB765291", None, None, None
)
assert not_accessory_info_service_iid_2 == 3
assert iid_storage.allocated_iids == {"1": [1, 2, 3]}
not_accessory_info_service_iid_2 = iid_storage.get_or_allocate_iid(
1, "000000BB-0000-1000-8000-0026BB765291", None, None, None
)
assert not_accessory_info_service_iid_2 == 3
assert iid_storage.allocated_iids == {"1": [1, 2, 3]}
accessory_info_service_iid = iid_storage.get_or_allocate_iid(
1, "0000003E-0000-1000-8000-0026BB765291", None, None, None
)
assert accessory_info_service_iid == 1
assert iid_storage.allocated_iids == {"1": [1, 2, 3]}
accessory_info_service_iid = iid_storage.get_or_allocate_iid(
1, "0000003E-0000-1000-8000-0026BB765291", None, None, None
)
assert accessory_info_service_iid == 1
assert iid_storage.allocated_iids == {"1": [1, 2, 3]}
accessory_info_service_iid = iid_storage.get_or_allocate_iid(
2, "0000003E-0000-1000-8000-0026BB765291", None, None, None
)
assert accessory_info_service_iid == 1
assert iid_storage.allocated_iids == {"1": [1, 2, 3], "2": [1]}