diff --git a/django/test/utils.py b/django/test/utils.py index dff9c4e25b..961fece55c 100644 --- a/django/test/utils.py +++ b/django/test/utils.py @@ -555,3 +555,20 @@ def reset_warning_registry(): for mod in sys.modules.values(): if hasattr(mod, key): getattr(mod, key).clear() + + +@contextmanager +def freeze_time(t): + """ + Context manager to temporarily freeze time.time(). This temporarily + modifies the time function of the time module. Modules which import the + time function directly (e.g. `from time import time`) won't be affected + This isn't meant as a public API, but helps reduce some repetitive code in + Django's test suite. + """ + _real_time = time.time + time.time = lambda: t + try: + yield + finally: + time.time = _real_time diff --git a/tests/signed_cookies_tests/tests.py b/tests/signed_cookies_tests/tests.py index ff8fe76bf6..e53d7bd624 100644 --- a/tests/signed_cookies_tests/tests.py +++ b/tests/signed_cookies_tests/tests.py @@ -1,10 +1,9 @@ from __future__ import unicode_literals -import time - from django.core import signing from django.http import HttpRequest, HttpResponse from django.test import TestCase, override_settings +from django.test.utils import freeze_time class SignedCookieTest(TestCase): @@ -46,22 +45,18 @@ class SignedCookieTest(TestCase): def test_max_age_argument(self): value = 'hello' - _time = time.time - time.time = lambda: 123456789 - try: + with freeze_time(123456789): response = HttpResponse() response.set_signed_cookie('c', value) request = HttpRequest() request.COOKIES['c'] = response.cookies['c'].value self.assertEqual(request.get_signed_cookie('c'), value) - time.time = lambda: 123456800 + with freeze_time(123456800): self.assertEqual(request.get_signed_cookie('c', max_age=12), value) self.assertEqual(request.get_signed_cookie('c', max_age=11), value) self.assertRaises(signing.SignatureExpired, request.get_signed_cookie, 'c', max_age=10) - finally: - time.time = _time @override_settings(SECRET_KEY=b'\xe7') def test_signed_cookies_with_binary_key(self): diff --git a/tests/signing/tests.py b/tests/signing/tests.py index 707cbba445..32b8bb3b5e 100644 --- a/tests/signing/tests.py +++ b/tests/signing/tests.py @@ -1,10 +1,10 @@ from __future__ import unicode_literals import datetime -import time from django.core import signing from django.test import TestCase +from django.test.utils import freeze_time from django.utils.encoding import force_str from django.utils import six @@ -117,23 +117,15 @@ class TestTimestampSigner(TestCase): def test_timestamp_signer(self): value = 'hello' - _time = time.time - time.time = lambda: 123456789 - try: + with freeze_time(123456789): signer = signing.TimestampSigner('predictable-key') ts = signer.sign(value) self.assertNotEqual(ts, signing.Signer('predictable-key').sign(value)) - self.assertEqual(signer.unsign(ts), value) - time.time = lambda: 123456800 - self.assertEqual(signer.unsign(ts, max_age=13), value) + + with freeze_time(123456800): self.assertEqual(signer.unsign(ts, max_age=12), value) # max_age parameter can also accept a datetime.timedelta object self.assertEqual(signer.unsign(ts, max_age=datetime.timedelta(seconds=11)), value) - self.assertRaises( - signing.SignatureExpired, signer.unsign, ts, max_age=10) - with self.assertRaises(signing.SignatureExpired): - self.assertEqual(signer.unsign(ts, max_age=datetime.timedelta(seconds=10)), value) - finally: - time.time = _time + self.assertRaises(signing.SignatureExpired, signer.unsign, ts, max_age=10)