Fixed #23792 -- Added test.utils.freeze_time() context manager.

This commit is contained in:
Thomas Chaumeny 2014-11-10 19:33:49 +01:00 committed by Tim Graham
parent 54085b0f9b
commit 994d6137a2
3 changed files with 25 additions and 21 deletions

View File

@ -555,3 +555,20 @@ def reset_warning_registry():
for mod in sys.modules.values(): for mod in sys.modules.values():
if hasattr(mod, key): if hasattr(mod, key):
getattr(mod, key).clear() 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

View File

@ -1,10 +1,9 @@
from __future__ import unicode_literals from __future__ import unicode_literals
import time
from django.core import signing from django.core import signing
from django.http import HttpRequest, HttpResponse from django.http import HttpRequest, HttpResponse
from django.test import TestCase, override_settings from django.test import TestCase, override_settings
from django.test.utils import freeze_time
class SignedCookieTest(TestCase): class SignedCookieTest(TestCase):
@ -46,22 +45,18 @@ class SignedCookieTest(TestCase):
def test_max_age_argument(self): def test_max_age_argument(self):
value = 'hello' value = 'hello'
_time = time.time with freeze_time(123456789):
time.time = lambda: 123456789
try:
response = HttpResponse() response = HttpResponse()
response.set_signed_cookie('c', value) response.set_signed_cookie('c', value)
request = HttpRequest() request = HttpRequest()
request.COOKIES['c'] = response.cookies['c'].value request.COOKIES['c'] = response.cookies['c'].value
self.assertEqual(request.get_signed_cookie('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=12), value)
self.assertEqual(request.get_signed_cookie('c', max_age=11), value) self.assertEqual(request.get_signed_cookie('c', max_age=11), value)
self.assertRaises(signing.SignatureExpired, self.assertRaises(signing.SignatureExpired,
request.get_signed_cookie, 'c', max_age=10) request.get_signed_cookie, 'c', max_age=10)
finally:
time.time = _time
@override_settings(SECRET_KEY=b'\xe7') @override_settings(SECRET_KEY=b'\xe7')
def test_signed_cookies_with_binary_key(self): def test_signed_cookies_with_binary_key(self):

View File

@ -1,10 +1,10 @@
from __future__ import unicode_literals from __future__ import unicode_literals
import datetime import datetime
import time
from django.core import signing from django.core import signing
from django.test import TestCase from django.test import TestCase
from django.test.utils import freeze_time
from django.utils.encoding import force_str from django.utils.encoding import force_str
from django.utils import six from django.utils import six
@ -117,23 +117,15 @@ class TestTimestampSigner(TestCase):
def test_timestamp_signer(self): def test_timestamp_signer(self):
value = 'hello' value = 'hello'
_time = time.time with freeze_time(123456789):
time.time = lambda: 123456789
try:
signer = signing.TimestampSigner('predictable-key') signer = signing.TimestampSigner('predictable-key')
ts = signer.sign(value) ts = signer.sign(value)
self.assertNotEqual(ts, self.assertNotEqual(ts,
signing.Signer('predictable-key').sign(value)) signing.Signer('predictable-key').sign(value))
self.assertEqual(signer.unsign(ts), 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) self.assertEqual(signer.unsign(ts, max_age=12), value)
# max_age parameter can also accept a datetime.timedelta object # max_age parameter can also accept a datetime.timedelta object
self.assertEqual(signer.unsign(ts, max_age=datetime.timedelta(seconds=11)), value) self.assertEqual(signer.unsign(ts, max_age=datetime.timedelta(seconds=11)), value)
self.assertRaises( self.assertRaises(signing.SignatureExpired, signer.unsign, ts, max_age=10)
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