* Fix bluetooth diagnostics on macos The pyobjc objects cannot be pickled which cases dataclasses asdict to raise an exception when trying to do the deepcopy We now implement our own as_dict to avoid this problem * add cover
250 lines
9.6 KiB
Python
250 lines
9.6 KiB
Python
"""Test bluetooth diagnostics."""
|
|
|
|
|
|
from unittest.mock import ANY, patch
|
|
|
|
from bleak.backends.scanner import AdvertisementData, BLEDevice
|
|
|
|
from homeassistant.components import bluetooth
|
|
from homeassistant.components.bluetooth.const import DEFAULT_ADDRESS
|
|
|
|
from . import inject_advertisement
|
|
|
|
from tests.common import MockConfigEntry
|
|
from tests.components.diagnostics import get_diagnostics_for_config_entry
|
|
|
|
|
|
async def test_diagnostics(
|
|
hass, hass_client, mock_bleak_scanner_start, enable_bluetooth, two_adapters
|
|
):
|
|
"""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="Linux",
|
|
), patch(
|
|
"homeassistant.components.bluetooth.diagnostics.get_dbus_managed_objects",
|
|
return_value={
|
|
"org.bluez": {
|
|
"/org/bluez/hci0": {
|
|
"org.bluez.Adapter1": {
|
|
"Name": "BlueZ 5.63",
|
|
"Alias": "BlueZ 5.63",
|
|
"Modalias": "usb:v1D6Bp0246d0540",
|
|
"Discovering": False,
|
|
},
|
|
"org.bluez.AdvertisementMonitorManager1": {
|
|
"SupportedMonitorTypes": ["or_patterns"],
|
|
"SupportedFeatures": [],
|
|
},
|
|
}
|
|
}
|
|
},
|
|
):
|
|
entry1 = MockConfigEntry(
|
|
domain=bluetooth.DOMAIN, data={}, unique_id="00:00:00:00:00:01"
|
|
)
|
|
entry1.add_to_hass(hass)
|
|
|
|
entry2 = MockConfigEntry(
|
|
domain=bluetooth.DOMAIN, data={}, unique_id="00:00:00:00:00:02"
|
|
)
|
|
entry2.add_to_hass(hass)
|
|
|
|
assert await hass.config_entries.async_setup(entry1.entry_id)
|
|
await hass.async_block_till_done()
|
|
assert await hass.config_entries.async_setup(entry2.entry_id)
|
|
await hass.async_block_till_done()
|
|
|
|
diag = await get_diagnostics_for_config_entry(hass, hass_client, entry1)
|
|
assert diag == {
|
|
"adapters": {
|
|
"hci0": {
|
|
"address": "00:00:00:00:00:01",
|
|
"hw_version": "usbid:1234",
|
|
"passive_scan": False,
|
|
"sw_version": "BlueZ 4.63",
|
|
},
|
|
"hci1": {
|
|
"address": "00:00:00:00:00:02",
|
|
"hw_version": "usbid:1234",
|
|
"passive_scan": True,
|
|
"sw_version": "BlueZ 4.63",
|
|
},
|
|
},
|
|
"dbus": {
|
|
"org.bluez": {
|
|
"/org/bluez/hci0": {
|
|
"org.bluez.Adapter1": {
|
|
"Alias": "BlueZ " "5.63",
|
|
"Discovering": False,
|
|
"Modalias": "usb:v1D6Bp0246d0540",
|
|
"Name": "BlueZ " "5.63",
|
|
},
|
|
"org.bluez.AdvertisementMonitorManager1": {
|
|
"SupportedFeatures": [],
|
|
"SupportedMonitorTypes": ["or_patterns"],
|
|
},
|
|
}
|
|
}
|
|
},
|
|
"manager": {
|
|
"adapters": {
|
|
"hci0": {
|
|
"address": "00:00:00:00:00:01",
|
|
"hw_version": "usbid:1234",
|
|
"passive_scan": False,
|
|
"sw_version": "BlueZ 4.63",
|
|
},
|
|
"hci1": {
|
|
"address": "00:00:00:00:00:02",
|
|
"hw_version": "usbid:1234",
|
|
"passive_scan": True,
|
|
"sw_version": "BlueZ 4.63",
|
|
},
|
|
},
|
|
"connectable_history": [],
|
|
"history": [],
|
|
"scanners": [
|
|
{
|
|
"adapter": "hci0",
|
|
"discovered_devices": [
|
|
{"address": "44:44:33:11:23:45", "name": "x", "rssi": -60}
|
|
],
|
|
"last_detection": ANY,
|
|
"name": "hci0 (00:00:00:00:00:01)",
|
|
"source": "00:00:00:00:00:01",
|
|
"start_time": ANY,
|
|
"type": "HaScanner",
|
|
},
|
|
{
|
|
"adapter": "hci0",
|
|
"discovered_devices": [
|
|
{"address": "44:44:33:11:23:45", "name": "x", "rssi": -60}
|
|
],
|
|
"last_detection": ANY,
|
|
"name": "hci0 (00:00:00:00:00:01)",
|
|
"source": "00:00:00:00:00:01",
|
|
"start_time": ANY,
|
|
"type": "HaScanner",
|
|
},
|
|
{
|
|
"adapter": "hci1",
|
|
"discovered_devices": [
|
|
{"address": "44:44:33:11:23:45", "name": "x", "rssi": -60}
|
|
],
|
|
"last_detection": ANY,
|
|
"name": "hci1 (00:00:00:00:00:02)",
|
|
"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.
|
|
switchbot_device = BLEDevice("44:44:33:11:23:45", "wohand")
|
|
switchbot_adv = AdvertisementData(
|
|
local_name="wohand", service_uuids=[], manufacturer_data={1: b"\x01"}
|
|
)
|
|
|
|
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()
|
|
|
|
inject_advertisement(hass, switchbot_device, switchbot_adv)
|
|
|
|
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": [
|
|
{
|
|
"address": "44:44:33:11:23:45",
|
|
"advertisement": ANY,
|
|
"connectable": True,
|
|
"manufacturer_data": ANY,
|
|
"name": "wohand",
|
|
"rssi": 0,
|
|
"service_data": {},
|
|
"service_uuids": [],
|
|
"source": "local",
|
|
"time": ANY,
|
|
}
|
|
],
|
|
"history": [
|
|
{
|
|
"address": "44:44:33:11:23:45",
|
|
"advertisement": ANY,
|
|
"connectable": True,
|
|
"manufacturer_data": ANY,
|
|
"name": "wohand",
|
|
"rssi": 0,
|
|
"service_data": {},
|
|
"service_uuids": [],
|
|
"source": "local",
|
|
"time": ANY,
|
|
}
|
|
],
|
|
"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",
|
|
}
|
|
],
|
|
},
|
|
}
|