diff --git a/django/test/simple.py b/django/test/simple.py
index de8b527..62e7326 100644
a
|
b
|
def reorder_suite(suite, classes):
|
193 | 193 | |
194 | 194 | |
195 | 195 | def dependency_ordered(test_databases, dependencies): |
196 | | """Reorder test_databases into an order that honors the dependencies |
| 196 | """ |
| 197 | Reorder test_databases into an order that honors the dependencies |
197 | 198 | described in TEST_DEPENDENCIES. |
198 | 199 | """ |
199 | 200 | ordered_test_databases = [] |
200 | 201 | resolved_databases = set() |
| 202 | |
| 203 | # Maps db signature to dependencies of all it's aliases |
| 204 | dependencies_map = {} |
| 205 | |
| 206 | # sanity check - no DB can depend on it's own alias |
| 207 | for sig, (_, aliases) in test_databases: |
| 208 | all_deps = set() |
| 209 | for alias in aliases: |
| 210 | all_deps.update(dependencies.get(alias, [])) |
| 211 | if not all_deps.isdisjoint(aliases): |
| 212 | raise ImproperlyConfigured( |
| 213 | "Circular dependency: databases %r depend on each other, " |
| 214 | "but are aliases." % aliases) |
| 215 | dependencies_map[sig] = all_deps |
| 216 | |
201 | 217 | while test_databases: |
202 | 218 | changed = False |
203 | 219 | deferred = [] |
204 | 220 | |
205 | | while test_databases: |
206 | | signature, (db_name, aliases) = test_databases.pop() |
207 | | dependencies_satisfied = True |
208 | | for alias in aliases: |
209 | | if alias in dependencies: |
210 | | if all(a in resolved_databases |
211 | | for a in dependencies[alias]): |
212 | | # all dependencies for this alias are satisfied |
213 | | dependencies.pop(alias) |
214 | | resolved_databases.add(alias) |
215 | | else: |
216 | | dependencies_satisfied = False |
217 | | else: |
218 | | resolved_databases.add(alias) |
219 | | |
220 | | if dependencies_satisfied: |
| 221 | # Try to find a DB that has all it's dependencies met |
| 222 | for signature, (db_name, aliases) in test_databases: |
| 223 | if dependencies_map[signature].issubset(resolved_databases): |
| 224 | resolved_databases.update(aliases) |
221 | 225 | ordered_test_databases.append((signature, (db_name, aliases))) |
222 | 226 | changed = True |
223 | 227 | else: |
… |
… |
class DjangoTestSuiteRunner(object):
|
282 | 286 | # we only need to create the test database once. |
283 | 287 | item = test_databases.setdefault( |
284 | 288 | connection.creation.test_db_signature(), |
285 | | (connection.settings_dict['NAME'], []) |
| 289 | (connection.settings_dict['NAME'], set()) |
286 | 290 | ) |
287 | | item[1].append(alias) |
| 291 | item[1].add(alias) |
288 | 292 | |
289 | 293 | if 'TEST_DEPENDENCIES' in connection.settings_dict: |
290 | 294 | dependencies[alias] = ( |
… |
… |
class DjangoTestSuiteRunner(object):
|
297 | 301 | # Second pass -- actually create the databases. |
298 | 302 | old_names = [] |
299 | 303 | mirrors = [] |
| 304 | |
300 | 305 | for signature, (db_name, aliases) in dependency_ordered( |
301 | 306 | test_databases.items(), dependencies): |
| 307 | test_db_name = None |
302 | 308 | # Actually create the database for the first connection |
303 | | connection = connections[aliases[0]] |
304 | | old_names.append((connection, db_name, True)) |
305 | | test_db_name = connection.creation.create_test_db( |
306 | | self.verbosity, autoclobber=not self.interactive) |
307 | | for alias in aliases[1:]: |
| 309 | |
| 310 | for alias in aliases: |
308 | 311 | connection = connections[alias] |
309 | | if db_name: |
310 | | old_names.append((connection, db_name, False)) |
311 | | connection.settings_dict['NAME'] = test_db_name |
| 312 | old_names.append((connection, db_name, True)) |
| 313 | if test_db_name is None: |
| 314 | test_db_name = connection.creation.create_test_db( |
| 315 | self.verbosity, autoclobber=not self.interactive) |
312 | 316 | else: |
313 | | # If settings_dict['NAME'] isn't defined, we have a backend |
314 | | # where the name isn't important -- e.g., SQLite, which |
315 | | # uses :memory:. Force create the database instead of |
316 | | # assuming it's a duplicate. |
317 | | old_names.append((connection, db_name, True)) |
318 | | connection.creation.create_test_db( |
319 | | self.verbosity, autoclobber=not self.interactive) |
| 317 | connection.settings_dict['NAME'] = test_db_name |
320 | 318 | |
321 | 319 | for alias, mirror_alias in mirrored_aliases.items(): |
322 | 320 | mirrors.append((alias, connections[alias].settings_dict['NAME'])) |
diff --git a/tests/regressiontests/test_runner/tests.py b/tests/regressiontests/test_runner/tests.py
index ccb65b4..2af4eb9 100644
a
|
b
|
class DependencyOrderingTests(unittest.TestCase):
|
110 | 110 | |
111 | 111 | self.assertRaises(ImproperlyConfigured, simple.dependency_ordered, raw, dependencies=dependencies) |
112 | 112 | |
| 113 | def test_own_alias_dependency(self): |
| 114 | raw = [ |
| 115 | ('s1', ('s1_db', ['alpha', 'bravo'])) |
| 116 | ] |
| 117 | dependencies = { |
| 118 | 'alpha': ['bravo'] |
| 119 | } |
| 120 | |
| 121 | with self.assertRaises(ImproperlyConfigured): |
| 122 | simple.dependency_ordered(raw, dependencies=dependencies) |
| 123 | |
| 124 | # reordering aliases shouldn't matter |
| 125 | raw = [ |
| 126 | ('s1', ('s1_db', ['bravo', 'alpha'])) |
| 127 | ] |
| 128 | |
| 129 | with self.assertRaises(ImproperlyConfigured): |
| 130 | simple.dependency_ordered(raw, dependencies=dependencies) |
| 131 | |
113 | 132 | |
114 | 133 | class MockTestRunner(object): |
115 | 134 | invoked = False |