def test_exclude_migration_tests(self): m = Migration("0002_add_new_not_null_field", "app_add_not_null_column") linter = MigrationLinter(exclude_migration_tests=[], database="mysql") linter.lint_migration(m) self.assertTrue(linter.has_errors) linter = MigrationLinter(exclude_migration_tests=["NOT_NULL"], database="mysql") linter.lint_migration(m) self.assertFalse(linter.has_errors)
def test_multiple_linters(self): l1 = MigrationLinter(fixtures.ADD_NOT_NULL_COLUMN_PROJECT) l2 = MigrationLinter(fixtures.RENAME_COLUMN_PROJECT) l3 = MigrationLinter(fixtures.CORRECT_PROJECT) l1.lint_migration( Migration( os.path.join( fixtures.ADD_NOT_NULL_COLUMN_PROJECT, 'test_app/migrations/0002_add_new_not_null_field.py'))) l2.lint_migration( Migration( os.path.join(fixtures.RENAME_COLUMN_PROJECT, 'test_app/migrations/0002_rename_column.py'))) l3.lint_migration( Migration( os.path.join(fixtures.CORRECT_PROJECT, 'test_app1/migrations/0001_initial.py'))) l3.lint_migration( Migration( os.path.join(fixtures.CORRECT_PROJECT, 'test_app1/migrations/0002_a_new_null_field.py'))) self.assertTrue(l1.has_errors) self.assertTrue(l2.has_errors) self.assertFalse(l3.has_errors) self.assertEqual(l1.nb_total, 1) self.assertEqual(l2.nb_total, 1) self.assertEqual(l3.nb_total, 2)
class DataMigrationDetectionTestCase(unittest.TestCase): def setUp(self, *args, **kwargs): self.test_project_path = os.path.dirname(settings.BASE_DIR) self.linter = MigrationLinter( self.test_project_path, include_apps=fixtures.DATA_MIGRATIONS, ) def test_reverse_data_migration(self): self.assertEqual(0, self.linter.nb_warnings) reverse_migration = self.linter.migration_loader.disk_migrations[( "app_data_migrations", "0002_missing_reverse")] self.linter.lint_migration(reverse_migration) self.assertEqual(1, self.linter.nb_warnings) self.assertFalse(self.linter.has_errors) def test_reverse_data_migration_ignore(self): reverse_migration = self.linter.migration_loader.disk_migrations[( "app_data_migrations", "0003_incorrect_arguments")] self.linter.lint_migration(reverse_migration) self.assertEqual(1, self.linter.nb_warnings) self.assertFalse(self.linter.has_errors) def test_exclude_warning_from_test(self): self.linter = MigrationLinter( self.test_project_path, include_apps=fixtures.DATA_MIGRATIONS, exclude_migration_tests=("RUNPYTHON_REVERSIBLE", ), ) reverse_migration = self.linter.migration_loader.disk_migrations[( "app_data_migrations", "0002_missing_reverse")] self.linter.lint_migration(reverse_migration) self.assertEqual(0, self.linter.nb_warnings) self.assertEqual(1, self.linter.nb_valid) self.assertFalse(self.linter.has_errors) def test_warnings_as_errors(self): self.linter = MigrationLinter( self.test_project_path, include_apps=fixtures.DATA_MIGRATIONS, warnings_as_errors=True, ) reverse_migration = self.linter.migration_loader.disk_migrations[( "app_data_migrations", "0003_incorrect_arguments")] self.linter.lint_migration(reverse_migration) self.assertEqual(0, self.linter.nb_warnings) self.assertEqual(1, self.linter.nb_erroneous) self.assertTrue(self.linter.has_errors)
def write_migration_files(self, changes): super(Command, self).write_migration_files(changes) if ( not getattr(settings, "MIGRATION_LINTER_OVERRIDE_MAKEMIGRATIONS", False) and not self.lint ): return if self.dry_run: """ Since we rely on the 'sqlmigrate' to lint the migrations, we can only lint if the migration files have been generated. Since the 'dry-run' option won't generate the files, we cannot lint migrations. """ return should_keep_migration = ( ask_should_keep_migration if self.interactive else default_should_keep_migration ) # Lint migrations linter = MigrationLinter( path=os.environ["DJANGO_SETTINGS_MODULE"], database=self.database, no_cache=True, exclude_migration_tests=self.exclude_migrations_tests, warnings_as_errors=self.warnings_as_errors, ) for app_label, app_migrations in changes.items(): if self.verbosity >= 1: self.stdout.write( self.style.MIGRATE_HEADING("Linting for '%s':" % app_label) + "\n" ) for migration in app_migrations: linter.lint_migration(migration) if linter.has_errors: if not should_keep_migration(): self.delete_migration(migration) linter.reset_counters()
def test_has_errors(self): project_path = fixtures.MULTI_COMMIT_PROJECT linter = MigrationLinter(project_path) self.assertFalse(linter.has_errors) linter.lint_migration('test_app', '0001') self.assertFalse(linter.has_errors) linter.lint_migration('test_app', '0002') self.assertTrue(linter.has_errors) linter.lint_migration('test_app', '0001') self.assertTrue(linter.has_errors)
def test_has_errors(self): linter = MigrationLinter() self.assertFalse(linter.has_errors) m = Migration("0001_create_table", "app_add_not_null_column") linter.lint_migration(m) self.assertFalse(linter.has_errors) m = Migration("0002_add_new_not_null_field", "app_add_not_null_column") linter.lint_migration(m) self.assertTrue(linter.has_errors) m = Migration("0001_create_table", "app_add_not_null_column") linter.lint_migration(m) self.assertTrue(linter.has_errors)
def test_has_errors(self): project_path = fixtures.MULTI_COMMIT_PROJECT linter = MigrationLinter(project_path) self.assertFalse(linter.has_errors) m = Migration(os.path.join(project_path, 'test_app/migrations/0001_create_table.py')) linter.lint_migration(m) self.assertFalse(linter.has_errors) m = Migration(os.path.join(project_path, 'test_app/migrations/0002_add_new_not_null_field.py')) linter.lint_migration(m) self.assertTrue(linter.has_errors) m = Migration(os.path.join(project_path, 'test_app/migrations/0001_create_table.py')) linter.lint_migration(m) self.assertTrue(linter.has_errors)
def test_multiple_linters(self): l1 = MigrationLinter(fixtures.ADD_NOT_NULL_COLUMN_PROJECT) l2 = MigrationLinter(fixtures.RENAME_COLUMN_PROJECT) l3 = MigrationLinter(fixtures.CORRECT_PROJECT) l1.lint_migration('test_app', '0002') l2.lint_migration('test_app', '0002') l3.lint_migration('test_app1', '0001') l3.lint_migration('test_app1', '0002') self.assertTrue(l1.has_errors) self.assertTrue(l2.has_errors) self.assertFalse(l3.has_errors) self.assertEqual(l1.nb_total, 1) self.assertEqual(l2.nb_total, 1) self.assertEqual(l3.nb_total, 2)
class DataMigrationDetectionTestCase(unittest.TestCase): def setUp(self, *args, **kwargs): self.test_project_path = os.path.dirname(settings.BASE_DIR) self.linter = MigrationLinter( self.test_project_path, include_apps=fixtures.DATA_MIGRATIONS, ) def test_reverse_data_migration(self): self.assertEqual(0, self.linter.nb_warnings) reverse_migration = self.linter.migration_loader.disk_migrations[ ("app_data_migrations", "0002_missing_reverse") ] self.linter.lint_migration(reverse_migration) self.assertEqual(1, self.linter.nb_warnings) self.assertFalse(self.linter.has_errors) def test_reverse_data_migration_ignore(self): reverse_migration = self.linter.migration_loader.disk_migrations[ ("app_data_migrations", "0003_incorrect_arguments") ] self.linter.lint_migration(reverse_migration) self.assertEqual(1, self.linter.nb_warnings) self.assertFalse(self.linter.has_errors) def test_exclude_warning_from_test(self): self.linter = MigrationLinter( self.test_project_path, include_apps=fixtures.DATA_MIGRATIONS, exclude_migration_tests=("REVERSIBLE_DATA_MIGRATION",), ) reverse_migration = self.linter.migration_loader.disk_migrations[ ("app_data_migrations", "0002_missing_reverse") ] self.linter.lint_migration(reverse_migration) self.assertEqual(0, self.linter.nb_warnings) self.assertEqual(1, self.linter.nb_valid) self.assertFalse(self.linter.has_errors) def test_warnings_as_errors(self): self.linter = MigrationLinter( self.test_project_path, include_apps=fixtures.DATA_MIGRATIONS, warnings_as_errors=True, ) reverse_migration = self.linter.migration_loader.disk_migrations[ ("app_data_migrations", "0003_incorrect_arguments") ] self.linter.lint_migration(reverse_migration) self.assertEqual(0, self.linter.nb_warnings) self.assertEqual(1, self.linter.nb_erroneous) self.assertTrue(self.linter.has_errors) def test_missing_get_model_import(self): def incorrect_importing_model_forward(apps, schema_editor): from tests.test_project.app_data_migrations.models import MyModel MyModel.objects.filter(id=1).first() issues = MigrationLinter.get_data_migration_model_import_issues( incorrect_importing_model_forward ) self.assertEqual(1, len(issues)) def test_correct_get_model_import(self): def correct_importing_model_forward(apps, schema_editor): MyModel = apps.get_model("app_data_migrations", "MyModel") MyVeryLongLongLongModel = apps.get_model( "app_data_migrations", "MyVeryLongLongLongModel" ) MyModel.objects.filter(id=1).first() MyVeryLongLongLongModel.objects.filter(id=1).first() issues = MigrationLinter.get_data_migration_model_import_issues( correct_importing_model_forward ) self.assertEqual(0, len(issues))