hass-core/tests/components/bluetooth/test_diagnostics.py
J. Nick Koston c798723c27
Fix bluetooth diagnostics on macos (#79680)
* 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
2022-10-06 04:32:29 +02:00

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",
}
],
},
}