From a1bc9a239f1613a4f51fcd87217eb7034b30e563 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Tue, 5 Dec 2023 13:07:51 -1000 Subject: [PATCH] fix patching time --- .../components/bluetooth/__init__.py | 3 +- homeassistant/components/bluetooth/manager.py | 5 +- homeassistant/components/bluetooth/models.py | 5 +- tests/components/bluetooth/__init__.py | 21 ++++- .../bluetooth/test_advertisement_tracker.py | 47 +++++------ .../components/bluetooth/test_base_scanner.py | 49 +++-------- tests/components/bluetooth/test_manager.py | 21 +++-- .../test_passive_update_coordinator.py | 18 +++-- .../test_passive_update_processor.py | 11 ++- tests/components/bluetooth/test_scanner.py | 81 ++++++++----------- tests/components/bthome/test_binary_sensor.py | 17 +--- tests/components/bthome/test_sensor.py | 17 +--- tests/components/govee_ble/test_sensor.py | 4 +- tests/components/oralb/test_sensor.py | 4 +- .../components/private_ble_device/__init__.py | 2 +- .../components/qingping/test_binary_sensor.py | 2 +- tests/components/qingping/test_sensor.py | 2 +- tests/components/sensorpush/test_sensor.py | 2 +- .../xiaomi_ble/test_binary_sensor.py | 6 +- tests/components/xiaomi_ble/test_sensor.py | 6 +- 20 files changed, 129 insertions(+), 194 deletions(-) diff --git a/homeassistant/components/bluetooth/__init__.py b/homeassistant/components/bluetooth/__init__.py index 2873479de58..4a53347e826 100644 --- a/homeassistant/components/bluetooth/__init__.py +++ b/homeassistant/components/bluetooth/__init__.py @@ -21,6 +21,7 @@ from bluetooth_adapters import ( adapter_unique_name, get_adapters, ) +from bluetooth_data_tools import monotonic_time_coarse as MONOTONIC_TIME from habluetooth import ( BaseHaScanner, BluetoothScannerDevice, @@ -80,7 +81,7 @@ from .const import ( LINUX_FIRMWARE_LOAD_FALLBACK_SECONDS, SOURCE_LOCAL, ) -from .manager import MONOTONIC_TIME, HomeAssistantBluetoothManager +from .manager import HomeAssistantBluetoothManager from .match import BluetoothCallbackMatcher, IntegrationMatcher from .models import BluetoothCallback, BluetoothChange from .storage import BluetoothStorage diff --git a/homeassistant/components/bluetooth/manager.py b/homeassistant/components/bluetooth/manager.py index f1ae2878bc5..d0a83c97ac7 100644 --- a/homeassistant/components/bluetooth/manager.py +++ b/homeassistant/components/bluetooth/manager.py @@ -4,11 +4,10 @@ from __future__ import annotations from collections.abc import Callable, Iterable import itertools import logging -from typing import Final from bleak_retry_connector import BleakSlotManager from bluetooth_adapters import BluetoothAdapters -from habluetooth import BluetoothManager, manager +from habluetooth import BluetoothManager from homeassistant import config_entries from homeassistant.const import EVENT_LOGGING_CHANGED @@ -34,8 +33,6 @@ from .models import BluetoothCallback, BluetoothChange, BluetoothServiceInfoBlea from .storage import BluetoothStorage from .util import async_load_history_from_system -MONOTONIC_TIME: Final = manager.MONOTONIC_TIME - _LOGGER = logging.getLogger(__name__) diff --git a/homeassistant/components/bluetooth/models.py b/homeassistant/components/bluetooth/models.py index a35c5be6daf..20e18661907 100644 --- a/homeassistant/components/bluetooth/models.py +++ b/homeassistant/components/bluetooth/models.py @@ -3,9 +3,8 @@ from __future__ import annotations from collections.abc import Callable from enum import Enum -from typing import TYPE_CHECKING, Final +from typing import TYPE_CHECKING -from bluetooth_data_tools import monotonic_time_coarse from home_assistant_bluetooth import BluetoothServiceInfoBleak if TYPE_CHECKING: @@ -14,8 +13,6 @@ if TYPE_CHECKING: MANAGER: BluetoothManager | None = None -MONOTONIC_TIME: Final = monotonic_time_coarse - BluetoothChange = Enum("BluetoothChange", "ADVERTISEMENT") BluetoothCallback = Callable[[BluetoothServiceInfoBleak, BluetoothChange], None] diff --git a/tests/components/bluetooth/__init__.py b/tests/components/bluetooth/__init__.py index fdb59117d08..5ad4b5a6c31 100644 --- a/tests/components/bluetooth/__init__.py +++ b/tests/components/bluetooth/__init__.py @@ -5,12 +5,12 @@ from contextlib import contextmanager import itertools import time from typing import Any -from unittest.mock import MagicMock +from unittest.mock import MagicMock, patch from bleak import BleakClient from bleak.backends.scanner import AdvertisementData, BLEDevice from bluetooth_adapters import DEFAULT_ADDRESS -from habluetooth import BaseHaScanner, BluetoothManager +from habluetooth import BaseHaScanner, BluetoothManager, get_manager from homeassistant.components.bluetooth import ( DOMAIN, @@ -18,7 +18,6 @@ from homeassistant.components.bluetooth import ( BluetoothServiceInfo, BluetoothServiceInfoBleak, async_get_advertisement_callback, - models, ) from homeassistant.core import HomeAssistant from homeassistant.setup import async_setup_component @@ -36,6 +35,7 @@ __all__ = ( "generate_advertisement_data", "generate_ble_device", "MockBleakClient", + "patch_bluetooth_time", ) ADVERTISEMENT_DATA_DEFAULTS = { @@ -55,6 +55,19 @@ BLE_DEVICE_DEFAULTS = { } +@contextmanager +def patch_bluetooth_time(mock_time: float) -> None: + """Patch the bluetooth time.""" + with patch( + "homeassistant.components.bluetooth.MONOTONIC_TIME", return_value=mock_time + ), patch( + "habluetooth.base_scanner.monotonic_time_coarse", return_value=mock_time + ), patch( + "habluetooth.manager.monotonic_time_coarse", return_value=mock_time + ), patch("habluetooth.scanner.monotonic_time_coarse", return_value=mock_time): + yield + + def generate_advertisement_data(**kwargs: Any) -> AdvertisementData: """Generate advertisement data with defaults.""" new = kwargs.copy() @@ -87,7 +100,7 @@ def generate_ble_device( def _get_manager() -> BluetoothManager: """Return the bluetooth manager.""" - return models.MANAGER + return get_manager() def inject_advertisement( diff --git a/tests/components/bluetooth/test_advertisement_tracker.py b/tests/components/bluetooth/test_advertisement_tracker.py index 8681287baa2..190b05e60e8 100644 --- a/tests/components/bluetooth/test_advertisement_tracker.py +++ b/tests/components/bluetooth/test_advertisement_tracker.py @@ -1,7 +1,6 @@ """Tests for the Bluetooth integration advertisement tracking.""" from datetime import timedelta import time -from unittest.mock import patch from habluetooth.advertisement_tracker import ADVERTISING_TIMES_NEEDED import pytest @@ -25,6 +24,7 @@ from . import ( generate_ble_device, inject_advertisement_with_time_and_source, inject_advertisement_with_time_and_source_connectable, + patch_bluetooth_time, ) from tests.common import async_fire_time_changed @@ -70,9 +70,8 @@ async def test_advertisment_interval_shorter_than_adapter_stack_timeout( ) monotonic_now = start_monotonic_time + ((ADVERTISING_TIMES_NEEDED - 1) * 2) - with patch( - "homeassistant.components.bluetooth.manager.MONOTONIC_TIME", - return_value=monotonic_now + UNAVAILABLE_TRACK_SECONDS, + with patch_bluetooth_time( + monotonic_now + UNAVAILABLE_TRACK_SECONDS, ): async_fire_time_changed( hass, dt_util.utcnow() + timedelta(seconds=UNAVAILABLE_TRACK_SECONDS) @@ -123,9 +122,8 @@ async def test_advertisment_interval_longer_than_adapter_stack_timeout_connectab monotonic_now = start_monotonic_time + ( (ADVERTISING_TIMES_NEEDED - 1) * ONE_HOUR_SECONDS ) - with patch( - "homeassistant.components.bluetooth.manager.MONOTONIC_TIME", - return_value=monotonic_now + UNAVAILABLE_TRACK_SECONDS, + with patch_bluetooth_time( + monotonic_now + UNAVAILABLE_TRACK_SECONDS, ): async_fire_time_changed( hass, dt_util.utcnow() + timedelta(seconds=UNAVAILABLE_TRACK_SECONDS) @@ -189,9 +187,8 @@ async def test_advertisment_interval_longer_than_adapter_stack_timeout_adapter_c monotonic_now = start_monotonic_time + ( (ADVERTISING_TIMES_NEEDED - 1) * ONE_HOUR_SECONDS ) - with patch( - "homeassistant.components.bluetooth.manager.MONOTONIC_TIME", - return_value=monotonic_now + UNAVAILABLE_TRACK_SECONDS, + with patch_bluetooth_time( + monotonic_now + UNAVAILABLE_TRACK_SECONDS, ): async_fire_time_changed( hass, dt_util.utcnow() + timedelta(seconds=UNAVAILABLE_TRACK_SECONDS) @@ -245,9 +242,8 @@ async def test_advertisment_interval_longer_than_adapter_stack_timeout_not_conne monotonic_now = start_monotonic_time + ( (ADVERTISING_TIMES_NEEDED - 1) * ONE_HOUR_SECONDS ) - with patch( - "homeassistant.components.bluetooth.manager.MONOTONIC_TIME", - return_value=monotonic_now + UNAVAILABLE_TRACK_SECONDS, + with patch_bluetooth_time( + monotonic_now + UNAVAILABLE_TRACK_SECONDS, ): async_fire_time_changed( hass, dt_util.utcnow() + timedelta(seconds=UNAVAILABLE_TRACK_SECONDS) @@ -321,9 +317,8 @@ async def test_advertisment_interval_shorter_than_adapter_stack_timeout_adapter_ monotonic_now = start_monotonic_time + ( (ADVERTISING_TIMES_NEEDED - 1) * ONE_HOUR_SECONDS ) - with patch( - "homeassistant.components.bluetooth.manager.MONOTONIC_TIME", - return_value=monotonic_now + UNAVAILABLE_TRACK_SECONDS, + with patch_bluetooth_time( + monotonic_now + UNAVAILABLE_TRACK_SECONDS, ): async_fire_time_changed( hass, dt_util.utcnow() + timedelta(seconds=UNAVAILABLE_TRACK_SECONDS) @@ -402,9 +397,8 @@ async def test_advertisment_interval_longer_than_adapter_stack_timeout_adapter_c monotonic_now = start_monotonic_time + ( (ADVERTISING_TIMES_NEEDED - 1) * ONE_HOUR_SECONDS ) - with patch( - "homeassistant.components.bluetooth.manager.MONOTONIC_TIME", - return_value=monotonic_now + UNAVAILABLE_TRACK_SECONDS, + with patch_bluetooth_time( + monotonic_now + UNAVAILABLE_TRACK_SECONDS, ): async_fire_time_changed( hass, dt_util.utcnow() + timedelta(seconds=UNAVAILABLE_TRACK_SECONDS) @@ -415,9 +409,8 @@ async def test_advertisment_interval_longer_than_adapter_stack_timeout_adapter_c cancel_scanner() # Now that the scanner is gone we should go back to the stack default timeout - with patch( - "homeassistant.components.bluetooth.manager.MONOTONIC_TIME", - return_value=monotonic_now + UNAVAILABLE_TRACK_SECONDS, + with patch_bluetooth_time( + monotonic_now + UNAVAILABLE_TRACK_SECONDS, ): async_fire_time_changed( hass, dt_util.utcnow() + timedelta(seconds=UNAVAILABLE_TRACK_SECONDS) @@ -427,9 +420,8 @@ async def test_advertisment_interval_longer_than_adapter_stack_timeout_adapter_c assert switchbot_device_went_unavailable is False # Now that the scanner is gone we should go back to the stack default timeout - with patch( - "homeassistant.components.bluetooth.manager.MONOTONIC_TIME", - return_value=monotonic_now + UNAVAILABLE_TRACK_SECONDS, + with patch_bluetooth_time( + monotonic_now + UNAVAILABLE_TRACK_SECONDS, ): async_fire_time_changed( hass, @@ -484,9 +476,8 @@ async def test_advertisment_interval_longer_increasing_than_adapter_stack_timeou ) monotonic_now = start_monotonic_time + UNAVAILABLE_TRACK_SECONDS + 1 - with patch( - "homeassistant.components.bluetooth.manager.MONOTONIC_TIME", - return_value=monotonic_now + UNAVAILABLE_TRACK_SECONDS, + with patch_bluetooth_time( + monotonic_now + UNAVAILABLE_TRACK_SECONDS, ): async_fire_time_changed( hass, dt_util.utcnow() + timedelta(seconds=UNAVAILABLE_TRACK_SECONDS) diff --git a/tests/components/bluetooth/test_base_scanner.py b/tests/components/bluetooth/test_base_scanner.py index 1228a4efc5b..bda976959fc 100644 --- a/tests/components/bluetooth/test_base_scanner.py +++ b/tests/components/bluetooth/test_base_scanner.py @@ -35,6 +35,7 @@ from . import ( _get_manager, generate_advertisement_data, generate_ble_device, + patch_bluetooth_time, ) from tests.common import async_fire_time_changed, load_fixture @@ -212,10 +213,7 @@ async def test_remote_scanner_expires_connectable( expire_utc = dt_util.utcnow() + timedelta( seconds=CONNECTABLE_FALLBACK_MAXIMUM_STALE_ADVERTISEMENT_SECONDS + 1 ) - with patch( - "habluetooth.base_scanner.MONOTONIC_TIME", - return_value=expire_monotonic, - ): + with patch_bluetooth_time(expire_monotonic): async_fire_time_changed(hass, expire_utc) await hass.async_block_till_done() @@ -295,10 +293,7 @@ async def test_remote_scanner_expires_non_connectable( expire_utc = dt_util.utcnow() + timedelta( seconds=CONNECTABLE_FALLBACK_MAXIMUM_STALE_ADVERTISEMENT_SECONDS + 1 ) - with patch( - "habluetooth.base_scanner.MONOTONIC_TIME", - return_value=expire_monotonic, - ): + with patch_bluetooth_time(expire_monotonic): async_fire_time_changed(hass, expire_utc) await hass.async_block_till_done() @@ -311,10 +306,7 @@ async def test_remote_scanner_expires_non_connectable( expire_utc = dt_util.utcnow() + timedelta( seconds=FALLBACK_MAXIMUM_STALE_ADVERTISEMENT_SECONDS + 1 ) - with patch( - "habluetooth.base_scanner.MONOTONIC_TIME", - return_value=expire_monotonic, - ): + with patch_bluetooth_time(expire_monotonic): async_fire_time_changed(hass, expire_utc) await hass.async_block_till_done() @@ -512,10 +504,7 @@ async def test_device_with_ten_minute_advertising_interval( connectable=False, ) - with patch( - "habluetooth.base_scanner.MONOTONIC_TIME", - return_value=new_time, - ): + with patch_bluetooth_time(new_time): scanner.inject_advertisement(bparasite_device, bparasite_device_adv) original_device = scanner.discovered_devices_and_advertisement_data[ @@ -525,10 +514,7 @@ async def test_device_with_ten_minute_advertising_interval( for _ in range(1, 20): new_time += advertising_interval - with patch( - "habluetooth.base_scanner.MONOTONIC_TIME", - return_value=new_time, - ): + with patch_bluetooth_time(new_time): scanner.inject_advertisement(bparasite_device, bparasite_device_adv) # Make sure the BLEDevice object gets updated @@ -543,10 +529,7 @@ async def test_device_with_ten_minute_advertising_interval( bluetooth.async_address_present(hass, bparasite_device.address, False) is True ) assert bparasite_device_went_unavailable is False - with patch( - "homeassistant.components.bluetooth.manager.MONOTONIC_TIME", - return_value=new_time, - ): + with patch_bluetooth_time(new_time): async_fire_time_changed(hass, dt_util.utcnow() + timedelta(seconds=future_time)) await hass.async_block_till_done() @@ -556,13 +539,7 @@ async def test_device_with_ten_minute_advertising_interval( future_time + advertising_interval + TRACKER_BUFFERING_WOBBLE_SECONDS + 1 ) - with patch( - "homeassistant.components.bluetooth.manager.MONOTONIC_TIME", - return_value=missed_advertisement_future_time, - ), patch( - "habluetooth.base_scanner.MONOTONIC_TIME", - return_value=missed_advertisement_future_time, - ): + with patch_bluetooth_time(missed_advertisement_future_time): # Fire once for the scanner to expire the device async_fire_time_changed( hass, dt_util.utcnow() + timedelta(seconds=UNAVAILABLE_TRACK_SECONDS) @@ -626,10 +603,7 @@ async def test_scanner_stops_responding( + SCANNER_WATCHDOG_INTERVAL.total_seconds() ) # We hit the timer with no detections, so we reset the adapter and restart the scanner - with patch( - "habluetooth.base_scanner.MONOTONIC_TIME", - return_value=failure_reached_time, - ): + with patch_bluetooth_time(failure_reached_time): async_fire_time_changed(hass, dt_util.utcnow() + SCANNER_WATCHDOG_INTERVAL) await hass.async_block_till_done() @@ -650,10 +624,7 @@ async def test_scanner_stops_responding( failure_reached_time += 1 - with patch( - "habluetooth.base_scanner.MONOTONIC_TIME", - return_value=failure_reached_time, - ): + with patch_bluetooth_time(failure_reached_time): scanner.inject_advertisement(bparasite_device, bparasite_device_adv) # As soon as we get a detection, we know the scanner is working again diff --git a/tests/components/bluetooth/test_manager.py b/tests/components/bluetooth/test_manager.py index a3e557d7cd0..33683977ef0 100644 --- a/tests/components/bluetooth/test_manager.py +++ b/tests/components/bluetooth/test_manager.py @@ -46,6 +46,7 @@ from . import ( inject_advertisement_with_source, inject_advertisement_with_time_and_source, inject_advertisement_with_time_and_source_connectable, + patch_bluetooth_time, ) from tests.common import async_fire_time_changed, load_fixture @@ -960,9 +961,8 @@ async def test_goes_unavailable_dismisses_discovery_and_makes_discoverable( return_value=[{"flow_id": "mock_flow_id"}], ) as mock_async_progress_by_init_data_type, patch.object( hass.config_entries.flow, "async_abort" - ) as mock_async_abort, patch( - "homeassistant.components.bluetooth.manager.MONOTONIC_TIME", - return_value=monotonic_now + FALLBACK_MAXIMUM_STALE_ADVERTISEMENT_SECONDS, + ) as mock_async_abort, patch_bluetooth_time( + monotonic_now + FALLBACK_MAXIMUM_STALE_ADVERTISEMENT_SECONDS, ): async_fire_time_changed( hass, dt_util.utcnow() + timedelta(seconds=UNAVAILABLE_TRACK_SECONDS) @@ -1103,9 +1103,8 @@ async def test_set_fallback_interval_small( ) monotonic_now = start_monotonic_time + 2 - with patch( - "homeassistant.components.bluetooth.manager.MONOTONIC_TIME", - return_value=monotonic_now + UNAVAILABLE_TRACK_SECONDS, + with patch_bluetooth_time( + monotonic_now + UNAVAILABLE_TRACK_SECONDS, ): async_fire_time_changed( hass, dt_util.utcnow() + timedelta(seconds=UNAVAILABLE_TRACK_SECONDS) @@ -1168,9 +1167,8 @@ async def test_set_fallback_interval_big( # Check that device hasn't expired after a day monotonic_now = start_monotonic_time + 86400 - with patch( - "homeassistant.components.bluetooth.manager.MONOTONIC_TIME", - return_value=monotonic_now + UNAVAILABLE_TRACK_SECONDS, + with patch_bluetooth_time( + monotonic_now + UNAVAILABLE_TRACK_SECONDS, ): async_fire_time_changed( hass, dt_util.utcnow() + timedelta(seconds=UNAVAILABLE_TRACK_SECONDS) @@ -1182,9 +1180,8 @@ async def test_set_fallback_interval_big( # Try again after it has expired monotonic_now = start_monotonic_time + 604800 - with patch( - "homeassistant.components.bluetooth.manager.MONOTONIC_TIME", - return_value=monotonic_now + UNAVAILABLE_TRACK_SECONDS, + with patch_bluetooth_time( + monotonic_now + UNAVAILABLE_TRACK_SECONDS, ): async_fire_time_changed( hass, dt_util.utcnow() + timedelta(seconds=UNAVAILABLE_TRACK_SECONDS) diff --git a/tests/components/bluetooth/test_passive_update_coordinator.py b/tests/components/bluetooth/test_passive_update_coordinator.py index 86f0ee4b5de..b6e50ebc565 100644 --- a/tests/components/bluetooth/test_passive_update_coordinator.py +++ b/tests/components/bluetooth/test_passive_update_coordinator.py @@ -22,7 +22,11 @@ from homeassistant.helpers.service_info.bluetooth import BluetoothServiceInfo from homeassistant.setup import async_setup_component from homeassistant.util import dt as dt_util -from . import inject_bluetooth_service_info, patch_all_discovered_devices +from . import ( + inject_bluetooth_service_info, + patch_all_discovered_devices, + patch_bluetooth_time, +) from tests.common import async_fire_time_changed @@ -159,10 +163,9 @@ async def test_unavailable_callbacks_mark_the_coordinator_unavailable( monotonic_now = start_monotonic + FALLBACK_MAXIMUM_STALE_ADVERTISEMENT_SECONDS + 1 - with patch( - "homeassistant.components.bluetooth.manager.MONOTONIC_TIME", - return_value=monotonic_now, - ), patch_all_discovered_devices([MagicMock(address="44:44:33:11:23:45")]): + with patch_bluetooth_time(monotonic_now), patch_all_discovered_devices( + [MagicMock(address="44:44:33:11:23:45")] + ): async_fire_time_changed( hass, dt_util.utcnow() @@ -176,9 +179,8 @@ async def test_unavailable_callbacks_mark_the_coordinator_unavailable( monotonic_now = start_monotonic + FALLBACK_MAXIMUM_STALE_ADVERTISEMENT_SECONDS + 2 - with patch( - "homeassistant.components.bluetooth.manager.MONOTONIC_TIME", - return_value=monotonic_now, + with patch_bluetooth_time( + monotonic_now, ), patch_all_discovered_devices([MagicMock(address="44:44:33:11:23:45")]): async_fire_time_changed( hass, diff --git a/tests/components/bluetooth/test_passive_update_processor.py b/tests/components/bluetooth/test_passive_update_processor.py index 8cc76e01d8c..345c4b62b7e 100644 --- a/tests/components/bluetooth/test_passive_update_processor.py +++ b/tests/components/bluetooth/test_passive_update_processor.py @@ -48,6 +48,7 @@ from . import ( inject_bluetooth_service_info, inject_bluetooth_service_info_bleak, patch_all_discovered_devices, + patch_bluetooth_time, ) from tests.common import ( @@ -471,9 +472,8 @@ async def test_unavailable_after_no_data( assert processor.available is True monotonic_now = start_monotonic + FALLBACK_MAXIMUM_STALE_ADVERTISEMENT_SECONDS + 1 - with patch( - "homeassistant.components.bluetooth.manager.MONOTONIC_TIME", - return_value=monotonic_now, + with patch_bluetooth_time( + monotonic_now, ), patch_all_discovered_devices([MagicMock(address="44:44:33:11:23:45")]): async_fire_time_changed( hass, dt_util.utcnow() + timedelta(seconds=UNAVAILABLE_TRACK_SECONDS) @@ -490,9 +490,8 @@ async def test_unavailable_after_no_data( monotonic_now = start_monotonic + FALLBACK_MAXIMUM_STALE_ADVERTISEMENT_SECONDS + 2 - with patch( - "homeassistant.components.bluetooth.manager.MONOTONIC_TIME", - return_value=monotonic_now, + with patch_bluetooth_time( + monotonic_now, ), patch_all_discovered_devices([MagicMock(address="44:44:33:11:23:45")]): async_fire_time_changed( hass, dt_util.utcnow() + timedelta(seconds=UNAVAILABLE_TRACK_SECONDS) diff --git a/tests/components/bluetooth/test_scanner.py b/tests/components/bluetooth/test_scanner.py index c33bfd6db84..7673acb80dc 100644 --- a/tests/components/bluetooth/test_scanner.py +++ b/tests/components/bluetooth/test_scanner.py @@ -25,6 +25,7 @@ from . import ( async_setup_with_one_adapter, generate_advertisement_data, generate_ble_device, + patch_bluetooth_time, ) from tests.common import MockConfigEntry, async_fire_time_changed @@ -226,9 +227,8 @@ async def test_recovery_from_dbus_restart( mock_discovered = [MagicMock()] # Ensure we don't restart the scanner if we don't need to - with patch( - "habluetooth.base_scanner.MONOTONIC_TIME", - return_value=start_time_monotonic + 10, + with patch_bluetooth_time( + start_time_monotonic + 10, ): async_fire_time_changed(hass, dt_util.utcnow() + SCANNER_WATCHDOG_INTERVAL) await hass.async_block_till_done() @@ -236,9 +236,8 @@ async def test_recovery_from_dbus_restart( assert called_start == 1 # Fire a callback to reset the timer - with patch( - "habluetooth.base_scanner.MONOTONIC_TIME", - return_value=start_time_monotonic, + with patch_bluetooth_time( + start_time_monotonic, ): _callback( generate_ble_device("44:44:33:11:23:42", "any_name"), @@ -246,9 +245,8 @@ async def test_recovery_from_dbus_restart( ) # Ensure we don't restart the scanner if we don't need to - with patch( - "habluetooth.base_scanner.MONOTONIC_TIME", - return_value=start_time_monotonic + 20, + with patch_bluetooth_time( + start_time_monotonic + 20, ): async_fire_time_changed(hass, dt_util.utcnow() + SCANNER_WATCHDOG_INTERVAL) await hass.async_block_till_done() @@ -256,9 +254,8 @@ async def test_recovery_from_dbus_restart( assert called_start == 1 # We hit the timer, so we restart the scanner - with patch( - "habluetooth.base_scanner.MONOTONIC_TIME", - return_value=start_time_monotonic + SCANNER_WATCHDOG_TIMEOUT + 20, + with patch_bluetooth_time( + start_time_monotonic + SCANNER_WATCHDOG_TIMEOUT + 20, ): async_fire_time_changed( hass, dt_util.utcnow() + SCANNER_WATCHDOG_INTERVAL + timedelta(seconds=20) @@ -301,9 +298,8 @@ async def test_adapter_recovery(hass: HomeAssistant, one_adapter: None) -> None: scanner = MockBleakScanner() start_time_monotonic = time.monotonic() - with patch( - "habluetooth.base_scanner.MONOTONIC_TIME", - return_value=start_time_monotonic, + with patch_bluetooth_time( + start_time_monotonic, ), patch( "habluetooth.scanner.OriginalBleakScanner", return_value=scanner, @@ -316,9 +312,8 @@ async def test_adapter_recovery(hass: HomeAssistant, one_adapter: None) -> None: mock_discovered = [MagicMock()] # Ensure we don't restart the scanner if we don't need to - with patch( - "habluetooth.base_scanner.MONOTONIC_TIME", - return_value=start_time_monotonic + 10, + with patch_bluetooth_time( + start_time_monotonic + 10, ): async_fire_time_changed(hass, dt_util.utcnow() + SCANNER_WATCHDOG_INTERVAL) await hass.async_block_till_done() @@ -326,9 +321,8 @@ async def test_adapter_recovery(hass: HomeAssistant, one_adapter: None) -> None: assert called_start == 1 # Ensure we don't restart the scanner if we don't need to - with patch( - "habluetooth.base_scanner.MONOTONIC_TIME", - return_value=start_time_monotonic + 20, + with patch_bluetooth_time( + start_time_monotonic + 20, ): async_fire_time_changed(hass, dt_util.utcnow() + SCANNER_WATCHDOG_INTERVAL) await hass.async_block_till_done() @@ -336,9 +330,8 @@ async def test_adapter_recovery(hass: HomeAssistant, one_adapter: None) -> None: assert called_start == 1 # We hit the timer with no detections, so we reset the adapter and restart the scanner - with patch( - "habluetooth.base_scanner.MONOTONIC_TIME", - return_value=start_time_monotonic + with patch_bluetooth_time( + start_time_monotonic + SCANNER_WATCHDOG_TIMEOUT + SCANNER_WATCHDOG_INTERVAL.total_seconds(), ), patch( @@ -390,9 +383,8 @@ async def test_adapter_scanner_fails_to_start_first_time( scanner = MockBleakScanner() start_time_monotonic = time.monotonic() - with patch( - "habluetooth.base_scanner.MONOTONIC_TIME", - return_value=start_time_monotonic, + with patch_bluetooth_time( + start_time_monotonic, ), patch( "habluetooth.scanner.OriginalBleakScanner", return_value=scanner, @@ -405,9 +397,8 @@ async def test_adapter_scanner_fails_to_start_first_time( mock_discovered = [MagicMock()] # Ensure we don't restart the scanner if we don't need to - with patch( - "habluetooth.base_scanner.MONOTONIC_TIME", - return_value=start_time_monotonic + 10, + with patch_bluetooth_time( + start_time_monotonic + 10, ): async_fire_time_changed(hass, dt_util.utcnow() + SCANNER_WATCHDOG_INTERVAL) await hass.async_block_till_done() @@ -415,9 +406,8 @@ async def test_adapter_scanner_fails_to_start_first_time( assert called_start == 1 # Ensure we don't restart the scanner if we don't need to - with patch( - "habluetooth.base_scanner.MONOTONIC_TIME", - return_value=start_time_monotonic + 20, + with patch_bluetooth_time( + start_time_monotonic + 20, ): async_fire_time_changed(hass, dt_util.utcnow() + SCANNER_WATCHDOG_INTERVAL) await hass.async_block_till_done() @@ -425,9 +415,8 @@ async def test_adapter_scanner_fails_to_start_first_time( assert called_start == 1 # We hit the timer with no detections, so we reset the adapter and restart the scanner - with patch( - "habluetooth.base_scanner.MONOTONIC_TIME", - return_value=start_time_monotonic + with patch_bluetooth_time( + start_time_monotonic + SCANNER_WATCHDOG_TIMEOUT + SCANNER_WATCHDOG_INTERVAL.total_seconds(), ), patch( @@ -441,9 +430,8 @@ async def test_adapter_scanner_fails_to_start_first_time( # We hit the timer again the previous start call failed, make sure # we try again - with patch( - "habluetooth.base_scanner.MONOTONIC_TIME", - return_value=start_time_monotonic + with patch_bluetooth_time( + start_time_monotonic + SCANNER_WATCHDOG_TIMEOUT + SCANNER_WATCHDOG_INTERVAL.total_seconds(), ), patch( @@ -504,9 +492,8 @@ async def test_adapter_fails_to_start_and_takes_a_bit_to_init( with patch( "habluetooth.scanner.ADAPTER_INIT_TIME", 0, - ), patch( - "habluetooth.base_scanner.MONOTONIC_TIME", - return_value=start_time_monotonic, + ), patch_bluetooth_time( + start_time_monotonic, ), patch( "habluetooth.scanner.OriginalBleakScanner", return_value=scanner, @@ -555,9 +542,8 @@ async def test_restart_takes_longer_than_watchdog_time( with patch( "habluetooth.scanner.ADAPTER_INIT_TIME", 0, - ), patch( - "habluetooth.base_scanner.MONOTONIC_TIME", - return_value=start_time_monotonic, + ), patch_bluetooth_time( + start_time_monotonic, ), patch( "habluetooth.scanner.OriginalBleakScanner", return_value=scanner, @@ -568,9 +554,8 @@ async def test_restart_takes_longer_than_watchdog_time( # Now force a recover adapter 2x for _ in range(2): - with patch( - "habluetooth.base_scanner.MONOTONIC_TIME", - return_value=start_time_monotonic + with patch_bluetooth_time( + start_time_monotonic + SCANNER_WATCHDOG_TIMEOUT + SCANNER_WATCHDOG_INTERVAL.total_seconds(), ): diff --git a/tests/components/bthome/test_binary_sensor.py b/tests/components/bthome/test_binary_sensor.py index 168988e510f..c38bec3ba44 100644 --- a/tests/components/bthome/test_binary_sensor.py +++ b/tests/components/bthome/test_binary_sensor.py @@ -2,7 +2,6 @@ from datetime import timedelta import logging import time -from unittest.mock import patch import pytest @@ -25,6 +24,7 @@ from tests.common import MockConfigEntry, async_fire_time_changed from tests.components.bluetooth import ( inject_bluetooth_service_info, patch_all_discovered_devices, + patch_bluetooth_time, ) _LOGGER = logging.getLogger(__name__) @@ -236,10 +236,7 @@ async def test_unavailable(hass: HomeAssistant) -> None: # Fastforward time without BLE advertisements monotonic_now = start_monotonic + FALLBACK_MAXIMUM_STALE_ADVERTISEMENT_SECONDS + 1 - with patch( - "homeassistant.components.bluetooth.manager.MONOTONIC_TIME", - return_value=monotonic_now, - ), patch_all_discovered_devices([]): + with patch_bluetooth_time(monotonic_now), patch_all_discovered_devices([]): async_fire_time_changed( hass, dt_util.utcnow() @@ -290,10 +287,7 @@ async def test_sleepy_device(hass: HomeAssistant) -> None: # Fastforward time without BLE advertisements monotonic_now = start_monotonic + FALLBACK_MAXIMUM_STALE_ADVERTISEMENT_SECONDS + 1 - with patch( - "homeassistant.components.bluetooth.manager.MONOTONIC_TIME", - return_value=monotonic_now, - ), patch_all_discovered_devices([]): + with patch_bluetooth_time(monotonic_now), patch_all_discovered_devices([]): async_fire_time_changed( hass, dt_util.utcnow() @@ -344,10 +338,7 @@ async def test_sleepy_device_restores_state(hass: HomeAssistant) -> None: # Fastforward time without BLE advertisements monotonic_now = start_monotonic + FALLBACK_MAXIMUM_STALE_ADVERTISEMENT_SECONDS + 1 - with patch( - "homeassistant.components.bluetooth.manager.MONOTONIC_TIME", - return_value=monotonic_now, - ), patch_all_discovered_devices([]): + with patch_bluetooth_time(monotonic_now), patch_all_discovered_devices([]): async_fire_time_changed( hass, dt_util.utcnow() diff --git a/tests/components/bthome/test_sensor.py b/tests/components/bthome/test_sensor.py index c1f8e26ccb2..0b6e7a42cfb 100644 --- a/tests/components/bthome/test_sensor.py +++ b/tests/components/bthome/test_sensor.py @@ -2,7 +2,6 @@ from datetime import timedelta import logging import time -from unittest.mock import patch import pytest @@ -25,6 +24,7 @@ from tests.common import MockConfigEntry, async_fire_time_changed from tests.components.bluetooth import ( inject_bluetooth_service_info, patch_all_discovered_devices, + patch_bluetooth_time, ) _LOGGER = logging.getLogger(__name__) @@ -1150,10 +1150,7 @@ async def test_unavailable(hass: HomeAssistant) -> None: # Fastforward time without BLE advertisements monotonic_now = start_monotonic + FALLBACK_MAXIMUM_STALE_ADVERTISEMENT_SECONDS + 1 - with patch( - "homeassistant.components.bluetooth.manager.MONOTONIC_TIME", - return_value=monotonic_now, - ), patch_all_discovered_devices([]): + with patch_bluetooth_time(monotonic_now), patch_all_discovered_devices([]): async_fire_time_changed( hass, dt_util.utcnow() @@ -1206,10 +1203,7 @@ async def test_sleepy_device(hass: HomeAssistant) -> None: # Fastforward time without BLE advertisements monotonic_now = start_monotonic + FALLBACK_MAXIMUM_STALE_ADVERTISEMENT_SECONDS + 1 - with patch( - "homeassistant.components.bluetooth.manager.MONOTONIC_TIME", - return_value=monotonic_now, - ), patch_all_discovered_devices([]): + with patch_bluetooth_time(monotonic_now), patch_all_discovered_devices([]): async_fire_time_changed( hass, dt_util.utcnow() @@ -1262,10 +1256,7 @@ async def test_sleepy_device_restore_state(hass: HomeAssistant) -> None: # Fastforward time without BLE advertisements monotonic_now = start_monotonic + FALLBACK_MAXIMUM_STALE_ADVERTISEMENT_SECONDS + 1 - with patch( - "homeassistant.components.bluetooth.manager.MONOTONIC_TIME", - return_value=monotonic_now, - ), patch_all_discovered_devices([]): + with patch_bluetooth_time(monotonic_now), patch_all_discovered_devices([]): async_fire_time_changed( hass, dt_util.utcnow() diff --git a/tests/components/govee_ble/test_sensor.py b/tests/components/govee_ble/test_sensor.py index 185ae2404da..5828a2c6570 100644 --- a/tests/components/govee_ble/test_sensor.py +++ b/tests/components/govee_ble/test_sensor.py @@ -113,7 +113,7 @@ async def test_gvh5178_multi_sensor(hass: HomeAssistant) -> None: monotonic_now = start_monotonic + FALLBACK_MAXIMUM_STALE_ADVERTISEMENT_SECONDS + 1 with patch( - "homeassistant.components.bluetooth.manager.MONOTONIC_TIME", + "homeassistant.components.bluetooth.MONOTONIC_TIME", return_value=monotonic_now, ), patch_all_discovered_devices([]): async_fire_time_changed( @@ -140,7 +140,7 @@ async def test_gvh5178_multi_sensor(hass: HomeAssistant) -> None: # Fastforward time without BLE advertisements with patch( - "homeassistant.components.bluetooth.manager.MONOTONIC_TIME", + "homeassistant.components.bluetooth.MONOTONIC_TIME", return_value=monotonic_now, ), patch_all_discovered_devices([]): async_fire_time_changed( diff --git a/tests/components/oralb/test_sensor.py b/tests/components/oralb/test_sensor.py index 49de6db6e13..c5533d1d0e2 100644 --- a/tests/components/oralb/test_sensor.py +++ b/tests/components/oralb/test_sensor.py @@ -64,7 +64,7 @@ async def test_sensors( monotonic_now = start_monotonic + FALLBACK_MAXIMUM_STALE_ADVERTISEMENT_SECONDS + 1 with patch( - "homeassistant.components.bluetooth.manager.MONOTONIC_TIME", + "homeassistant.components.bluetooth.MONOTONIC_TIME", return_value=monotonic_now, ), patch_all_discovered_devices([]): async_fire_time_changed( @@ -115,7 +115,7 @@ async def test_sensors_io_series_4( monotonic_now = start_monotonic + FALLBACK_MAXIMUM_STALE_ADVERTISEMENT_SECONDS + 1 with patch( - "homeassistant.components.bluetooth.manager.MONOTONIC_TIME", + "homeassistant.components.bluetooth.MONOTONIC_TIME", return_value=monotonic_now, ), patch_all_discovered_devices([]): async_fire_time_changed( diff --git a/tests/components/private_ble_device/__init__.py b/tests/components/private_ble_device/__init__.py index df9929293a1..a0e9b1972a5 100644 --- a/tests/components/private_ble_device/__init__.py +++ b/tests/components/private_ble_device/__init__.py @@ -71,7 +71,7 @@ async def async_inject_broadcast( async def async_move_time_forwards(hass: HomeAssistant, offset: float): """Mock time advancing from now to now+offset.""" with patch( - "homeassistant.components.bluetooth.manager.MONOTONIC_TIME", + "homeassistant.components.bluetooth.MONOTONIC_TIME", return_value=time.monotonic() + offset, ): async_fire_time_changed(hass, dt_util.utcnow() + timedelta(seconds=offset)) diff --git a/tests/components/qingping/test_binary_sensor.py b/tests/components/qingping/test_binary_sensor.py index 9b83cd8c590..dc2c03a8926 100644 --- a/tests/components/qingping/test_binary_sensor.py +++ b/tests/components/qingping/test_binary_sensor.py @@ -73,7 +73,7 @@ async def test_binary_sensor_restore_state(hass: HomeAssistant) -> None: monotonic_now = start_monotonic + FALLBACK_MAXIMUM_STALE_ADVERTISEMENT_SECONDS + 1 with patch( - "homeassistant.components.bluetooth.manager.MONOTONIC_TIME", + "homeassistant.components.bluetooth.MONOTONIC_TIME", return_value=monotonic_now, ), patch_all_discovered_devices([]): async_fire_time_changed( diff --git a/tests/components/qingping/test_sensor.py b/tests/components/qingping/test_sensor.py index 2fedbba9e5c..dced628a197 100644 --- a/tests/components/qingping/test_sensor.py +++ b/tests/components/qingping/test_sensor.py @@ -83,7 +83,7 @@ async def test_binary_sensor_restore_state(hass: HomeAssistant) -> None: monotonic_now = start_monotonic + FALLBACK_MAXIMUM_STALE_ADVERTISEMENT_SECONDS + 1 with patch( - "homeassistant.components.bluetooth.manager.MONOTONIC_TIME", + "homeassistant.components.bluetooth.MONOTONIC_TIME", return_value=monotonic_now, ), patch_all_discovered_devices([]): async_fire_time_changed( diff --git a/tests/components/sensorpush/test_sensor.py b/tests/components/sensorpush/test_sensor.py index e00b626b20b..d48a920bb69 100644 --- a/tests/components/sensorpush/test_sensor.py +++ b/tests/components/sensorpush/test_sensor.py @@ -56,7 +56,7 @@ async def test_sensors(hass: HomeAssistant) -> None: monotonic_now = start_monotonic + FALLBACK_MAXIMUM_STALE_ADVERTISEMENT_SECONDS + 1 with patch( - "homeassistant.components.bluetooth.manager.MONOTONIC_TIME", + "homeassistant.components.bluetooth.MONOTONIC_TIME", return_value=monotonic_now, ), patch_all_discovered_devices([]): async_fire_time_changed( diff --git a/tests/components/xiaomi_ble/test_binary_sensor.py b/tests/components/xiaomi_ble/test_binary_sensor.py index 32d1fea7f62..30be00295ee 100644 --- a/tests/components/xiaomi_ble/test_binary_sensor.py +++ b/tests/components/xiaomi_ble/test_binary_sensor.py @@ -295,7 +295,7 @@ async def test_unavailable(hass: HomeAssistant) -> None: monotonic_now = start_monotonic + FALLBACK_MAXIMUM_STALE_ADVERTISEMENT_SECONDS + 1 with patch( - "homeassistant.components.bluetooth.manager.MONOTONIC_TIME", + "homeassistant.components.bluetooth.MONOTONIC_TIME", return_value=monotonic_now, ), patch_all_discovered_devices([]): async_fire_time_changed( @@ -348,7 +348,7 @@ async def test_sleepy_device(hass: HomeAssistant) -> None: monotonic_now = start_monotonic + FALLBACK_MAXIMUM_STALE_ADVERTISEMENT_SECONDS + 1 with patch( - "homeassistant.components.bluetooth.manager.MONOTONIC_TIME", + "homeassistant.components.bluetooth.MONOTONIC_TIME", return_value=monotonic_now, ), patch_all_discovered_devices([]): async_fire_time_changed( @@ -401,7 +401,7 @@ async def test_sleepy_device_restore_state(hass: HomeAssistant) -> None: monotonic_now = start_monotonic + FALLBACK_MAXIMUM_STALE_ADVERTISEMENT_SECONDS + 1 with patch( - "homeassistant.components.bluetooth.manager.MONOTONIC_TIME", + "homeassistant.components.bluetooth.MONOTONIC_TIME", return_value=monotonic_now, ), patch_all_discovered_devices([]): async_fire_time_changed( diff --git a/tests/components/xiaomi_ble/test_sensor.py b/tests/components/xiaomi_ble/test_sensor.py index b0ddd99a7c2..59a539c028b 100644 --- a/tests/components/xiaomi_ble/test_sensor.py +++ b/tests/components/xiaomi_ble/test_sensor.py @@ -693,7 +693,7 @@ async def test_unavailable(hass: HomeAssistant) -> None: monotonic_now = start_monotonic + FALLBACK_MAXIMUM_STALE_ADVERTISEMENT_SECONDS + 1 with patch( - "homeassistant.components.bluetooth.manager.MONOTONIC_TIME", + "homeassistant.components.bluetooth.MONOTONIC_TIME", return_value=monotonic_now, ), patch_all_discovered_devices([]): async_fire_time_changed( @@ -740,7 +740,7 @@ async def test_sleepy_device(hass: HomeAssistant) -> None: monotonic_now = start_monotonic + FALLBACK_MAXIMUM_STALE_ADVERTISEMENT_SECONDS + 1 with patch( - "homeassistant.components.bluetooth.manager.MONOTONIC_TIME", + "homeassistant.components.bluetooth.MONOTONIC_TIME", return_value=monotonic_now, ), patch_all_discovered_devices([]): async_fire_time_changed( @@ -789,7 +789,7 @@ async def test_sleepy_device_restore_state(hass: HomeAssistant) -> None: monotonic_now = start_monotonic + FALLBACK_MAXIMUM_STALE_ADVERTISEMENT_SECONDS + 1 with patch( - "homeassistant.components.bluetooth.manager.MONOTONIC_TIME", + "homeassistant.components.bluetooth.MONOTONIC_TIME", return_value=monotonic_now, ), patch_all_discovered_devices([]): async_fire_time_changed(