Test for circular dependencies using manifests (#22908)
* Integration dependencies * Lint * Lint * Fix one test * Lint * Fix load custom component integration Fix async issue Add circular dependency detection in manifest validation * Fix test * Address review comment * Apply suggestions from code review Co-Authored-By: balloob <paulus@home-assistant.io>
This commit is contained in:
parent
4110bd0acf
commit
cac00f5b26
11 changed files with 314 additions and 89 deletions
|
@ -128,16 +128,17 @@ async def async_from_config_dict(config: Dict[str, Any],
|
|||
hass.config_entries = config_entries.ConfigEntries(hass, config)
|
||||
await hass.config_entries.async_initialize()
|
||||
|
||||
components = _get_components(hass, config)
|
||||
domains = _get_domains(hass, config)
|
||||
|
||||
# Resolve all dependencies of all components.
|
||||
for component in list(components):
|
||||
try:
|
||||
components.update(loader.component_dependencies(hass, component))
|
||||
except loader.LoaderError:
|
||||
# Ignore it, or we'll break startup
|
||||
# It will be properly handled during setup.
|
||||
pass
|
||||
for dep_domains in await asyncio.gather(*[
|
||||
loader.async_component_dependencies(hass, domain)
|
||||
for domain in domains
|
||||
], return_exceptions=True):
|
||||
# Result is either a set or an exception. We ignore exceptions
|
||||
# It will be properly handled during setup of the domain.
|
||||
if isinstance(dep_domains, set):
|
||||
domains.update(dep_domains)
|
||||
|
||||
# setup components
|
||||
res = await core_component.async_setup(hass, config)
|
||||
|
@ -151,10 +152,10 @@ async def async_from_config_dict(config: Dict[str, Any],
|
|||
_LOGGER.info("Home Assistant core initialized")
|
||||
|
||||
# stage 0, load logging components
|
||||
for component in components:
|
||||
if component in LOGGING_COMPONENT:
|
||||
for domain in domains:
|
||||
if domain in LOGGING_COMPONENT:
|
||||
hass.async_create_task(
|
||||
async_setup_component(hass, component, config))
|
||||
async_setup_component(hass, domain, config))
|
||||
|
||||
await hass.async_block_till_done()
|
||||
|
||||
|
@ -165,18 +166,18 @@ async def async_from_config_dict(config: Dict[str, Any],
|
|||
hass.helpers.area_registry.async_get_registry())
|
||||
|
||||
# stage 1
|
||||
for component in components:
|
||||
if component in FIRST_INIT_COMPONENT:
|
||||
for domain in domains:
|
||||
if domain in FIRST_INIT_COMPONENT:
|
||||
hass.async_create_task(
|
||||
async_setup_component(hass, component, config))
|
||||
async_setup_component(hass, domain, config))
|
||||
|
||||
await hass.async_block_till_done()
|
||||
|
||||
# stage 2
|
||||
for component in components:
|
||||
if component in FIRST_INIT_COMPONENT or component in LOGGING_COMPONENT:
|
||||
for domain in domains:
|
||||
if domain in FIRST_INIT_COMPONENT or domain in LOGGING_COMPONENT:
|
||||
continue
|
||||
hass.async_create_task(async_setup_component(hass, component, config))
|
||||
hass.async_create_task(async_setup_component(hass, domain, config))
|
||||
|
||||
await hass.async_block_till_done()
|
||||
|
||||
|
@ -398,18 +399,17 @@ async def async_mount_local_lib_path(config_dir: str) -> str:
|
|||
|
||||
|
||||
@core.callback
|
||||
def _get_components(hass: core.HomeAssistant,
|
||||
config: Dict[str, Any]) -> Set[str]:
|
||||
"""Get components to set up."""
|
||||
def _get_domains(hass: core.HomeAssistant, config: Dict[str, Any]) -> Set[str]:
|
||||
"""Get domains of components to set up."""
|
||||
# Filter out the repeating and common config section [homeassistant]
|
||||
components = set(key.split(' ')[0] for key in config.keys()
|
||||
if key != core.DOMAIN)
|
||||
domains = set(key.split(' ')[0] for key in config.keys()
|
||||
if key != core.DOMAIN)
|
||||
|
||||
# Add config entry domains
|
||||
components.update(hass.config_entries.async_domains()) # type: ignore
|
||||
domains.update(hass.config_entries.async_domains()) # type: ignore
|
||||
|
||||
# Make sure the Hass.io component is loaded
|
||||
if 'HASSIO' in os.environ:
|
||||
components.add('hassio')
|
||||
domains.add('hassio')
|
||||
|
||||
return components
|
||||
return domains
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue