Reduce registry overhead in tests (#110955)

* Avoid scheduling registry loads as tasks in tests

Since we patch out async_load in Store, these will not yield
to the event loop so it makes sense to await them instead
of creating tasks

This reduced my local test run times ~2.5% on average

* mock out save as well so we do not schedule tasks to save empty data

* tweaks

* fix lingering files

* another one

* too much for one PR, reduce

* fix targets
This commit is contained in:
J. Nick Koston 2024-02-20 20:01:50 -06:00 committed by GitHub
parent a542b36997
commit 98d5f2fc01
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 46 additions and 19 deletions

View File

@ -17,7 +17,7 @@ import pathlib
import threading
import time
from types import ModuleType
from typing import Any, NoReturn
from typing import Any, NoReturn, TypeVar
from unittest.mock import AsyncMock, Mock, patch
from aiohttp.test_utils import unused_port as get_test_instance_port # noqa: F401
@ -194,13 +194,26 @@ def get_test_home_assistant() -> Generator[HomeAssistant, None, None]:
loop.close()
_T = TypeVar("_T", bound=Mapping[str, Any] | Sequence[Any])
class StoreWithoutWriteLoad(storage.Store[_T]):
"""Fake store that does not write or load. Used for testing."""
async def async_save(self, *args: Any, **kwargs: Any) -> None:
"""Save the data."""
@asynccontextmanager
async def async_test_home_assistant(
event_loop: asyncio.AbstractEventLoop | None = None,
load_registries: bool = True,
storage_dir: str | None = None,
) -> AsyncGenerator[HomeAssistant, None]:
"""Return a Home Assistant object pointing at test config dir."""
hass = HomeAssistant(get_test_config_dir())
if storage_dir:
hass.config.config_dir = storage_dir
store = auth_store.AuthStore(hass)
hass.auth = auth.AuthManager(hass, store, {}, {})
ensure_auth_manager_loaded(hass.auth)
@ -284,23 +297,36 @@ async def async_test_home_assistant(
hass
)
if load_registries:
with patch(
"homeassistant.helpers.storage.Store.async_load", return_value=None
with patch.object(
StoreWithoutWriteLoad, "async_load", return_value=None
), patch(
"homeassistant.helpers.area_registry.AreaRegistryStore",
StoreWithoutWriteLoad,
), patch(
"homeassistant.helpers.device_registry.DeviceRegistryStore",
StoreWithoutWriteLoad,
), patch(
"homeassistant.helpers.entity_registry.EntityRegistryStore",
StoreWithoutWriteLoad,
), patch(
"homeassistant.helpers.storage.Store", # Floor & label registry are different
StoreWithoutWriteLoad,
), patch(
"homeassistant.helpers.issue_registry.IssueRegistryStore",
StoreWithoutWriteLoad,
), patch(
"homeassistant.helpers.restore_state.RestoreStateData.async_setup_dump",
return_value=None,
), patch(
"homeassistant.helpers.restore_state.start.async_at_start",
):
await asyncio.gather(
ar.async_load(hass),
dr.async_load(hass),
er.async_load(hass),
fr.async_load(hass),
ir.async_load(hass),
lr.async_load(hass),
rs.async_load(hass),
)
await ar.async_load(hass)
await dr.async_load(hass)
await er.async_load(hass)
await fr.async_load(hass)
await ir.async_load(hass)
await lr.async_load(hass)
await rs.async_load(hass)
hass.data[bootstrap.DATA_REGISTRIES_LOADED] = None
hass.set_state(CoreState.running)

View File

@ -560,10 +560,10 @@ async def test_loading_corrupt_core_file(
tmpdir: py.path.local, caplog: pytest.LogCaptureFixture
) -> None:
"""Test we handle unrecoverable corruption in a core file."""
async with async_test_home_assistant() as hass:
tmp_storage = await hass.async_add_executor_job(tmpdir.mkdir, "temp_storage")
hass.config.config_dir = tmp_storage
loop = asyncio.get_running_loop()
tmp_storage = await loop.run_in_executor(None, tmpdir.mkdir, "temp_storage")
async with async_test_home_assistant(storage_dir=tmp_storage) as hass:
storage_key = "core.anything"
store = storage.Store(
hass, MOCK_VERSION_2, storage_key, minor_version=MOCK_MINOR_VERSION_1
@ -618,13 +618,14 @@ async def test_loading_corrupt_file_known_domain(
tmpdir: py.path.local, caplog: pytest.LogCaptureFixture
) -> None:
"""Test we handle unrecoverable corruption for a known domain."""
async with async_test_home_assistant() as hass:
loop = asyncio.get_running_loop()
tmp_storage = await loop.run_in_executor(None, tmpdir.mkdir, "temp_storage")
async with async_test_home_assistant(storage_dir=tmp_storage) as hass:
hass.config.components.add("testdomain")
storage_key = "testdomain.testkey"
tmp_storage = await hass.async_add_executor_job(tmpdir.mkdir, "temp_storage")
hass.config.config_dir = tmp_storage
store = storage.Store(
hass, MOCK_VERSION_2, storage_key, minor_version=MOCK_MINOR_VERSION_1
)