Make bootstrap cancelation safe (#90420)

This commit is contained in:
J. Nick Koston 2023-03-28 11:22:41 -10:00 committed by GitHub
parent e22618a555
commit f60e9c71a2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 32 additions and 10 deletions

View File

@ -515,16 +515,15 @@ async def async_setup_multi_components(
)
for domain in domains
}
await asyncio.wait(futures.values())
errors = [domain for domain in domains if futures[domain].exception()]
for domain in errors:
exception = futures[domain].exception()
assert exception is not None
_LOGGER.error(
"Error setting up integration %s - received exception",
domain,
exc_info=(type(exception), exception, exception.__traceback__),
)
results = await asyncio.gather(*futures.values(), return_exceptions=True)
for idx, domain in enumerate(futures):
result = results[idx]
if isinstance(result, BaseException):
_LOGGER.error(
"Error setting up integration %s - received exception",
domain,
exc_info=(type(result), result, result.__traceback__),
)
async def _async_set_up_integrations(

View File

@ -806,3 +806,26 @@ async def test_warning_logged_on_wrap_up_timeout(
await hass.async_block_till_done()
assert "Setup timed out for bootstrap - moving forward" in caplog.text
@pytest.mark.parametrize("load_registries", [False])
async def test_bootstrap_is_cancellation_safe(
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
) -> None:
"""Test cancellation during async_setup_component does not cancel bootstrap."""
with patch.object(
bootstrap, "async_setup_component", side_effect=asyncio.CancelledError
):
await bootstrap._async_set_up_integrations(hass, {"cancel_integration": {}})
await hass.async_block_till_done()
assert "Error setting up integration cancel_integration" in caplog.text
@pytest.mark.parametrize("load_registries", [False])
async def test_bootstrap_empty_integrations(
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
) -> None:
"""Test setting up an empty integrations does not raise."""
await bootstrap.async_setup_multi_components(hass, set(), {})
await hass.async_block_till_done()