diff options
Diffstat (limited to 'tests/migrations/test_executor.py')
| -rw-r--r-- | tests/migrations/test_executor.py | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/tests/migrations/test_executor.py b/tests/migrations/test_executor.py index 12bdabb172..32cdc5e09c 100644 --- a/tests/migrations/test_executor.py +++ b/tests/migrations/test_executor.py @@ -1,5 +1,6 @@ from django.apps.registry import apps as global_apps from django.db import connection +from django.db.migrations.exceptions import InvalidMigrationPlan from django.db.migrations.executor import MigrationExecutor from django.db.migrations.graph import MigrationGraph from django.db.migrations.recorder import MigrationRecorder @@ -145,6 +146,64 @@ class ExecutorTests(MigrationTestBase): executor.recorder.record_unapplied("migrations", "0002_second") executor.recorder.record_unapplied("migrations", "0001_initial") + @override_settings(MIGRATION_MODULES={ + "migrations": "migrations.test_migrations", + "migrations2": "migrations2.test_migrations_2_no_deps", + }) + def test_mixed_plan_not_supported(self): + """ + Although the MigrationExecutor interfaces allows for mixed migration + plans (combined forwards and backwards migrations) this is not + supported. + """ + # Prepare for mixed plan + executor = MigrationExecutor(connection) + plan = executor.migration_plan([("migrations", "0002_second")]) + self.assertEqual( + plan, + [ + (executor.loader.graph.nodes["migrations", "0001_initial"], False), + (executor.loader.graph.nodes["migrations", "0002_second"], False), + ], + ) + executor.migrate(None, plan) + # Rebuild the graph to reflect the new DB state + executor.loader.build_graph() + self.assertIn(('migrations', '0001_initial'), executor.loader.applied_migrations) + self.assertIn(('migrations', '0002_second'), executor.loader.applied_migrations) + self.assertNotIn(('migrations2', '0001_initial'), executor.loader.applied_migrations) + + # Generate mixed plan + plan = executor.migration_plan([ + ("migrations", None), + ("migrations2", "0001_initial"), + ]) + msg = ( + 'Migration plans with both forwards and backwards migrations are ' + 'not supported. Please split your migration process into separate ' + 'plans of only forwards OR backwards migrations.' + ) + with self.assertRaisesMessage(InvalidMigrationPlan, msg) as cm: + executor.migrate(None, plan) + self.assertEqual( + cm.exception.args[1], + [ + (executor.loader.graph.nodes["migrations", "0002_second"], True), + (executor.loader.graph.nodes["migrations", "0001_initial"], True), + (executor.loader.graph.nodes["migrations2", "0001_initial"], False), + ], + ) + # Rebuild the graph to reflect the new DB state + executor.loader.build_graph() + executor.migrate([ + ("migrations", None), + ("migrations2", None), + ]) + # Are the tables gone? + self.assertTableNotExists("migrations_author") + self.assertTableNotExists("migrations_book") + self.assertTableNotExists("migrations2_otherauthor") + @override_settings(MIGRATION_MODULES={"migrations": "migrations.test_migrations"}) def test_soft_apply(self): """ |
