Switch async_track_time_interval to use async_call_later internally (#99220)

pull/99235/head
J. Nick Koston 2023-08-28 13:56:22 -05:00 committed by GitHub
parent 821d74e904
commit 80d2309896
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 59 additions and 62 deletions

View File

@ -1514,24 +1514,19 @@ def async_track_time_interval(
"""Add a listener that fires repetitively at every timedelta interval."""
remove: CALLBACK_TYPE
interval_listener_job: HassJob[[datetime], None]
interval_seconds = interval.total_seconds()
job = HassJob(
action, f"track time interval {interval}", cancel_on_shutdown=cancel_on_shutdown
)
def next_interval() -> datetime:
"""Return the next interval."""
return dt_util.utcnow() + interval
@callback
def interval_listener(now: datetime) -> None:
"""Handle elapsed intervals."""
nonlocal remove
nonlocal interval_listener_job
remove = async_track_point_in_utc_time(
hass, interval_listener_job, next_interval()
)
remove = async_call_later(hass, interval_seconds, interval_listener_job)
hass.async_run_hass_job(job, now)
if name:
@ -1542,7 +1537,7 @@ def async_track_time_interval(
interval_listener_job = HassJob(
interval_listener, job_name, cancel_on_shutdown=cancel_on_shutdown
)
remove = async_track_point_in_utc_time(hass, interval_listener_job, next_interval())
remove = async_call_later(hass, interval_seconds, interval_listener_job)
def remove_listener() -> None:
"""Remove interval listener."""

View File

@ -3,7 +3,7 @@ from collections.abc import Awaitable, Callable, Generator
from typing import Any
from unittest.mock import AsyncMock, Mock, patch
from freezegun import freeze_time
from freezegun.api import FrozenDateTimeFactory
from gardena_bluetooth.client import Client
from gardena_bluetooth.const import DeviceInformation
from gardena_bluetooth.exceptions import CharacteristicNotFound
@ -49,19 +49,19 @@ def mock_read_char_raw():
@pytest.fixture
async def scan_step(
hass: HomeAssistant,
hass: HomeAssistant, freezer: FrozenDateTimeFactory
) -> Generator[None, None, Callable[[], Awaitable[None]]]:
"""Step system time forward."""
with freeze_time("2023-01-01", tz_offset=1) as frozen_time:
freezer.move_to("2023-01-01T01:00:00Z")
async def delay():
"""Trigger delay in system."""
frozen_time.tick(delta=SCAN_INTERVAL)
async_fire_time_changed(hass)
await hass.async_block_till_done()
async def delay():
"""Trigger delay in system."""
freezer.tick(delta=SCAN_INTERVAL)
async_fire_time_changed(hass)
await hass.async_block_till_done()
yield delay
return delay
@pytest.fixture(autouse=True)

View File

@ -5,11 +5,13 @@ from datetime import timedelta
import logging
from unittest import mock
from freezegun.api import FrozenDateTimeFactory
from pymodbus.exceptions import ModbusException
import pytest
from homeassistant.components.modbus.const import MODBUS_DOMAIN as DOMAIN, TCP
from homeassistant.const import CONF_HOST, CONF_NAME, CONF_PORT, CONF_SLAVE, CONF_TYPE
from homeassistant.core import HomeAssistant
from homeassistant.setup import async_setup_component
import homeassistant.util.dt as dt_util
@ -140,26 +142,26 @@ async def mock_pymodbus_return_fixture(hass, register_words, mock_modbus):
@pytest.fixture(name="mock_do_cycle")
async def mock_do_cycle_fixture(hass, mock_pymodbus_exception, mock_pymodbus_return):
async def mock_do_cycle_fixture(
hass: HomeAssistant,
freezer: FrozenDateTimeFactory,
mock_pymodbus_exception,
mock_pymodbus_return,
) -> FrozenDateTimeFactory:
"""Trigger update call with time_changed event."""
now = dt_util.utcnow() + timedelta(seconds=90)
with mock.patch(
"homeassistant.helpers.event.dt_util.utcnow", return_value=now, autospec=True
):
async_fire_time_changed(hass, now)
await hass.async_block_till_done()
return now
freezer.tick(timedelta(seconds=90))
async_fire_time_changed(hass)
await hass.async_block_till_done()
return freezer
async def do_next_cycle(hass, now, cycle):
async def do_next_cycle(
hass: HomeAssistant, freezer: FrozenDateTimeFactory, cycle: int
) -> None:
"""Trigger update call with time_changed event."""
now += timedelta(seconds=cycle)
with mock.patch(
"homeassistant.helpers.event.dt_util.utcnow", return_value=now, autospec=True
):
async_fire_time_changed(hass, now)
await hass.async_block_till_done()
return now
freezer.tick(timedelta(seconds=cycle))
async_fire_time_changed(hass)
await hass.async_block_till_done()
@pytest.fixture(name="mock_test_state")

View File

@ -1,4 +1,5 @@
"""Thetests for the Modbus sensor component."""
from freezegun.api import FrozenDateTimeFactory
import pytest
from homeassistant.components.binary_sensor import DOMAIN as SENSOR_DOMAIN
@ -199,14 +200,13 @@ async def test_all_binary_sensor(hass: HomeAssistant, expected, mock_do_cycle) -
],
)
async def test_lazy_error_binary_sensor(
hass: HomeAssistant, start_expect, end_expect, mock_do_cycle
hass: HomeAssistant, start_expect, end_expect, mock_do_cycle: FrozenDateTimeFactory
) -> None:
"""Run test for given config."""
now = mock_do_cycle
assert hass.states.get(ENTITY_ID).state == start_expect
now = await do_next_cycle(hass, now, 11)
await do_next_cycle(hass, mock_do_cycle, 11)
assert hass.states.get(ENTITY_ID).state == start_expect
now = await do_next_cycle(hass, now, 11)
await do_next_cycle(hass, mock_do_cycle, 11)
assert hass.states.get(ENTITY_ID).state == end_expect

View File

@ -1,4 +1,5 @@
"""The tests for the Modbus climate component."""
from freezegun.api import FrozenDateTimeFactory
import pytest
from homeassistant.components.climate import DOMAIN as CLIMATE_DOMAIN
@ -597,16 +598,15 @@ async def test_restore_state_climate(
],
)
async def test_lazy_error_climate(
hass: HomeAssistant, mock_do_cycle, start_expect, end_expect
hass: HomeAssistant, mock_do_cycle: FrozenDateTimeFactory, start_expect, end_expect
) -> None:
"""Run test for sensor."""
hass.states.async_set(ENTITY_ID, 17)
await hass.async_block_till_done()
now = mock_do_cycle
assert hass.states.get(ENTITY_ID).state == start_expect
now = await do_next_cycle(hass, now, 11)
await do_next_cycle(hass, mock_do_cycle, 11)
assert hass.states.get(ENTITY_ID).state == start_expect
now = await do_next_cycle(hass, now, 11)
await do_next_cycle(hass, mock_do_cycle, 11)
assert hass.states.get(ENTITY_ID).state == end_expect

