mirror of
https://github.com/home-assistant/core.git
synced 2026-08-31 10:16:17 -05:00
87 lines
2.5 KiB
Python
87 lines
2.5 KiB
Python
"""Test the freezegun modifications in tests.patch_time."""
|
|
|
|
from collections.abc import Generator
|
|
import datetime
|
|
import sys
|
|
import time
|
|
import types
|
|
|
|
from freezegun import freeze_time
|
|
import pytest
|
|
|
|
|
|
@pytest.fixture
|
|
def lazy_module() -> Generator[types.ModuleType]:
|
|
"""Register a module which only resolves its attributes when they are read."""
|
|
module = types.ModuleType("freezegun_lazy_module")
|
|
module.probed = []
|
|
|
|
def module_getattr(name: str) -> object:
|
|
module.probed.append(name)
|
|
raise AttributeError(name)
|
|
|
|
module.__getattr__ = module_getattr
|
|
module.__dir__ = lambda: ["lazy_attribute"]
|
|
|
|
sys.modules[module.__name__] = module
|
|
yield module
|
|
del sys.modules[module.__name__]
|
|
|
|
|
|
def test_freezing_time_does_not_resolve_lazy_attributes(
|
|
lazy_module: types.ModuleType,
|
|
) -> None:
|
|
"""Test freezing time does not read attributes which are not set yet."""
|
|
with freeze_time("2023-01-01"):
|
|
pass
|
|
|
|
assert lazy_module.probed == []
|
|
|
|
|
|
def test_freezing_time_rescans_a_changed_module(
|
|
lazy_module: types.ModuleType,
|
|
) -> None:
|
|
"""Test an attribute set after the first freeze is patched by the next one."""
|
|
real_datetime = datetime.datetime
|
|
|
|
with freeze_time("2023-01-01"):
|
|
pass
|
|
|
|
lazy_module.datetime = real_datetime
|
|
|
|
with freeze_time("2023-01-01"):
|
|
assert lazy_module.datetime is not real_datetime
|
|
assert lazy_module.datetime.now() == real_datetime(2023, 1, 1)
|
|
|
|
assert lazy_module.datetime is real_datetime
|
|
|
|
|
|
def test_time_is_readable_after_unfreeze() -> None:
|
|
"""Test stale patched time functions do not raise after time is unfrozen.
|
|
|
|
A thread which entered a patched time function, or still holds a patched
|
|
class, keeps using it while another thread stops freeze_time; the freezegun
|
|
stacks are then already empty, see
|
|
https://github.com/spulec/freezegun/issues/345.
|
|
"""
|
|
|
|
def capture() -> tuple:
|
|
# Function locals, unlike module globals, are not restored by
|
|
# freezegun's unpatching, so these stay patched after the freeze ends.
|
|
with freeze_time("2023-01-01"):
|
|
return (
|
|
datetime.datetime,
|
|
datetime.date,
|
|
time.time,
|
|
time.time_ns,
|
|
time.monotonic,
|
|
)
|
|
|
|
fake_datetime, fake_date, fake_time, fake_time_ns, fake_monotonic = capture()
|
|
|
|
assert fake_datetime.now().year >= 2023
|
|
assert fake_date.today().year >= 2023
|
|
assert fake_time() > 0
|
|
assert fake_time_ns() > 0
|
|
assert fake_monotonic() >= 0
|