Commit a15cfb2e authored by Aymeric Augustin's avatar Aymeric Augustin
Browse files

Simplified timezones tests with settings_changed.

All relevant state is now properly reset whenever TIME_ZONE or USE_TZ
are changed in tests.
parent 3e8b40f4
Loading
Loading
Loading
Loading
+22 −2
Original line number Diff line number Diff line
import os
import time

from django.conf import settings
from django.db import connections
from django.dispatch import receiver, Signal
from django.template import context
from django.utils import timezone

template_rendered = Signal(providing_args=["template", "context"])

setting_changed = Signal(providing_args=["setting", "value"])


@receiver(setting_changed)
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':
        USE_TZ, TIME_ZONE = kwargs['value'], settings.TIME_ZONE
    elif kwargs['setting'] == 'TIME_ZONE' and not settings.USE_TZ:
        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

    tz = 'UTC' if USE_TZ else TIME_ZONE
    for conn in connections.all():
        conn.settings_dict['TIME_ZONE'] = tz
        tz_sql = conn.ops.set_time_zone_sql()
        if tz_sql:
            conn.cursor().execute(tz_sql, [tz])


@receiver(setting_changed)
def clear_context_processors_cache(**kwargs):
    if kwargs['setting'] == 'TEMPLATE_CONTEXT_PROCESSORS':
+0 −1
Original line number Diff line number Diff line
@@ -95,7 +95,6 @@ utc = pytz.utc if pytz else UTC()

# In order to avoid accessing the settings at compile time,
# wrap the expression in a function and cache the result.
# If you change settings.TIME_ZONE in tests, reset _localtime to None.
_localtime = None

def get_default_timezone():
+17 −42
Original line number Diff line number Diff line
@@ -50,32 +50,8 @@ requires_tz_support = skipUnless(TZ_SUPPORT,
        "time zone, but your operating system isn't able to do that.")


class BaseDateTimeTests(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):
@override_settings(TIME_ZONE='Africa/Nairobi', USE_TZ=False)
class LegacyDatabaseTests(TestCase):

    def test_naive_datetime(self):
        dt = datetime.datetime(2011, 9, 1, 13, 20, 30)
@@ -269,8 +245,8 @@ class LegacyDatabaseTests(BaseDateTimeTests):
                transform=lambda d: d)


@override_settings(USE_TZ=True)
class NewDatabaseTests(BaseDateTimeTests):
@override_settings(TIME_ZONE='Africa/Nairobi', USE_TZ=True)
class NewDatabaseTests(TestCase):

    @requires_tz_support
    def test_naive_datetime(self):
@@ -486,7 +462,8 @@ class NewDatabaseTests(BaseDateTimeTests):
        self.assertEqual(e.dt, None)


class SerializationTests(BaseDateTimeTests):
@override_settings(TIME_ZONE='Africa/Nairobi')
class SerializationTests(TestCase):

    # Backend-specific notes:
    # - JSON supports only milliseconds, microseconds will be truncated.
@@ -639,8 +616,9 @@ class SerializationTests(BaseDateTimeTests):
            obj = serializers.deserialize('yaml', data).next().object
            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
    def test_localtime_templatetag_and_filters(self):
@@ -723,10 +701,8 @@ class TemplateTests(BaseDateTimeTests):
        tpl = Template("{% load tz %}{{ dt|localtime }}|{{ dt|utc }}")
        ctx = Context({'dt': datetime.datetime(2011, 9, 1, 12, 20, 30)})

        timezone._localtime = None
        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")
        timezone._localtime = None

        # Use a pytz timezone as argument
        tpl = Template("{% load tz %}{{ dt|timezone:tz }}")
@@ -864,11 +840,9 @@ class TemplateTests(BaseDateTimeTests):
        tpl = Template("{% load tz %}{{ dt }}")
        ctx = Context({'dt': datetime.datetime(2011, 9, 1, 12, 20, 30, tzinfo=EAT)})

        timezone._localtime = None
        with self.settings(TIME_ZONE=None):
            # the actual value depends on the system time zone of the host
            self.assertTrue(tpl.render(ctx).startswith("2011"))
        timezone._localtime = None

    @requires_tz_support
    def test_now_template_tag_uses_current_time_zone(self):
@@ -879,8 +853,8 @@ class TemplateTests(BaseDateTimeTests):
            self.assertEqual(tpl.render(Context({})), "+0700")


@override_settings(DATETIME_FORMAT='c', USE_L10N=False, USE_TZ=False)
class LegacyFormsTests(BaseDateTimeTests):
@override_settings(DATETIME_FORMAT='c', TIME_ZONE='Africa/Nairobi', USE_L10N=False, USE_TZ=False)
class LegacyFormsTests(TestCase):

    def test_form(self):
        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))


@override_settings(DATETIME_FORMAT='c', USE_L10N=False, USE_TZ=True)
class NewFormsTests(BaseDateTimeTests):
@override_settings(DATETIME_FORMAT='c', TIME_ZONE='Africa/Nairobi', USE_L10N=False, USE_TZ=True)
class NewFormsTests(TestCase):

    @requires_tz_support
    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))


@override_settings(DATETIME_FORMAT='c', USE_L10N=False, USE_TZ=True)
class AdminTests(BaseDateTimeTests):
@override_settings(DATETIME_FORMAT='c', TIME_ZONE='Africa/Nairobi', USE_L10N=False, USE_TZ=True)
class AdminTests(TestCase):

    urls = 'modeltests.timezones.urls'
    fixtures = ['tz_users.xml']
@@ -1012,7 +986,8 @@ class AdminTests(BaseDateTimeTests):
        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):
        self.assertEqual(