Prevent Bluetooth reconnects from blocking shutdown (#104150)

pull/104210/head
J. Nick Koston 2023-11-19 08:22:26 -06:00 committed by GitHub
parent e7cec9b148
commit d3b4dd226b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 28 additions and 0 deletions

View File

@ -124,6 +124,7 @@ class BluetoothManager:
"storage",
"slot_manager",
"_debug",
"shutdown",
)
def __init__(
@ -165,6 +166,7 @@ class BluetoothManager:
self.storage = storage
self.slot_manager = slot_manager
self._debug = _LOGGER.isEnabledFor(logging.DEBUG)
self.shutdown = False
@property
def supports_passive_scan(self) -> bool:
@ -259,6 +261,7 @@ class BluetoothManager:
def async_stop(self, event: Event) -> None:
"""Stop the Bluetooth integration at shutdown."""
_LOGGER.debug("Stopping bluetooth manager")
self.shutdown = True
if self._cancel_unavailable_tracking:
self._cancel_unavailable_tracking()
self._cancel_unavailable_tracking = None

View File

@ -270,6 +270,8 @@ class HaBleakClientWrapper(BleakClient):
"""Connect to the specified GATT server."""
assert models.MANAGER is not None
manager = models.MANAGER
if manager.shutdown:
raise BleakError("Bluetooth is already shutdown")
if debug_logging := _LOGGER.isEnabledFor(logging.DEBUG):
_LOGGER.debug("%s: Looking for backend to connect", self.__address)
wrapped_backend = self._async_get_best_available_backend_and_device(manager)

View File

@ -7,6 +7,7 @@ from unittest.mock import patch
import bleak
from bleak.backends.device import BLEDevice
from bleak.backends.scanner import AdvertisementData
from bleak.exc import BleakError
import pytest
from homeassistant.components.bluetooth import (
@ -366,3 +367,25 @@ async def test_we_switch_adapters_on_failure(
assert await client.connect() is False
cancel_hci0()
cancel_hci1()
async def test_raise_after_shutdown(
hass: HomeAssistant,
two_adapters: None,
enable_bluetooth: None,
install_bleak_catcher,
mock_platform_client_that_raises_on_connect,
) -> None:
"""Ensure the slot gets released on connection exception."""
manager = _get_manager()
hci0_device_advs, cancel_hci0, cancel_hci1 = _generate_scanners_with_fake_devices(
hass
)
# hci0 has 2 slots, hci1 has 1 slot
with patch.object(manager, "shutdown", True):
ble_device = hci0_device_advs["00:00:00:00:00:01"][0]
client = bleak.BleakClient(ble_device)
with pytest.raises(BleakError, match="shutdown"):
await client.connect()
cancel_hci0()
cancel_hci1()