Permalink
Browse files

Fixed #22811 -- Allowed setting both the old and new TEST database se…

…ttings.

An ImproperlyConfigured exception will be raised they mismatch.
  • Loading branch information...
1 parent dfa3505 commit 1c58cabad7f5b792e9cfd8f00feffd8212fdfbb1 @timgraham timgraham committed Jun 11, 2014
Showing with 141 additions and 8 deletions.
  1. +19 −7 django/db/utils.py
  2. +2 −0 docs/ref/settings.txt
  3. +4 −1 docs/releases/1.7.txt
  4. +116 −0 tests/backends/tests.py
View
@@ -183,6 +183,7 @@ def ensure_defaults(self, alias):
'USER_CREATE': 'CREATE_USER',
'PASSWD': 'PASSWORD',
}
+ TEST_SETTING_RENAMES_REVERSE = {v: k for k, v in TEST_SETTING_RENAMES.items()}
def prepare_test_settings(self, alias):
"""
@@ -193,18 +194,29 @@ def prepare_test_settings(self, alias):
except KeyError:
raise ConnectionDoesNotExist("The connection %s doesn't exist" % alias)
+ test_dict_set = 'TEST' in conn
test_settings = conn.setdefault('TEST', {})
+ old_test_settings = {}
for key, value in six.iteritems(conn):
if key.startswith('TEST_'):
new_key = key[5:]
new_key = self.TEST_SETTING_RENAMES.get(new_key, new_key)
- if new_key in test_settings:
- raise ImproperlyConfigured("Connection %s has both %s and TEST[%s] specified." %
- (alias, key, new_key))
- warnings.warn("In Django 1.9 the %s connection setting will be moved "
- "to a %s entry in the TEST setting" % (key, new_key),
- RemovedInDjango19Warning, stacklevel=2)
- test_settings[new_key] = value
+ old_test_settings[new_key] = value
+
+ if old_test_settings:
+ if test_dict_set:
+ if test_settings != old_test_settings:
+ raise ImproperlyConfigured(
+ "Connection '%s' has mismatched TEST and TEST_* "
+ "database settings." % alias)
+ else:
+ test_settings = old_test_settings
+ for key, _ in six.iteritems(old_test_settings):
+ warnings.warn("In Django 1.9 the %s connection setting will be moved "
+ "to a %s entry in the TEST setting" %
+ (self.TEST_SETTING_RENAMES_REVERSE.get(key, key), key),
+ RemovedInDjango19Warning, stacklevel=2)
+
for key in list(conn.keys()):
if key.startswith('TEST_'):
del conn[key]
View
@@ -586,6 +586,8 @@ TEST
All :setting:`TEST <DATABASE-TEST>` sub-entries used to be independent
entries in the database settings dictionary, with a ``TEST_`` prefix.
+ For backwards compatibility with older versions of Django, you can define
+ both versions of the settings as long as they match.
Further, ``TEST_CREATE``, ``TEST_USER_CREATE`` and ``TEST_PASSWD``
were changed to ``CREATE_DB``, ``CREATE_USER`` and ``PASSWORD``
respectively.
View
@@ -1546,9 +1546,12 @@ will be removed in Django 1.8.
Reorganization of database test settings
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
All database settings with a ``TEST_`` prefix have been deprecated in favor of
entries in a :setting:`TEST <DATABASE-TEST>` dictionary in the database
-settings. The old settings will be supported until Django 1.9.
+settings. The old settings will be supported until Django 1.9. For backwards
+compatibility with older versions of Django, you can define both versions of
+the settings as long as they match.
FastCGI support
~~~~~~~~~~~~~~~
View
@@ -11,6 +11,7 @@
import warnings
from django.conf import settings
+from django.core.exceptions import ImproperlyConfigured
from django.core.management.color import no_style
from django.db import (connection, connections, DEFAULT_DB_ALIAS,
DatabaseError, IntegrityError, reset_queries, transaction)
@@ -1077,3 +1078,118 @@ def equal(value, max_d, places, result):
'0.1')
equal('0.1234567890', 12, 0,
'0')
+
+
+class DBTestSettingsRenamedTests(TestCase):
+
+ mismatch_msg = ("Connection 'test-deprecation' has mismatched TEST "
+ "and TEST_* database settings.")
+
+ def setUp(self):
+ self.handler = ConnectionHandler()
+ self.db_settings = {'default': {}}
+
+ def test_mismatched_database_test_settings_1(self):
+ # if the TEST setting is used, all TEST_* keys must appear in it.
+ self.db_settings.update({
+ 'test-deprecation': {
+ 'TEST': {},
+ 'TEST_NAME': 'foo',
+ }
+ })
+ with override_settings(DATABASES=self.db_settings):
+ with self.assertRaisesMessage(ImproperlyConfigured, self.mismatch_msg):
+ self.handler.prepare_test_settings('test-deprecation')
+
+ def test_mismatched_database_test_settings_2(self):
+ # if the TEST setting is used, all TEST_* keys must match.
+ self.db_settings.update({
+ 'test-deprecation': {
+ 'TEST': {'NAME': 'foo'},
+ 'TEST_NAME': 'bar',
+ },
+ })
+ with override_settings(DATABASES=self.db_settings):
+ with self.assertRaisesMessage(ImproperlyConfigured, self.mismatch_msg):
+ self.handler.prepare_test_settings('test-deprecation')
+
+ def test_mismatched_database_test_settings_3(self):
+ # Verifies the mapping of an aliased key.
+ self.db_settings.update({
+ 'test-deprecation': {
+ 'TEST': {'CREATE_DB': 'foo'},
+ 'TEST_CREATE': 'bar',
+ },
+ })
+ with override_settings(DATABASES=self.db_settings):
+ with self.assertRaisesMessage(ImproperlyConfigured, self.mismatch_msg):
+ self.handler.prepare_test_settings('test-deprecation')
+
+ def test_mismatched_database_test_settings_4(self):
+ # Verifies the mapping of an aliased key when the aliased key is missing.
+ self.db_settings.update({
+ 'test-deprecation': {
+ 'TEST': {},
+ 'TEST_CREATE': 'bar',
+ },
+ })
+ with override_settings(DATABASES=self.db_settings):
+ with self.assertRaisesMessage(ImproperlyConfigured, self.mismatch_msg):
+ self.handler.prepare_test_settings('test-deprecation')
+
+ def test_mismatched_settings_old_none(self):
+ self.db_settings.update({
+ 'test-deprecation': {
+ 'TEST': {'CREATE_DB': None},
+ 'TEST_CREATE': '',
+ },
+ })
+ with override_settings(DATABASES=self.db_settings):
+ with self.assertRaisesMessage(ImproperlyConfigured, self.mismatch_msg):
+ self.handler.prepare_test_settings('test-deprecation')
+
+ def test_mismatched_settings_new_none(self):
+ self.db_settings.update({
+ 'test-deprecation': {
+ 'TEST': {},
+ 'TEST_CREATE': None,
+ },
+ })
+ with override_settings(DATABASES=self.db_settings):
+ with self.assertRaisesMessage(ImproperlyConfigured, self.mismatch_msg):
+ self.handler.prepare_test_settings('test-deprecation')
+
+ def test_matched_test_settings(self):
+ # should be able to define new settings and the old, if they match
+ self.db_settings.update({
+ 'test-deprecation': {
+ 'TEST': {'NAME': 'foo'},
+ 'TEST_NAME': 'foo',
+ },
+ })
+ with override_settings(DATABASES=self.db_settings):
+ self.handler.prepare_test_settings('test-deprecation')
+
+ def test_new_settings_only(self):
+ # should be able to define new settings without the old
+ self.db_settings.update({
+ 'test-deprecation': {
+ 'TEST': {'NAME': 'foo'},
+ },
+ })
+ with override_settings(DATABASES=self.db_settings):
+ self.handler.prepare_test_settings('test-deprecation')
+
+ def test_old_settings_only(self):
+ # should be able to define old settings without the new
+ self.db_settings.update({
+ 'test-deprecation': {
+ 'TEST_NAME': 'foo',
+ },
+ })
+ with override_settings(DATABASES=self.db_settings):
+ self.handler.prepare_test_settings('test-deprecation')
+
+ def test_empty_settings(self):
+ with override_settings(DATABASES=self.db_settings):
+ self.handler.prepare_test_settings('default')

0 comments on commit 1c58cab

Please sign in to comment.