Add startup timeout to bluetooth (#75848)

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
This commit is contained in:
J. Nick Koston 2022-07-28 11:14:13 -10:00 committed by GitHub
parent 6ba0b9cff2
commit 702cef3fc7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 36 additions and 1 deletions

View File

@ -1,6 +1,7 @@
"""The bluetooth integration."""
from __future__ import annotations
import asyncio
from asyncio import Future
from collections.abc import Callable
from dataclasses import dataclass
@ -45,6 +46,7 @@ _LOGGER = logging.getLogger(__name__)
UNAVAILABLE_TRACK_SECONDS: Final = 60 * 5
START_TIMEOUT = 15
SOURCE_LOCAL: Final = "local"
@ -330,7 +332,13 @@ class BluetoothManager:
self._device_detected, {}
)
try:
await self.scanner.start()
async with async_timeout.timeout(START_TIMEOUT):
await self.scanner.start()
except asyncio.TimeoutError as ex:
self._cancel_device_detected()
raise ConfigEntryNotReady(
f"Timed out starting Bluetooth after {START_TIMEOUT} seconds"
) from ex
except (FileNotFoundError, BleakError) as ex:
self._cancel_device_detected()
raise ConfigEntryNotReady(f"Failed to start Bluetooth: {ex}") from ex

View File

@ -97,6 +97,33 @@ async def test_setup_and_stop_broken_bluetooth(hass, caplog):
assert len(bluetooth.async_discovered_service_info(hass)) == 0
async def test_setup_and_stop_broken_bluetooth_hanging(hass, caplog):
"""Test we fail gracefully when bluetooth/dbus is hanging."""
mock_bt = []
async def _mock_hang():
await asyncio.sleep(1)
with patch.object(bluetooth, "START_TIMEOUT", 0), patch(
"homeassistant.components.bluetooth.HaBleakScanner.async_setup"
), patch(
"homeassistant.components.bluetooth.HaBleakScanner.start",
side_effect=_mock_hang,
), patch(
"homeassistant.components.bluetooth.async_get_bluetooth", return_value=mock_bt
):
assert await async_setup_component(
hass, bluetooth.DOMAIN, {bluetooth.DOMAIN: {}}
)
await hass.async_block_till_done()
hass.bus.async_fire(EVENT_HOMEASSISTANT_STARTED)
await hass.async_block_till_done()
hass.bus.async_fire(EVENT_HOMEASSISTANT_STOP)
await hass.async_block_till_done()
assert "Timed out starting Bluetooth" in caplog.text
async def test_setup_and_retry_adapter_not_yet_available(hass, caplog):
"""Test we retry if the adapter is not yet available."""
mock_bt = []