Author: russellm Date: 2010-11-25 06:37:28 -0600 (Thu, 25 Nov 2010) New Revision: 14696
Modified: django/trunk/django/test/simple.py Log: 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. Modified: django/trunk/django/test/simple.py =================================================================== --- django/trunk/django/test/simple.py 2010-11-24 19:52:34 UTC (rev 14695) +++ django/trunk/django/test/simple.py 2010-11-25 12:37:28 UTC (rev 14696) @@ -217,19 +217,52 @@ 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 @@ 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() -- You received this message because you are subscribed to the Google Groups "Django updates" group. To post to this group, send email to django-upda...@googlegroups.com. To unsubscribe from this group, send email to django-updates+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-updates?hl=en.