Use eventloop for scheduling (#37184)

Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
This commit is contained in:
J. Nick Koston 2020-06-29 11:39:24 -05:00 committed by GitHub
parent 0f72008090
commit 89a9634d35
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
42 changed files with 366 additions and 272 deletions

View file

@ -31,8 +31,7 @@ from homeassistant.const import (
SUN_EVENT_SUNRISE, SUN_EVENT_SUNRISE,
SUN_EVENT_SUNSET, SUN_EVENT_SUNSET,
) )
import homeassistant.helpers.config_validation as cv from homeassistant.helpers import config_validation as cv, event
from homeassistant.helpers.event import async_track_time_interval
from homeassistant.helpers.restore_state import RestoreEntity from homeassistant.helpers.restore_state import RestoreEntity
from homeassistant.helpers.sun import get_astral_event_date from homeassistant.helpers.sun import get_astral_event_date
from homeassistant.util import slugify from homeassistant.util import slugify
@ -224,7 +223,7 @@ class FluxSwitch(SwitchEntity, RestoreEntity):
if self.is_on: if self.is_on:
return return
self.unsub_tracker = async_track_time_interval( self.unsub_tracker = event.async_track_time_interval(
self.hass, self.hass,
self.async_flux_update, self.async_flux_update,
datetime.timedelta(seconds=self._interval), datetime.timedelta(seconds=self._interval),

View file

@ -17,12 +17,8 @@ from homeassistant.const import (
STATE_UNKNOWN, STATE_UNKNOWN,
) )
from homeassistant.core import callback from homeassistant.core import callback
import homeassistant.helpers.config_validation as cv from homeassistant.helpers import config_validation as cv, event
from homeassistant.helpers.entity import Entity from homeassistant.helpers.entity import Entity
from homeassistant.helpers.event import (
async_track_point_in_utc_time,
async_track_state_change,
)
from homeassistant.util import dt as dt_util from homeassistant.util import dt as dt_util
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -116,11 +112,11 @@ class StatisticsSensor(Entity):
self.async_schedule_update_ha_state(True) self.async_schedule_update_ha_state(True)
@callback @callback
def async_stats_sensor_startup(event): def async_stats_sensor_startup(_):
"""Add listener and get recorded state.""" """Add listener and get recorded state."""
_LOGGER.debug("Startup for %s", self.entity_id) _LOGGER.debug("Startup for %s", self.entity_id)
async_track_state_change( event.async_track_state_change(
self.hass, self._entity_id, async_stats_sensor_state_listener self.hass, self._entity_id, async_stats_sensor_state_listener
) )
@ -296,7 +292,7 @@ class StatisticsSensor(Entity):
self.async_schedule_update_ha_state(True) self.async_schedule_update_ha_state(True)
self._update_listener = None self._update_listener = None
self._update_listener = async_track_point_in_utc_time( self._update_listener = event.async_track_point_in_utc_time(
self.hass, _scheduled_update, next_to_purge_timestamp self.hass, _scheduled_update, next_to_purge_timestamp
) )

View file

@ -9,8 +9,8 @@ from homeassistant.const import (
SUN_EVENT_SUNSET, SUN_EVENT_SUNSET,
) )
from homeassistant.core import callback from homeassistant.core import callback
from homeassistant.helpers import event
from homeassistant.helpers.entity import Entity from homeassistant.helpers.entity import Entity
from homeassistant.helpers.event import async_track_point_in_utc_time
from homeassistant.helpers.sun import ( from homeassistant.helpers.sun import (
get_astral_location, get_astral_location,
get_location_astral_event_next, get_location_astral_event_next,
@ -99,7 +99,7 @@ class Sun(Entity):
self.rising = self.phase = None self.rising = self.phase = None
self._next_change = None self._next_change = None
def update_location(event): def update_location(_event):
self.location = get_astral_location(self.hass) self.location = get_astral_location(self.hass)
self.update_events(dt_util.utcnow()) self.update_events(dt_util.utcnow())
@ -135,9 +135,9 @@ class Sun(Entity):
STATE_ATTR_RISING: self.rising, STATE_ATTR_RISING: self.rising,
} }
def _check_event(self, utc_point_in_time, event, before): def _check_event(self, utc_point_in_time, sun_event, before):
next_utc = get_location_astral_event_next( next_utc = get_location_astral_event_next(
self.location, event, utc_point_in_time self.location, sun_event, utc_point_in_time
) )
if next_utc < self._next_change: if next_utc < self._next_change:
self._next_change = next_utc self._next_change = next_utc
@ -207,7 +207,9 @@ class Sun(Entity):
self.update_sun_position(utc_point_in_time) self.update_sun_position(utc_point_in_time)
# Set timer for the next solar event # Set timer for the next solar event
async_track_point_in_utc_time(self.hass, self.update_events, self._next_change) event.async_track_point_in_utc_time(
self.hass, self.update_events, self._next_change
)
_LOGGER.debug("next time: %s", self._next_change.isoformat()) _LOGGER.debug("next time: %s", self._next_change.isoformat())
@callback @callback
@ -232,6 +234,6 @@ class Sun(Entity):
# position update just drop it # position update just drop it
if utc_point_in_time + delta * 1.25 > self._next_change: if utc_point_in_time + delta * 1.25 > self._next_change:
return return
async_track_point_in_utc_time( event.async_track_point_in_utc_time(
self.hass, self.update_sun_position, utc_point_in_time + delta self.hass, self.update_sun_position, utc_point_in_time + delta
) )

View file

@ -14,8 +14,7 @@ from homeassistant.const import (
SUN_EVENT_SUNSET, SUN_EVENT_SUNSET,
) )
from homeassistant.core import callback from homeassistant.core import callback
import homeassistant.helpers.config_validation as cv from homeassistant.helpers import config_validation as cv, event
from homeassistant.helpers.event import async_track_point_in_utc_time
from homeassistant.helpers.sun import get_astral_event_date, get_astral_event_next from homeassistant.helpers.sun import get_astral_event_date, get_astral_event_next
from homeassistant.util import dt as dt_util from homeassistant.util import dt as dt_util
@ -55,9 +54,9 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
async_add_entities([sensor]) async_add_entities([sensor])
def is_sun_event(event): def is_sun_event(sun_event):
"""Return true if event is sun event not time.""" """Return true if event is sun event not time."""
return event in (SUN_EVENT_SUNRISE, SUN_EVENT_SUNSET) return sun_event in (SUN_EVENT_SUNRISE, SUN_EVENT_SUNSET)
class TodSensor(BinarySensorEntity): class TodSensor(BinarySensorEntity):
@ -236,6 +235,6 @@ class TodSensor(BinarySensorEntity):
self._calculate_next_update() self._calculate_next_update()
self.async_write_ha_state() self.async_write_ha_state()
async_track_point_in_utc_time( event.async_track_point_in_utc_time(
self.hass, self._point_in_time_listener, self.next_update self.hass, self._point_in_time_listener, self.next_update
) )

View file

@ -4,7 +4,7 @@ MINOR_VERSION = 113
PATCH_VERSION = "0.dev0" PATCH_VERSION = "0.dev0"
__short_version__ = f"{MAJOR_VERSION}.{MINOR_VERSION}" __short_version__ = f"{MAJOR_VERSION}.{MINOR_VERSION}"
__version__ = f"{__short_version__}.{PATCH_VERSION}" __version__ = f"{__short_version__}.{PATCH_VERSION}"
REQUIRED_PYTHON_VER = (3, 7, 0) REQUIRED_PYTHON_VER = (3, 7, 1)
# Truthy date string triggers showing related deprecation warning messages. # Truthy date string triggers showing related deprecation warning messages.
REQUIRED_NEXT_PYTHON_VER = (3, 8, 0) REQUIRED_NEXT_PYTHON_VER = (3, 8, 0)
REQUIRED_NEXT_PYTHON_DATE = "" REQUIRED_NEXT_PYTHON_DATE = ""

View file

