From 16f032e69fb9c06fd0d9feda35bba12195651214 Mon Sep 17 00:00:00 2001 From: Jim Nicholls Date: Sat, 13 Aug 2016 19:33:58 +1000 Subject: [1.10.x] Fixed #27054 -- Fixed makemigrations crash with a read-only database. Backport of 76ab8851181675a59425f9637bdbf3f2de95f6f1 from master --- tests/migrations/test_commands.py | 25 ++++++++++++++++++++++++- tests/migrations/test_loader.py | 14 ++++++++++++-- 2 files changed, 36 insertions(+), 3 deletions(-) (limited to 'tests') diff --git a/tests/migrations/test_commands.py b/tests/migrations/test_commands.py index 09abd21103..dca1a46780 100644 --- a/tests/migrations/test_commands.py +++ b/tests/migrations/test_commands.py @@ -12,7 +12,9 @@ from django.core.management import CommandError, call_command from django.db import ( ConnectionHandler, DatabaseError, connection, connections, models, ) -from django.db.migrations.exceptions import InconsistentMigrationHistory +from django.db.migrations.exceptions import ( + InconsistentMigrationHistory, MigrationSchemaMissing, +) from django.db.migrations.recorder import MigrationRecorder from django.test import ignore_warnings, mock, override_settings from django.utils import six @@ -595,6 +597,27 @@ class MakeMigrationsTests(MigrationTestBase): init_file = os.path.join(migration_dir, '__init__.py') self.assertTrue(os.path.exists(init_file)) + def test_makemigrations_other_datbase_is_readonly(self): + """ + makemigrations ignores the non-default database if it's read-only. + """ + def patched_ensure_schema(migration_recorder): + from django.db import connections + if migration_recorder.connection is connections['other']: + raise MigrationSchemaMissing() + else: + return mock.DEFAULT + + self.assertTableNotExists('migrations_unicodemodel') + apps.register_model('migrations', UnicodeModel) + with mock.patch.object( + MigrationRecorder, 'ensure_schema', + autospec=True, side_effect=patched_ensure_schema): + with self.temporary_migration_module() as migration_dir: + call_command("makemigrations", "migrations", verbosity=0) + initial_file = os.path.join(migration_dir, "0001_initial.py") + self.assertTrue(os.path.exists(initial_file)) + def test_failing_migration(self): # If a migration fails to serialize, it shouldn't generate an empty file. #21280 apps.register_model('migrations', UnserializableModel) diff --git a/tests/migrations/test_loader.py b/tests/migrations/test_loader.py index c97cddb913..b46f35f7ed 100644 --- a/tests/migrations/test_loader.py +++ b/tests/migrations/test_loader.py @@ -4,11 +4,12 @@ from unittest import skipIf from django.db import connection, connections from django.db.migrations.exceptions import ( - AmbiguityError, InconsistentMigrationHistory, NodeNotFoundError, + AmbiguityError, InconsistentMigrationHistory, MigrationSchemaMissing, + NodeNotFoundError, ) from django.db.migrations.loader import MigrationLoader from django.db.migrations.recorder import MigrationRecorder -from django.test import TestCase, modify_settings, override_settings +from django.test import TestCase, mock, modify_settings, override_settings from django.utils import six @@ -464,3 +465,12 @@ class LoaderTests(TestCase): ('app1', '4_auto'), } self.assertEqual(plan, expected_plan) + + def test_readonly_database(self): + """ + check_consistent_history() ignores read-only databases, possibly + without a django_migrations table. + """ + with mock.patch.object(MigrationRecorder, 'ensure_schema', side_effect=MigrationSchemaMissing()): + loader = MigrationLoader(connection=None) + loader.check_consistent_history(connection) -- cgit v1.3