mirror of
https://github.com/home-assistant/core.git
synced 2026-05-08 17:49:37 +01:00
Add support for importing integrations in the executor (#111336)
* Add support for pre-imports at setup time alternative solution to #111331 * refactor * refactor * refactor * mark >1.0s integrations * no point in executor if already loaded * no point in executor if already loaded * cleanup * cleanup * two more * one more * analytics loads a lot more integrations * cloud * debug * psutil, hardwre * try zha * Update homeassistant/setup.py * await * comments * coverage * coverage * coverage * move logic to loader * move logic to loader * preserve comments
This commit is contained in:
+83
-1
@@ -1,4 +1,5 @@
|
||||
"""Test to verify that we can load components."""
|
||||
import asyncio
|
||||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
@@ -173,6 +174,20 @@ async def test_get_integration(hass: HomeAssistant) -> None:
|
||||
assert hue_light == integration.get_platform("light")
|
||||
|
||||
|
||||
async def test_async_get_component(hass: HomeAssistant) -> None:
|
||||
"""Test resolving integration."""
|
||||
with pytest.raises(loader.IntegrationNotLoaded):
|
||||
loader.async_get_loaded_integration(hass, "hue")
|
||||
|
||||
integration = await loader.async_get_integration(hass, "hue")
|
||||
assert await integration.async_get_component() == hue
|
||||
assert integration.get_platform("light") == hue_light
|
||||
|
||||
integration = loader.async_get_loaded_integration(hass, "hue")
|
||||
assert await integration.async_get_component() == hue
|
||||
assert integration.get_platform("light") == hue_light
|
||||
|
||||
|
||||
async def test_get_integration_exceptions(hass: HomeAssistant) -> None:
|
||||
"""Test resolving integration."""
|
||||
integration = await loader.async_get_integration(hass, "hue")
|
||||
@@ -223,6 +238,41 @@ async def test_get_platform_caches_failures_when_component_loaded(
|
||||
assert integration.get_platform("light") == hue_light
|
||||
|
||||
|
||||
async def test_async_get_platform_caches_failures_when_component_loaded(
|
||||
hass: HomeAssistant,
|
||||
) -> None:
|
||||
"""Test async_get_platform cache failures only when the component is loaded."""
|
||||
integration = await loader.async_get_integration(hass, "hue")
|
||||
|
||||
with pytest.raises(ImportError), patch(
|
||||
"homeassistant.loader.importlib.import_module", side_effect=ImportError("Boom")
|
||||
):
|
||||
assert integration.get_component() == hue
|
||||
|
||||
with pytest.raises(ImportError), patch(
|
||||
"homeassistant.loader.importlib.import_module", side_effect=ImportError("Boom")
|
||||
):
|
||||
assert await integration.async_get_platform("light") == hue_light
|
||||
|
||||
# Hue is not loaded so we should still hit the import_module path
|
||||
with pytest.raises(ImportError), patch(
|
||||
"homeassistant.loader.importlib.import_module", side_effect=ImportError("Boom")
|
||||
):
|
||||
assert await integration.async_get_platform("light") == hue_light
|
||||
|
||||
assert integration.get_component() == hue
|
||||
|
||||
# Hue is loaded so we should cache the import_module failure now
|
||||
with pytest.raises(ImportError), patch(
|
||||
"homeassistant.loader.importlib.import_module", side_effect=ImportError("Boom")
|
||||
):
|
||||
assert await integration.async_get_platform("light") == hue_light
|
||||
|
||||
# Hue is loaded and the last call should have cached the import_module failure
|
||||
with pytest.raises(ImportError):
|
||||
assert await integration.async_get_platform("light") == hue_light
|
||||
|
||||
|
||||
async def test_get_integration_legacy(
|
||||
hass: HomeAssistant, enable_custom_integrations: None
|
||||
) -> None:
|
||||
@@ -368,7 +418,9 @@ async def test_integrations_only_once(hass: HomeAssistant) -> None:
|
||||
assert await int_1 is await int_2
|
||||
|
||||
|
||||
def _get_test_integration(hass, name, config_flow):
|
||||
def _get_test_integration(
|
||||
hass: HomeAssistant, name: str, config_flow: bool, import_executor: bool = False
|
||||
) -> loader.Integration:
|
||||
"""Return a generated test integration."""
|
||||
return loader.Integration(
|
||||
hass,
|
||||
@@ -384,6 +436,7 @@ def _get_test_integration(hass, name, config_flow):
|
||||
"homekit": {"models": [name]},
|
||||
"ssdp": [{"manufacturer": name, "modelName": name}],
|
||||
"mqtt": [f"{name}/discovery"],
|
||||
"import_executor": import_executor,
|
||||
},
|
||||
)
|
||||
|
||||
@@ -725,6 +778,35 @@ async def test_get_mqtt(hass: HomeAssistant) -> None:
|
||||
assert mqtt["test_2"] == ["test_2/discovery"]
|
||||
|
||||
|
||||
async def test_import_platform_executor(
|
||||
hass: HomeAssistant, enable_custom_integrations: None
|
||||
) -> None:
|
||||
"""Test import a platform in the executor."""
|
||||
integration = await loader.async_get_integration(
|
||||
hass, "test_package_loaded_executor"
|
||||
)
|
||||
|
||||
config_flow_task_1 = asyncio.create_task(
|
||||
integration.async_get_platform("config_flow")
|
||||
)
|
||||
config_flow_task_2 = asyncio.create_task(
|
||||
integration.async_get_platform("config_flow")
|
||||
)
|
||||
config_flow_task_3 = asyncio.create_task(
|
||||
integration.async_get_platform("config_flow")
|
||||
)
|
||||
|
||||
config_flow_task1_result = await config_flow_task_1
|
||||
config_flow_task2_result = await config_flow_task_2
|
||||
config_flow_task3_result = await config_flow_task_3
|
||||
|
||||
assert (
|
||||
config_flow_task1_result == config_flow_task2_result == config_flow_task3_result
|
||||
)
|
||||
|
||||
assert await config_flow_task1_result._async_has_devices(hass) is True
|
||||
|
||||
|
||||
async def test_get_custom_components_recovery_mode(hass: HomeAssistant) -> None:
|
||||
"""Test that we get empty custom components in recovery mode."""
|
||||
hass.config.recovery_mode = True
|
||||
|
||||
Reference in New Issue
Block a user