@ -2,6 +2,7 @@
from datetime import datetime, timedelta from datetime import datetime, timedelta
import functools as ft import functools as ft
import logging import logging
import time
from typing import Any, Awaitable, Callable, Dict, Iterable, Optional, Union from typing import Any, Awaitable, Callable, Dict, Iterable, Optional, Union
import attr import attr
@ -316,26 +317,21 @@ def async_track_point_in_utc_time(
point_in_time = dt_util.as_utc(point_in_time) point_in_time = dt_util.as_utc(point_in_time)
@callback @callback
def point_in_time_listener(event: Event) -> None: def point_in_time_listener() -> None:
"""Listen for matching time_changed events.""" """Listen for matching time_changed events."""
now = event.data[ATTR_NOW] hass.async_run_job(action, point_in_time)
if now < point_in_time or hasattr(point_in_time_listener, "run"): cancel_callback = hass.loop.call_at(
return hass.loop.time() + point_in_time.timestamp() - time.time(),
point_in_time_listener,
)
# Set variable so that we will never run twice. @callback
# Because the event bus might have to wait till a thread comes def unsub_point_in_time_listener() -> None:
# available to execute this listener it might occur that the """Cancel the call_later."""
# listener gets lined up twice to be executed. This will make cancel_callback.cancel()
# sure the second time it does nothing.
setattr(point_in_time_listener, "run", True)
async_unsub()
hass.async_run_job(action, now) return unsub_point_in_time_listener
async_unsub = hass.bus.async_listen(EVENT_TIME_CHANGED, point_in_time_listener)
return async_unsub
track_point_in_utc_time = threaded_listener_factory(async_track_point_in_utc_time) track_point_in_utc_time = threaded_listener_factory(async_track_point_in_utc_time)

View file

@ -8,7 +8,7 @@ from typing import Any, Awaitable, Callable, List, Optional
import aiohttp import aiohttp
from homeassistant.core import CALLBACK_TYPE, HomeAssistant, callback from homeassistant.core import CALLBACK_TYPE, HomeAssistant, callback
from homeassistant.helpers.event import async_track_point_in_utc_time from homeassistant.helpers import event
from homeassistant.util.dt import utcnow from homeassistant.util.dt import utcnow
from .debounce import Debouncer from .debounce import Debouncer
@ -99,7 +99,7 @@ class DataUpdateCoordinator:
# minimizing the time between the point and the real activation. # minimizing the time between the point and the real activation.
# That way we obtain a constant update frequency, # That way we obtain a constant update frequency,
# as long as the update process takes less than a second # as long as the update process takes less than a second
self._unsub_refresh = async_track_point_in_utc_time( self._unsub_refresh = event.async_track_point_in_utc_time(
self.hass, self.hass,
self._handle_refresh_interval, self._handle_refresh_interval,
utcnow().replace(microsecond=0) + self.update_interval, utcnow().replace(microsecond=0) + self.update_interval,

View file

@ -11,6 +11,7 @@ import logging
import os import os
import sys import sys
import threading import threading
import time
import uuid import uuid
from aiohttp.test_utils import unused_port as get_test_instance_port # noqa from aiohttp.test_utils import unused_port as get_test_instance_port # noqa
@ -284,9 +285,22 @@ fire_mqtt_message = threadsafe_callback_factory(async_fire_mqtt_message)
@ha.callback @ha.callback
def async_fire_time_changed(hass, time): def async_fire_time_changed(hass, datetime_):
"""Fire a time changes event.""" """Fire a time changes event."""
hass.bus.async_fire(EVENT_TIME_CHANGED, {"now": date_util.as_utc(time)}) hass.bus.async_fire(EVENT_TIME_CHANGED, {"now": date_util.as_utc(datetime_)})
for task in list(hass.loop._scheduled):
if not isinstance(task, asyncio.TimerHandle):
continue
if task.cancelled():
continue
future_seconds = task.when() - hass.loop.time()
mock_seconds_into_future = datetime_.timestamp() - time.time()
if mock_seconds_into_future >= future_seconds:
task._run()
task.cancel()
fire_time_changed = threadsafe_callback_factory(async_fire_time_changed) fire_time_changed = threadsafe_callback_factory(async_fire_time_changed)

View file

@ -1,5 +1,5 @@
"""The tests for the AsusWrt sensor platform.""" """The tests for the AsusWrt sensor platform."""
from datetime import datetime, timedelta from datetime import timedelta
from aioasuswrt.asuswrt import Device from aioasuswrt.asuswrt import Device
@ -16,7 +16,6 @@ from homeassistant.components.asuswrt import (
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_USERNAME from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_USERNAME
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.setup import async_setup_component from homeassistant.setup import async_setup_component
import homeassistant.util.dt as dt_util
from homeassistant.util.dt import utcnow from homeassistant.util.dt import utcnow
from tests.async_mock import AsyncMock, patch from tests.async_mock import AsyncMock, patch
@ -51,7 +50,7 @@ MOCK_BYTES_TOTAL = [60000000000, 50000000000]
MOCK_CURRENT_TRANSFER_RATES = [20000000, 10000000] MOCK_CURRENT_TRANSFER_RATES = [20000000, 10000000]
async def test_sensors(hass: HomeAssistant): async def test_sensors(hass: HomeAssistant, mock_device_tracker_conf):
"""Test creating an AsusWRT sensor.""" """Test creating an AsusWRT sensor."""
with patch("homeassistant.components.asuswrt.AsusWrt") as AsusWrt: with patch("homeassistant.components.asuswrt.AsusWrt") as AsusWrt:
AsusWrt().connection.async_connect = AsyncMock() AsusWrt().connection.async_connect = AsyncMock()
@ -61,23 +60,17 @@ async def test_sensors(hass: HomeAssistant):
return_value=MOCK_CURRENT_TRANSFER_RATES return_value=MOCK_CURRENT_TRANSFER_RATES
) )
now = datetime(2020, 1, 1, 1, tzinfo=dt_util.UTC) assert await async_setup_component(hass, DOMAIN, VALID_CONFIG_ROUTER_SSH)
with patch(("homeassistant.helpers.event.dt_util.utcnow"), return_value=now): await hass.async_block_till_done()
assert await async_setup_component(hass, DOMAIN, VALID_CONFIG_ROUTER_SSH) async_fire_time_changed(hass, utcnow() + timedelta(seconds=30))
await hass.async_block_till_done() await hass.async_block_till_done()
async_fire_time_changed(hass, utcnow() + timedelta(seconds=30))
await hass.async_block_till_done()
assert ( assert (
hass.states.get(f"{sensor.DOMAIN}.asuswrt_devices_connected").state hass.states.get(f"{sensor.DOMAIN}.asuswrt_devices_connected").state == "3"
== "3" )
) assert (
assert ( hass.states.get(f"{sensor.DOMAIN}.asuswrt_download_speed").state == "160.0"
hass.states.get(f"{sensor.DOMAIN}.asuswrt_download_speed").state )
== "160.0" assert hass.states.get(f"{sensor.DOMAIN}.asuswrt_download").state == "60.0"
) assert hass.states.get(f"{sensor.DOMAIN}.asuswrt_upload_speed").state == "80.0"
assert hass.states.get(f"{sensor.DOMAIN}.asuswrt_download").state == "60.0" assert hass.states.get(f"{sensor.DOMAIN}.asuswrt_upload").state == "50.0"
assert (
hass.states.get(f"{sensor.DOMAIN}.asuswrt_upload_speed").state == "80.0"
)
assert hass.states.get(f"{sensor.DOMAIN}.asuswrt_upload").state == "50.0"

View file

@ -37,7 +37,7 @@ def teardown():
dt_util.set_default_time_zone(ORIG_TIME_ZONE) dt_util.set_default_time_zone(ORIG_TIME_ZONE)
async def test_sunset_trigger(hass, calls): async def test_sunset_trigger(hass, calls, legacy_patchable_time):
"""Test the sunset trigger.""" """Test the sunset trigger."""
now = datetime(2015, 9, 15, 23, tzinfo=dt_util.UTC) now = datetime(2015, 9, 15, 23, tzinfo=dt_util.UTC)
trigger_time = datetime(2015, 9, 16, 2, tzinfo=dt_util.UTC) trigger_time = datetime(2015, 9, 16, 2, tzinfo=dt_util.UTC)
@ -70,7 +70,7 @@ async def test_sunset_trigger(hass, calls):
assert len(calls) == 1 assert len(calls) == 1
async def test_sunrise_trigger(hass, calls): async def test_sunrise_trigger(hass, calls, legacy_patchable_time):
"""Test the sunrise trigger.""" """Test the sunrise trigger."""
now = datetime(2015, 9, 13, 23, tzinfo=dt_util.UTC) now = datetime(2015, 9, 13, 23, tzinfo=dt_util.UTC)
trigger_time = datetime(2015, 9, 16, 14, tzinfo=dt_util.UTC) trigger_time = datetime(2015, 9, 16, 14, tzinfo=dt_util.UTC)
@ -92,7 +92,7 @@ async def test_sunrise_trigger(hass, calls):
assert len(calls) == 1 assert len(calls) == 1
async def test_sunset_trigger_with_offset(hass, calls): async def test_sunset_trigger_with_offset(hass, calls, legacy_patchable_time):
"""Test the sunset trigger with offset.""" """Test the sunset trigger with offset."""
now = datetime(2015, 9, 15, 23, tzinfo=dt_util.UTC) now = datetime(2015, 9, 15, 23, tzinfo=dt_util.UTC)
trigger_time = datetime(2015, 9, 16, 2, 30, tzinfo=dt_util.UTC) trigger_time = datetime(2015, 9, 16, 2, 30, tzinfo=dt_util.UTC)
@ -125,7 +125,7 @@ async def test_sunset_trigger_with_offset(hass, calls):
assert calls[0].data["some"] == "sun - sunset - 0:30:00" assert calls[0].data["some"] == "sun - sunset - 0:30:00"
async def test_sunrise_trigger_with_offset(hass, calls): async def test_sunrise_trigger_with_offset(hass, calls, legacy_patchable_time):
"""Test the sunrise trigger with offset.""" """Test the sunrise trigger with offset."""
now = datetime(2015, 9, 13, 23, tzinfo=dt_util.UTC) now = datetime(2015, 9, 13, 23, tzinfo=dt_util.UTC)
trigger_time = datetime(2015, 9, 16, 13, 30, tzinfo=dt_util.UTC) trigger_time = datetime(2015, 9, 16, 13, 30, tzinfo=dt_util.UTC)

View file

@ -6,7 +6,7 @@ import ssl
from homeassistant.components.cert_expiry.const import DOMAIN from homeassistant.components.cert_expiry.const import DOMAIN
from homeassistant.config_entries import ENTRY_STATE_SETUP_RETRY from homeassistant.config_entries import ENTRY_STATE_SETUP_RETRY
from homeassistant.const import CONF_HOST, CONF_PORT, STATE_UNAVAILABLE, STATE_UNKNOWN from homeassistant.const import CONF_HOST, CONF_PORT, STATE_UNAVAILABLE, STATE_UNKNOWN
import homeassistant.util.dt as dt_util from homeassistant.util.dt import utcnow
from .const import HOST, PORT from .const import HOST, PORT
from .helpers import future_timestamp, static_datetime from .helpers import future_timestamp, static_datetime
@ -91,7 +91,7 @@ async def test_async_setup_entry_host_unavailable(hass):
assert entry.state == ENTRY_STATE_SETUP_RETRY assert entry.state == ENTRY_STATE_SETUP_RETRY
next_update = dt_util.utcnow() + timedelta(seconds=45) next_update = utcnow() + timedelta(seconds=45)
async_fire_time_changed(hass, next_update) async_fire_time_changed(hass, next_update)
with patch( with patch(
"homeassistant.components.cert_expiry.helper.get_cert", "homeassistant.components.cert_expiry.helper.get_cert",
@ -115,8 +115,6 @@ async def test_update_sensor(hass):
timestamp = future_timestamp(100) timestamp = future_timestamp(100)
with patch("homeassistant.util.dt.utcnow", return_value=starting_time), patch( with patch("homeassistant.util.dt.utcnow", return_value=starting_time), patch(
"homeassistant.helpers.update_coordinator.utcnow", return_value=starting_time
), patch(
"homeassistant.components.cert_expiry.get_cert_expiry_timestamp", "homeassistant.components.cert_expiry.get_cert_expiry_timestamp",
return_value=timestamp, return_value=timestamp,
): ):
@ -139,14 +137,11 @@ async def test_update_sensor(hass):
assert state.attributes.get("is_valid") assert state.attributes.get("is_valid")
next_update = starting_time + timedelta(hours=24) next_update = starting_time + timedelta(hours=24)
with patch("homeassistant.util.dt.utcnow", return_value=next_update), patch( with patch("homeassistant.util.dt.utcnow", return_value=next_update), patch(
"homeassistant.helpers.update_coordinator.utcnow", return_value=next_update
), patch(
"homeassistant.components.cert_expiry.get_cert_expiry_timestamp", "homeassistant.components.cert_expiry.get_cert_expiry_timestamp",
return_value=timestamp, return_value=timestamp,
): ):
async_fire_time_changed(hass, next_update) async_fire_time_changed(hass, utcnow() + timedelta(hours=24))
await hass.async_block_till_done() await hass.async_block_till_done()
state = hass.states.get("sensor.cert_expiry_example_com") state = hass.states.get("sensor.cert_expiry_example_com")
@ -176,8 +171,6 @@ async def test_update_sensor_network_errors(hass):
timestamp = future_timestamp(100) timestamp = future_timestamp(100)
with patch("homeassistant.util.dt.utcnow", return_value=starting_time), patch( with patch("homeassistant.util.dt.utcnow", return_value=starting_time), patch(
"homeassistant.helpers.update_coordinator.utcnow", return_value=starting_time
), patch(
"homeassistant.components.cert_expiry.get_cert_expiry_timestamp", "homeassistant.components.cert_expiry.get_cert_expiry_timestamp",
return_value=timestamp, return_value=timestamp,
): ):
@ -202,12 +195,10 @@ async def test_update_sensor_network_errors(hass):
next_update = starting_time + timedelta(hours=24) next_update = starting_time + timedelta(hours=24)
with patch("homeassistant.util.dt.utcnow", return_value=next_update), patch( with patch("homeassistant.util.dt.utcnow", return_value=next_update), patch(
"homeassistant.helpers.update_coordinator.utcnow", return_value=next_update
), patch(
"homeassistant.components.cert_expiry.helper.get_cert", "homeassistant.components.cert_expiry.helper.get_cert",
side_effect=socket.gaierror, side_effect=socket.gaierror,
): ):
async_fire_time_changed(hass, next_update) async_fire_time_changed(hass, utcnow() + timedelta(hours=24))
await hass.async_block_till_done() await hass.async_block_till_done()
next_update = starting_time + timedelta(hours=48) next_update = starting_time + timedelta(hours=48)
@ -216,12 +207,10 @@ async def test_update_sensor_network_errors(hass):
assert state.state == STATE_UNAVAILABLE assert state.state == STATE_UNAVAILABLE
with patch("homeassistant.util.dt.utcnow", return_value=next_update), patch( with patch("homeassistant.util.dt.utcnow", return_value=next_update), patch(
"homeassistant.helpers.update_coordinator.utcnow", return_value=next_update
), patch(
"homeassistant.components.cert_expiry.get_cert_expiry_timestamp", "homeassistant.components.cert_expiry.get_cert_expiry_timestamp",
return_value=timestamp, return_value=timestamp,
): ):
async_fire_time_changed(hass, next_update) async_fire_time_changed(hass, utcnow() + timedelta(hours=48))
await hass.async_block_till_done() await hass.async_block_till_done()
state = hass.states.get("sensor.cert_expiry_example_com") state = hass.states.get("sensor.cert_expiry_example_com")
@ -234,12 +223,10 @@ async def test_update_sensor_network_errors(hass):
next_update = starting_time + timedelta(hours=72) next_update = starting_time + timedelta(hours=72)
with patch("homeassistant.util.dt.utcnow", return_value=next_update), patch( with patch("homeassistant.util.dt.utcnow", return_value=next_update), patch(
"homeassistant.helpers.update_coordinator.utcnow", return_value=next_update
), patch(
"homeassistant.components.cert_expiry.helper.get_cert", "homeassistant.components.cert_expiry.helper.get_cert",
side_effect=ssl.SSLError("something bad"), side_effect=ssl.SSLError("something bad"),
): ):
async_fire_time_changed(hass, next_update) async_fire_time_changed(hass, utcnow() + timedelta(hours=72))
await hass.async_block_till_done() await hass.async_block_till_done()
state = hass.states.get("sensor.cert_expiry_example_com") state = hass.states.get("sensor.cert_expiry_example_com")
@ -258,11 +245,9 @@ async def test_update_sensor_network_errors(hass):
next_update = starting_time + timedelta(hours=96) next_update = starting_time + timedelta(hours=96)
with patch("homeassistant.util.dt.utcnow", return_value=next_update), patch( with patch("homeassistant.util.dt.utcnow", return_value=next_update), patch(
"homeassistant.helpers.update_coordinator.utcnow", return_value=next_update
), patch(
"homeassistant.components.cert_expiry.helper.get_cert", side_effect=Exception() "homeassistant.components.cert_expiry.helper.get_cert", side_effect=Exception()
): ):
async_fire_time_changed(hass, next_update) async_fire_time_changed(hass, utcnow() + timedelta(hours=96))
await hass.async_block_till_done() await hass.async_block_till_done()
state = hass.states.get("sensor.cert_expiry_example_com") state = hass.states.get("sensor.cert_expiry_example_com")

View file

@ -51,7 +51,9 @@ async def test_sync_entities(aioclient_mock, hass, cloud_prefs):
assert len(mock_request_sync.mock_calls) == 1 assert len(mock_request_sync.mock_calls) == 1
async def test_google_update_expose_trigger_sync(hass, cloud_prefs): async def test_google_update_expose_trigger_sync(
hass, legacy_patchable_time, cloud_prefs
):
"""Test Google config responds to updating exposed entities.""" """Test Google config responds to updating exposed entities."""
config = CloudGoogleConfig( config = CloudGoogleConfig(
hass, hass,

View file

@ -225,12 +225,14 @@ async def test_discover_platform(mock_demo_setup_scanner, mock_see, hass):
async def test_update_stale(hass, mock_device_tracker_conf): async def test_update_stale(hass, mock_device_tracker_conf):
"""Test stalled update.""" """Test stalled update."""
scanner = getattr(hass.components, "test.device_tracker").SCANNER scanner = getattr(hass.components, "test.device_tracker").SCANNER
scanner.reset() scanner.reset()
scanner.come_home("DEV1") scanner.come_home("DEV1")
register_time = datetime(2015, 9, 15, 23, tzinfo=dt_util.UTC) now = dt_util.utcnow()
scan_time = datetime(2015, 9, 15, 23, 1, tzinfo=dt_util.UTC) register_time = datetime(now.year + 1, 9, 15, 23, tzinfo=dt_util.UTC)
scan_time = datetime(now.year + 1, 9, 15, 23, 1, tzinfo=dt_util.UTC)
with patch( with patch(
"homeassistant.components.device_tracker.legacy.dt_util.utcnow", "homeassistant.components.device_tracker.legacy.dt_util.utcnow",
@ -433,8 +435,10 @@ async def test_see_state(hass, yaml_devices):
async def test_see_passive_zone_state(hass, mock_device_tracker_conf): async def test_see_passive_zone_state(hass, mock_device_tracker_conf):
"""Test that the device tracker sets gps for passive trackers.""" """Test that the device tracker sets gps for passive trackers."""
register_time = datetime(2015, 9, 15, 23, tzinfo=dt_util.UTC) now = dt_util.utcnow()
scan_time = datetime(2015, 9, 15, 23, 1, tzinfo=dt_util.UTC)
register_time = datetime(now.year + 1, 9, 15, 23, tzinfo=dt_util.UTC)
scan_time = datetime(now.year + 1, 9, 15, 23, 1, tzinfo=dt_util.UTC)
with assert_setup_component(1, zone.DOMAIN): with assert_setup_component(1, zone.DOMAIN):
zone_info = { zone_info = {

View file

@ -159,7 +159,7 @@ async def test_async_track_time_interval_backoff(hass):
_LOGGER.debug("Backoff...") _LOGGER.debug("Backoff...")
for idx in range(1, len(intervals)): for idx in range(1, len(intervals)):
tme += intervals[idx] tme += intervals[idx]
async_fire_time_changed(hass, tme) async_fire_time_changed(hass, tme + timedelta(seconds=0.1))
await hass.async_block_till_done() await hass.async_block_till_done()
assert call_count == idx + 1 assert call_count == idx + 1
@ -167,7 +167,7 @@ async def test_async_track_time_interval_backoff(hass):
_LOGGER.debug("Max backoff reached - intervals[-1]") _LOGGER.debug("Max backoff reached - intervals[-1]")
for _idx in range(1, 10): for _idx in range(1, 10):
tme += intervals[-1] tme += intervals[-1]
async_fire_time_changed(hass, tme) async_fire_time_changed(hass, tme + timedelta(seconds=0.1))
await hass.async_block_till_done() await hass.async_block_till_done()
assert call_count == idx + 1 + _idx assert call_count == idx + 1 + _idx
@ -176,14 +176,14 @@ async def test_async_track_time_interval_backoff(hass):
call_count = 0 call_count = 0
ret_val = True ret_val = True
tme += intervals[-1] tme += intervals[-1]
async_fire_time_changed(hass, tme) async_fire_time_changed(hass, tme + timedelta(seconds=0.1))
await hass.async_block_till_done() await hass.async_block_till_done()
assert call_count == 1 assert call_count == 1
_LOGGER.debug("No backoff - intervals[0]") _LOGGER.debug("No backoff - intervals[0]")
for _idx in range(2, 10): for _idx in range(2, 10):
tme += intervals[0] tme += intervals[0]
async_fire_time_changed(hass, tme) async_fire_time_changed(hass, tme + timedelta(seconds=0.1))
await hass.async_block_till_done() await hass.async_block_till_done()
assert call_count == _idx assert call_count == _idx

View file

@ -282,7 +282,7 @@ async def test_flux_before_sunrise_known_location(hass):
# pylint: disable=invalid-name # pylint: disable=invalid-name
async def test_flux_after_sunrise_before_sunset(hass): async def test_flux_after_sunrise_before_sunset(hass, legacy_patchable_time):
"""Test the flux switch after sunrise and before sunset.""" """Test the flux switch after sunrise and before sunset."""
platform = getattr(hass.components, "test.light") platform = getattr(hass.components, "test.light")
platform.init() platform.init()
@ -336,7 +336,7 @@ async def test_flux_after_sunrise_before_sunset(hass):
# pylint: disable=invalid-name # pylint: disable=invalid-name
async def test_flux_after_sunset_before_stop(hass): async def test_flux_after_sunset_before_stop(hass, legacy_patchable_time):
"""Test the flux switch after sunset and before stop.""" """Test the flux switch after sunset and before stop."""
platform = getattr(hass.components, "test.light") platform = getattr(hass.components, "test.light")
platform.init() platform.init()
@ -391,7 +391,7 @@ async def test_flux_after_sunset_before_stop(hass):
# pylint: disable=invalid-name # pylint: disable=invalid-name
async def test_flux_after_stop_before_sunrise(hass): async def test_flux_after_stop_before_sunrise(hass, legacy_patchable_time):
"""Test the flux switch after stop and before sunrise.""" """Test the flux switch after stop and before sunrise."""
platform = getattr(hass.components, "test.light") platform = getattr(hass.components, "test.light")
platform.init() platform.init()
@ -445,7 +445,7 @@ async def test_flux_after_stop_before_sunrise(hass):
# pylint: disable=invalid-name # pylint: disable=invalid-name
async def test_flux_with_custom_start_stop_times(hass): async def test_flux_with_custom_start_stop_times(hass, legacy_patchable_time):
"""Test the flux with custom start and stop times.""" """Test the flux with custom start and stop times."""
platform = getattr(hass.components, "test.light") platform = getattr(hass.components, "test.light")
platform.init() platform.init()
@ -558,7 +558,9 @@ async def test_flux_before_sunrise_stop_next_day(hass):
# pylint: disable=invalid-name # pylint: disable=invalid-name
async def test_flux_after_sunrise_before_sunset_stop_next_day(hass): async def test_flux_after_sunrise_before_sunset_stop_next_day(
hass, legacy_patchable_time
):
""" """
Test the flux switch after sunrise and before sunset. Test the flux switch after sunrise and before sunset.
@ -618,7 +620,9 @@ async def test_flux_after_sunrise_before_sunset_stop_next_day(hass):
# pylint: disable=invalid-name # pylint: disable=invalid-name
@pytest.mark.parametrize("x", [0, 1]) @pytest.mark.parametrize("x", [0, 1])
async def test_flux_after_sunset_before_midnight_stop_next_day(hass, x): async def test_flux_after_sunset_before_midnight_stop_next_day(
hass, legacy_patchable_time, x
):
"""Test the flux switch after sunset and before stop. """Test the flux switch after sunset and before stop.
This test has the stop_time on the next day (after midnight). This test has the stop_time on the next day (after midnight).
@ -792,7 +796,7 @@ async def test_flux_after_stop_before_sunrise_stop_next_day(hass):
# pylint: disable=invalid-name # pylint: disable=invalid-name
async def test_flux_with_custom_colortemps(hass): async def test_flux_with_custom_colortemps(hass, legacy_patchable_time):
"""Test the flux with custom start and stop colortemps.""" """Test the flux with custom start and stop colortemps."""
platform = getattr(hass.components, "test.light") platform = getattr(hass.components, "test.light")
platform.init() platform.init()
@ -849,7 +853,7 @@ async def test_flux_with_custom_colortemps(hass):
# pylint: disable=invalid-name # pylint: disable=invalid-name
async def test_flux_with_custom_brightness(hass): async def test_flux_with_custom_brightness(hass, legacy_patchable_time):
"""Test the flux with custom start and stop colortemps.""" """Test the flux with custom start and stop colortemps."""
platform = getattr(hass.components, "test.light") platform = getattr(hass.components, "test.light")
platform.init() platform.init()
@ -904,7 +908,7 @@ async def test_flux_with_custom_brightness(hass):
assert call.data[light.ATTR_XY_COLOR] == [0.506, 0.385] assert call.data[light.ATTR_XY_COLOR] == [0.506, 0.385]
async def test_flux_with_multiple_lights(hass): async def test_flux_with_multiple_lights(hass, legacy_patchable_time):
"""Test the flux switch with multiple light entities.""" """Test the flux switch with multiple light entities."""
platform = getattr(hass.components, "test.light") platform = getattr(hass.components, "test.light")
platform.init() platform.init()
@ -982,7 +986,7 @@ async def test_flux_with_multiple_lights(hass):
assert call.data[light.ATTR_XY_COLOR] == [0.46, 0.376] assert call.data[light.ATTR_XY_COLOR] == [0.46, 0.376]
async def test_flux_with_mired(hass): async def test_flux_with_mired(hass, legacy_patchable_time):
"""Test the flux switch´s mode mired.""" """Test the flux switch´s mode mired."""
platform = getattr(hass.components, "test.light") platform = getattr(hass.components, "test.light")
platform.init() platform.init()
@ -1034,7 +1038,7 @@ async def test_flux_with_mired(hass):
assert call.data[light.ATTR_COLOR_TEMP] == 269 assert call.data[light.ATTR_COLOR_TEMP] == 269
async def test_flux_with_rgb(hass): async def test_flux_with_rgb(hass, legacy_patchable_time):
"""Test the flux switch´s mode rgb.""" """Test the flux switch´s mode rgb."""
platform = getattr(hass.components, "test.light") platform = getattr(hass.components, "test.light")
platform.init() platform.init()

View file

@ -32,7 +32,11 @@ from homeassistant.setup import async_setup_component
from homeassistant.util.unit_system import METRIC_SYSTEM from homeassistant.util.unit_system import METRIC_SYSTEM
from tests.async_mock import patch from tests.async_mock import patch
from tests.common import assert_setup_component, mock_restore_cache from tests.common import (
assert_setup_component,
async_fire_time_changed,
mock_restore_cache,
)
from tests.components.climate import common from tests.components.climate import common
ENTITY = "climate.test" ENTITY = "climate.test"
@ -949,13 +953,13 @@ async def test_temp_change_ac_trigger_on_long_enough_3(hass, setup_comp_7):
await hass.async_block_till_done() await hass.async_block_till_done()
await common.async_set_temperature(hass, 25) await common.async_set_temperature(hass, 25)
test_time = datetime.datetime.now(pytz.UTC) test_time = datetime.datetime.now(pytz.UTC)
_send_time_changed(hass, test_time) async_fire_time_changed(hass, test_time)
await hass.async_block_till_done() await hass.async_block_till_done()
assert 0 == len(calls) assert 0 == len(calls)
_send_time_changed(hass, test_time + datetime.timedelta(minutes=5)) async_fire_time_changed(hass, test_time + datetime.timedelta(minutes=5))
await hass.async_block_till_done() await hass.async_block_till_done()
assert 0 == len(calls) assert 0 == len(calls)
_send_time_changed(hass, test_time + datetime.timedelta(minutes=10)) async_fire_time_changed(hass, test_time + datetime.timedelta(minutes=10))
await hass.async_block_till_done() await hass.async_block_till_done()
assert 1 == len(calls) assert 1 == len(calls)
call = calls[0] call = calls[0]
@ -972,13 +976,13 @@ async def test_temp_change_ac_trigger_off_long_enough_3(hass, setup_comp_7):
await hass.async_block_till_done() await hass.async_block_till_done()
await common.async_set_temperature(hass, 25) await common.async_set_temperature(hass, 25)
test_time = datetime.datetime.now(pytz.UTC) test_time = datetime.datetime.now(pytz.UTC)
_send_time_changed(hass, test_time) async_fire_time_changed(hass, test_time)
await hass.async_block_till_done() await hass.async_block_till_done()
assert 0 == len(calls) assert 0 == len(calls)
_send_time_changed(hass, test_time + datetime.timedelta(minutes=5)) async_fire_time_changed(hass, test_time + datetime.timedelta(minutes=5))
await hass.async_block_till_done() await hass.async_block_till_done()
assert 0 == len(calls) assert 0 == len(calls)
_send_time_changed(hass, test_time + datetime.timedelta(minutes=10)) async_fire_time_changed(hass, test_time + datetime.timedelta(minutes=10))
await hass.async_block_till_done() await hass.async_block_till_done()
assert 1 == len(calls) assert 1 == len(calls)
call = calls[0] call = calls[0]
@ -987,11 +991,6 @@ async def test_temp_change_ac_trigger_off_long_enough_3(hass, setup_comp_7):
assert ENT_SWITCH == call.data["entity_id"] assert ENT_SWITCH == call.data["entity_id"]
def _send_time_changed(hass, now):
"""Send a time changed event."""
hass.bus.async_fire(ha.EVENT_TIME_CHANGED, {ha.ATTR_NOW: now})
@pytest.fixture @pytest.fixture
async def setup_comp_8(hass): async def setup_comp_8(hass):
"""Initialize components.""" """Initialize components."""
@ -1025,13 +1024,13 @@ async def test_temp_change_heater_trigger_on_long_enough_2(hass, setup_comp_8):
await hass.async_block_till_done() await hass.async_block_till_done()
await common.async_set_temperature(hass, 25) await common.async_set_temperature(hass, 25)
test_time = datetime.datetime.now(pytz.UTC) test_time = datetime.datetime.now(pytz.UTC)
_send_time_changed(hass, test_time) async_fire_time_changed(hass, test_time)
await hass.async_block_till_done() await hass.async_block_till_done()
assert 0 == len(calls) assert 0 == len(calls)
_send_time_changed(hass, test_time + datetime.timedelta(minutes=5)) async_fire_time_changed(hass, test_time + datetime.timedelta(minutes=5))
await hass.async_block_till_done() await hass.async_block_till_done()
assert 0 == len(calls) assert 0 == len(calls)
_send_time_changed(hass, test_time + datetime.timedelta(minutes=10)) async_fire_time_changed(hass, test_time + datetime.timedelta(minutes=10))
await hass.async_block_till_done() await hass.async_block_till_done()
assert 1 == len(calls) assert 1 == len(calls)
call = calls[0] call = calls[0]
@ -1048,13 +1047,13 @@ async def test_temp_change_heater_trigger_off_long_enough_2(hass, setup_comp_8):
await hass.async_block_till_done() await hass.async_block_till_done()
await common.async_set_temperature(hass, 25) await common.async_set_temperature(hass, 25)
test_time = datetime.datetime.now(pytz.UTC) test_time = datetime.datetime.now(pytz.UTC)
_send_time_changed(hass, test_time) async_fire_time_changed(hass, test_time)
await hass.async_block_till_done() await hass.async_block_till_done()
assert 0 == len(calls) assert 0 == len(calls)
_send_time_changed(hass, test_time + datetime.timedelta(minutes=5)) async_fire_time_changed(hass, test_time + datetime.timedelta(minutes=5))
await hass.async_block_till_done() await hass.async_block_till_done()
assert 0 == len(calls) assert 0 == len(calls)
_send_time_changed(hass, test_time + datetime.timedelta(minutes=10)) async_fire_time_changed(hass, test_time + datetime.timedelta(minutes=10))
await hass.async_block_till_done() await hass.async_block_till_done()
assert 1 == len(calls) assert 1 == len(calls)
call = calls[0] call = calls[0]

View file

@ -567,7 +567,7 @@ async def test_bicycle(hass, requests_mock_credentials_check):
assert sensor.attributes.get(ATTR_ICON) == ICON_BICYCLE assert sensor.attributes.get(ATTR_ICON) == ICON_BICYCLE
async def test_location_zone(hass, requests_mock_truck_response): async def test_location_zone(hass, requests_mock_truck_response, legacy_patchable_time):
"""Test that origin/destination supplied by a zone works.""" """Test that origin/destination supplied by a zone works."""
utcnow = dt_util.utcnow() utcnow = dt_util.utcnow()
# Patching 'utcnow' to gain more control over the timed update. # Patching 'utcnow' to gain more control over the timed update.
@ -618,7 +618,9 @@ async def test_location_zone(hass, requests_mock_truck_response):
_assert_truck_sensor(sensor) _assert_truck_sensor(sensor)
async def test_location_sensor(hass, requests_mock_truck_response): async def test_location_sensor(
hass, requests_mock_truck_response, legacy_patchable_time
):
"""Test that origin/destination supplied by a sensor works.""" """Test that origin/destination supplied by a sensor works."""
utcnow = dt_util.utcnow() utcnow = dt_util.utcnow()
# Patching 'utcnow' to gain more control over the timed update. # Patching 'utcnow' to gain more control over the timed update.
@ -658,7 +660,9 @@ async def test_location_sensor(hass, requests_mock_truck_response):
_assert_truck_sensor(sensor) _assert_truck_sensor(sensor)
async def test_location_person(hass, requests_mock_truck_response): async def test_location_person(
hass, requests_mock_truck_response, legacy_patchable_time
):
"""Test that origin/destination supplied by a person works.""" """Test that origin/destination supplied by a person works."""
utcnow = dt_util.utcnow() utcnow = dt_util.utcnow()
# Patching 'utcnow' to gain more control over the timed update. # Patching 'utcnow' to gain more control over the timed update.
@ -707,7 +711,9 @@ async def test_location_person(hass, requests_mock_truck_response):
_assert_truck_sensor(sensor) _assert_truck_sensor(sensor)
async def test_location_device_tracker(hass, requests_mock_truck_response): async def test_location_device_tracker(
hass, requests_mock_truck_response, legacy_patchable_time
):
"""Test that origin/destination supplied by a device_tracker works.""" """Test that origin/destination supplied by a device_tracker works."""
utcnow = dt_util.utcnow() utcnow = dt_util.utcnow()
# Patching 'utcnow' to gain more control over the timed update. # Patching 'utcnow' to gain more control over the timed update.
@ -757,7 +763,7 @@ async def test_location_device_tracker(hass, requests_mock_truck_response):
async def test_location_device_tracker_added_after_update( async def test_location_device_tracker_added_after_update(
hass, requests_mock_truck_response, caplog hass, requests_mock_truck_response, legacy_patchable_time, caplog
): ):
"""Test that device_tracker added after first update works.""" """Test that device_tracker added after first update works."""
caplog.set_level(logging.ERROR) caplog.set_level(logging.ERROR)

View file

@ -2,7 +2,7 @@
This includes tests for all mock object types. This includes tests for all mock object types.
""" """
from datetime import datetime, timedelta from datetime import timedelta
import pytest import pytest
@ -37,9 +37,7 @@ from homeassistant.const import (
ATTR_BATTERY_CHARGING, ATTR_BATTERY_CHARGING,
ATTR_BATTERY_LEVEL, ATTR_BATTERY_LEVEL,
ATTR_ENTITY_ID, ATTR_ENTITY_ID,
ATTR_NOW,
ATTR_SERVICE, ATTR_SERVICE,
EVENT_TIME_CHANGED,
STATE_OFF, STATE_OFF,
STATE_ON, STATE_ON,
STATE_UNAVAILABLE, STATE_UNAVAILABLE,
@ -49,7 +47,7 @@ from homeassistant.helpers.event import TRACK_STATE_CHANGE_CALLBACKS
import homeassistant.util.dt as dt_util import homeassistant.util.dt as dt_util
from tests.async_mock import Mock, patch from tests.async_mock import Mock, patch
from tests.common import async_mock_service from tests.common import async_fire_time_changed, async_mock_service
async def test_debounce(hass): async def test_debounce(hass):
@ -66,11 +64,11 @@ async def test_debounce(hass):
debounce_demo = debounce(demo_func) debounce_demo = debounce(demo_func)
assert debounce_demo.__name__ == "demo_func" assert debounce_demo.__name__ == "demo_func"
now = datetime(2018, 1, 1, 20, 0, 0, tzinfo=dt_util.UTC) now = dt_util.utcnow()
with patch("homeassistant.util.dt.utcnow", return_value=now): with patch("homeassistant.util.dt.utcnow", return_value=now):
await hass.async_add_executor_job(debounce_demo, mock, "value") await hass.async_add_executor_job(debounce_demo, mock, "value")
hass.bus.async_fire(EVENT_TIME_CHANGED, {ATTR_NOW: now + timedelta(seconds=3)}) async_fire_time_changed(hass, now + timedelta(seconds=3))
await hass.async_block_till_done() await hass.async_block_till_done()
assert counter == 1 assert counter == 1
assert len(arguments) == 2 assert len(arguments) == 2
@ -79,7 +77,7 @@ async def test_debounce(hass):
await hass.async_add_executor_job(debounce_demo, mock, "value") await hass.async_add_executor_job(debounce_demo, mock, "value")
await hass.async_add_executor_job(debounce_demo, mock, "value") await hass.async_add_executor_job(debounce_demo, mock, "value")
hass.bus.async_fire(EVENT_TIME_CHANGED, {ATTR_NOW: now + timedelta(seconds=3)}) async_fire_time_changed(hass, now + timedelta(seconds=3))
await hass.async_block_till_done() await hass.async_block_till_done()
assert counter == 2 assert counter == 2

View file

@ -5,13 +5,16 @@ from unittest import mock
from aiohomekit.testing import FakeController from aiohomekit.testing import FakeController
import pytest import pytest
import homeassistant.util.dt as dt_util
import tests.async_mock import tests.async_mock
@pytest.fixture @pytest.fixture
def utcnow(request): def utcnow(request):
"""Freeze time at a known point.""" """Freeze time at a known point."""
start_dt = datetime.datetime(2019, 1, 1, 0, 0, 0) now = dt_util.utcnow()
start_dt = datetime.datetime(now.year + 1, 1, 1, 0, 0, 0)
with mock.patch("homeassistant.util.dt.utcnow") as dt_utcnow: with mock.patch("homeassistant.util.dt.utcnow") as dt_utcnow:
dt_utcnow.return_value = start_dt dt_utcnow.return_value = start_dt
yield dt_utcnow yield dt_utcnow

View file

@ -85,7 +85,7 @@ async def test_unload_entry(hass):
assert islamic_prayer_times.DOMAIN not in hass.data assert islamic_prayer_times.DOMAIN not in hass.data
async def test_islamic_prayer_times_timestamp_format(hass): async def test_islamic_prayer_times_timestamp_format(hass, legacy_patchable_time):
"""Test Islamic prayer times timestamp format.""" """Test Islamic prayer times timestamp format."""
entry = MockConfigEntry(domain=islamic_prayer_times.DOMAIN, data={}) entry = MockConfigEntry(domain=islamic_prayer_times.DOMAIN, data={})
entry.add_to_hass(hass) entry.add_to_hass(hass)
@ -94,7 +94,6 @@ async def test_islamic_prayer_times_timestamp_format(hass):
"prayer_times_calculator.PrayerTimesCalculator.fetch_prayer_times", "prayer_times_calculator.PrayerTimesCalculator.fetch_prayer_times",
return_value=PRAYER_TIMES, return_value=PRAYER_TIMES,
), patch("homeassistant.util.dt.now", return_value=NOW): ), patch("homeassistant.util.dt.now", return_value=NOW):
await hass.config_entries.async_setup(entry.entry_id) await hass.config_entries.async_setup(entry.entry_id)
assert ( assert (
@ -103,7 +102,7 @@ async def test_islamic_prayer_times_timestamp_format(hass):
) )
async def test_update(hass): async def test_update(hass, legacy_patchable_time):
"""Test sensors are updated with new prayer times.""" """Test sensors are updated with new prayer times."""
entry = MockConfigEntry(domain=islamic_prayer_times.DOMAIN, data={}) entry = MockConfigEntry(domain=islamic_prayer_times.DOMAIN, data={})
entry.add_to_hass(hass) entry.add_to_hass(hass)

View file

@ -8,7 +8,7 @@ from tests.async_mock import patch
from tests.common import MockConfigEntry from tests.common import MockConfigEntry
async def test_islamic_prayer_times_sensors(hass): async def test_islamic_prayer_times_sensors(hass, legacy_patchable_time):
"""Test minimum Islamic prayer times configuration.""" """Test minimum Islamic prayer times configuration."""
entry = MockConfigEntry(domain=islamic_prayer_times.DOMAIN, data={}) entry = MockConfigEntry(domain=islamic_prayer_times.DOMAIN, data={})
entry.add_to_hass(hass) entry.add_to_hass(hass)
@ -17,7 +17,6 @@ async def test_islamic_prayer_times_sensors(hass):
"prayer_times_calculator.PrayerTimesCalculator.fetch_prayer_times", "prayer_times_calculator.PrayerTimesCalculator.fetch_prayer_times",
return_value=PRAYER_TIMES, return_value=PRAYER_TIMES,
), patch("homeassistant.util.dt.now", return_value=NOW): ), patch("homeassistant.util.dt.now", return_value=NOW):
await hass.config_entries.async_setup(entry.entry_id) await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done() await hass.async_block_till_done()

View file

@ -60,7 +60,16 @@ MELACHA_TEST_IDS = [
ids=MELACHA_TEST_IDS, ids=MELACHA_TEST_IDS,
) )
async def test_issur_melacha_sensor( async def test_issur_melacha_sensor(
hass, now, candle_lighting, havdalah, diaspora, tzname, latitude, longitude, result hass,
legacy_patchable_time,
now,
candle_lighting,
havdalah,
diaspora,
tzname,
latitude,
longitude,
result,
): ):
"""Test Issur Melacha sensor output.""" """Test Issur Melacha sensor output."""
time_zone = dt_util.get_time_zone(tzname) time_zone = dt_util.get_time_zone(tzname)

View file

@ -144,7 +144,16 @@ TEST_IDS = [
ids=TEST_IDS, ids=TEST_IDS,
) )
async def test_jewish_calendar_sensor( async def test_jewish_calendar_sensor(
hass, now, tzname, latitude, longitude, language, sensor, diaspora, result hass,
legacy_patchable_time,
now,
tzname,
latitude,
longitude,
language,
sensor,
diaspora,
result,
): ):
"""Test Jewish calendar sensor output.""" """Test Jewish calendar sensor output."""
time_zone = dt_util.get_time_zone(tzname) time_zone = dt_util.get_time_zone(tzname)
@ -478,6 +487,7 @@ SHABBAT_TEST_IDS = [
) )
async def test_shabbat_times_sensor( async def test_shabbat_times_sensor(
hass, hass,
legacy_patchable_time,
language, language,
now, now,
candle_lighting, candle_lighting,
@ -553,7 +563,7 @@ OMER_TEST_IDS = [
@pytest.mark.parametrize(["test_time", "result"], OMER_PARAMS, ids=OMER_TEST_IDS) @pytest.mark.parametrize(["test_time", "result"], OMER_PARAMS, ids=OMER_TEST_IDS)
async def test_omer_sensor(hass, test_time, result): async def test_omer_sensor(hass, legacy_patchable_time, test_time, result):
"""Test Omer Count sensor output.""" """Test Omer Count sensor output."""
test_time = hass.config.time_zone.localize(test_time) test_time = hass.config.time_zone.localize(test_time)
@ -587,7 +597,7 @@ DAFYOMI_TEST_IDS = [
@pytest.mark.parametrize(["test_time", "result"], DAFYOMI_PARAMS, ids=DAFYOMI_TEST_IDS) @pytest.mark.parametrize(["test_time", "result"], DAFYOMI_PARAMS, ids=DAFYOMI_TEST_IDS)
async def test_dafyomi_sensor(hass, test_time, result): async def test_dafyomi_sensor(hass, legacy_patchable_time, test_time, result):
"""Test Daf Yomi sensor output.""" """Test Daf Yomi sensor output."""
test_time = hass.config.time_zone.localize(test_time) test_time = hass.config.time_zone.localize(test_time)

View file

@ -1450,7 +1450,7 @@ async def test_armed_custom_bypass_with_specific_pending(hass):
assert STATE_ALARM_ARMED_CUSTOM_BYPASS == hass.states.get(entity_id).state assert STATE_ALARM_ARMED_CUSTOM_BYPASS == hass.states.get(entity_id).state
async def test_arm_away_after_disabled_disarmed(hass): async def test_arm_away_after_disabled_disarmed(hass, legacy_patchable_time):
"""Test pending state with and without zero trigger time.""" """Test pending state with and without zero trigger time."""
assert await async_setup_component( assert await async_setup_component(
hass, hass,

View file

@ -1348,7 +1348,7 @@ async def test_trigger_with_specific_pending(hass, mqtt_mock):
assert STATE_ALARM_DISARMED == hass.states.get(entity_id).state assert STATE_ALARM_DISARMED == hass.states.get(entity_id).state
async def test_arm_away_after_disabled_disarmed(hass, mqtt_mock): async def test_arm_away_after_disabled_disarmed(hass, legacy_patchable_time, mqtt_mock):
"""Test pending state with and without zero trigger time.""" """Test pending state with and without zero trigger time."""
assert await async_setup_component( assert await async_setup_component(
hass, hass,

View file

@ -23,9 +23,8 @@ from tests.common import MockConfigEntry, load_fixture
"datapoint.Forecast.datetime.datetime", "datapoint.Forecast.datetime.datetime",
Mock(now=Mock(return_value=datetime(2020, 4, 25, 12, tzinfo=timezone.utc))), Mock(now=Mock(return_value=datetime(2020, 4, 25, 12, tzinfo=timezone.utc))),
) )
async def test_one_sensor_site_running(hass, requests_mock): async def test_one_sensor_site_running(hass, requests_mock, legacy_patchable_time):
"""Test the Met Office sensor platform.""" """Test the Met Office sensor platform."""
# all metoffice test data encapsulated in here # all metoffice test data encapsulated in here
mock_json = json.loads(load_fixture("metoffice.json")) mock_json = json.loads(load_fixture("metoffice.json"))
all_sites = json.dumps(mock_json["all_sites"]) all_sites = json.dumps(mock_json["all_sites"])
@ -62,7 +61,7 @@ async def test_one_sensor_site_running(hass, requests_mock):
"datapoint.Forecast.datetime.datetime", "datapoint.Forecast.datetime.datetime",
Mock(now=Mock(return_value=datetime(2020, 4, 25, 12, tzinfo=timezone.utc))), Mock(now=Mock(return_value=datetime(2020, 4, 25, 12, tzinfo=timezone.utc))),
) )
async def test_two_sensor_sites_running(hass, requests_mock): async def test_two_sensor_sites_running(hass, requests_mock, legacy_patchable_time):
"""Test we handle two sets of sensors running for two different sites.""" """Test we handle two sets of sensors running for two different sites."""
# all metoffice test data encapsulated in here # all metoffice test data encapsulated in here

View file

@ -20,7 +20,7 @@ from tests.common import MockConfigEntry, async_fire_time_changed, load_fixture
"datapoint.Forecast.datetime.datetime", "datapoint.Forecast.datetime.datetime",
Mock(now=Mock(return_value=datetime(2020, 4, 25, 12, tzinfo=timezone.utc))), Mock(now=Mock(return_value=datetime(2020, 4, 25, 12, tzinfo=timezone.utc))),
) )
async def test_site_cannot_connect(hass, requests_mock): async def test_site_cannot_connect(hass, requests_mock, legacy_patchable_time):
"""Test we handle cannot connect error.""" """Test we handle cannot connect error."""
requests_mock.get("/public/data/val/wxfcs/all/json/sitelist/", text="") requests_mock.get("/public/data/val/wxfcs/all/json/sitelist/", text="")
@ -42,7 +42,7 @@ async def test_site_cannot_connect(hass, requests_mock):
"datapoint.Forecast.datetime.datetime", "datapoint.Forecast.datetime.datetime",
Mock(now=Mock(return_value=datetime(2020, 4, 25, 12, tzinfo=timezone.utc))), Mock(now=Mock(return_value=datetime(2020, 4, 25, 12, tzinfo=timezone.utc))),
) )
async def test_site_cannot_update(hass, requests_mock): async def test_site_cannot_update(hass, requests_mock, legacy_patchable_time):
"""Test we handle cannot connect error.""" """Test we handle cannot connect error."""
# all metoffice test data encapsulated in here # all metoffice test data encapsulated in here
@ -77,7 +77,7 @@ async def test_site_cannot_update(hass, requests_mock):
"datapoint.Forecast.datetime.datetime", "datapoint.Forecast.datetime.datetime",
Mock(now=Mock(return_value=datetime(2020, 4, 25, 12, tzinfo=timezone.utc))), Mock(now=Mock(return_value=datetime(2020, 4, 25, 12, tzinfo=timezone.utc))),
) )
async def test_one_weather_site_running(hass, requests_mock): async def test_one_weather_site_running(hass, requests_mock, legacy_patchable_time):
"""Test the Met Office weather platform.""" """Test the Met Office weather platform."""
# all metoffice test data encapsulated in here # all metoffice test data encapsulated in here
@ -111,7 +111,7 @@ async def test_one_weather_site_running(hass, requests_mock):
"datapoint.Forecast.datetime.datetime", "datapoint.Forecast.datetime.datetime",
Mock(now=Mock(return_value=datetime(2020, 4, 25, 12, tzinfo=timezone.utc))), Mock(now=Mock(return_value=datetime(2020, 4, 25, 12, tzinfo=timezone.utc))),
) )
async def test_two_weather_sites_running(hass, requests_mock): async def test_two_weather_sites_running(hass, requests_mock, legacy_patchable_time):
"""Test we handle two different weather sites both running.""" """Test we handle two different weather sites both running."""
# all metoffice test data encapsulated in here # all metoffice test data encapsulated in here

