Avoid sending empty integration list multiple times during subscribe_bootstrap_integrations (#49181)

This commit is contained in:
J. Nick Koston 2021-04-15 20:16:17 -10:00 committed by GitHub
parent 6604614c39
commit 564e7fa53c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 65 additions and 3 deletions

View File

@ -389,6 +389,7 @@ async def _async_watch_pending_setups(hass: core.HomeAssistant) -> None:
"""Periodic log of setups that are pending for longer than LOG_SLOW_STARTUP_INTERVAL."""
loop_count = 0
setup_started: dict[str, datetime] = hass.data[DATA_SETUP_STARTED]
previous_was_empty = True
while True:
now = dt_util.utcnow()
remaining_with_setup_started = {
@ -396,9 +397,11 @@ async def _async_watch_pending_setups(hass: core.HomeAssistant) -> None:
for domain in setup_started
}
_LOGGER.debug("Integration remaining: %s", remaining_with_setup_started)
async_dispatcher_send(
hass, SIGNAL_BOOTSTRAP_INTEGRATONS, remaining_with_setup_started
)
if remaining_with_setup_started or not previous_was_empty:
async_dispatcher_send(
hass, SIGNAL_BOOTSTRAP_INTEGRATONS, remaining_with_setup_started
)
previous_was_empty = not remaining_with_setup_started
await asyncio.sleep(SLOW_STARTUP_CHECK_INTERVAL)
loop_count += SLOW_STARTUP_CHECK_INTERVAL

View File

@ -7,8 +7,10 @@ from unittest.mock import Mock, patch
import pytest
from homeassistant import bootstrap, core, runner
from homeassistant.bootstrap import SIGNAL_BOOTSTRAP_INTEGRATONS
import homeassistant.config as config_util
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.dispatcher import async_dispatcher_connect
import homeassistant.util.dt as dt_util
from tests.common import (
@ -610,3 +612,60 @@ async def test_setup_safe_mode_if_no_frontend(
assert hass.config.skip_pip
assert hass.config.internal_url == "http://192.168.1.100:8123"
assert hass.config.external_url == "https://abcdef.ui.nabu.casa"
@pytest.mark.parametrize("load_registries", [False])
async def test_empty_integrations_list_is_only_sent_at_the_end_of_bootstrap(hass):
"""Test empty integrations list is only sent at the end of bootstrap."""
order = []
def gen_domain_setup(domain):
async def async_setup(hass, config):
order.append(domain)
await asyncio.sleep(0.1)
async def _background_task():
await asyncio.sleep(0.2)
await hass.async_create_task(_background_task())
return True
return async_setup
mock_integration(
hass,
MockModule(
domain="normal_integration",
async_setup=gen_domain_setup("normal_integration"),
partial_manifest={"after_dependencies": ["an_after_dep"]},
),
)
mock_integration(
hass,
MockModule(
domain="an_after_dep",
async_setup=gen_domain_setup("an_after_dep"),
),
)
integrations = []
@core.callback
def _bootstrap_integrations(data):
integrations.append(data)
async_dispatcher_connect(
hass, SIGNAL_BOOTSTRAP_INTEGRATONS, _bootstrap_integrations
)
with patch.object(bootstrap, "SLOW_STARTUP_CHECK_INTERVAL", 0.05):
await bootstrap._async_set_up_integrations(
hass, {"normal_integration": {}, "an_after_dep": {}}
)
assert integrations[0] != {}
assert "an_after_dep" in integrations[0]
assert integrations[-3] != {}
assert integrations[-1] == {}
assert "normal_integration" in hass.config.components
assert order == ["an_after_dep", "normal_integration"]