1
0
mirror of https://github.com/home-assistant/core.git synced 2026-05-08 09:38:58 +01:00

Improve dependencies resolution (#138502)

* Improve dependencies resolution

* Improve tests

* Better docstrings

* Fix comment

* Improve tests

* Improve logging

* Address feedback

* Address feedback

* Address feedback

* Address feedback

* Address feedback

* Simplify error handling

* small log change

* Add comment

* Address feedback

* shorter comments

* Add test
This commit is contained in:
Artur Pragacz
2025-03-11 10:12:23 +01:00
committed by GitHub
parent 52408e67b2
commit 4f25296c50
5 changed files with 398 additions and 247 deletions
+45 -17
View File
@@ -27,33 +27,42 @@ async def test_circular_component_dependencies(hass: HomeAssistant) -> None:
mock_integration(hass, MockModule("mod2", dependencies=["mod1"]))
mock_integration(hass, MockModule("mod3", dependencies=["mod1"]))
mod_4 = mock_integration(hass, MockModule("mod4", dependencies=["mod2", "mod3"]))
all_domains = {"mod1", "mod2", "mod3", "mod4"}
deps = await loader._async_component_dependencies(hass, mod_4)
assert deps == {"mod1", "mod2", "mod3", "mod4"}
deps = await loader._do_resolve_dependencies(mod_4, cache={})
assert deps == {"mod1", "mod2", "mod3"}
# Create a circular dependency
mock_integration(hass, MockModule("mod1", dependencies=["mod4"]))
with pytest.raises(loader.CircularDependency):
await loader._async_component_dependencies(hass, mod_4)
await loader._do_resolve_dependencies(mod_4, cache={})
# Create a different circular dependency
mock_integration(hass, MockModule("mod1", dependencies=["mod3"]))
with pytest.raises(loader.CircularDependency):
await loader._async_component_dependencies(hass, mod_4)
await loader._do_resolve_dependencies(mod_4, cache={})
# Create a circular after_dependency
mock_integration(
hass, MockModule("mod1", partial_manifest={"after_dependencies": ["mod4"]})
)
with pytest.raises(loader.CircularDependency):
await loader._async_component_dependencies(hass, mod_4)
await loader._do_resolve_dependencies(
mod_4,
cache={},
possible_after_dependencies=all_domains,
)
# Create a different circular after_dependency
mock_integration(
hass, MockModule("mod1", partial_manifest={"after_dependencies": ["mod3"]})
)
with pytest.raises(loader.CircularDependency):
await loader._async_component_dependencies(hass, mod_4)
await loader._do_resolve_dependencies(
mod_4,
cache={},
possible_after_dependencies=all_domains,
)
# Create a circular after_dependency without a hard dependency
mock_integration(
@@ -62,29 +71,48 @@ async def test_circular_component_dependencies(hass: HomeAssistant) -> None:
mod_4 = mock_integration(
hass, MockModule("mod4", partial_manifest={"after_dependencies": ["mod2"]})
)
# this currently doesn't raise, but it should. Will be improved in a follow-up.
await loader._async_component_dependencies(hass, mod_4)
with pytest.raises(loader.CircularDependency):
await loader._do_resolve_dependencies(
mod_4,
cache={},
possible_after_dependencies=all_domains,
)
result = await loader.resolve_integrations_after_dependencies(hass, (mod_4,))
assert result == {}
result = await loader.resolve_integrations_after_dependencies(
hass, (mod_4,), ignore_exceptions=True
)
assert result["mod4"] == {"mod4", "mod2", "mod1"}
async def test_nonexistent_component_dependencies(hass: HomeAssistant) -> None:
"""Test if we can detect nonexistent dependencies of components."""
mod_1 = mock_integration(hass, MockModule("mod1", dependencies=["nonexistent"]))
with pytest.raises(loader.IntegrationNotFound):
await loader._async_component_dependencies(hass, mod_1)
mod_2 = mock_integration(hass, MockModule("mod2", dependencies=["mod1"]))
assert not await mod_2.resolve_dependencies()
assert await mod_2.resolve_dependencies() is None
assert mod_2.all_dependencies_resolved
with pytest.raises(RuntimeError):
with pytest.raises(loader.IntegrationNotFound):
mod_2.all_dependencies # noqa: B018
# this currently is not resolved, because intermediate results are not cached
# this will be improved in a follow-up
assert not mod_1.all_dependencies_resolved
assert not await mod_1.resolve_dependencies()
with pytest.raises(RuntimeError):
assert mod_1.all_dependencies_resolved
assert await mod_1.resolve_dependencies() is None
with pytest.raises(loader.IntegrationNotFound):
mod_1.all_dependencies # noqa: B018
result = await loader.resolve_integrations_dependencies(hass, (mod_2, mod_1))
assert result == {}
mod_1 = mock_integration(
hass,
MockModule("mod1", partial_manifest={"after_dependencies": ["non.existent"]}),
)
mod_2 = mock_integration(hass, MockModule("mod2", dependencies=["mod1"]))
result = await loader.resolve_integrations_after_dependencies(hass, (mod_2, mod_1))
assert result == {}
def test_component_loader(hass: HomeAssistant) -> None:
"""Test loading components."""