View file

@ -39,7 +39,7 @@ async def test_platform_manually_configured(hass):
assert mikrotik.DOMAIN not in hass.data assert mikrotik.DOMAIN not in hass.data
async def test_device_trackers(hass): async def test_device_trackers(hass, legacy_patchable_time):
"""Test device_trackers created by mikrotik.""" """Test device_trackers created by mikrotik."""
# test devices are added from wireless list only # test devices are added from wireless list only

View file

@ -1,46 +1,59 @@
"""The test for the moon sensor platform.""" """The test for the moon sensor platform."""
from datetime import datetime from datetime import datetime
import unittest
from homeassistant.setup import setup_component from homeassistant.components.homeassistant import (
DOMAIN as HA_DOMAIN,
SERVICE_UPDATE_ENTITY,
)
from homeassistant.const import ATTR_ENTITY_ID
from homeassistant.setup import async_setup_component
import homeassistant.util.dt as dt_util import homeassistant.util.dt as dt_util
from tests.async_mock import patch from tests.async_mock import patch
from tests.common import get_test_home_assistant
DAY1 = datetime(2017, 1, 1, 1, tzinfo=dt_util.UTC) DAY1 = datetime(2017, 1, 1, 1, tzinfo=dt_util.UTC)
DAY2 = datetime(2017, 1, 18, 1, tzinfo=dt_util.UTC) DAY2 = datetime(2017, 1, 18, 1, tzinfo=dt_util.UTC)
class TestMoonSensor(unittest.TestCase): async def test_moon_day1(hass):
"""Test the Moon sensor.""" """Test the Moon sensor."""
config = {"sensor": {"platform": "moon", "name": "moon_day1"}}
def setup_method(self, method): await async_setup_component(hass, HA_DOMAIN, {})
"""Set up things to be run when tests are started.""" assert await async_setup_component(hass, "sensor", config)
self.hass = get_test_home_assistant() await hass.async_block_till_done()
def teardown_method(self, method): assert hass.states.get("sensor.moon_day1")
"""Stop everything that was started."""
self.hass.stop()
@patch("homeassistant.components.moon.sensor.dt_util.utcnow", return_value=DAY1) with patch(
def test_moon_day1(self, mock_request): "homeassistant.components.moon.sensor.dt_util.utcnow", return_value=DAY1
"""Test the Moon sensor.""" ):
config = {"sensor": {"platform": "moon", "name": "moon_day1"}} await async_update_entity(hass, "sensor.moon_day1")
assert setup_component(self.hass, "sensor", config) assert hass.states.get("sensor.moon_day1").state == "waxing_crescent"
self.hass.block_till_done()
state = self.hass.states.get("sensor.moon_day1")
assert state.state == "waxing_crescent"
@patch("homeassistant.components.moon.sensor.dt_util.utcnow", return_value=DAY2) async def test_moon_day2(hass):
def test_moon_day2(self, mock_request): """Test the Moon sensor."""
"""Test the Moon sensor.""" config = {"sensor": {"platform": "moon", "name": "moon_day2"}}
config = {"sensor": {"platform": "moon", "name": "moon_day2"}}
assert setup_component(self.hass, "sensor", config) await async_setup_component(hass, HA_DOMAIN, {})
self.hass.block_till_done() assert await async_setup_component(hass, "sensor", config)
await hass.async_block_till_done()
state = self.hass.states.get("sensor.moon_day2") assert hass.states.get("sensor.moon_day2")
assert state.state == "waning_gibbous"
with patch(
"homeassistant.components.moon.sensor.dt_util.utcnow", return_value=DAY2
):
await async_update_entity(hass, "sensor.moon_day2")
assert hass.states.get("sensor.moon_day2").state == "waning_gibbous"
async def async_update_entity(hass, entity_id):
"""Run an update action for an entity."""
await hass.services.async_call(
HA_DOMAIN, SERVICE_UPDATE_ENTITY, {ATTR_ENTITY_ID: entity_id}, blocking=True,
)
await hass.async_block_till_done()

