Defer bluetooth scanner watchdog restart if one is already in progress (#80679)

This commit is contained in:
J. Nick Koston 2022-10-20 13:56:20 -05:00 committed by GitHub
parent 5589edd814
commit 03362bec1c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 72 additions and 0 deletions

View File

@ -347,6 +347,12 @@ class HaScanner(BaseHaScanner):
)
if time_since_last_detection < SCANNER_WATCHDOG_TIMEOUT:
return
if self._start_stop_lock.locked():
_LOGGER.debug(
"%s: Scanner is already restarting, deferring restart",
self.name,
)
return
_LOGGER.info(
"%s: Bluetooth scanner has gone quiet for %ss, restarting",
self.name,

View File

@ -1,4 +1,5 @@
"""Tests for the Bluetooth integration scanners."""
import asyncio
from datetime import timedelta
import time
from unittest.mock import MagicMock, patch
@ -487,3 +488,68 @@ async def test_adapter_fails_to_start_and_takes_a_bit_to_init(
assert len(mock_recover_adapter.mock_calls) == 1
assert "Waiting for adapter to initialize" in caplog.text
async def test_restart_takes_longer_than_watchdog_time(hass, one_adapter, caplog):
"""Test we do not try to recover the adapter again if the restart is still in progress."""
release_start_event = asyncio.Event()
called_start = 0
class MockBleakScanner:
async def start(self, *args, **kwargs):
"""Mock Start."""
nonlocal called_start
called_start += 1
if called_start == 1:
return
await release_start_event.wait()
async def stop(self, *args, **kwargs):
"""Mock Start."""
@property
def discovered_devices(self):
"""Mock discovered_devices."""
return []
def register_detection_callback(self, callback: AdvertisementDataCallback):
"""Mock Register Detection Callback."""
scanner = MockBleakScanner()
start_time_monotonic = time.monotonic()
with patch(
"homeassistant.components.bluetooth.scanner.ADAPTER_INIT_TIME",
0,
), patch(
"homeassistant.components.bluetooth.scanner.MONOTONIC_TIME",
return_value=start_time_monotonic,
), patch(
"homeassistant.components.bluetooth.scanner.OriginalBleakScanner",
return_value=scanner,
), patch(
"homeassistant.components.bluetooth.util.recover_adapter", return_value=True
):
await async_setup_with_one_adapter(hass)
assert called_start == 1
# Now force a recover adapter 2x
for _ in range(2):
with patch(
"homeassistant.components.bluetooth.scanner.MONOTONIC_TIME",
return_value=start_time_monotonic
+ SCANNER_WATCHDOG_TIMEOUT
+ SCANNER_WATCHDOG_INTERVAL.total_seconds(),
):
async_fire_time_changed(
hass, dt_util.utcnow() + SCANNER_WATCHDOG_INTERVAL
)
await asyncio.sleep(0)
# Now release the start event
release_start_event.set()
await hass.async_block_till_done()
assert "already restarting" in caplog.text