Simplified timezones tests with settings_changed.

All relevant state is now properly reset whenever TIME_ZONE or USE_TZ
are changed in tests.
This commit is contained in:
Aymeric Augustin 2012-04-29 16:03:46 +02:00
parent 3e8b40f479
commit a15cfb2e45
3 changed files with 39 additions and 45 deletions

View File

@ -1,27 +1,47 @@
import os
import time
from django.conf import settings from django.conf import settings
from django.db import connections from django.db import connections
from django.dispatch import receiver, Signal from django.dispatch import receiver, Signal
from django.template import context from django.template import context
from django.utils import timezone
template_rendered = Signal(providing_args=["template", "context"]) template_rendered = Signal(providing_args=["template", "context"])
setting_changed = Signal(providing_args=["setting", "value"]) setting_changed = Signal(providing_args=["setting", "value"])
@receiver(setting_changed) @receiver(setting_changed)
def update_connections_time_zone(**kwargs): def update_connections_time_zone(**kwargs):
if kwargs['setting'] == 'TIME_ZONE':
# Reset process time zone
if hasattr(time, 'tzset'):
if kwargs['value']:
os.environ['TZ'] = kwargs['value']
else:
os.environ.pop('TZ', None)
time.tzset()
# Reset local time zone cache
timezone._localtime = None
# Reset the database connections' time zone
if kwargs['setting'] == 'USE_TZ' and settings.TIME_ZONE != 'UTC': if kwargs['setting'] == 'USE_TZ' and settings.TIME_ZONE != 'UTC':
USE_TZ, TIME_ZONE = kwargs['value'], settings.TIME_ZONE USE_TZ, TIME_ZONE = kwargs['value'], settings.TIME_ZONE
elif kwargs['setting'] == 'TIME_ZONE' and not settings.USE_TZ: elif kwargs['setting'] == 'TIME_ZONE' and not settings.USE_TZ:
USE_TZ, TIME_ZONE = settings.USE_TZ, kwargs['value'] USE_TZ, TIME_ZONE = settings.USE_TZ, kwargs['value']
else: # no need to change the database connnections' time zones else:
# no need to change the database connnections' time zones
return return
tz = 'UTC' if USE_TZ else TIME_ZONE tz = 'UTC' if USE_TZ else TIME_ZONE
for conn in connections.all(): for conn in connections.all():
conn.settings_dict['TIME_ZONE'] = tz
tz_sql = conn.ops.set_time_zone_sql() tz_sql = conn.ops.set_time_zone_sql()
if tz_sql: if tz_sql:
conn.cursor().execute(tz_sql, [tz]) conn.cursor().execute(tz_sql, [tz])
@receiver(setting_changed) @receiver(setting_changed)
def clear_context_processors_cache(**kwargs): def clear_context_processors_cache(**kwargs):
if kwargs['setting'] == 'TEMPLATE_CONTEXT_PROCESSORS': if kwargs['setting'] == 'TEMPLATE_CONTEXT_PROCESSORS':

View File

@ -95,7 +95,6 @@ utc = pytz.utc if pytz else UTC()
# In order to avoid accessing the settings at compile time, # In order to avoid accessing the settings at compile time,
# wrap the expression in a function and cache the result. # wrap the expression in a function and cache the result.
# If you change settings.TIME_ZONE in tests, reset _localtime to None.
_localtime = None _localtime = None
def get_default_timezone(): def get_default_timezone():

View File