View file

@ -52,7 +52,9 @@ DEFAULT_CONFIG = {
} }
async def test_setting_sensor_value_expires_availability_topic(hass, mqtt_mock, caplog): async def test_setting_sensor_value_expires_availability_topic(
hass, mqtt_mock, legacy_patchable_time, caplog
):
"""Test the expiration of the value.""" """Test the expiration of the value."""
assert await async_setup_component( assert await async_setup_component(
hass, hass,
@ -82,7 +84,9 @@ async def test_setting_sensor_value_expires_availability_topic(hass, mqtt_mock,
await expires_helper(hass, mqtt_mock, caplog) await expires_helper(hass, mqtt_mock, caplog)
async def test_setting_sensor_value_expires(hass, mqtt_mock, caplog): async def test_setting_sensor_value_expires(
hass, mqtt_mock, legacy_patchable_time, caplog
):
"""Test the expiration of the value.""" """Test the expiration of the value."""
assert await async_setup_component( assert await async_setup_component(
hass, hass,
@ -520,7 +524,7 @@ async def test_discovery_update_binary_sensor(hass, mqtt_mock, caplog):
async def test_expiration_on_discovery_and_discovery_update_of_binary_sensor( async def test_expiration_on_discovery_and_discovery_update_of_binary_sensor(
hass, mqtt_mock, caplog hass, mqtt_mock, legacy_patchable_time, caplog
): ):
"""Test that binary_sensor with expire_after set behaves correctly on discovery and discovery update.""" """Test that binary_sensor with expire_after set behaves correctly on discovery and discovery update."""
entry = hass.config_entries.async_entries(mqtt.DOMAIN)[0] entry = hass.config_entries.async_entries(mqtt.DOMAIN)[0]

View file

@ -70,7 +70,9 @@ async def test_setting_sensor_value_via_mqtt_message(hass, mqtt_mock):
assert state.attributes.get("unit_of_measurement") == "fav unit" assert state.attributes.get("unit_of_measurement") == "fav unit"
async def test_setting_sensor_value_expires(hass, mqtt_mock, caplog): async def test_setting_sensor_value_expires(
hass, mqtt_mock, legacy_patchable_time, caplog
):
"""Test the expiration of the value.""" """Test the expiration of the value."""
assert await async_setup_component( assert await async_setup_component(
hass, hass,
@ -91,7 +93,8 @@ async def test_setting_sensor_value_expires(hass, mqtt_mock, caplog):
state = hass.states.get("sensor.test") state = hass.states.get("sensor.test")
assert state.state == "unknown" assert state.state == "unknown"
now = datetime(2017, 1, 1, 1, tzinfo=dt_util.UTC) realnow = dt_util.utcnow()
now = datetime(realnow.year + 1, 1, 1, 1, tzinfo=dt_util.UTC)
with patch(("homeassistant.helpers.event.dt_util.utcnow"), return_value=now): with patch(("homeassistant.helpers.event.dt_util.utcnow"), return_value=now):
async_fire_time_changed(hass, now) async_fire_time_changed(hass, now)
async_fire_mqtt_message(hass, "test-topic", "100") async_fire_mqtt_message(hass, "test-topic", "100")

View file

@ -6,13 +6,16 @@ import unittest
import pytest import pytest
from homeassistant import core as ha
from homeassistant.components import pilight from homeassistant.components import pilight
from homeassistant.setup import setup_component from homeassistant.setup import setup_component
from homeassistant.util import dt as dt_util from homeassistant.util import dt as dt_util
from tests.async_mock import patch from tests.async_mock import patch
from tests.common import assert_setup_component, get_test_home_assistant from tests.common import (
assert_setup_component,
async_fire_time_changed,
get_test_home_assistant,
)
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -196,13 +199,13 @@ class TestPilight(unittest.TestCase):
service_data1["protocol"] = [service_data1["protocol"]] service_data1["protocol"] = [service_data1["protocol"]]
service_data2["protocol"] = [service_data2["protocol"]] service_data2["protocol"] = [service_data2["protocol"]]
self.hass.bus.fire(ha.EVENT_TIME_CHANGED, {ha.ATTR_NOW: dt_util.utcnow()}) async_fire_time_changed(self.hass, dt_util.utcnow())
self.hass.block_till_done() self.hass.block_till_done()
error_log_call = mock_pilight_error.call_args_list[-1] error_log_call = mock_pilight_error.call_args_list[-1]
assert str(service_data1) in str(error_log_call) assert str(service_data1) in str(error_log_call)
new_time = dt_util.utcnow() + timedelta(seconds=5) new_time = dt_util.utcnow() + timedelta(seconds=5)
self.hass.bus.fire(ha.EVENT_TIME_CHANGED, {ha.ATTR_NOW: new_time}) async_fire_time_changed(self.hass, new_time)
self.hass.block_till_done() self.hass.block_till_done()
error_log_call = mock_pilight_error.call_args_list[-1] error_log_call = mock_pilight_error.call_args_list[-1]
assert str(service_data2) in str(error_log_call) assert str(service_data2) in str(error_log_call)
@ -407,6 +410,6 @@ class TestPilightCallrateThrottler(unittest.TestCase):
for i in range(3): for i in range(3):
exp.append(i) exp.append(i)
shifted_time = now + (timedelta(seconds=delay + 0.1) * i) shifted_time = now + (timedelta(seconds=delay + 0.1) * i)
self.hass.bus.fire(ha.EVENT_TIME_CHANGED, {ha.ATTR_NOW: shifted_time}) async_fire_time_changed(self.hass, shifted_time)
self.hass.block_till_done() self.hass.block_till_done()
assert runs == exp assert runs == exp

View file

@ -2,11 +2,12 @@
from datetime import timedelta from datetime import timedelta
import io import io
from homeassistant import core as ha
from homeassistant.config import async_process_ha_core_config from homeassistant.config import async_process_ha_core_config
from homeassistant.setup import async_setup_component from homeassistant.setup import async_setup_component
from homeassistant.util import dt as dt_util from homeassistant.util import dt as dt_util
from tests.common import async_fire_time_changed
async def test_bad_posting(hass, aiohttp_client): async def test_bad_posting(hass, aiohttp_client):
"""Test that posting to wrong api endpoint fails.""" """Test that posting to wrong api endpoint fails."""
@ -74,7 +75,7 @@ async def test_posting_url(hass, aiohttp_client):
# await timeout # await timeout
shifted_time = dt_util.utcnow() + timedelta(seconds=15) shifted_time = dt_util.utcnow() + timedelta(seconds=15)
hass.bus.async_fire(ha.EVENT_TIME_CHANGED, {ha.ATTR_NOW: shifted_time}) async_fire_time_changed(hass, shifted_time)
await hass.async_block_till_done() await hass.async_block_till_done()
# back to initial state # back to initial state

View file

@ -15,7 +15,9 @@ from tests.common import date_util
from tests.test_util.aiohttp import AiohttpClientMocker from tests.test_util.aiohttp import AiohttpClientMocker
async def test_config_flow(hass, pvpc_aioclient_mock: AiohttpClientMocker): async def test_config_flow(
hass, legacy_patchable_time, pvpc_aioclient_mock: AiohttpClientMocker
):
""" """
Test config flow for pvpc_hourly_pricing. Test config flow for pvpc_hourly_pricing.

View file

@ -29,7 +29,7 @@ async def _process_time_step(
async def test_sensor_availability( async def test_sensor_availability(
hass, caplog, pvpc_aioclient_mock: AiohttpClientMocker hass, caplog, legacy_patchable_time, pvpc_aioclient_mock: AiohttpClientMocker
): ):
"""Test sensor availability and handling of cloud access.""" """Test sensor availability and handling of cloud access."""
hass.config.time_zone = timezone("Europe/Madrid") hass.config.time_zone = timezone("Europe/Madrid")

View file

@ -116,7 +116,7 @@ async def test_entity_availability(hass, monkeypatch):
assert hass.states.get("binary_sensor.test").state == STATE_OFF assert hass.states.get("binary_sensor.test").state == STATE_OFF
async def test_off_delay(hass, monkeypatch): async def test_off_delay(hass, legacy_patchable_time, monkeypatch):
"""Test off_delay option.""" """Test off_delay option."""
# setup mocking rflink module # setup mocking rflink module
event_callback, create, _, _ = await mock_rflink(hass, CONFIG, DOMAIN, monkeypatch) event_callback, create, _, _ = await mock_rflink(hass, CONFIG, DOMAIN, monkeypatch)

View file

@ -3,6 +3,8 @@ from datetime import datetime, timedelta
import statistics import statistics
import unittest import unittest
import pytest
from homeassistant.components import recorder from homeassistant.components import recorder
from homeassistant.components.statistics.sensor import StatisticsSensor from homeassistant.components.statistics.sensor import StatisticsSensor
from homeassistant.const import ATTR_UNIT_OF_MEASUREMENT, STATE_UNKNOWN, TEMP_CELSIUS from homeassistant.const import ATTR_UNIT_OF_MEASUREMENT, STATE_UNKNOWN, TEMP_CELSIUS
@ -18,6 +20,12 @@ from tests.common import (
from tests.components.recorder.common import wait_recording_done from tests.components.recorder.common import wait_recording_done
@pytest.fixture(autouse=True)
def mock_legacy_time(legacy_patchable_time):
"""Make time patchable for all the tests."""
yield
class TestStatisticsSensor(unittest.TestCase): class TestStatisticsSensor(unittest.TestCase):
"""Test the Statistics sensor.""" """Test the Statistics sensor."""
@ -36,10 +44,7 @@ class TestStatisticsSensor(unittest.TestCase):
self.change = round(self.values[-1] - self.values[0], 2) self.change = round(self.values[-1] - self.values[0], 2)
self.average_change = round(self.change / (len(self.values) - 1), 2) self.average_change = round(self.change / (len(self.values) - 1), 2)
self.change_rate = round(self.change / (60 * (self.count - 1)), 2) self.change_rate = round(self.change / (60 * (self.count - 1)), 2)
self.addCleanup(self.hass.stop)
def teardown_method(self, method):
"""Stop everything that was started."""
self.hass.stop()
def test_binary_sensor_source(self): def test_binary_sensor_source(self):
"""Test if source is a sensor.""" """Test if source is a sensor."""

View file

@ -12,7 +12,7 @@ import homeassistant.util.dt as dt_util
from tests.async_mock import patch from tests.async_mock import patch
async def test_setting_rising(hass): async def test_setting_rising(hass, legacy_patchable_time):
"""Test retrieving sun setting and rising.""" """Test retrieving sun setting and rising."""
utc_now = datetime(2016, 11, 1, 8, 0, 0, tzinfo=dt_util.UTC) utc_now = datetime(2016, 11, 1, 8, 0, 0, tzinfo=dt_util.UTC)
with patch("homeassistant.helpers.condition.dt_util.utcnow", return_value=utc_now): with patch("homeassistant.helpers.condition.dt_util.utcnow", return_value=utc_now):
@ -103,7 +103,7 @@ async def test_setting_rising(hass):
) )
async def test_state_change(hass): async def test_state_change(hass, legacy_patchable_time):
"""Test if the state changes at next setting/rising.""" """Test if the state changes at next setting/rising."""
now = datetime(2016, 6, 1, 8, 0, 0, tzinfo=dt_util.UTC) now = datetime(2016, 6, 1, 8, 0, 0, tzinfo=dt_util.UTC)
with patch("homeassistant.helpers.condition.dt_util.utcnow", return_value=now): with patch("homeassistant.helpers.condition.dt_util.utcnow", return_value=now):

View file

@ -2,6 +2,7 @@
from datetime import datetime, timedelta from datetime import datetime, timedelta
import unittest import unittest
import pytest
import pytz import pytz
from homeassistant import setup from homeassistant import setup
@ -15,6 +16,12 @@ from tests.async_mock import patch
from tests.common import assert_setup_component, get_test_home_assistant from tests.common import assert_setup_component, get_test_home_assistant
@pytest.fixture(autouse=True)
def mock_legacy_time(legacy_patchable_time):
"""Make time patchable for all the tests."""
yield
class TestBinarySensorTod(unittest.TestCase): class TestBinarySensorTod(unittest.TestCase):
"""Test for Binary sensor tod platform.""" """Test for Binary sensor tod platform."""

View file

@ -11,7 +11,7 @@ from tests.common import assert_setup_component, load_fixture
NOW = datetime(2016, 6, 9, 1, tzinfo=dt_util.UTC) NOW = datetime(2016, 6, 9, 1, tzinfo=dt_util.UTC)
async def test_default_setup(hass, aioclient_mock): async def test_default_setup(hass, legacy_patchable_time, aioclient_mock):
"""Test the default setup.""" """Test the default setup."""
aioclient_mock.get( aioclient_mock.get(
"https://aa015h6buqvih86i1.api.met.no/weatherapi/locationforecast/1.9/", "https://aa015h6buqvih86i1.api.met.no/weatherapi/locationforecast/1.9/",
@ -19,6 +19,7 @@ async def test_default_setup(hass, aioclient_mock):
) )
config = {"platform": "yr", "elevation": 0} config = {"platform": "yr", "elevation": 0}
hass.allow_pool = True hass.allow_pool = True
with patch( with patch(
"homeassistant.components.yr.sensor.dt_util.utcnow", return_value=NOW "homeassistant.components.yr.sensor.dt_util.utcnow", return_value=NOW
), assert_setup_component(1): ), assert_setup_component(1):
@ -31,7 +32,7 @@ async def test_default_setup(hass, aioclient_mock):
assert state.attributes.get("unit_of_measurement") is None assert state.attributes.get("unit_of_measurement") is None
async def test_custom_setup(hass, aioclient_mock): async def test_custom_setup(hass, legacy_patchable_time, aioclient_mock):
"""Test a custom setup.""" """Test a custom setup."""
aioclient_mock.get( aioclient_mock.get(
"https://aa015h6buqvih86i1.api.met.no/weatherapi/locationforecast/1.9/", "https://aa015h6buqvih86i1.api.met.no/weatherapi/locationforecast/1.9/",
@ -50,6 +51,7 @@ async def test_custom_setup(hass, aioclient_mock):
], ],
} }
hass.allow_pool = True hass.allow_pool = True
with patch( with patch(
"homeassistant.components.yr.sensor.dt_util.utcnow", return_value=NOW "homeassistant.components.yr.sensor.dt_util.utcnow", return_value=NOW
), assert_setup_component(1): ), assert_setup_component(1):
@ -77,7 +79,7 @@ async def test_custom_setup(hass, aioclient_mock):
assert state.state == "3.5" assert state.state == "3.5"
async def test_forecast_setup(hass, aioclient_mock): async def test_forecast_setup(hass, legacy_patchable_time, aioclient_mock):
"""Test a custom setup with 24h forecast.""" """Test a custom setup with 24h forecast."""
aioclient_mock.get( aioclient_mock.get(
"https://aa015h6buqvih86i1.api.met.no/weatherapi/locationforecast/1.9/", "https://aa015h6buqvih86i1.api.met.no/weatherapi/locationforecast/1.9/",
@ -97,6 +99,7 @@ async def test_forecast_setup(hass, aioclient_mock):
], ],
} }
hass.allow_pool = True hass.allow_pool = True
with patch( with patch(
"homeassistant.components.yr.sensor.dt_util.utcnow", return_value=NOW "homeassistant.components.yr.sensor.dt_util.utcnow", return_value=NOW
), assert_setup_component(1): ), assert_setup_component(1):

View file

@ -5,7 +5,7 @@ import logging
import pytest import pytest
import requests_mock as _requests_mock import requests_mock as _requests_mock
from homeassistant import core as ha, util from homeassistant import core as ha, loader, util
from homeassistant.auth.const import GROUP_ID_ADMIN, GROUP_ID_READ_ONLY from homeassistant.auth.const import GROUP_ID_ADMIN, GROUP_ID_READ_ONLY
from homeassistant.auth.providers import homeassistant, legacy_api_password from homeassistant.auth.providers import homeassistant, legacy_api_password
from homeassistant.components import mqtt from homeassistant.components import mqtt
@ -15,7 +15,9 @@ from homeassistant.components.websocket_api.auth import (
TYPE_AUTH_REQUIRED, TYPE_AUTH_REQUIRED,
) )
from homeassistant.components.websocket_api.http import URL from homeassistant.components.websocket_api.http import URL
from homeassistant.const import ATTR_NOW, EVENT_TIME_CHANGED
from homeassistant.exceptions import ServiceNotFound from homeassistant.exceptions import ServiceNotFound
from homeassistant.helpers import event
from homeassistant.setup import async_setup_component from homeassistant.setup import async_setup_component
from homeassistant.util import location from homeassistant.util import location
@ -315,3 +317,43 @@ async def mqtt_mock(hass, mqtt_client_mock, mqtt_config):
component = hass.data["mqtt"] component = hass.data["mqtt"]
component.reset_mock() component.reset_mock()
return component return component
@pytest.fixture
def legacy_patchable_time():
"""Allow time to be patchable by using event listeners instead of asyncio loop."""
@ha.callback
@loader.bind_hass
def async_track_point_in_utc_time(hass, action, point_in_time):
"""Add a listener that fires once after a specific point in UTC time."""
# Ensure point_in_time is UTC
point_in_time = event.dt_util.as_utc(point_in_time)
@ha.callback
def point_in_time_listener(event):
"""Listen for matching time_changed events."""
now = event.data[ATTR_NOW]
if now < point_in_time or hasattr(point_in_time_listener, "run"):
return
# Set variable so that we will never run twice.
# Because the event bus might have to wait till a thread comes
# available to execute this listener it might occur that the
# listener gets lined up twice to be executed. This will make
# sure the second time it does nothing.
setattr(point_in_time_listener, "run", True)
async_unsub()
hass.async_run_job(action, now)
async_unsub = hass.bus.async_listen(EVENT_TIME_CHANGED, point_in_time_listener)
return async_unsub
with patch(
"homeassistant.helpers.event.async_track_point_in_utc_time",
async_track_point_in_utc_time,
):
yield

View file

@ -38,11 +38,6 @@ def teardown():
dt_util.set_default_time_zone(DEFAULT_TIME_ZONE) dt_util.set_default_time_zone(DEFAULT_TIME_ZONE)
def _send_time_changed(hass, now):
"""Send a time changed event."""
hass.bus.async_fire(ha.EVENT_TIME_CHANGED, {ha.ATTR_NOW: now})
async def test_track_point_in_time(hass): async def test_track_point_in_time(hass):
"""Test track point in time.""" """Test track point in time."""
before_birthday = datetime(1985, 7, 9, 12, 0, 0, tzinfo=dt_util.UTC) before_birthday = datetime(1985, 7, 9, 12, 0, 0, tzinfo=dt_util.UTC)
@ -55,16 +50,16 @@ async def test_track_point_in_time(hass):
hass, callback(lambda x: runs.append(1)), birthday_paulus hass, callback(lambda x: runs.append(1)), birthday_paulus
) )
_send_time_changed(hass, before_birthday) async_fire_time_changed(hass, before_birthday)
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(runs) == 0 assert len(runs) == 0
_send_time_changed(hass, birthday_paulus) async_fire_time_changed(hass, birthday_paulus)
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(runs) == 1 assert len(runs) == 1
# A point in time tracker will only fire once, this should do nothing # A point in time tracker will only fire once, this should do nothing
_send_time_changed(hass, birthday_paulus) async_fire_time_changed(hass, birthday_paulus)
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(runs) == 1 assert len(runs) == 1
@ -72,7 +67,7 @@ async def test_track_point_in_time(hass):
hass, callback(lambda x: runs.append(1)), birthday_paulus hass, callback(lambda x: runs.append(1)), birthday_paulus
) )
_send_time_changed(hass, after_birthday) async_fire_time_changed(hass, after_birthday)
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(runs) == 2 assert len(runs) == 2
@ -81,7 +76,7 @@ async def test_track_point_in_time(hass):
) )
unsub() unsub()
_send_time_changed(hass, after_birthday) async_fire_time_changed(hass, after_birthday)
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(runs) == 2 assert len(runs) == 2
@ -458,26 +453,26 @@ async def test_track_time_interval(hass):
hass, lambda x: specific_runs.append(1), timedelta(seconds=10) hass, lambda x: specific_runs.append(1), timedelta(seconds=10)
) )
_send_time_changed(hass, utc_now + timedelta(seconds=5)) async_fire_time_changed(hass, utc_now + timedelta(seconds=5))
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(specific_runs) == 0 assert len(specific_runs) == 0
_send_time_changed(hass, utc_now + timedelta(seconds=13)) async_fire_time_changed(hass, utc_now + timedelta(seconds=13))
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(specific_runs) == 1 assert len(specific_runs) == 1
_send_time_changed(hass, utc_now + timedelta(minutes=20)) async_fire_time_changed(hass, utc_now + timedelta(minutes=20))
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(specific_runs) == 2 assert len(specific_runs) == 2
unsub() unsub()
_send_time_changed(hass, utc_now + timedelta(seconds=30)) async_fire_time_changed(hass, utc_now + timedelta(seconds=30))
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(specific_runs) == 2 assert len(specific_runs) == 2
async def test_track_sunrise(hass): async def test_track_sunrise(hass, legacy_patchable_time):
"""Test track the sunrise.""" """Test track the sunrise."""
latitude = 32.87336 latitude = 32.87336
longitude = 117.22743 longitude = 117.22743
@ -514,17 +509,17 @@ async def test_track_sunrise(hass):
unsub2 = async_track_sunrise(hass, lambda: offset_runs.append(1), offset) unsub2 = async_track_sunrise(hass, lambda: offset_runs.append(1), offset)
# run tests # run tests
_send_time_changed(hass, next_rising - offset) async_fire_time_changed(hass, next_rising - offset)
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(runs) == 0 assert len(runs) == 0
assert len(offset_runs) == 0 assert len(offset_runs) == 0
_send_time_changed(hass, next_rising) async_fire_time_changed(hass, next_rising)
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(runs) == 1 assert len(runs) == 1
assert len(offset_runs) == 0 assert len(offset_runs) == 0
_send_time_changed(hass, next_rising + offset) async_fire_time_changed(hass, next_rising + offset)
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(runs) == 1 assert len(runs) == 1
assert len(offset_runs) == 1 assert len(offset_runs) == 1
@ -532,13 +527,13 @@ async def test_track_sunrise(hass):
unsub() unsub()
unsub2() unsub2()
_send_time_changed(hass, next_rising + offset) async_fire_time_changed(hass, next_rising + offset)
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(runs) == 1 assert len(runs) == 1
assert len(offset_runs) == 1 assert len(offset_runs) == 1
async def test_track_sunrise_update_location(hass): async def test_track_sunrise_update_location(hass, legacy_patchable_time):
"""Test track the sunrise.""" """Test track the sunrise."""
# Setup sun component # Setup sun component
hass.config.latitude = 32.87336 hass.config.latitude = 32.87336
@ -567,7 +562,7 @@ async def test_track_sunrise_update_location(hass):
async_track_sunrise(hass, lambda: runs.append(1)) async_track_sunrise(hass, lambda: runs.append(1))
# Mimic sunrise # Mimic sunrise
_send_time_changed(hass, next_rising) async_fire_time_changed(hass, next_rising)
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(runs) == 1 assert len(runs) == 1
@ -577,7 +572,7 @@ async def test_track_sunrise_update_location(hass):
await hass.async_block_till_done() await hass.async_block_till_done()
# Mimic sunrise # Mimic sunrise
_send_time_changed(hass, next_rising) async_fire_time_changed(hass, next_rising)
await hass.async_block_till_done() await hass.async_block_till_done()
# Did not increase # Did not increase
assert len(runs) == 1 assert len(runs) == 1
@ -593,12 +588,12 @@ async def test_track_sunrise_update_location(hass):
mod += 1 mod += 1
# Mimic sunrise at new location # Mimic sunrise at new location
_send_time_changed(hass, next_rising) async_fire_time_changed(hass, next_rising)
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(runs) == 2 assert len(runs) == 2
async def test_track_sunset(hass): async def test_track_sunset(hass, legacy_patchable_time):
"""Test track the sunset.""" """Test track the sunset."""
latitude = 32.87336 latitude = 32.87336
longitude = 117.22743 longitude = 117.22743
@ -635,17 +630,17 @@ async def test_track_sunset(hass):
unsub2 = async_track_sunset(hass, lambda: offset_runs.append(1), offset) unsub2 = async_track_sunset(hass, lambda: offset_runs.append(1), offset)
# Run tests # Run tests
_send_time_changed(hass, next_setting - offset) async_fire_time_changed(hass, next_setting - offset)
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(runs) == 0 assert len(runs) == 0
assert len(offset_runs) == 0 assert len(offset_runs) == 0
_send_time_changed(hass, next_setting) async_fire_time_changed(hass, next_setting)
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(runs) == 1 assert len(runs) == 1
assert len(offset_runs) == 0 assert len(offset_runs) == 0
_send_time_changed(hass, next_setting + offset) async_fire_time_changed(hass, next_setting + offset)
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(runs) == 1 assert len(runs) == 1
assert len(offset_runs) == 1 assert len(offset_runs) == 1
@ -653,7 +648,7 @@ async def test_track_sunset(hass):
unsub() unsub()
unsub2() unsub2()
_send_time_changed(hass, next_setting + offset) async_fire_time_changed(hass, next_setting + offset)
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(runs) == 1 assert len(runs) == 1
assert len(offset_runs) == 1 assert len(offset_runs) == 1
@ -669,17 +664,17 @@ async def test_async_track_time_change(hass):
hass, lambda x: specific_runs.append(1), second=[0, 30] hass, lambda x: specific_runs.append(1), second=[0, 30]
) )
_send_time_changed(hass, datetime(2014, 5, 24, 12, 0, 0)) async_fire_time_changed(hass, datetime(2014, 5, 24, 12, 0, 0))
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(specific_runs) == 1 assert len(specific_runs) == 1
assert len(wildcard_runs) == 1 assert len(wildcard_runs) == 1
_send_time_changed(hass, datetime(2014, 5, 24, 12, 0, 15)) async_fire_time_changed(hass, datetime(2014, 5, 24, 12, 0, 15))
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(specific_runs) == 1 assert len(specific_runs) == 1
assert len(wildcard_runs) == 2 assert len(wildcard_runs) == 2
_send_time_changed(hass, datetime(2014, 5, 24, 12, 0, 30)) async_fire_time_changed(hass, datetime(2014, 5, 24, 12, 0, 30))
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(specific_runs) == 2 assert len(specific_runs) == 2
assert len(wildcard_runs) == 3 assert len(wildcard_runs) == 3
@ -687,7 +682,7 @@ async def test_async_track_time_change(hass):
unsub() unsub()
unsub_utc() unsub_utc()
_send_time_changed(hass, datetime(2014, 5, 24, 12, 0, 30)) async_fire_time_changed(hass, datetime(2014, 5, 24, 12, 0, 30))
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(specific_runs) == 2 assert len(specific_runs) == 2
assert len(wildcard_runs) == 3 assert len(wildcard_runs) == 3
@ -701,21 +696,21 @@ async def test_periodic_task_minute(hass):
hass, lambda x: specific_runs.append(1), minute="/5", second=0 hass, lambda x: specific_runs.append(1), minute="/5", second=0
) )
_send_time_changed(hass, datetime(2014, 5, 24, 12, 0, 0)) async_fire_time_changed(hass, datetime(2014, 5, 24, 12, 0, 0))
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(specific_runs) == 1 assert len(specific_runs) == 1
_send_time_changed(hass, datetime(2014, 5, 24, 12, 3, 0)) async_fire_time_changed(hass, datetime(2014, 5, 24, 12, 3, 0))
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(specific_runs) == 1 assert len(specific_runs) == 1
_send_time_changed(hass, datetime(2014, 5, 24, 12, 5, 0)) async_fire_time_changed(hass, datetime(2014, 5, 24, 12, 5, 0))
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(specific_runs) == 2 assert len(specific_runs) == 2
unsub() unsub()
_send_time_changed(hass, datetime(2014, 5, 24, 12, 5, 0)) async_fire_time_changed(hass, datetime(2014, 5, 24, 12, 5, 0))
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(specific_runs) == 2 assert len(specific_runs) == 2
@ -728,29 +723,29 @@ async def test_periodic_task_hour(hass):
hass, lambda x: specific_runs.append(1), hour="/2", minute=0, second=0 hass, lambda x: specific_runs.append(1), hour="/2", minute=0, second=0
) )
_send_time_changed(hass, datetime(2014, 5, 24, 22, 0, 0)) async_fire_time_changed(hass, datetime(2014, 5, 24, 22, 0, 0))
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(specific_runs) == 1 assert len(specific_runs) == 1
_send_time_changed(hass, datetime(2014, 5, 24, 23, 0, 0)) async_fire_time_changed(hass, datetime(2014, 5, 24, 23, 0, 0))
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(specific_runs) == 1 assert len(specific_runs) == 1
_send_time_changed(hass, datetime(2014, 5, 25, 0, 0, 0)) async_fire_time_changed(hass, datetime(2014, 5, 25, 0, 0, 0))
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(specific_runs) == 2 assert len(specific_runs) == 2
_send_time_changed(hass, datetime(2014, 5, 25, 1, 0, 0)) async_fire_time_changed(hass, datetime(2014, 5, 25, 1, 0, 0))
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(specific_runs) == 2 assert len(specific_runs) == 2
_send_time_changed(hass, datetime(2014, 5, 25, 2, 0, 0)) async_fire_time_changed(hass, datetime(2014, 5, 25, 2, 0, 0))
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(specific_runs) == 3 assert len(specific_runs) == 3
unsub() unsub()
_send_time_changed(hass, datetime(2014, 5, 25, 2, 0, 0)) async_fire_time_changed(hass, datetime(2014, 5, 25, 2, 0, 0))
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(specific_runs) == 3 assert len(specific_runs) == 3
@ -764,7 +759,7 @@ async def test_periodic_task_wrong_input(hass):
hass, lambda x: specific_runs.append(1), hour="/two" hass, lambda x: specific_runs.append(1), hour="/two"
) )
_send_time_changed(hass, datetime(2014, 5, 2, 0, 0, 0)) async_fire_time_changed(hass, datetime(2014, 5, 2, 0, 0, 0))
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(specific_runs) == 0 assert len(specific_runs) == 0
@ -777,29 +772,29 @@ async def test_periodic_task_clock_rollback(hass):
hass, lambda x: specific_runs.append(1), hour="/2", minute=0, second=0 hass, lambda x: specific_runs.append(1), hour="/2", minute=0, second=0
) )
_send_time_changed(hass, datetime(2014, 5, 24, 22, 0, 0)) async_fire_time_changed(hass, datetime(2014, 5, 24, 22, 0, 0))
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(specific_runs) == 1 assert len(specific_runs) == 1
_send_time_changed(hass, datetime(2014, 5, 24, 23, 0, 0)) async_fire_time_changed(hass, datetime(2014, 5, 24, 23, 0, 0))
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(specific_runs) == 1 assert len(specific_runs) == 1
_send_time_changed(hass, datetime(2014, 5, 24, 22, 0, 0)) async_fire_time_changed(hass, datetime(2014, 5, 24, 22, 0, 0))
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(specific_runs) == 2 assert len(specific_runs) == 2
_send_time_changed(hass, datetime(2014, 5, 24, 0, 0, 0)) async_fire_time_changed(hass, datetime(2014, 5, 24, 0, 0, 0))
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(specific_runs) == 3 assert len(specific_runs) == 3
_send_time_changed(hass, datetime(2014, 5, 25, 2, 0, 0)) async_fire_time_changed(hass, datetime(2014, 5, 25, 2, 0, 0))
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(specific_runs) == 4 assert len(specific_runs) == 4
unsub() unsub()
_send_time_changed(hass, datetime(2014, 5, 25, 2, 0, 0)) async_fire_time_changed(hass, datetime(2014, 5, 25, 2, 0, 0))
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(specific_runs) == 4 assert len(specific_runs) == 4
@ -812,15 +807,15 @@ async def test_periodic_task_duplicate_time(hass):
hass, lambda x: specific_runs.append(1), hour="/2", minute=0, second=0 hass, lambda x: specific_runs.append(1), hour="/2", minute=0, second=0
) )
_send_time_changed(hass, datetime(2014, 5, 24, 22, 0, 0)) async_fire_time_changed(hass, datetime(2014, 5, 24, 22, 0, 0))
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(specific_runs) == 1 assert len(specific_runs) == 1
_send_time_changed(hass, datetime(2014, 5, 24, 22, 0, 0)) async_fire_time_changed(hass, datetime(2014, 5, 24, 22, 0, 0))
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(specific_runs) == 1 assert len(specific_runs) == 1
_send_time_changed(hass, datetime(2014, 5, 25, 0, 0, 0)) async_fire_time_changed(hass, datetime(2014, 5, 25, 0, 0, 0))
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(specific_runs) == 2 assert len(specific_runs) == 2
@ -837,19 +832,19 @@ async def test_periodic_task_entering_dst(hass):
hass, lambda x: specific_runs.append(1), hour=2, minute=30, second=0 hass, lambda x: specific_runs.append(1), hour=2, minute=30, second=0
) )
_send_time_changed(hass, timezone.localize(datetime(2018, 3, 25, 1, 50, 0))) async_fire_time_changed(hass, timezone.localize(datetime(2018, 3, 25, 1, 50, 0)))
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(specific_runs) == 0 assert len(specific_runs) == 0
_send_time_changed(hass, timezone.localize(datetime(2018, 3, 25, 3, 50, 0))) async_fire_time_changed(hass, timezone.localize(datetime(2018, 3, 25, 3, 50, 0)))
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(specific_runs) == 0 assert len(specific_runs) == 0
_send_time_changed(hass, timezone.localize(datetime(2018, 3, 26, 1, 50, 0))) async_fire_time_changed(hass, timezone.localize(datetime(2018, 3, 26, 1, 50, 0)))
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(specific_runs) == 0 assert len(specific_runs) == 0
_send_time_changed(hass, timezone.localize(datetime(2018, 3, 26, 2, 50, 0))) async_fire_time_changed(hass, timezone.localize(datetime(2018, 3, 26, 2, 50, 0)))
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(specific_runs) == 1 assert len(specific_runs) == 1
@ -866,25 +861,25 @@ async def test_periodic_task_leaving_dst(hass):
hass, lambda x: specific_runs.append(1), hour=2, minute=30, second=0 hass, lambda x: specific_runs.append(1), hour=2, minute=30, second=0
) )
_send_time_changed( async_fire_time_changed(
hass, timezone.localize(datetime(2018, 10, 28, 2, 5, 0), is_dst=False) hass, timezone.localize(datetime(2018, 10, 28, 2, 5, 0), is_dst=False)
) )
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(specific_runs) == 0 assert len(specific_runs) == 0
_send_time_changed( async_fire_time_changed(
hass, timezone.localize(datetime(2018, 10, 28, 2, 55, 0), is_dst=False) hass, timezone.localize(datetime(2018, 10, 28, 2, 55, 0), is_dst=False)
) )
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(specific_runs) == 1 assert len(specific_runs) == 1
_send_time_changed( async_fire_time_changed(
hass, timezone.localize(datetime(2018, 10, 28, 2, 5, 0), is_dst=True) hass, timezone.localize(datetime(2018, 10, 28, 2, 5, 0), is_dst=True)
) )
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(specific_runs) == 1 assert len(specific_runs) == 1
_send_time_changed( async_fire_time_changed(
hass, timezone.localize(datetime(2018, 10, 28, 2, 55, 0), is_dst=True) hass, timezone.localize(datetime(2018, 10, 28, 2, 55, 0), is_dst=True)
) )
await hass.async_block_till_done() await hass.async_block_till_done()