mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 21:27:38 +00:00
Pre-import more frontend deps to avoid importing when the event loop is running (#112031)
This commit is contained in:
parent
9e428c6c5f
commit
08897137ff
@ -22,16 +22,25 @@ import yarl
|
|||||||
|
|
||||||
from . import config as conf_util, config_entries, core, loader, requirements
|
from . import config as conf_util, config_entries, core, loader, requirements
|
||||||
|
|
||||||
# Pre-import config and lovelace which have no requirements here to avoid
|
# Pre-import frontend deps which have no requirements here to avoid
|
||||||
# loading them at run time and blocking the event loop. We do this ahead
|
# loading them at run time and blocking the event loop. We do this ahead
|
||||||
# of time so that we do not have to flag frontends deps with `import_executor`
|
# of time so that we do not have to flag frontend deps with `import_executor`
|
||||||
# as it would create a thundering heard of executor jobs trying to import
|
# as it would create a thundering heard of executor jobs trying to import
|
||||||
# frontend deps at the same time.
|
# frontend deps at the same time.
|
||||||
from .components import (
|
from .components import (
|
||||||
api as api_pre_import, # noqa: F401
|
api as api_pre_import, # noqa: F401
|
||||||
|
auth as auth_pre_import, # noqa: F401
|
||||||
config as config_pre_import, # noqa: F401
|
config as config_pre_import, # noqa: F401
|
||||||
|
device_automation as device_automation_pre_import, # noqa: F401
|
||||||
|
diagnostics as diagnostics_pre_import, # noqa: F401
|
||||||
|
file_upload as file_upload_pre_import, # noqa: F401
|
||||||
http,
|
http,
|
||||||
lovelace as lovelace_pre_import, # noqa: F401
|
lovelace as lovelace_pre_import, # noqa: F401
|
||||||
|
onboarding as onboarding_pre_import, # noqa: F401
|
||||||
|
repairs as repairs_pre_import, # noqa: F401
|
||||||
|
search as search_pre_import, # noqa: F401
|
||||||
|
system_log as system_log_pre_import, # noqa: F401
|
||||||
|
websocket_api as websocket_api_pre_import, # noqa: F401
|
||||||
)
|
)
|
||||||
from .const import (
|
from .const import (
|
||||||
FORMAT_DATETIME,
|
FORMAT_DATETIME,
|
||||||
|
@ -3,12 +3,13 @@ import asyncio
|
|||||||
from collections.abc import Generator, Iterable
|
from collections.abc import Generator, Iterable
|
||||||
import glob
|
import glob
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
from typing import Any
|
from typing import Any
|
||||||
from unittest.mock import AsyncMock, Mock, patch
|
from unittest.mock import AsyncMock, Mock, patch
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from homeassistant import bootstrap, runner
|
from homeassistant import bootstrap, loader, runner
|
||||||
import homeassistant.config as config_util
|
import homeassistant.config as config_util
|
||||||
from homeassistant.config_entries import HANDLERS, ConfigEntry
|
from homeassistant.config_entries import HANDLERS, ConfigEntry
|
||||||
from homeassistant.const import SIGNAL_BOOTSTRAP_INTEGRATIONS
|
from homeassistant.const import SIGNAL_BOOTSTRAP_INTEGRATIONS
|
||||||
@ -1023,3 +1024,46 @@ async def test_bootstrap_dependencies(
|
|||||||
f"Dependency {integration} will wait for dependencies dict_keys(['mqtt'])"
|
f"Dependency {integration} will wait for dependencies dict_keys(['mqtt'])"
|
||||||
in caplog.text
|
in caplog.text
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def test_frontend_deps_pre_import_no_requirements(hass: HomeAssistant) -> None:
|
||||||
|
"""Test frontend dependencies are pre-imported and do not have any requirements."""
|
||||||
|
pre_imports = [
|
||||||
|
name.removesuffix("_pre_import")
|
||||||
|
for name in dir(bootstrap)
|
||||||
|
if name.endswith("_pre_import")
|
||||||
|
]
|
||||||
|
|
||||||
|
# Make sure future refactoring does not
|
||||||
|
# accidentally remove the pre-imports
|
||||||
|
# or change the naming convention without
|
||||||
|
# updating this test.
|
||||||
|
assert len(pre_imports) > 3
|
||||||
|
|
||||||
|
for pre_import in pre_imports:
|
||||||
|
integration = await loader.async_get_integration(hass, pre_import)
|
||||||
|
assert not integration.requirements
|
||||||
|
|
||||||
|
|
||||||
|
async def test_bootstrap_does_not_preload_stage_1_integrations() -> None:
|
||||||
|
"""Test that the bootstrap does not preload stage 1 integrations.
|
||||||
|
|
||||||
|
If this test fails it means that stage1 integrations are being
|
||||||
|
loaded too soon and will not get their requirements updated
|
||||||
|
before they are loaded at runtime.
|
||||||
|
"""
|
||||||
|
|
||||||
|
process = await asyncio.create_subprocess_exec(
|
||||||
|
sys.executable,
|
||||||
|
"-c",
|
||||||
|
"import homeassistant.bootstrap; import sys; print(sys.modules)",
|
||||||
|
stdout=asyncio.subprocess.PIPE,
|
||||||
|
)
|
||||||
|
stdout, _ = await process.communicate()
|
||||||
|
assert process.returncode == 0
|
||||||
|
decoded_stdout = stdout.decode()
|
||||||
|
|
||||||
|
# Ensure no stage1 integrations have been imported
|
||||||
|
# as a side effect of importing the pre-imports
|
||||||
|
for integration in bootstrap.STAGE_1_INTEGRATIONS:
|
||||||
|
assert f"homeassistant.components.{integration}" not in decoded_stdout
|
||||||
|
Loading…
x
Reference in New Issue
Block a user