@ -50,32 +50,8 @@ requires_tz_support = skipUnless(TZ_SUPPORT,
"time zone, but your operating system isn't able to do that.") "time zone, but your operating system isn't able to do that.")
class BaseDateTimeTests(TestCase): @override_settings(TIME_ZONE='Africa/Nairobi', USE_TZ=False)
class LegacyDatabaseTests(TestCase):
@classmethod
def setUpClass(self):
self._old_time_zone = settings.TIME_ZONE
settings.TIME_ZONE = connection.settings_dict['TIME_ZONE'] = 'Africa/Nairobi'
timezone._localtime = None
if TZ_SUPPORT:
self._old_tz = os.environ.get('TZ')
os.environ['TZ'] = 'Africa/Nairobi'
time.tzset()
@classmethod
def tearDownClass(self):
settings.TIME_ZONE = connection.settings_dict['TIME_ZONE'] = self._old_time_zone
timezone._localtime = None
if TZ_SUPPORT:
if self._old_tz is None:
del os.environ['TZ']
else:
os.environ['TZ'] = self._old_tz
time.tzset()
@override_settings(USE_TZ=False)
class LegacyDatabaseTests(BaseDateTimeTests):
def test_naive_datetime(self): def test_naive_datetime(self):
dt = datetime.datetime(2011, 9, 1, 13, 20, 30) dt = datetime.datetime(2011, 9, 1, 13, 20, 30)
@ -269,8 +245,8 @@ class LegacyDatabaseTests(BaseDateTimeTests):
transform=lambda d: d) transform=lambda d: d)
@override_settings(USE_TZ=True) @override_settings(TIME_ZONE='Africa/Nairobi', USE_TZ=True)
class NewDatabaseTests(BaseDateTimeTests): class NewDatabaseTests(TestCase):
@requires_tz_support @requires_tz_support
def test_naive_datetime(self): def test_naive_datetime(self):
@ -486,7 +462,8 @@ class NewDatabaseTests(BaseDateTimeTests):
self.assertEqual(e.dt, None) self.assertEqual(e.dt, None)
class SerializationTests(BaseDateTimeTests): @override_settings(TIME_ZONE='Africa/Nairobi')
class SerializationTests(TestCase):
# Backend-specific notes: # Backend-specific notes:
# - JSON supports only milliseconds, microseconds will be truncated. # - JSON supports only milliseconds, microseconds will be truncated.
@ -639,8 +616,9 @@ class SerializationTests(BaseDateTimeTests):
obj = serializers.deserialize('yaml', data).next().object obj = serializers.deserialize('yaml', data).next().object
self.assertEqual(obj.dt.replace(tzinfo=UTC), dt) self.assertEqual(obj.dt.replace(tzinfo=UTC), dt)
@override_settings(DATETIME_FORMAT='c', USE_L10N=False, USE_TZ=True)
class TemplateTests(BaseDateTimeTests): @override_settings(DATETIME_FORMAT='c', TIME_ZONE='Africa/Nairobi', USE_L10N=False, USE_TZ=True)
class TemplateTests(TestCase):
@requires_tz_support @requires_tz_support
def test_localtime_templatetag_and_filters(self): def test_localtime_templatetag_and_filters(self):
@ -723,10 +701,8 @@ class TemplateTests(BaseDateTimeTests):
tpl = Template("{% load tz %}{{ dt|localtime }}|{{ dt|utc }}") tpl = Template("{% load tz %}{{ dt|localtime }}|{{ dt|utc }}")
ctx = Context({'dt': datetime.datetime(2011, 9, 1, 12, 20, 30)}) ctx = Context({'dt': datetime.datetime(2011, 9, 1, 12, 20, 30)})
timezone._localtime = None
with self.settings(TIME_ZONE='Europe/Paris'): with self.settings(TIME_ZONE='Europe/Paris'):
self.assertEqual(tpl.render(ctx), "2011-09-01T12:20:30+02:00|2011-09-01T10:20:30+00:00") self.assertEqual(tpl.render(ctx), "2011-09-01T12:20:30+02:00|2011-09-01T10:20:30+00:00")
timezone._localtime = None
# Use a pytz timezone as argument # Use a pytz timezone as argument
tpl = Template("{% load tz %}{{ dt|timezone:tz }}") tpl = Template("{% load tz %}{{ dt|timezone:tz }}")
@ -864,11 +840,9 @@ class TemplateTests(BaseDateTimeTests):
tpl = Template("{% load tz %}{{ dt }}") tpl = Template("{% load tz %}{{ dt }}")
ctx = Context({'dt': datetime.datetime(2011, 9, 1, 12, 20, 30, tzinfo=EAT)}) ctx = Context({'dt': datetime.datetime(2011, 9, 1, 12, 20, 30, tzinfo=EAT)})
timezone._localtime = None
with self.settings(TIME_ZONE=None): with self.settings(TIME_ZONE=None):
# the actual value depends on the system time zone of the host # the actual value depends on the system time zone of the host
self.assertTrue(tpl.render(ctx).startswith("2011")) self.assertTrue(tpl.render(ctx).startswith("2011"))
timezone._localtime = None
@requires_tz_support @requires_tz_support
def test_now_template_tag_uses_current_time_zone(self): def test_now_template_tag_uses_current_time_zone(self):
@ -879,8 +853,8 @@ class TemplateTests(BaseDateTimeTests):
self.assertEqual(tpl.render(Context({})), "+0700") self.assertEqual(tpl.render(Context({})), "+0700")
@override_settings(DATETIME_FORMAT='c', USE_L10N=False, USE_TZ=False) @override_settings(DATETIME_FORMAT='c', TIME_ZONE='Africa/Nairobi', USE_L10N=False, USE_TZ=False)
class LegacyFormsTests(BaseDateTimeTests): class LegacyFormsTests(TestCase):
def test_form(self): def test_form(self):
form = EventForm({'dt': u'2011-09-01 13:20:30'}) form = EventForm({'dt': u'2011-09-01 13:20:30'})
@ -914,8 +888,8 @@ class LegacyFormsTests(BaseDateTimeTests):
self.assertEqual(e.dt, datetime.datetime(2011, 9, 1, 13, 20, 30)) self.assertEqual(e.dt, datetime.datetime(2011, 9, 1, 13, 20, 30))
@override_settings(DATETIME_FORMAT='c', USE_L10N=False, USE_TZ=True) @override_settings(DATETIME_FORMAT='c', TIME_ZONE='Africa/Nairobi', USE_L10N=False, USE_TZ=True)
class NewFormsTests(BaseDateTimeTests): class NewFormsTests(TestCase):
@requires_tz_support @requires_tz_support
def test_form(self): def test_form(self):
@ -960,8 +934,8 @@ class NewFormsTests(BaseDateTimeTests):
self.assertEqual(e.dt, datetime.datetime(2011, 9, 1, 10, 20, 30, tzinfo=UTC)) self.assertEqual(e.dt, datetime.datetime(2011, 9, 1, 10, 20, 30, tzinfo=UTC))
@override_settings(DATETIME_FORMAT='c', USE_L10N=False, USE_TZ=True) @override_settings(DATETIME_FORMAT='c', TIME_ZONE='Africa/Nairobi', USE_L10N=False, USE_TZ=True)
class AdminTests(BaseDateTimeTests): class AdminTests(TestCase):
urls = 'modeltests.timezones.urls' urls = 'modeltests.timezones.urls'
fixtures = ['tz_users.xml'] fixtures = ['tz_users.xml']
@ -1012,7 +986,8 @@ class AdminTests(BaseDateTimeTests):
self.assertContains(response, t.created.astimezone(ICT).isoformat()) self.assertContains(response, t.created.astimezone(ICT).isoformat())
class UtilitiesTests(BaseDateTimeTests): @override_settings(TIME_ZONE='Africa/Nairobi')
class UtilitiesTests(TestCase):
def test_make_aware(self): def test_make_aware(self):
self.assertEqual( self.assertEqual(