mirror of
https://github.com/home-assistant/core.git
synced 2025-11-11 20:10:12 +00:00
Add startup timeout to bluetooth (#75848)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
This commit is contained in:
committed by
Franck Nijhof
parent
53870dd0bc
commit
e4e36b51b6
@@ -1,6 +1,7 @@
|
|||||||
"""The bluetooth integration."""
|
"""The bluetooth integration."""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import asyncio
|
||||||
from collections.abc import Callable
|
from collections.abc import Callable
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
@@ -8,6 +9,7 @@ from enum import Enum
|
|||||||
import logging
|
import logging
|
||||||
from typing import Final, Union
|
from typing import Final, Union
|
||||||
|
|
||||||
|
import async_timeout
|
||||||
from bleak import BleakError
|
from bleak import BleakError
|
||||||
from bleak.backends.device import BLEDevice
|
from bleak.backends.device import BLEDevice
|
||||||
from bleak.backends.scanner import AdvertisementData
|
from bleak.backends.scanner import AdvertisementData
|
||||||
@@ -43,6 +45,7 @@ _LOGGER = logging.getLogger(__name__)
|
|||||||
|
|
||||||
|
|
||||||
UNAVAILABLE_TRACK_SECONDS: Final = 60 * 5
|
UNAVAILABLE_TRACK_SECONDS: Final = 60 * 5
|
||||||
|
START_TIMEOUT = 15
|
||||||
|
|
||||||
SOURCE_LOCAL: Final = "local"
|
SOURCE_LOCAL: Final = "local"
|
||||||
|
|
||||||
@@ -300,7 +303,13 @@ class BluetoothManager:
|
|||||||
self._device_detected, {}
|
self._device_detected, {}
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
|
async with async_timeout.timeout(START_TIMEOUT):
|
||||||
await self.scanner.start()
|
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:
|
except (FileNotFoundError, BleakError) as ex:
|
||||||
self._cancel_device_detected()
|
self._cancel_device_detected()
|
||||||
raise ConfigEntryNotReady(f"Failed to start Bluetooth: {ex}") from ex
|
raise ConfigEntryNotReady(f"Failed to start Bluetooth: {ex}") from ex
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
"""Tests for the Bluetooth integration."""
|
"""Tests for the Bluetooth integration."""
|
||||||
|
import asyncio
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
from unittest.mock import MagicMock, patch
|
from unittest.mock import MagicMock, patch
|
||||||
|
|
||||||
@@ -95,6 +96,33 @@ async def test_setup_and_stop_broken_bluetooth(hass, caplog):
|
|||||||
assert len(bluetooth.async_discovered_service_info(hass)) == 0
|
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):
|
async def test_setup_and_retry_adapter_not_yet_available(hass, caplog):
|
||||||
"""Test we retry if the adapter is not yet available."""
|
"""Test we retry if the adapter is not yet available."""
|
||||||
mock_bt = []
|
mock_bt = []
|
||||||
|
|||||||
Reference in New Issue
Block a user