diff options
| author | Markus Holtermann <info@markusholtermann.eu> | 2014-09-26 00:24:17 +0200 |
|---|---|---|
| committer | Markus Holtermann <info@markusholtermann.eu> | 2014-10-30 00:17:29 +0100 |
| commit | 85086c815873c4cf0bc2f1f2809119088cbe55f1 (patch) | |
| tree | 1228f4757eaeea0ba9f11f40a95cebff6d770a0c /tests | |
| parent | 388c6038fdc7ce1d1314b1ffdf5943807f123977 (diff) | |
Fixed #23556 -- Raised a more meaningful error message when migrations refer to an unavailable node
Diffstat (limited to 'tests')
17 files changed, 286 insertions, 5 deletions
diff --git a/tests/migrations/test_graph.py b/tests/migrations/test_graph.py index 3fcdd12667..e70481a462 100644 --- a/tests/migrations/test_graph.py +++ b/tests/migrations/test_graph.py @@ -1,5 +1,5 @@ from django.test import TestCase -from django.db.migrations.graph import MigrationGraph, CircularDependencyError +from django.db.migrations.graph import CircularDependencyError, MigrationGraph, NodeNotFoundError class GraphTests(TestCase): @@ -156,10 +156,10 @@ class GraphTests(TestCase): graph = MigrationGraph() message = "Node ('app_b', '0001') not a valid node" - with self.assertRaisesMessage(ValueError, message): + with self.assertRaisesMessage(NodeNotFoundError, message): graph.forwards_plan(("app_b", "0001")) - with self.assertRaisesMessage(ValueError, message): + with self.assertRaisesMessage(NodeNotFoundError, message): graph.backwards_plan(("app_b", "0001")) def test_missing_parent_nodes(self): @@ -175,7 +175,7 @@ class GraphTests(TestCase): graph.add_dependency("app_a.0003", ("app_a", "0003"), ("app_a", "0002")) graph.add_dependency("app_a.0002", ("app_a", "0002"), ("app_a", "0001")) msg = "Migration app_a.0001 dependencies reference nonexistent parent node ('app_b', '0002')" - with self.assertRaisesMessage(KeyError, msg): + with self.assertRaisesMessage(NodeNotFoundError, msg): graph.add_dependency("app_a.0001", ("app_a", "0001"), ("app_b", "0002")) def test_missing_child_nodes(self): @@ -186,5 +186,5 @@ class GraphTests(TestCase): graph = MigrationGraph() graph.add_node(("app_a", "0001"), None) msg = "Migration app_a.0002 dependencies reference nonexistent child node ('app_a', '0002')" - with self.assertRaisesMessage(KeyError, msg): + with self.assertRaisesMessage(NodeNotFoundError, msg): graph.add_dependency("app_a.0002", ("app_a", "0002"), ("app_a", "0001")) diff --git a/tests/migrations/test_loader.py b/tests/migrations/test_loader.py index 676c843e9d..a921321525 100644 --- a/tests/migrations/test_loader.py +++ b/tests/migrations/test_loader.py @@ -1,7 +1,10 @@ +from __future__ import unicode_literals + from unittest import skipIf from django.test import TestCase, override_settings from django.db import connection, connections +from django.db.migrations.graph import NodeNotFoundError from django.db.migrations.loader import MigrationLoader, AmbiguityError from django.db.migrations.recorder import MigrationRecorder from django.test import modify_settings @@ -187,3 +190,104 @@ class LoaderTests(TestCase): 2, ) recorder.flush() + + @override_settings(MIGRATION_MODULES={"migrations": "migrations.test_migrations_squashed_complex"}) + def test_loading_squashed_complex(self): + "Tests loading a complex set of squashed migrations" + + loader = MigrationLoader(connection) + recorder = MigrationRecorder(connection) + + def num_nodes(): + plan = set(loader.graph.forwards_plan(('migrations', '7_auto'))) + return len(plan - loader.applied_migrations) + + # Empty database: use squashed migration + loader.build_graph() + self.assertEqual(num_nodes(), 5) + + # Starting at 1 or 2 should use the squashed migration too + recorder.record_applied("migrations", "1_auto") + loader.build_graph() + self.assertEqual(num_nodes(), 4) + + recorder.record_applied("migrations", "2_auto") + loader.build_graph() + self.assertEqual(num_nodes(), 3) + + # However, starting at 3 to 5 cannot use the squashed migration + recorder.record_applied("migrations", "3_auto") + loader.build_graph() + self.assertEqual(num_nodes(), 4) + + recorder.record_applied("migrations", "4_auto") + loader.build_graph() + self.assertEqual(num_nodes(), 3) + + # Starting at 5 to 7 we are passed the squashed migrations + recorder.record_applied("migrations", "5_auto") + loader.build_graph() + self.assertEqual(num_nodes(), 2) + + recorder.record_applied("migrations", "6_auto") + loader.build_graph() + self.assertEqual(num_nodes(), 1) + + recorder.record_applied("migrations", "7_auto") + loader.build_graph() + self.assertEqual(num_nodes(), 0) + + recorder.flush() + + @override_settings(MIGRATION_MODULES={"migrations": "migrations.test_migrations_squashed_erroneous"}) + def test_loading_squashed_erroneous(self): + "Tests loading a complex but erroneous set of squashed migrations" + + loader = MigrationLoader(connection) + recorder = MigrationRecorder(connection) + + def num_nodes(): + plan = set(loader.graph.forwards_plan(('migrations', '7_auto'))) + return len(plan - loader.applied_migrations) + + # Empty database: use squashed migration + loader.build_graph() + self.assertEqual(num_nodes(), 5) + + # Starting at 1 or 2 should use the squashed migration too + recorder.record_applied("migrations", "1_auto") + loader.build_graph() + self.assertEqual(num_nodes(), 4) + + recorder.record_applied("migrations", "2_auto") + loader.build_graph() + self.assertEqual(num_nodes(), 3) + + # However, starting at 3 or 4 we'd need to use non-existing migrations + msg = ("Migration migrations.6_auto depends on nonexistent node ('migrations', '5_auto'). " + "Django tried to replace migration migrations.5_auto with any of " + "[migrations.3_squashed_5] but wasn't able to because some of the replaced " + "migrations are already applied.") + + recorder.record_applied("migrations", "3_auto") + with self.assertRaisesMessage(NodeNotFoundError, msg): + loader.build_graph() + + recorder.record_applied("migrations", "4_auto") + with self.assertRaisesMessage(NodeNotFoundError, msg): + loader.build_graph() + + # Starting at 5 to 7 we are passed the squashed migrations + recorder.record_applied("migrations", "5_auto") + loader.build_graph() + self.assertEqual(num_nodes(), 2) + + recorder.record_applied("migrations", "6_auto") + loader.build_graph() + self.assertEqual(num_nodes(), 1) + + recorder.record_applied("migrations", "7_auto") + loader.build_graph() + self.assertEqual(num_nodes(), 0) + + recorder.flush() diff --git a/tests/migrations/test_migrations_squashed_complex/1_auto.py b/tests/migrations/test_migrations_squashed_complex/1_auto.py new file mode 100644 index 0000000000..25edcfa290 --- /dev/null +++ b/tests/migrations/test_migrations_squashed_complex/1_auto.py @@ -0,0 +1,11 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + operations = [ + migrations.RunPython(lambda apps, schema_editor: None) + ] diff --git a/tests/migrations/test_migrations_squashed_complex/2_auto.py b/tests/migrations/test_migrations_squashed_complex/2_auto.py new file mode 100644 index 0000000000..9107c35868 --- /dev/null +++ b/tests/migrations/test_migrations_squashed_complex/2_auto.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [("migrations", "1_auto")] + + operations = [ + migrations.RunPython(lambda apps, schema_editor: None) + ] diff --git a/tests/migrations/test_migrations_squashed_complex/3_auto.py b/tests/migrations/test_migrations_squashed_complex/3_auto.py new file mode 100644 index 0000000000..98e679fc12 --- /dev/null +++ b/tests/migrations/test_migrations_squashed_complex/3_auto.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [("migrations", "2_auto")] + + operations = [ + migrations.RunPython(lambda apps, schema_editor: None) + ] diff --git a/tests/migrations/test_migrations_squashed_complex/3_squashed_5.py b/tests/migrations/test_migrations_squashed_complex/3_squashed_5.py new file mode 100644 index 0000000000..ac1bcdee6d --- /dev/null +++ b/tests/migrations/test_migrations_squashed_complex/3_squashed_5.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + replaces = [ + ("migrations", "3_auto"), + ("migrations", "4_auto"), + ("migrations", "5_auto"), + ] + + dependencies = [("migrations", "2_auto")] + + operations = [ + migrations.RunPython(lambda apps, schema_editor: None) + ] diff --git a/tests/migrations/test_migrations_squashed_complex/4_auto.py b/tests/migrations/test_migrations_squashed_complex/4_auto.py new file mode 100644 index 0000000000..8fab746542 --- /dev/null +++ b/tests/migrations/test_migrations_squashed_complex/4_auto.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [("migrations", "3_auto")] + + operations = [ + migrations.RunPython(lambda apps, schema_editor: None) + ] diff --git a/tests/migrations/test_migrations_squashed_complex/5_auto.py b/tests/migrations/test_migrations_squashed_complex/5_auto.py new file mode 100644 index 0000000000..5dda63aae5 --- /dev/null +++ b/tests/migrations/test_migrations_squashed_complex/5_auto.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [("migrations", "4_auto")] + + operations = [ + migrations.RunPython(lambda apps, schema_editor: None) + ] diff --git a/tests/migrations/test_migrations_squashed_complex/6_auto.py b/tests/migrations/test_migrations_squashed_complex/6_auto.py new file mode 100644 index 0000000000..5ca558bc3b --- /dev/null +++ b/tests/migrations/test_migrations_squashed_complex/6_auto.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [("migrations", "5_auto")] + + operations = [ + migrations.RunPython(lambda apps, schema_editor: None) + ] diff --git a/tests/migrations/test_migrations_squashed_complex/7_auto.py b/tests/migrations/test_migrations_squashed_complex/7_auto.py new file mode 100644 index 0000000000..e9f5533364 --- /dev/null +++ b/tests/migrations/test_migrations_squashed_complex/7_auto.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [("migrations", "6_auto")] + + operations = [ + migrations.RunPython(lambda apps, schema_editor: None) + ] diff --git a/tests/migrations/test_migrations_squashed_complex/__init__.py b/tests/migrations/test_migrations_squashed_complex/__init__.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/migrations/test_migrations_squashed_complex/__init__.py diff --git a/tests/migrations/test_migrations_squashed_erroneous/1_auto.py b/tests/migrations/test_migrations_squashed_erroneous/1_auto.py new file mode 100644 index 0000000000..25edcfa290 --- /dev/null +++ b/tests/migrations/test_migrations_squashed_erroneous/1_auto.py @@ -0,0 +1,11 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + operations = [ + migrations.RunPython(lambda apps, schema_editor: None) + ] diff --git a/tests/migrations/test_migrations_squashed_erroneous/2_auto.py b/tests/migrations/test_migrations_squashed_erroneous/2_auto.py new file mode 100644 index 0000000000..9107c35868 --- /dev/null +++ b/tests/migrations/test_migrations_squashed_erroneous/2_auto.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [("migrations", "1_auto")] + + operations = [ + migrations.RunPython(lambda apps, schema_editor: None) + ] diff --git a/tests/migrations/test_migrations_squashed_erroneous/3_squashed_5.py b/tests/migrations/test_migrations_squashed_erroneous/3_squashed_5.py new file mode 100644 index 0000000000..ac1bcdee6d --- /dev/null +++ b/tests/migrations/test_migrations_squashed_erroneous/3_squashed_5.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + replaces = [ + ("migrations", "3_auto"), + ("migrations", "4_auto"), + ("migrations", "5_auto"), + ] + + dependencies = [("migrations", "2_auto")] + + operations = [ + migrations.RunPython(lambda apps, schema_editor: None) + ] diff --git a/tests/migrations/test_migrations_squashed_erroneous/6_auto.py b/tests/migrations/test_migrations_squashed_erroneous/6_auto.py new file mode 100644 index 0000000000..5ca558bc3b --- /dev/null +++ b/tests/migrations/test_migrations_squashed_erroneous/6_auto.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [("migrations", "5_auto")] + + operations = [ + migrations.RunPython(lambda apps, schema_editor: None) + ] diff --git a/tests/migrations/test_migrations_squashed_erroneous/7_auto.py b/tests/migrations/test_migrations_squashed_erroneous/7_auto.py new file mode 100644 index 0000000000..e9f5533364 --- /dev/null +++ b/tests/migrations/test_migrations_squashed_erroneous/7_auto.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [("migrations", "6_auto")] + + operations = [ + migrations.RunPython(lambda apps, schema_editor: None) + ] diff --git a/tests/migrations/test_migrations_squashed_erroneous/__init__.py b/tests/migrations/test_migrations_squashed_erroneous/__init__.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/migrations/test_migrations_squashed_erroneous/__init__.py |
