Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move Test settings into an inner dictionary in database settings #2400

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions django/db/backends/creation.py
Expand Up @@ -390,8 +390,8 @@ def _get_test_db_name(self):
_create_test_db() and when no external munging is done with the 'NAME'
or 'TEST_NAME' settings.
"""
if self.connection.settings_dict['TEST_NAME']:
return self.connection.settings_dict['TEST_NAME']
if self.connection.settings_dict['TEST']['NAME']:
return self.connection.settings_dict['TEST']['NAME']
return TEST_DATABASE_PREFIX + self.connection.settings_dict['NAME']

def _create_test_db(self, verbosity, autoclobber):
Expand Down
9 changes: 5 additions & 4 deletions django/db/backends/mysql/creation.py
Expand Up @@ -34,10 +34,11 @@ class DatabaseCreation(BaseDatabaseCreation):

def sql_table_creation_suffix(self):
suffix = []
if self.connection.settings_dict['TEST_CHARSET']:
suffix.append('CHARACTER SET %s' % self.connection.settings_dict['TEST_CHARSET'])
if self.connection.settings_dict['TEST_COLLATION']:
suffix.append('COLLATE %s' % self.connection.settings_dict['TEST_COLLATION'])
test_settings = self.connection.settings_dict['TEST']
if test_settings['CHARSET']:
suffix.append('CHARACTER SET %s' % test_settings['CHARSET'])
if test_settings['COLLATION']:
suffix.append('COLLATE %s' % test_settings['COLLATION'])
return ' '.join(suffix)

def sql_for_inline_foreign_key_references(self, model, field, known_models, style):
Expand Down
62 changes: 24 additions & 38 deletions django/db/backends/oracle/creation.py
Expand Up @@ -119,7 +119,9 @@ def _create_test_db(self, verbosity=1, autoclobber=False):
real_settings = settings.DATABASES[self.connection.alias]
real_settings['SAVED_USER'] = self.connection.settings_dict['SAVED_USER'] = self.connection.settings_dict['USER']
real_settings['SAVED_PASSWORD'] = self.connection.settings_dict['SAVED_PASSWORD'] = self.connection.settings_dict['PASSWORD']
real_settings['TEST_USER'] = real_settings['USER'] = self.connection.settings_dict['TEST_USER'] = self.connection.settings_dict['USER'] = TEST_USER
real_test_settings = real_settings['TEST']
test_settings = self.connection.settings_dict['TEST']
real_test_settings['USER'] = real_settings['USER'] = test_settings['USER'] = self.connection.settings_dict['USER'] = TEST_USER
real_settings['PASSWORD'] = self.connection.settings_dict['PASSWORD'] = TEST_PASSWD

return self.connection.settings_dict['NAME']
Expand Down Expand Up @@ -216,56 +218,40 @@ def _execute_statements(self, cursor, statements, parameters, verbosity):
sys.stderr.write("Failed (%s)\n" % (err))
raise

def _test_settings_get(self, key, default=None, prefixed=None):
"""
Return a value from the test settings dict,
or a given default,
or a prefixed entry from the main settings dict
"""
settings_dict = self.connection.settings_dict
val = settings_dict['TEST'].get(key, default)
if val is None:
val = TEST_DATABASE_PREFIX + settings_dict[prefixed]
return val

def _test_database_name(self):
name = TEST_DATABASE_PREFIX + self.connection.settings_dict['NAME']
try:
if self.connection.settings_dict['TEST_NAME']:
name = self.connection.settings_dict['TEST_NAME']
except AttributeError:
pass
return name
return self._test_settings_get('NAME', prefixed='NAME')

def _test_database_create(self):
return self.connection.settings_dict.get('TEST_CREATE', True)
return self._test_settings_get('CREATE', default=True)

def _test_user_create(self):
return self.connection.settings_dict.get('TEST_USER_CREATE', True)
return self._test_settings_get('USER_CREATE', default=True)

def _test_database_user(self):
name = TEST_DATABASE_PREFIX + self.connection.settings_dict['USER']
try:
if self.connection.settings_dict['TEST_USER']:
name = self.connection.settings_dict['TEST_USER']
except KeyError:
pass
return name
return self._test_settings_get('USER', prefixed='USER')

def _test_database_passwd(self):
name = PASSWORD
try:
if self.connection.settings_dict['TEST_PASSWD']:
name = self.connection.settings_dict['TEST_PASSWD']
except KeyError:
pass
return name
return self._test_settings_get('PASSWD', default=PASSWORD)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this setting is now in a sub-dictionary and elides the TEST_ prefix, should the key be named PASSWORD rather than PASSWD to be more consistent with the non-test settings?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. Thanks.


def _test_database_tblspace(self):
name = TEST_DATABASE_PREFIX + self.connection.settings_dict['NAME']
try:
if self.connection.settings_dict['TEST_TBLSPACE']:
name = self.connection.settings_dict['TEST_TBLSPACE']
except KeyError:
pass
return name
return self._test_settings_get('TBLSPACE', prefixed='NAME')

def _test_database_tblspace_tmp(self):
name = TEST_DATABASE_PREFIX + self.connection.settings_dict['NAME'] + '_temp'
try:
if self.connection.settings_dict['TEST_TBLSPACE_TMP']:
name = self.connection.settings_dict['TEST_TBLSPACE_TMP']
except KeyError:
pass
return name
settings_dict = self.connection.settings_dict
return settings_dict['TEST'].get('TBLSPACE_TMP',
TEST_DATABASE_PREFIX + settings_dict['NAME'] + '_temp')

def _get_test_db_name(self):
"""
Expand Down
7 changes: 4 additions & 3 deletions django/db/backends/postgresql_psycopg2/creation.py
Expand Up @@ -39,9 +39,10 @@ class DatabaseCreation(BaseDatabaseCreation):
}

