summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorJacob Walls <jacobtylerwalls@gmail.com>2021-12-24 18:37:22 -0500
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2022-01-21 17:10:31 +0100
commit2d8232fa716f5fe46eec9f35a0e90c2d0f126279 (patch)
tree1b600a3c218b92db5077ede96ea86ca574b8a428 /tests
parenteeff1787b0aa23016e4844c0f537d5093a95a356 (diff)
Fixed #26760 -- Added --prune option to migrate command.
Diffstat (limited to 'tests')
-rw-r--r--tests/migrations/test_commands.py86
-rw-r--r--tests/migrations/test_migrations_squashed_no_replaces/0001_squashed_0002.py21
-rw-r--r--tests/migrations/test_migrations_squashed_no_replaces/__init__.py0
3 files changed, 107 insertions, 0 deletions
diff --git a/tests/migrations/test_commands.py b/tests/migrations/test_commands.py
index f274c8486b..5709372cbc 100644
--- a/tests/migrations/test_commands.py
+++ b/tests/migrations/test_commands.py
@@ -1043,6 +1043,92 @@ class MigrateTests(MigrationTestBase):
call_command('migrate', 'migrated_app', 'zero', verbosity=0)
call_command('migrate', 'migrated_unapplied_app', 'zero', verbosity=0)
+ @override_settings(MIGRATION_MODULES={
+ 'migrations': 'migrations.test_migrations_squashed_no_replaces',
+ })
+ def test_migrate_prune(self):
+ """
+ With prune=True, references to migration files deleted from the
+ migrations module (such as after being squashed) are removed from the
+ django_migrations table.
+ """
+ recorder = MigrationRecorder(connection)
+ recorder.record_applied('migrations', '0001_initial')
+ recorder.record_applied('migrations', '0002_second')
+ recorder.record_applied('migrations', '0001_squashed_0002')
+ out = io.StringIO()
+ try:
+ call_command('migrate', 'migrations', prune=True, stdout=out, no_color=True)
+ self.assertEqual(
+ out.getvalue(),
+ 'Pruning migrations:\n'
+ ' Pruning migrations.0001_initial OK\n'
+ ' Pruning migrations.0002_second OK\n',
+ )
+ applied_migrations = [
+ migration
+ for migration in recorder.applied_migrations()
+ if migration[0] == 'migrations'
+ ]
+ self.assertEqual(applied_migrations, [('migrations', '0001_squashed_0002')])
+ finally:
+ recorder.record_unapplied('migrations', '0001_initial')
+ recorder.record_unapplied('migrations', '0001_second')
+ recorder.record_unapplied('migrations', '0001_squashed_0002')
+
+ @override_settings(MIGRATION_MODULES={'migrations': 'migrations.test_migrations_squashed'})
+ def test_prune_deleted_squashed_migrations_in_replaces(self):
+ out = io.StringIO()
+ with self.temporary_migration_module(
+ module='migrations.test_migrations_squashed'
+ ) as migration_dir:
+ try:
+ call_command('migrate', 'migrations', verbosity=0)
+ # Delete the replaced migrations.
+ os.remove(os.path.join(migration_dir, '0001_initial.py'))
+ os.remove(os.path.join(migration_dir, '0002_second.py'))
+ # --prune cannot be used before removing the "replaces"
+ # attribute.
+ call_command(
+ 'migrate', 'migrations', prune=True, stdout=out, no_color=True,
+ )
+ self.assertEqual(
+ out.getvalue(),
+ "Pruning migrations:\n"
+ " Cannot use --prune because the following squashed "
+ "migrations have their 'replaces' attributes and may not "
+ "be recorded as applied:\n"
+ " migrations.0001_squashed_0002\n"
+ " Re-run 'manage.py migrate' if they are not marked as "
+ "applied, and remove 'replaces' attributes in their "
+ "Migration classes.\n"
+ )
+ finally:
+ # Unmigrate everything.
+ call_command('migrate', 'migrations', 'zero', verbosity=0)
+
+ @override_settings(
+ MIGRATION_MODULES={'migrations': 'migrations.test_migrations_squashed'}
+ )
+ def test_prune_no_migrations_to_prune(self):
+ out = io.StringIO()
+ call_command('migrate', 'migrations', prune=True, stdout=out, no_color=True)
+ self.assertEqual(
+ out.getvalue(),
+ 'Pruning migrations:\n'
+ ' No migrations to prune.\n',
+ )
+ out = io.StringIO()
+ call_command(
+ 'migrate', 'migrations', prune=True, stdout=out, no_color=True, verbosity=0,
+ )
+ self.assertEqual(out.getvalue(), '')
+
+ def test_prune_no_app_label(self):
+ msg = 'Migrations can be pruned only when an app is specified.'
+ with self.assertRaisesMessage(CommandError, msg):
+ call_command('migrate', prune=True)
+
class MakeMigrationsTests(MigrationTestBase):
"""
diff --git a/tests/migrations/test_migrations_squashed_no_replaces/0001_squashed_0002.py b/tests/migrations/test_migrations_squashed_no_replaces/0001_squashed_0002.py
new file mode 100644
index 0000000000..b261b859a1
--- /dev/null
+++ b/tests/migrations/test_migrations_squashed_no_replaces/0001_squashed_0002.py
@@ -0,0 +1,21 @@
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ operations = [
+ migrations.CreateModel(
+ "Author",
+ [
+ ("id", models.AutoField(primary_key=True)),
+ ("name", models.CharField(max_length=255)),
+ ],
+ ),
+ migrations.CreateModel(
+ "Book",
+ [
+ ("id", models.AutoField(primary_key=True)),
+ ("author", models.ForeignKey("migrations.Author", models.SET_NULL, null=True)),
+ ],
+ ),
+ ]
diff --git a/tests/migrations/test_migrations_squashed_no_replaces/__init__.py b/tests/migrations/test_migrations_squashed_no_replaces/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/migrations/test_migrations_squashed_no_replaces/__init__.py