[1.7.x] Fixed #22811 -- Allowed setting both the old and new TEST database settings.

An ImproperlyConfigured exception will be raised they mismatch.

Backport of 1c58cabad7 and a2cd0e12c9 from master
This commit is contained in:
Tim Graham 2014-06-11 15:26:17 -04:00
parent 961c9d6c6b
commit e51662e7bc
4 changed files with 149 additions and 9 deletions

View File

@ -187,6 +187,7 @@ class ConnectionHandler(object):
'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):
"""
@ -197,18 +198,29 @@ class ConnectionHandler(object):
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))
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.update(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" % (key, new_key),
"to a %s entry in the TEST setting" %
(self.TEST_SETTING_RENAMES_REVERSE.get(key, key), key),
RemovedInDjango19Warning, stacklevel=2)
test_settings[new_key] = value
for key in list(conn.keys()):
if key.startswith('TEST_'):
del conn[key]

View File

@ -614,6 +614,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 File

@ -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 File

@ -10,6 +10,7 @@ import threading
import unittest
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, transaction)
@ -24,7 +25,7 @@ from django.db.models.sql.constants import CURSOR
from django.db.utils import ConnectionHandler
from django.test import (TestCase, TransactionTestCase, override_settings,
skipUnlessDBFeature, skipIfDBFeature)
from django.test.utils import str_prefix
from django.test.utils import str_prefix, IgnoreAllDeprecationWarningsMixin
from django.utils import six
from django.utils.six.moves import xrange
@ -1015,3 +1016,125 @@ class BackendUtilTests(TestCase):
'0.1')
equal('0.1234567890', 12, 0,
'0')
class DBTestSettingsRenamedTests(IgnoreAllDeprecationWarningsMixin, TestCase):
mismatch_msg = ("Connection 'test-deprecation' has mismatched TEST "
"and TEST_* database settings.")
@classmethod
def setUpClass(cls):
# Silence "UserWarning: Overriding setting DATABASES can lead to
# unexpected behavior."
cls.warning_classes.append(UserWarning)
def setUp(self):
super(DBTestSettingsRenamedTests, self).setUp()
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')