def sql_table_creation_suffix(self):
assert self.connection.settings_dict['TEST_COLLATION'] is None, "PostgreSQL does not support collation setting at database creation time."
if self.connection.settings_dict['TEST_CHARSET']:
return "WITH ENCODING '%s'" % self.connection.settings_dict['TEST_CHARSET']
test_settings = self.connection.settings_dict['TEST']
assert test_settings['COLLATION'] is None, "PostgreSQL does not support collation setting at database creation time."
if test_settings['CHARSET']:
return "WITH ENCODING '%s'" % test_settings['CHARSET']
return ''

def sql_indexes_for_field(self, model, f, style):
Expand Down
4 changes: 2 additions & 2 deletions django/db/backends/sqlite3/creation.py
Expand Up @@ -47,7 +47,7 @@ def sql_remove_table_constraints(self, model, references_to_delete, style):
return []

def _get_test_db_name(self):
test_database_name = self.connection.settings_dict['TEST_NAME']
test_database_name = self.connection.settings_dict['TEST']['NAME']
if test_database_name and test_database_name != ':memory:':
return test_database_name
return ':memory:'
Expand Down Expand Up @@ -83,7 +83,7 @@ def test_db_signature(self):

This takes into account the special cases of ":memory:" and "" for
SQLite since the databases will be distinct despite having the same
TEST_NAME. See http://www.sqlite.org/inmemorydb.html
TEST NAME. See http://www.sqlite.org/inmemorydb.html
"""
test_dbname = self._get_test_db_name()
sig = [self.connection.settings_dict['NAME']]
Expand Down
38 changes: 36 additions & 2 deletions django/db/utils.py
Expand Up @@ -180,14 +180,48 @@ def ensure_defaults(self, alias):
conn.setdefault('TIME_ZONE', 'UTC' if settings.USE_TZ else settings.TIME_ZONE)
for setting in ['NAME', 'USER', 'PASSWORD', 'HOST', 'PORT']:
conn.setdefault(setting, '')
for setting in ['TEST_CHARSET', 'TEST_COLLATION', 'TEST_NAME', 'TEST_MIRROR']:
conn.setdefault(setting, None)

TEST_SETTING_RENAMES = {
'CREATE': 'CREATE_DB',
'USER_CREATE': 'CREATE_USER',
}

def prepare_test_settings(self, alias):
"""
Makes sure the test settings are available in the 'TEST' sub-dictionary.
"""
try:
conn = self.databases[alias]
except KeyError:
raise ConnectionDoesNotExist("The connection %s doesn't exist" % alias)

test_settings = conn.setdefault('TEST', {})
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))
test_settings_warning = ("In Django 1.9 the %s connection setting will be moved "
"to a %s entry in the TEST setting")
warnings.warn(PendingDeprecationWarning(test_settings_warning % (key, new_key)),
stacklevel=2)
test_settings[new_key] = value
# Check that they didn't just use the old name with 'TEST_' removed
for key, new_key in six.iteritems(self.TEST_SETTING_RENAMES):
if key in test_settings:
warnings.warn("Test setting %s was renamed to %s; specified value (%s) ignored" %
(key, new_key, test_settings[key]), stacklevel=2)
for key in ['CHARSET', 'COLLATION', 'NAME', 'MIRROR']:
test_settings.setdefault(key, None)

def __getitem__(self, alias):
if hasattr(self._connections, alias):
return getattr(self._connections, alias)

self.ensure_defaults(alias)
self.prepare_test_settings(alias)
db = self.databases[alias]
backend = load_backend(db['ENGINE'])
conn = backend.DatabaseWrapper(db, alias)
Expand Down
19 changes: 9 additions & 10 deletions django/test/runner.py
Expand Up @@ -170,7 +170,7 @@ def is_discoverable(label):
def dependency_ordered(test_databases, dependencies):
"""
Reorder test_databases into an order that honors the dependencies
described in TEST_DEPENDENCIES.
described in TEST[DEPENDENCIES].
"""
ordered_test_databases = []
resolved_databases = set()
Expand Down Expand Up @@ -204,7 +204,7 @@ def dependency_ordered(test_databases, dependencies):

if not changed:
raise ImproperlyConfigured(
"Circular dependency in TEST_DEPENDENCIES")
"Circular dependency in TEST[DEPENDENCIES]")
test_databases = deferred
return ordered_test_databases

Expand Down Expand Up @@ -261,11 +261,11 @@ def setup_databases(verbosity, interactive, **kwargs):
default_sig = connections[DEFAULT_DB_ALIAS].creation.test_db_signature()
for alias in connections:
connection = connections[alias]
if connection.settings_dict['TEST_MIRROR']:
test_settings = connection.settings_dict['TEST']
if test_settings['MIRROR']:
# If the database is marked as a test mirror, save
# the alias.
mirrored_aliases[alias] = (
connection.settings_dict['TEST_MIRROR'])
mirrored_aliases[alias] = test_settings['MIRROR']
else:
# Store a tuple with DB parameters that uniquely identify it.
# If we have two aliases with the same values for that tuple,
Expand All @@ -276,13 +276,12 @@ def setup_databases(verbosity, interactive, **kwargs):
)
item[1].add(alias)

if 'TEST_DEPENDENCIES' in connection.settings_dict:
dependencies[alias] = (
connection.settings_dict['TEST_DEPENDENCIES'])
if 'DEPENDENCIES' in test_settings:
dependencies[alias] = test_settings['DEPENDENCIES']
else:
if alias != DEFAULT_DB_ALIAS and connection.creation.test_db_signature() != default_sig:
dependencies[alias] = connection.settings_dict.get(
'TEST_DEPENDENCIES', [DEFAULT_DB_ALIAS])
#TODO: Huh? we already know ('DEPENDENCIES' not in test_settings)
dependencies[alias] = test_settings.get('DEPENDENCIES', [DEFAULT_DB_ALIAS])

# Second pass -- actually create the databases.
old_names = []
Expand Down
2 changes: 1 addition & 1 deletion django/test/testcases.py
Expand Up @@ -762,7 +762,7 @@ def _databases_names(self, include_mirrors=True):
# including mirrors or not. Otherwise, just on the default DB.
if getattr(self, 'multi_db', False):
return [alias for alias in connections
if include_mirrors or not connections[alias].settings_dict['TEST_MIRROR']]
if include_mirrors or not connections[alias].settings_dict['TEST']['MIRROR']]
else:
return [DEFAULT_DB_ALIAS]

Expand Down