mirror of
https://github.com/home-assistant/core.git
synced 2025-07-17 10:17:09 +00:00
Handle garbage in the context_id column during migration (#90544)
* Handle garbage in the context_id column during migration * Update homeassistant/components/recorder/migration.py * lint
This commit is contained in:
parent
e32d89215d
commit
aad1f4b766
@ -1355,6 +1355,12 @@ def _context_id_to_bytes(context_id: str | None) -> bytes | None:
|
|||||||
"""Convert a context_id to bytes."""
|
"""Convert a context_id to bytes."""
|
||||||
if context_id is None:
|
if context_id is None:
|
||||||
return None
|
return None
|
||||||
|
with contextlib.suppress(ValueError):
|
||||||
|
# There may be garbage in the context_id column
|
||||||
|
# from custom integrations that are not UUIDs or
|
||||||
|
# ULIDs that filled the column to the max length
|
||||||
|
# so we need to catch the ValueError and return
|
||||||
|
# None if it happens
|
||||||
if len(context_id) == 32:
|
if len(context_id) == 32:
|
||||||
return UUID(context_id).bytes
|
return UUID(context_id).bytes
|
||||||
if len(context_id) == 26:
|
if len(context_id) == 26:
|
||||||
|
@ -671,6 +671,19 @@ async def test_migrate_events_context_ids(
|
|||||||
context_parent_id=None,
|
context_parent_id=None,
|
||||||
context_parent_id_bin=None,
|
context_parent_id_bin=None,
|
||||||
),
|
),
|
||||||
|
Events(
|
||||||
|
event_type="garbage_context_id_event",
|
||||||
|
event_data=None,
|
||||||
|
origin_idx=0,
|
||||||
|
time_fired=None,
|
||||||
|
time_fired_ts=1677721632.552529,
|
||||||
|
context_id="adapt_lgt:b'5Cf*':interval:b'0R'",
|
||||||
|
context_id_bin=None,
|
||||||
|
context_user_id=None,
|
||||||
|
context_user_id_bin=None,
|
||||||
|
context_parent_id=None,
|
||||||
|
context_parent_id_bin=None,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -695,12 +708,13 @@ async def test_migrate_events_context_ids(
|
|||||||
"empty_context_id_event",
|
"empty_context_id_event",
|
||||||
"ulid_context_id_event",
|
"ulid_context_id_event",
|
||||||
"invalid_context_id_event",
|
"invalid_context_id_event",
|
||||||
|
"garbage_context_id_event",
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.all()
|
.all()
|
||||||
)
|
)
|
||||||
assert len(events) == 4
|
assert len(events) == 5
|
||||||
return {event.event_type: _object_as_dict(event) for event in events}
|
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 instance.async_add_executor_job(_fetch_migrated_events)
|
||||||
@ -746,6 +760,14 @@ async def test_migrate_events_context_ids(
|
|||||||
assert invalid_context_id_event["context_user_id_bin"] is None
|
assert invalid_context_id_event["context_user_id_bin"] is None
|
||||||
assert invalid_context_id_event["context_parent_id_bin"] is None
|
assert invalid_context_id_event["context_parent_id_bin"] is None
|
||||||
|
|
||||||
|
garbage_context_id_event = events_by_type["garbage_context_id_event"]
|
||||||
|
assert garbage_context_id_event["context_id"] is None
|
||||||
|
assert garbage_context_id_event["context_user_id"] is None
|
||||||
|
assert garbage_context_id_event["context_parent_id"] is None
|
||||||
|
assert garbage_context_id_event["context_id_bin"] == b"\x00" * 16
|
||||||
|
assert garbage_context_id_event["context_user_id_bin"] is None
|
||||||
|
assert garbage_context_id_event["context_parent_id_bin"] is None
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("enable_migrate_context_ids", [True])
|
@pytest.mark.parametrize("enable_migrate_context_ids", [True])
|
||||||
async def test_migrate_states_context_ids(
|
async def test_migrate_states_context_ids(
|
||||||
@ -803,6 +825,16 @@ async def test_migrate_states_context_ids(
|
|||||||
context_parent_id=None,
|
context_parent_id=None,
|
||||||
context_parent_id_bin=None,
|
context_parent_id_bin=None,
|
||||||
),
|
),
|
||||||
|
States(
|
||||||
|
entity_id="state.garbage_context_id",
|
||||||
|
last_updated_ts=1677721632.552529,
|
||||||
|
context_id="adapt_lgt:b'5Cf*':interval:b'0R'",
|
||||||
|
context_id_bin=None,
|
||||||
|
context_user_id=None,
|
||||||
|
context_user_id_bin=None,
|
||||||
|
context_parent_id=None,
|
||||||
|
context_parent_id_bin=None,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -827,12 +859,13 @@ async def test_migrate_states_context_ids(
|
|||||||
"state.empty_context_id",
|
"state.empty_context_id",
|
||||||
"state.ulid_context_id",
|
"state.ulid_context_id",
|
||||||
"state.invalid_context_id",
|
"state.invalid_context_id",
|
||||||
|
"state.garbage_context_id",
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.all()
|
.all()
|
||||||
)
|
)
|
||||||
assert len(events) == 4
|
assert len(events) == 5
|
||||||
return {state.entity_id: _object_as_dict(state) for state in events}
|
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 instance.async_add_executor_job(_fetch_migrated_states)
|
||||||
@ -877,6 +910,14 @@ async def test_migrate_states_context_ids(
|
|||||||
assert invalid_context_id["context_user_id_bin"] is None
|
assert invalid_context_id["context_user_id_bin"] is None
|
||||||
assert invalid_context_id["context_parent_id_bin"] is None
|
assert invalid_context_id["context_parent_id_bin"] is None
|
||||||
|
|
||||||
|
garbage_context_id = states_by_entity_id["state.garbage_context_id"]
|
||||||
|
assert garbage_context_id["context_id"] is None
|
||||||
|
assert garbage_context_id["context_user_id"] is None
|
||||||
|
assert garbage_context_id["context_parent_id"] is None
|
||||||
|
assert garbage_context_id["context_id_bin"] == b"\x00" * 16
|
||||||
|
assert garbage_context_id["context_user_id_bin"] is None
|
||||||
|
assert garbage_context_id["context_parent_id_bin"] is None
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("enable_migrate_event_type_ids", [True])
|
@pytest.mark.parametrize("enable_migrate_event_type_ids", [True])
|
||||||
async def test_migrate_event_type_ids(
|
async def test_migrate_event_type_ids(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user