From 635c2f3738de1abebe0eed86ff18c8926136583b Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 19 Sep 2022 19:58:18 -0500 Subject: [PATCH] Change bluetooth source to be the address of the adapter on Linux (#78795) --- homeassistant/components/bluetooth/scanner.py | 3 +- tests/components/bluetooth/conftest.py | 5 ++ .../components/bluetooth/test_diagnostics.py | 74 ++++++++++++++++++- 3 files changed, 78 insertions(+), 4 deletions(-) diff --git a/homeassistant/components/bluetooth/scanner.py b/homeassistant/components/bluetooth/scanner.py index f9bfcf7bb79..3f089326eb2 100644 --- a/homeassistant/components/bluetooth/scanner.py +++ b/homeassistant/components/bluetooth/scanner.py @@ -25,6 +25,7 @@ from homeassistant.helpers.event import async_track_time_interval from homeassistant.util.package import is_docker_env from .const import ( + DEFAULT_ADDRESS, SCANNER_WATCHDOG_INTERVAL, SCANNER_WATCHDOG_TIMEOUT, SOURCE_LOCAL, @@ -132,7 +133,7 @@ class HaScanner(BaseHaScanner): self._start_time = 0.0 self._callbacks: list[Callable[[BluetoothServiceInfoBleak], None]] = [] self.name = adapter_human_name(adapter, address) - self.source = self.adapter or SOURCE_LOCAL + self.source = address if address != DEFAULT_ADDRESS else adapter or SOURCE_LOCAL @property def discovered_devices(self) -> list[BLEDevice]: diff --git a/tests/components/bluetooth/conftest.py b/tests/components/bluetooth/conftest.py index 857af1e7eaa..2c0e2e6eb9c 100644 --- a/tests/components/bluetooth/conftest.py +++ b/tests/components/bluetooth/conftest.py @@ -19,6 +19,11 @@ def bluez_dbus_mock(): def macos_adapter(): """Fixture that mocks the macos adapter.""" with patch( + "homeassistant.components.bluetooth.platform.system", return_value="Darwin" + ), patch( + "homeassistant.components.bluetooth.scanner.platform.system", + return_value="Darwin", + ), patch( "homeassistant.components.bluetooth.util.platform.system", return_value="Darwin" ): yield diff --git a/tests/components/bluetooth/test_diagnostics.py b/tests/components/bluetooth/test_diagnostics.py index 9059fcb9ab1..d641cae9c7c 100644 --- a/tests/components/bluetooth/test_diagnostics.py +++ b/tests/components/bluetooth/test_diagnostics.py @@ -6,6 +6,7 @@ from unittest.mock import ANY, patch from bleak.backends.scanner import BLEDevice from homeassistant.components import bluetooth +from homeassistant.components.bluetooth.const import DEFAULT_ADDRESS from tests.common import MockConfigEntry from tests.components.diagnostics import get_diagnostics_for_config_entry @@ -117,7 +118,7 @@ async def test_diagnostics( ], "last_detection": ANY, "name": "hci0 (00:00:00:00:00:01)", - "source": "hci0", + "source": "00:00:00:00:00:01", "start_time": ANY, "type": "HaScanner", }, @@ -128,7 +129,7 @@ async def test_diagnostics( ], "last_detection": ANY, "name": "hci0 (00:00:00:00:00:01)", - "source": "hci0", + "source": "00:00:00:00:00:01", "start_time": ANY, "type": "HaScanner", }, @@ -139,10 +140,77 @@ async def test_diagnostics( ], "last_detection": ANY, "name": "hci1 (00:00:00:00:00:02)", - "source": "hci1", + "source": "00:00:00:00:00:02", "start_time": ANY, "type": "HaScanner", }, ], }, } + + +async def test_diagnostics_macos( + hass, hass_client, mock_bleak_scanner_start, mock_bluetooth_adapters, macos_adapter +): + """Test we can setup and unsetup bluetooth with multiple adapters.""" + # Normally we do not want to patch our classes, but since bleak will import + # a different scanner based on the operating system, we need to patch here + # because we cannot import the scanner class directly without it throwing an + # error if the test is not running on linux since we won't have the correct + # deps installed when testing on MacOS. + + with patch( + "homeassistant.components.bluetooth.scanner.HaScanner.discovered_devices", + [BLEDevice(name="x", rssi=-60, address="44:44:33:11:23:45")], + ), patch( + "homeassistant.components.bluetooth.diagnostics.platform.system", + return_value="Darwin", + ), patch( + "homeassistant.components.bluetooth.diagnostics.get_dbus_managed_objects", + return_value={}, + ): + entry1 = MockConfigEntry( + domain=bluetooth.DOMAIN, + data={}, + title="Core Bluetooth", + unique_id=DEFAULT_ADDRESS, + ) + entry1.add_to_hass(hass) + + assert await hass.config_entries.async_setup(entry1.entry_id) + await hass.async_block_till_done() + + diag = await get_diagnostics_for_config_entry(hass, hass_client, entry1) + assert diag == { + "adapters": { + "Core Bluetooth": { + "address": "00:00:00:00:00:00", + "passive_scan": False, + "sw_version": ANY, + } + }, + "manager": { + "adapters": { + "Core Bluetooth": { + "address": "00:00:00:00:00:00", + "passive_scan": False, + "sw_version": ANY, + } + }, + "connectable_history": [], + "history": [], + "scanners": [ + { + "adapter": "Core Bluetooth", + "discovered_devices": [ + {"address": "44:44:33:11:23:45", "name": "x", "rssi": -60} + ], + "last_detection": ANY, + "name": "Core Bluetooth", + "source": "Core Bluetooth", + "start_time": ANY, + "type": "HaScanner", + } + ], + }, + }