mirror of
https://github.com/home-assistant/core.git
synced 2025-04-24 17:27:52 +00:00
Fix wait for a dependency with config entries (#142318)
* Fix wait for dependency with config entries * test types * test coverage --------- Co-authored-by: J. Nick Koston <nick@koston.org>
This commit is contained in:
parent
a787c6a31e
commit
4813b5c882
@ -202,16 +202,19 @@ async def _async_process_dependencies(
|
||||
"""
|
||||
setup_futures = hass.data.setdefault(DATA_SETUP, {})
|
||||
|
||||
dependencies_tasks = {
|
||||
dep: setup_futures.get(dep)
|
||||
or create_eager_task(
|
||||
async_setup_component(hass, dep, config),
|
||||
name=f"setup {dep} as dependency of {integration.domain}",
|
||||
loop=hass.loop,
|
||||
)
|
||||
for dep in integration.dependencies
|
||||
if dep not in hass.config.components
|
||||
}
|
||||
dependencies_tasks: dict[str, asyncio.Future[bool]] = {}
|
||||
|
||||
for dep in integration.dependencies:
|
||||
fut = setup_futures.get(dep)
|
||||
if fut is None:
|
||||
if dep in hass.config.components:
|
||||
continue
|
||||
fut = create_eager_task(
|
||||
async_setup_component(hass, dep, config),
|
||||
name=f"setup {dep} as dependency of {integration.domain}",
|
||||
loop=hass.loop,
|
||||
)
|
||||
dependencies_tasks[dep] = fut
|
||||
|
||||
to_be_loaded = hass.data.get(DATA_SETUP_DONE, {})
|
||||
# We don't want to just wait for the futures from `to_be_loaded` here.
|
||||
@ -219,16 +222,18 @@ async def _async_process_dependencies(
|
||||
# scheduled to be set up, as if for whatever reason they had not been,
|
||||
# we would deadlock waiting for them here.
|
||||
for dep in integration.after_dependencies:
|
||||
if (
|
||||
dep not in dependencies_tasks
|
||||
and dep in to_be_loaded
|
||||
and dep not in hass.config.components
|
||||
):
|
||||
dependencies_tasks[dep] = setup_futures.get(dep) or create_eager_task(
|
||||
if dep not in to_be_loaded or dep in dependencies_tasks:
|
||||
continue
|
||||
fut = setup_futures.get(dep)
|
||||
if fut is None:
|
||||
if dep in hass.config.components:
|
||||
continue
|
||||
fut = create_eager_task(
|
||||
async_setup_component(hass, dep, config),
|
||||
name=f"setup {dep} as after dependency of {integration.domain}",
|
||||
loop=hass.loop,
|
||||
)
|
||||
dependencies_tasks[dep] = fut
|
||||
|
||||
if not dependencies_tasks:
|
||||
return []
|
||||
|
@ -353,6 +353,76 @@ async def test_component_not_setup_missing_dependencies(hass: HomeAssistant) ->
|
||||
assert await setup.async_setup_component(hass, "comp2", {})
|
||||
|
||||
|
||||
async def test_component_not_setup_already_setup_dependencies(
|
||||
hass: HomeAssistant,
|
||||
) -> None:
|
||||
"""Test we do not set up component dependencies if they are already set up."""
|
||||
mock_integration(
|
||||
hass,
|
||||
MockModule(
|
||||
"comp",
|
||||
dependencies=["dep1"],
|
||||
partial_manifest={"after_dependencies": ["dep2"]},
|
||||
),
|
||||
)
|
||||
mock_integration(hass, MockModule("dep1"))
|
||||
mock_integration(hass, MockModule("dep2"))
|
||||
|
||||
setup.async_set_domains_to_be_loaded(hass, {"comp", "dep2"})
|
||||
|
||||
hass.config.components.add("dep1")
|
||||
hass.config.components.add("dep2")
|
||||
|
||||
with patch(
|
||||
"homeassistant.setup.async_setup_component",
|
||||
side_effect=setup.async_setup_component,
|
||||
) as mock_setup:
|
||||
await mock_setup(hass, "comp", {})
|
||||
|
||||
assert mock_setup.call_count == 1
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("mock_handlers")
|
||||
async def test_component_setup_dependencies_with_config_entry(
|
||||
hass: HomeAssistant,
|
||||
) -> None:
|
||||
"""Test we wait for a dependency with config entry."""
|
||||
calls: list[str] = []
|
||||
|
||||
async def mock_async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||
await asyncio.sleep(0)
|
||||
calls.append("entry")
|
||||
return True
|
||||
|
||||
mock_integration(hass, MockModule("comp", async_setup_entry=mock_async_setup_entry))
|
||||
mock_platform(hass, "comp.config_flow", None)
|
||||
MockConfigEntry(domain="comp").add_to_hass(hass)
|
||||
|
||||
async def mock_async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
||||
calls.append("comp")
|
||||
return True
|
||||
|
||||
mock_integration(
|
||||
hass,
|
||||
MockModule("comp2", dependencies=["comp"], async_setup=mock_async_setup),
|
||||
)
|
||||
mock_integration(
|
||||
hass,
|
||||
MockModule("comp3", dependencies=["comp"], async_setup=mock_async_setup),
|
||||
)
|
||||
|
||||
await asyncio.gather(
|
||||
setup.async_setup_component(hass, "comp2", {}),
|
||||
setup.async_setup_component(hass, "comp3", {}),
|
||||
)
|
||||
|
||||
assert "comp" in hass.config.components
|
||||
assert "comp2" in hass.config.components
|
||||
assert "comp3" in hass.config.components
|
||||
|
||||
assert calls == ["entry", "comp", "comp"]
|
||||
|
||||
|
||||
async def test_component_failing_setup(hass: HomeAssistant) -> None:
|
||||
"""Test component that fails setup."""
|
||||
mock_integration(hass, MockModule("comp", setup=lambda hass, config: False))
|
||||
|
Loading…
x
Reference in New Issue
Block a user