summaryrefslogtreecommitdiff
path: root/django
diff options
context:
space:
mode:
authorAymeric Augustin <aymeric.augustin@m4x.org>2013-06-11 22:56:09 +0200
committerAymeric Augustin <aymeric.augustin@m4x.org>2013-06-12 20:01:41 +0200
commit55cbd65985bfad02512a64a4cb8468140f15ee84 (patch)
treeab3e850489557ee7faf6f2ba2913ce2b2021729a /django
parent0938970491eee41ccde11bf3efe5b307ced8dba6 (diff)
Fixed #20579 -- Improved TransactionTestCase.available_apps.
Also moved its documentation to the 'advanced' section. It doesn't belong to the 'overview'. Same for TransactionTestCase.reset_sequences. When available_apps is set, after a TransactionTestCase, the database is now totally empty. post_syncdb is fired at the beginning of the next TransactionTestCase. Refs #20483.
Diffstat (limited to 'django')
-rw-r--r--django/core/management/commands/flush.py28
-rw-r--r--django/test/testcases.py35
2 files changed, 40 insertions, 23 deletions
diff --git a/django/core/management/commands/flush.py b/django/core/management/commands/flush.py
index 7054187e45..95dd634d08 100644
--- a/django/core/management/commands/flush.py
+++ b/django/core/management/commands/flush.py
@@ -32,9 +32,10 @@ class Command(NoArgsCommand):
connection = connections[db]
verbosity = int(options.get('verbosity'))
interactive = options.get('interactive')
- # 'reset_sequences' and 'allow_cascade' are stealth options
+ # The following are stealth options used by Django's internals.
reset_sequences = options.get('reset_sequences', True)
allow_cascade = options.get('allow_cascade', False)
+ inhibit_post_syncdb = options.get('inhibit_post_syncdb', False)
self.style = no_style()
@@ -75,16 +76,9 @@ Are you sure you want to do this?
"Hint: Look at the output of 'django-admin.py sqlflush'. That's the SQL this command wasn't able to run.\n"
"The full error: %s") % (connection.settings_dict['NAME'], e)
six.reraise(CommandError, CommandError(new_msg), sys.exc_info()[2])
- # Emit the post sync signal. This allows individual
- # applications to respond as if the database had been
- # sync'd from scratch.
- all_models = []
- for app in models.get_apps():
- all_models.extend([
- m for m in models.get_models(app, include_auto_created=True)
- if router.allow_syncdb(db, m)
- ])
- emit_post_sync_signal(set(all_models), verbosity, interactive, db)
+
+ if not inhibit_post_syncdb:
+ self.emit_post_syncdb(verbosity, interactive, db)
# Reinstall the initial_data fixture.
if options.get('load_initial_data'):
@@ -93,3 +87,15 @@ Are you sure you want to do this?
else:
self.stdout.write("Flush cancelled.\n")
+
+ @staticmethod
+ def emit_post_syncdb(verbosity, interactive, database):
+ # Emit the post sync signal. This allows individual applications to
+ # respond as if the database had been sync'd from scratch.
+ all_models = []
+ for app in models.get_apps():
+ all_models.extend([
+ m for m in models.get_models(app, include_auto_created=True)
+ if router.allow_syncdb(database, m)
+ ])
+ emit_post_sync_signal(set(all_models), verbosity, interactive, database)
diff --git a/django/test/testcases.py b/django/test/testcases.py
index 1dbb82e352..984d21ce18 100644
--- a/django/test/testcases.py
+++ b/django/test/testcases.py
@@ -24,6 +24,7 @@ from django.core.exceptions import ValidationError, ImproperlyConfigured
from django.core.handlers.wsgi import WSGIHandler
from django.core.management import call_command
from django.core.management.color import no_style
+from django.core.management.commands import flush
from django.core.servers.basehttp import (WSGIRequestHandler, WSGIServer,
WSGIServerException)
from django.core.urlresolvers import clear_url_caches, set_urlconf
@@ -196,9 +197,9 @@ class SimpleTestCase(ut2.TestCase):
def _pre_setup(self):
"""Performs any pre-test setup. This includes:
- * If the Test Case class has a 'urls' member, replace the
- ROOT_URLCONF with it.
- * Clearing the mail test outbox.
+ * Creating a test client.
+ * If the class has a 'urls' attribute, replace ROOT_URLCONF with it.
+ * Clearing the mail test outbox.
"""
self.client = self.client_class()
self._urlconf_setup()
@@ -212,6 +213,10 @@ class SimpleTestCase(ut2.TestCase):
clear_url_caches()
def _post_teardown(self):
+ """Performs any post-test things. This includes:
+
+ * Putting back the original ROOT_URLCONF if it was changed.
+ """
self._urlconf_teardown()
def _urlconf_teardown(self):
@@ -732,13 +737,17 @@ class TransactionTestCase(SimpleTestCase):
def _pre_setup(self):
"""Performs any pre-test setup. This includes:
- * Flushing the database.
- * If the Test Case class has a 'fixtures' member, installing the
- named fixtures.
+ * If the class has an 'available_apps' attribute, restricting the app
+ cache to these applications, then firing post_syncdb -- it must run
+ with the correct set of applications for the test case.
+ * If the class has a 'fixtures' attribute, installing these fixtures.
"""
super(TransactionTestCase, self)._pre_setup()
if self.available_apps is not None:
cache.set_available_apps(self.available_apps)
+ for db_name in self._databases_names(include_mirrors=False):
+ flush.Command.emit_post_syncdb(
+ verbosity=0, interactive=False, database=db_name)
try:
self._fixture_setup()
except Exception:
@@ -782,9 +791,9 @@ class TransactionTestCase(SimpleTestCase):
def _post_teardown(self):
"""Performs any post-test things. This includes:
- * Putting back the original ROOT_URLCONF if it was changed.
- * Force closing the connection, so that the next test gets
- a clean cursor.
+ * Flushing the contents of the database, to leave a clean slate. If
+ the class has an 'available_apps' attribute, post_syncdb isn't fired.
+ * Force-closing the connection, so the next test gets a clean cursor.
"""
try:
self._fixture_teardown()
@@ -801,12 +810,14 @@ class TransactionTestCase(SimpleTestCase):
cache.unset_available_apps()
def _fixture_teardown(self):
- # Allow TRUNCATE ... CASCADE when flushing only a subset of the apps
- allow_cascade = self.available_apps is not None
+ # Allow TRUNCATE ... CASCADE and don't emit the post_syncdb signal
+ # when flushing only a subset of the apps
for db_name in self._databases_names(include_mirrors=False):
call_command('flush', verbosity=0, interactive=False,
database=db_name, skip_validation=True,
- reset_sequences=False, allow_cascade=allow_cascade)
+ reset_sequences=False,
+ allow_cascade=self.available_apps is not None,
+ inhibit_post_syncdb=self.available_apps is not None)
def assertQuerysetEqual(self, qs, values, transform=repr, ordered=True):
items = six.moves.map(transform, qs)