Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Fixed #14415 -- Corrected the process of creating and destroying test…

… databases to prevent accidental deletion of the source database. Also improves the mirroring process to prevent some cross-connection effects. Thanks to Shai Berger for the help diagnosing and testing.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@14696 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 4ddde2f8d571adb0db269e2be6119ec4f06f0d05 1 parent 4a4d7bc
@freakboy3742 freakboy3742 authored
Showing with 49 additions and 13 deletions.
  1. +49 −13 django/test/simple.py
View
62 django/test/simple.py
@@ -217,19 +217,52 @@ def build_suite(self, test_labels, extra_tests=None, **kwargs):
def setup_databases(self, **kwargs):
from django.db import connections
- old_names = []
- mirrors = []
+
+ # First pass -- work out which databases actually need to be created,
+ # and which ones are test mirrors or duplicate entries in DATABASES
+ mirrored_aliases = {}
+ test_databases = {}
for alias in connections:
connection = connections[alias]
- # If the database is a test mirror, redirect it's connection
- # instead of creating a test database.
if connection.settings_dict['TEST_MIRROR']:
- mirrors.append((alias, connection))
- mirror_alias = connection.settings_dict['TEST_MIRROR']
- connections._connections[alias] = connections[mirror_alias]
+ # If the database is marked as a test mirror, save
+ # the alias.
+ mirrored_aliases[alias] = connection.settings_dict['TEST_MIRROR']
else:
- old_names.append((connection, connection.settings_dict['NAME']))
- connection.creation.create_test_db(self.verbosity, autoclobber=not self.interactive)
+ # Store the (engine, name) pair. If we have two aliases
+ # with the same pair, we only need to create the test database
+ # once.
+ test_databases.setdefault((
+ connection.settings_dict['HOST'],
+ connection.settings_dict['PORT'],
+ connection.settings_dict['ENGINE'],
+ connection.settings_dict['NAME'],
+ ), []).append(alias)
+
+ # Second pass -- actually create the databases.
+ old_names = []
+ mirrors = []
+ for (host, port, engine, db_name), aliases in test_databases.items():
+ # Actually create the database for the first connection
+ connection = connections[aliases[0]]
+ old_names.append((connection, db_name, True))
+ test_db_name = connection.creation.create_test_db(self.verbosity, autoclobber=not self.interactive)
+ for alias in aliases[1:]:
+ connection = connections[alias]
+ if db_name:
+ old_names.append((connection, db_name, False))
+ connection.settings_dict['NAME'] = test_db_name
+ else:
+ # If settings_dict['NAME'] isn't defined, we have a backend where
+ # the name isn't important -- e.g., SQLite, which uses :memory:.
+ # Force create the database instead of assuming it's a duplicate.
+ old_names.append((connection, db_name, True))
+ connection.creation.create_test_db(self.verbosity, autoclobber=not self.interactive)
+
+ for alias, mirror_alias in mirrored_aliases.items():
+ mirrors.append((alias, connections[alias].settings_dict['NAME']))
+ connections[alias].settings_dict['NAME'] = connections[mirror_alias].settings_dict['NAME']
+
return old_names, mirrors
def run_suite(self, suite, **kwargs):
@@ -239,11 +272,14 @@ def teardown_databases(self, old_config, **kwargs):
from django.db import connections
old_names, mirrors = old_config
# Point all the mirrors back to the originals
- for alias, connection in mirrors:
- connections._connections[alias] = connection
+ for alias, old_name in mirrors:
+ connections[alias].settings_dict['NAME'] = old_name
# Destroy all the non-mirror databases
- for connection, old_name in old_names:
- connection.creation.destroy_test_db(old_name, self.verbosity)
+ for connection, old_name, destroy in old_names:
+ if destroy:
+ connection.creation.destroy_test_db(old_name, self.verbosity)
+ else:
+ connection.settings_dict['NAME'] = old_name
def teardown_test_environment(self, **kwargs):
unittest.removeHandler()
Please sign in to comment.
Something went wrong with that request. Please try again.