diff options
| author | Andrew Godwin <andrew@aeracode.org> | 2014-08-19 19:50:14 -0700 |
|---|---|---|
| committer | Andrew Godwin <andrew@aeracode.org> | 2014-08-19 19:51:12 -0700 |
| commit | 9247da1032c1b8c98b0fcfb278bbbdbc8edc8783 (patch) | |
| tree | dc02b3156f7e6c6fe8ff57748144ff6430fff0dc /tests | |
| parent | fca677fa438879cbb3ebb828268cb2b976e514d8 (diff) | |
Fixed #23315: Operational dependency fail with mixed create/add
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/migrations/test_autodetector.py | 137 |
1 files changed, 65 insertions, 72 deletions
diff --git a/tests/migrations/test_autodetector.py b/tests/migrations/test_autodetector.py index 86f8ce3982..cb02b7aacd 100644 --- a/tests/migrations/test_autodetector.py +++ b/tests/migrations/test_autodetector.py @@ -131,12 +131,13 @@ class AutodetectorTests(TestCase): operation = migration.operations[operation_index] for attr, value in attrs.items(): if getattr(operation, attr, None) != value: - self.fail("Attribute mismatch for %s.%s op #%s, %s (expected %r):\n%s" % ( + self.fail("Attribute mismatch for %s.%s op #%s, %s (expected %r, got %r):\n%s" % ( app_label, migration.name, - operation_index + 1, + operation_index, attr, value, + getattr(operation, attr, None), self.repr_changes(changes), )) @@ -403,21 +404,14 @@ class AutodetectorTests(TestCase): after = self.make_project_state([self.author_with_publisher, self.publisher]) autodetector = MigrationAutodetector(before, after) changes = autodetector._detect_changes() - # Right number of migrations? - self.assertEqual(len(changes['testapp']), 1) - # Right number of actions? - migration = changes['testapp'][0] - self.assertEqual(len(migration.operations), 3) - # Right actions? - action = migration.operations[0] - self.assertEqual(action.__class__.__name__, "CreateModel") - action = migration.operations[1] - self.assertEqual(action.__class__.__name__, "CreateModel") - # Third action might vanish one day if the optimizer improves. - action = migration.operations[2] - self.assertEqual(action.__class__.__name__, "AddField") + # Right number/type of migrations? + self.assertNumberMigrations(changes, 'testapp', 1) + self.assertOperationTypes(changes, 'testapp', 0, ["CreateModel", "CreateModel", "AddField"]) + self.assertOperationAttributes(changes, "testapp", 0, 0, name="Author") + self.assertOperationAttributes(changes, "testapp", 0, 1, name="Publisher") + self.assertOperationAttributes(changes, "testapp", 0, 2, name="publisher") # Right dependencies? - self.assertEqual(migration.dependencies, []) + self.assertEqual(changes['testapp'][0].dependencies, []) def test_circular_fk_dependency(self): """ @@ -430,30 +424,18 @@ class AutodetectorTests(TestCase): autodetector = MigrationAutodetector(before, after) changes = autodetector._detect_changes() # Right number of migrations? - self.assertEqual(len(changes['testapp']), 1) - self.assertEqual(len(changes['otherapp']), 2) - # Right number of actions? - migration1 = changes['testapp'][0] - self.assertEqual(len(migration1.operations), 2) - migration2 = changes['otherapp'][0] - self.assertEqual(len(migration2.operations), 1) - migration3 = changes['otherapp'][1] - self.assertEqual(len(migration3.operations), 1) - # Right actions? - action = migration1.operations[0] - self.assertEqual(action.__class__.__name__, "CreateModel") - self.assertEqual(action.name, "Author") - self.assertEqual(len(action.fields), 3) - action = migration2.operations[0] - self.assertEqual(action.__class__.__name__, "CreateModel") - self.assertEqual(len(action.fields), 2) - action = migration3.operations[0] - self.assertEqual(action.__class__.__name__, "AddField") - self.assertEqual(action.name, "author") + self.assertNumberMigrations(changes, 'testapp', 1) + self.assertNumberMigrations(changes, 'otherapp', 2) + # Right types? + self.assertOperationTypes(changes, 'testapp', 0, ["CreateModel", "CreateModel"]) + self.assertOperationTypes(changes, 'otherapp', 0, ["CreateModel"]) + self.assertOperationTypes(changes, 'otherapp', 1, ["AddField"]) + self.assertOperationAttributes(changes, "testapp", 0, 0, name="Author") + self.assertOperationAttributes(changes, "testapp", 0, 1, name="Publisher") # Right dependencies? - self.assertEqual(migration1.dependencies, [("otherapp", "auto_1")]) - self.assertEqual(migration2.dependencies, []) - self.assertEqual(set(migration3.dependencies), set([("testapp", "auto_1"), ("otherapp", "auto_1")])) + self.assertEqual(changes['testapp'][0].dependencies, [("otherapp", "auto_1")]) + self.assertEqual(changes['otherapp'][0].dependencies, []) + self.assertEqual(set(changes['otherapp'][1].dependencies), set([("otherapp", "auto_1"), ("testapp", "auto_1")])) def test_same_app_circular_fk_dependency(self): """ @@ -465,24 +447,14 @@ class AutodetectorTests(TestCase): after = self.make_project_state([self.author_with_publisher, self.publisher_with_author]) autodetector = MigrationAutodetector(before, after) changes = autodetector._detect_changes() - # Right number of migrations? - self.assertEqual(len(changes['testapp']), 1) - # Right number of actions? - migration1 = changes['testapp'][0] - self.assertEqual(len(migration1.operations), 4) - # Right actions? - action = migration1.operations[0] - self.assertEqual(action.__class__.__name__, "CreateModel") - action = migration1.operations[1] - self.assertEqual(action.__class__.__name__, "CreateModel") - action = migration1.operations[2] - self.assertEqual(action.__class__.__name__, "AddField") - self.assertEqual(action.name, "publisher") - action = migration1.operations[3] - self.assertEqual(action.__class__.__name__, "AddField") - self.assertEqual(action.name, "author") + # Right number/type of migrations? + self.assertNumberMigrations(changes, 'testapp', 1) + self.assertOperationTypes(changes, 'testapp', 0, ["CreateModel", "CreateModel", "AddField"]) + self.assertOperationAttributes(changes, "testapp", 0, 0, name="Author") + self.assertOperationAttributes(changes, "testapp", 0, 1, name="Publisher") + self.assertOperationAttributes(changes, "testapp", 0, 2, name="publisher") # Right dependencies? - self.assertEqual(migration1.dependencies, []) + self.assertEqual(changes['testapp'][0].dependencies, []) def test_same_app_circular_fk_dependency_and_unique_together(self): """ @@ -495,23 +467,13 @@ class AutodetectorTests(TestCase): after = self.make_project_state([self.knight, self.rabbit]) autodetector = MigrationAutodetector(before, after) changes = autodetector._detect_changes() - # Right number of migrations? - self.assertEqual(len(changes['eggs']), 1) - # Right number of actions? - migration1 = changes['eggs'][0] - self.assertEqual(len(migration1.operations), 3) - # Right actions? - action = migration1.operations[0] - self.assertEqual(action.__class__.__name__, "CreateModel") - action = migration1.operations[1] - self.assertEqual(action.__class__.__name__, "CreateModel") - self.assertEqual(action.name, "Rabbit") - self.assertFalse("unique_together" in action.options) - action = migration1.operations[2] - self.assertEqual(action.__class__.__name__, "AlterUniqueTogether") - self.assertEqual(action.name, "rabbit") + # Right number/type of migrations? + self.assertNumberMigrations(changes, 'eggs', 1) + self.assertOperationTypes(changes, 'eggs', 0, ["CreateModel", "CreateModel", "AlterUniqueTogether"]) + self.assertFalse("unique_together" in changes['eggs'][0].operations[0].options) + self.assertFalse("unique_together" in changes['eggs'][0].operations[1].options) # Right dependencies? - self.assertEqual(migration1.dependencies, []) + self.assertEqual(changes['eggs'][0].dependencies, []) def test_unique_together(self): "Tests unique_together detection" @@ -1110,3 +1072,34 @@ class AutodetectorTests(TestCase): self.assertOperationTypes(changes, 'testapp', 0, ["AddField"]) self.assertOperationAttributes(changes, 'testapp', 0, 0, name="book") self.assertEqual(changes['testapp'][0].dependencies, [("otherapp", "__first__")]) + + def test_circular_dependency_mixed_addcreate(self): + """ + Tests that the dependency resolver knows to put all CreateModel + before AddField and not become unsolvable (#23315) + """ + address = ModelState("a", "Address", [ + ("id", models.AutoField(primary_key=True)), + ("country", models.ForeignKey("b.DeliveryCountry")), + ]) + person = ModelState("a", "Person", [ + ("id", models.AutoField(primary_key=True)), + ]) + apackage = ModelState("b", "APackage", [ + ("id", models.AutoField(primary_key=True)), + ("person", models.ForeignKey("a.person")), + ]) + country = ModelState("b", "DeliveryCountry", [ + ("id", models.AutoField(primary_key=True)), + ]) + # Make state + before = self.make_project_state([]) + after = self.make_project_state([address, person, apackage, country]) + autodetector = MigrationAutodetector(before, after) + changes = autodetector._detect_changes() + # Right number of migrations? + self.assertNumberMigrations(changes, 'a', 2) + self.assertNumberMigrations(changes, 'b', 1) + self.assertOperationTypes(changes, 'a', 0, ["CreateModel", "CreateModel"]) + self.assertOperationTypes(changes, 'a', 1, ["AddField"]) + self.assertOperationTypes(changes, 'b', 0, ["CreateModel", "CreateModel"]) |
