diff --git a/docs/other_plugins.rst b/docs/other_plugins.rst index 62222e3d..ceb44c9f 100644 --- a/docs/other_plugins.rst +++ b/docs/other_plugins.rst @@ -54,7 +54,7 @@ used in a particular test: ``@pytest.mark.now('2016-12-01T12:00:00')`` or ``@pytest.mark.now(enabled=True)``. If time is not specified in ``@pytest.mark.now``, then -``datetime.datetime.utcnow()`` value at the start of test is used as time value +current time at UTC timezone is used at the start of test as time value until it is modified by calling ``mocked_time.set(...)`` or ``mocked_time.sleep(...)`` diff --git a/tests/plugins/test_mocked_time.py b/tests/plugins/test_mocked_time.py index eba4087f..f0e57f31 100644 --- a/tests/plugins/test_mocked_time.py +++ b/tests/plugins/test_mocked_time.py @@ -21,7 +21,7 @@ def test_disabled_mocked_time_raises_on_usage_attempt(mocked_time): assert not mocked_time.is_enabled with pytest.raises(mocked_time_module.DisabledUsageError): - mocked_time.set(datetime.datetime.utcnow()) + mocked_time.set(datetime.datetime.now(datetime.timezone.utc)) with pytest.raises(mocked_time_module.DisabledUsageError): mocked_time.sleep(2) diff --git a/testsuite/mockserver/server.py b/testsuite/mockserver/server.py index 4fa3e52d..ef508fe3 100644 --- a/testsuite/mockserver/server.py +++ b/testsuite/mockserver/server.py @@ -1,5 +1,4 @@ import contextlib -import datetime import itertools import logging import pathlib @@ -19,6 +18,7 @@ from testsuite.utils import http from testsuite.utils import net as net_utils from testsuite.utils import url_util +from testsuite import utils from . import classes from . import exceptions @@ -281,7 +281,7 @@ def _log_request(self, started, request, response=None, exc=None): return fields = { '_type': 'mockserver_request', - 'timestamp': datetime.datetime.utcnow(), + 'timestamp': utils.utcnow(), 'method': request.method, 'url': request.rel_url, } diff --git a/testsuite/plugins/mocked_time.py b/testsuite/plugins/mocked_time.py index 9d4af25c..018410aa 100644 --- a/testsuite/plugins/mocked_time.py +++ b/testsuite/plugins/mocked_time.py @@ -37,13 +37,13 @@ def now(self) -> datetime.datetime: """:returns: current value of mock time""" if self._is_enabled: return self._now - return datetime.datetime.utcnow() + return utils.utcnow() def set(self, time: datetime.datetime): """Set mock time value""" if not self._is_enabled: raise DisabledUsageError(MOCK_TIME_DISABLED_MESSAGE) - self._now = time + self._now = utils.to_utc(time) @property def is_enabled(self) -> bool: @@ -87,10 +87,10 @@ def mocked_time(_mocked_time_enabled, now) -> MockedTime: def now(request) -> datetime.datetime: marker = request.node.get_closest_marker('now') if not marker or not marker.args: - return datetime.datetime.utcnow() + return utils.utcnow() stamp = marker.args[0] if isinstance(stamp, int): - return datetime.datetime.utcfromtimestamp(stamp) + return utils.utcfromtimestamp(stamp) return utils.to_utc(dateutil.parser.parse(stamp)) diff --git a/testsuite/utils/__init__.py b/testsuite/utils/__init__.py index f459ab06..f01d3272 100644 --- a/testsuite/utils/__init__.py +++ b/testsuite/utils/__init__.py @@ -1,15 +1,24 @@ -# flake8: noqa -import pytz +import datetime from .cached_property import cached_property -def to_utc(stamp): +def to_utc(stamp: datetime.datetime) -> datetime.datetime: if stamp.tzinfo is not None: - stamp = stamp.astimezone(pytz.utc).replace(tzinfo=None) + stamp = stamp.astimezone(datetime.timezone.utc).replace(tzinfo=None) return stamp -def timestring(stamp): +def timestring(stamp: datetime.datetime) -> str: stamp = to_utc(stamp) return stamp.strftime('%Y-%m-%dT%H:%M:%S.%f+0000') + + +def utcnow() -> datetime.datetime: + return datetime.datetime.now(datetime.timezone.utc).replace(tzinfo=None) + + +def utcfromtimestamp(stamp: int) -> datetime.datetime: + return datetime.datetime.fromtimestamp( + stamp, tz=datetime.timezone.utc + ).replace(tzinfo=None) diff --git a/testsuite/utils/compat.py b/testsuite/utils/compat.py index 5f437f84..5ede9d6b 100644 --- a/testsuite/utils/compat.py +++ b/testsuite/utils/compat.py @@ -1,5 +1,6 @@ import contextlib + # Required for python3.6 compatibility if not hasattr(contextlib, 'asynccontextmanager'): import contextlib2 # pylint: disable=import-error diff --git a/testsuite/utils/json_util.py b/testsuite/utils/json_util.py index 00b62382..6538751d 100644 --- a/testsuite/utils/json_util.py +++ b/testsuite/utils/json_util.py @@ -3,6 +3,7 @@ from bson import json_util from testsuite.utils import object_hook as object_hook_util +from testsuite import utils def loads(string, *args, **kwargs): @@ -22,7 +23,7 @@ def substitute(json_obj, *, object_hook=None): """Create transformed json by making substitutions: {"$mockserver": "/path", "$schema": true} -> "http://localhost:9999/path" - {"$dateDiff": 10} -> datetime.utcnow() + timedelta(seconds=10) + {"$dateDiff": 10} -> datetime.datetime.now(datetime.timezone.utc).replace(tzinfo=None) + timedelta(seconds=10) """ hook = object_hook_util.build_object_hook(object_hook=object_hook) return object_hook_util.substitute(json_obj, hook) @@ -58,6 +59,6 @@ def default(obj): def relative_dates_default(obj): """Add ``$dateDiff`` hook to ``bson.json_util.default``.""" if isinstance(obj, datetime.datetime): - diff = obj.replace(tzinfo=None) - datetime.datetime.utcnow() + diff = obj.replace(tzinfo=None) - utils.utcnow() return {'$dateDiff': diff.total_seconds()} return default(obj)