Regenerate instance ID on error (#94898)

pull/94891/head^2
Erik Montnemery 2023-06-20 11:16:51 +02:00 committed by GitHub
parent 2b1660c0f7
commit 609a573b55
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 65 additions and 5 deletions

View File

@ -1,6 +1,7 @@
"""Helper to create a unique instance ID."""
from __future__ import annotations
import logging
import uuid
from homeassistant.core import HomeAssistant
@ -12,17 +13,30 @@ DATA_VERSION = 1
LEGACY_UUID_FILE = ".uuid"
_LOGGER = logging.getLogger(__name__)
@singleton.singleton(DATA_KEY)
async def async_get(hass: HomeAssistant) -> str:
"""Get unique ID for the hass instance."""
store = storage.Store[dict[str, str]](hass, DATA_VERSION, DATA_KEY, True)
data: dict[str, str] | None = await storage.async_migrator(
hass,
hass.config.path(LEGACY_UUID_FILE),
store,
)
data: dict[str, str] | None = None
try:
data = await storage.async_migrator(
hass,
hass.config.path(LEGACY_UUID_FILE),
store,
)
except Exception: # pylint: disable=broad-exception-caught
_LOGGER.exception(
(
"Could not read hass instance ID from '%s' or '%s', a new instance ID "
"will be generated"
),
DATA_KEY,
LEGACY_UUID_FILE,
)
if data is not None:
return data["uuid"]

View File

@ -1,7 +1,10 @@
"""Tests for instance ID helper."""
from json import JSONDecodeError
from typing import Any
from unittest.mock import patch
import pytest
from homeassistant.core import HomeAssistant
from homeassistant.helpers import instance_id
@ -14,6 +17,25 @@ async def test_get_id_empty(hass: HomeAssistant, hass_storage: dict[str, Any]) -
assert hass_storage["core.uuid"]["data"]["uuid"] == uuid
async def test_get_id_load_fail(
hass: HomeAssistant, hass_storage: dict[str, Any], caplog: pytest.LogCaptureFixture
) -> None:
"""Migrate existing file with error."""
hass_storage["core.uuid"] = None # Invalid, will make store.async_load raise
uuid = await instance_id.async_get(hass)
assert uuid is not None
# Assert it's stored
assert hass_storage["core.uuid"]["data"]["uuid"] == uuid
assert (
"Could not read hass instance ID from 'core.uuid' or '.uuid', a "
"new instance ID will be generated" in caplog.text
)
async def test_get_id_migrate(
hass: HomeAssistant, hass_storage: dict[str, Any]
) -> None:
@ -30,3 +52,27 @@ async def test_get_id_migrate(
# assert old deleted
assert len(mock_remove.mock_calls) == 1
async def test_get_id_migrate_fail(
hass: HomeAssistant, hass_storage: dict[str, Any], caplog: pytest.LogCaptureFixture
) -> None:
"""Migrate existing file with error."""
with patch(
"homeassistant.util.json.load_json",
side_effect=JSONDecodeError("test_error", "test", 1),
), patch("os.path.isfile", return_value=True), patch("os.remove") as mock_remove:
uuid = await instance_id.async_get(hass)
assert uuid is not None
# Assert it's stored
assert hass_storage["core.uuid"]["data"]["uuid"] == uuid
# assert old not deleted
assert len(mock_remove.mock_calls) == 0
assert (
"Could not read hass instance ID from 'core.uuid' or '.uuid', a "
"new instance ID will be generated" in caplog.text
)