Skip to content

Commit

Permalink
fix: ensure scanner is stopped on cancellation (#36)
Browse files Browse the repository at this point in the history
  • Loading branch information
bdraco committed Apr 17, 2024
1 parent c632e14 commit a21d70a
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 1 deletion.
3 changes: 3 additions & 0 deletions src/habluetooth/scanner.py
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,9 @@ async def _async_start_attempt(self, attempt: int) -> bool:
f"{self.name}: Failed to start Bluetooth: {ex}; "
"Try power cycling the Bluetooth hardware."
) from ex
except BaseException:
await self._async_stop_scanner()
raise

self._log_start_success(attempt)
return True
Expand Down
38 changes: 37 additions & 1 deletion tests/test_scanner.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,17 @@ async def test_dbus_socket_missing_in_container(
"habluetooth.scanner.OriginalBleakScanner.start",
side_effect=FileNotFoundError,
),
patch(
"habluetooth.scanner.OriginalBleakScanner.stop",
) as mock_stop,
pytest.raises(
ScannerStartError,
match="DBus service not found; docker config may be missing",
),
):
scanner = HaScanner(BluetoothScanningMode.ACTIVE, "hci0", "AA:BB:CC:DD:EE:FF")
await scanner.async_start()
assert mock_stop.called
await scanner.async_stop()


Expand All @@ -96,14 +100,38 @@ async def test_dbus_socket_missing(caplog: pytest.LogCaptureFixture) -> None:
"habluetooth.scanner.OriginalBleakScanner.start",
side_effect=FileNotFoundError,
),
patch(
"habluetooth.scanner.OriginalBleakScanner.stop",
) as mock_stop,
pytest.raises(
ScannerStartError,
match="DBus service not found; make sure the DBus socket is available",
),
):
scanner = HaScanner(BluetoothScanningMode.ACTIVE, "hci0", "AA:BB:CC:DD:EE:FF")
await scanner.async_start()
await scanner.async_stop()
assert mock_stop.called
await scanner.async_stop()


@pytest.mark.asyncio
@pytest.mark.skipif("platform.system() != 'Linux'")
async def test_handle_cancellation(caplog: pytest.LogCaptureFixture) -> None:
"""Test cancellation stops."""
with (
patch("habluetooth.scanner.is_docker_env", return_value=False),
patch(
"habluetooth.scanner.OriginalBleakScanner.start",
side_effect=asyncio.CancelledError,
),
patch(
"habluetooth.scanner.OriginalBleakScanner.stop",
) as mock_stop,
):
scanner = HaScanner(BluetoothScanningMode.ACTIVE, "hci0", "AA:BB:CC:DD:EE:FF")
with pytest.raises(asyncio.CancelledError):
await scanner.async_start()
assert mock_stop.called


@pytest.mark.asyncio
Expand All @@ -116,10 +144,14 @@ async def test_dbus_broken_pipe_in_container(caplog: pytest.LogCaptureFixture) -
"habluetooth.scanner.OriginalBleakScanner.start",
side_effect=BrokenPipeError,
),
patch(
"habluetooth.scanner.OriginalBleakScanner.stop",
) as mock_stop,
pytest.raises(ScannerStartError, match="DBus connection broken"),
):
scanner = HaScanner(BluetoothScanningMode.ACTIVE, "hci0", "AA:BB:CC:DD:EE:FF")
await scanner.async_start()
assert mock_stop.called
await scanner.async_stop()


Expand All @@ -133,10 +165,14 @@ async def test_dbus_broken_pipe(caplog: pytest.LogCaptureFixture) -> None:
"habluetooth.scanner.OriginalBleakScanner.start",
side_effect=BrokenPipeError,
),
patch(
"habluetooth.scanner.OriginalBleakScanner.stop",
) as mock_stop,
pytest.raises(ScannerStartError, match="DBus connection broken:"),
):
scanner = HaScanner(BluetoothScanningMode.ACTIVE, "hci0", "AA:BB:CC:DD:EE:FF")
await scanner.async_start()
assert mock_stop.called
await scanner.async_stop()


Expand Down

0 comments on commit a21d70a

Please sign in to comment.