View File

@ -1,4 +1,5 @@
"""The tests for the Modbus cover component."""
from freezegun.api import FrozenDateTimeFactory
from pymodbus.exceptions import ModbusException
import pytest
@ -142,14 +143,13 @@ async def test_coil_cover(hass: HomeAssistant, expected, mock_do_cycle) -> None:
],
)
async def test_lazy_error_cover(
hass: HomeAssistant, start_expect, end_expect, mock_do_cycle
hass: HomeAssistant, start_expect, end_expect, mock_do_cycle: FrozenDateTimeFactory
) -> None:
"""Run test for given config."""
now = mock_do_cycle
assert hass.states.get(ENTITY_ID).state == start_expect
now = await do_next_cycle(hass, now, 11)
await do_next_cycle(hass, mock_do_cycle, 11)
assert hass.states.get(ENTITY_ID).state == start_expect
now = await do_next_cycle(hass, now, 11)
await do_next_cycle(hass, mock_do_cycle, 11)
assert hass.states.get(ENTITY_ID).state == end_expect

View File

@ -1,4 +1,5 @@
"""The tests for the Modbus sensor component."""
from freezegun.api import FrozenDateTimeFactory
import pytest
from homeassistant.components.modbus.const import (
@ -928,16 +929,15 @@ async def test_wrong_unpack(hass: HomeAssistant, mock_do_cycle) -> None:
],
)
async def test_lazy_error_sensor(
hass: HomeAssistant, mock_do_cycle, start_expect, end_expect
hass: HomeAssistant, mock_do_cycle: FrozenDateTimeFactory, start_expect, end_expect
) -> None:
"""Run test for sensor."""
hass.states.async_set(ENTITY_ID, 17)
await hass.async_block_till_done()
now = mock_do_cycle
assert hass.states.get(ENTITY_ID).state == start_expect
now = await do_next_cycle(hass, now, 11)
await do_next_cycle(hass, mock_do_cycle, 11)
assert hass.states.get(ENTITY_ID).state == start_expect
now = await do_next_cycle(hass, now, 11)
await do_next_cycle(hass, mock_do_cycle, 11)
assert hass.states.get(ENTITY_ID).state == end_expect

View File

@ -2,6 +2,7 @@
from datetime import timedelta
from unittest import mock
from freezegun.api import FrozenDateTimeFactory
from pymodbus.exceptions import ModbusException
import pytest
@ -237,14 +238,13 @@ async def test_all_switch(hass: HomeAssistant, mock_do_cycle, expected) -> None:
],
)
async def test_lazy_error_switch(
hass: HomeAssistant, start_expect, end_expect, mock_do_cycle
hass: HomeAssistant, start_expect, end_expect, mock_do_cycle: FrozenDateTimeFactory
) -> None:
"""Run test for given config."""
now = mock_do_cycle
assert hass.states.get(ENTITY_ID).state == start_expect
now = await do_next_cycle(hass, now, 11)
await do_next_cycle(hass, mock_do_cycle, 11)
assert hass.states.get(ENTITY_ID).state == start_expect
now = await do_next_cycle(hass, now, 11)
await do_next_cycle(hass, mock_do_cycle, 11)
assert hass.states.get(ENTITY_ID).state == end_expect

View File

@ -4,6 +4,7 @@ from unittest.mock import patch
from aiounifi.models.message import MessageKey
from aiounifi.websocket import WebsocketState
from freezegun.api import FrozenDateTimeFactory
from homeassistant import config_entries
from homeassistant.components.device_tracker import DOMAIN as TRACKER_DOMAIN
@ -169,6 +170,7 @@ async def test_tracked_clients(
async def test_tracked_wireless_clients_event_source(
hass: HomeAssistant,
aioclient_mock: AiohttpClientMocker,
freezer: FrozenDateTimeFactory,
mock_unifi_websocket,
mock_device_registry,
) -> None:
@ -234,10 +236,9 @@ async def test_tracked_wireless_clients_event_source(
assert hass.states.get("device_tracker.client").state == STATE_HOME
# Change time to mark client as away
new_time = dt_util.utcnow() + controller.option_detection_time
with patch("homeassistant.util.dt.utcnow", return_value=new_time):
async_fire_time_changed(hass, new_time)
await hass.async_block_till_done()
freezer.tick(controller.option_detection_time + timedelta(seconds=1))
async_fire_time_changed(hass)
await hass.async_block_till_done()
assert hass.states.get("device_tracker.client").state == STATE_NOT_HOME
@ -274,12 +275,11 @@ async def test_tracked_wireless_clients_event_source(
assert hass.states.get("device_tracker.client").state == STATE_HOME
# Change time to mark client as away
new_time = dt_util.utcnow() + controller.option_detection_time
with patch("homeassistant.util.dt.utcnow", return_value=new_time):
async_fire_time_changed(hass, new_time)
await hass.async_block_till_done()
freezer.tick(controller.option_detection_time + timedelta(seconds=1))
async_fire_time_changed(hass)
await hass.async_block_till_done()
assert hass.states.get("device_tracker.client").state == STATE_HOME
assert hass.states.get("device_tracker.client").state == STATE_NOT_HOME
async def test_tracked_devices(