From 19c2491f5c9f981207657d3cac23c48be58d418d Mon Sep 17 00:00:00 2001 From: Bryan Mutai Date: Mon, 22 Jun 2020 14:28:16 +0300 Subject: [PATCH] Refs #1696. Add middleware to warn for unapplied migrations --- .github/workflows/testing.yml | 32 ++++++++++++++++++++ tcms/bugs/migrations/0002_add_permissions.py | 9 ++++++ tcms/core/middleware.py | 22 ++++++++++++++ tcms/core/tests/test_middleware.py | 18 +++++++++++ tcms/settings/common.py | 1 + tcms/settings/test/migrations_tests.py | 9 ++++++ 6 files changed, 91 insertions(+) create mode 100644 tcms/core/tests/test_middleware.py create mode 100644 tcms/settings/test/migrations_tests.py diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml index e8a9942c8d..8fa5d73a17 100644 --- a/.github/workflows/testing.yml +++ b/.github/workflows/testing.yml @@ -35,6 +35,38 @@ jobs: coverage report -m bash <(curl -s https://codecov.io/bash) + test_check_unapplied_migrations_middleware: + name: middleware for unapplied migrations + runs-on: ubuntu-latest + strategy: + matrix: + python-version: [3.7] + + steps: + - uses: actions/checkout@v2 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v1 + with: + python-version: ${{ matrix.python-version }} + + - name: Install Python dependencies + run: | + sudo apt-get install libkrb5-dev gettext + pip install -r requirements/devel.txt + pushd tcms/ && npm install && popd + + - name: Run test + run: | + export LANG=en-us + export TEST_CHECK_UNAPPLIED_MIGRATIONS_MIDDLEWARE=1 + coverage run --source='.' ./manage.py test -v2 --noinput --settings=tcms.settings.test tcms.core.tests.test_middleware.TestCheckUnappliedMigrationsMiddleware + + - name: Send coverage to codecov.io + run: | + coverage report -m + bash <(curl -s https://codecov.io/bash) + without_internal_bugtracker: name: without internal bugtracker runs-on: ubuntu-latest diff --git a/tcms/bugs/migrations/0002_add_permissions.py b/tcms/bugs/migrations/0002_add_permissions.py index 049ddf611c..b9ab0aee7f 100644 --- a/tcms/bugs/migrations/0002_add_permissions.py +++ b/tcms/bugs/migrations/0002_add_permissions.py @@ -15,6 +15,14 @@ def forwards_add_perms(apps, schema_editor): tester.permissions.add(*app_perms) +def backwards(apps, schema_editor): + Group = apps.get_model('auth', 'Group') + Permission = apps.get_model('auth', 'Permission') + tester = Group.objects.get(name='Tester') + app_perms = Permission.objects.filter(content_type__app_label__contains='bugs') + tester.permissions.remove(*app_perms) + + class Migration(migrations.Migration): dependencies = [ ('bugs', '0001_initial'), @@ -23,4 +31,5 @@ class Migration(migrations.Migration): operations = [ migrations.RunPython(forwards_add_perms), + migrations.RunPython(forwards_add_perms, backwards), ] diff --git a/tcms/core/middleware.py b/tcms/core/middleware.py index 2464b96d91..4dc2bd84fc 100644 --- a/tcms/core/middleware.py +++ b/tcms/core/middleware.py @@ -7,6 +7,8 @@ from django.utils.deprecation import MiddlewareMixin from django.utils.safestring import mark_safe from django.utils.translation import gettext_lazy as _ +from django.db import DEFAULT_DB_ALIAS, connections +from django.db.migrations.executor import MigrationExecutor class CsrfDisableMiddleware(MiddlewareMixin): @@ -32,3 +34,23 @@ def process_request(self, request): } ) ) + + +class CheckUnappliedMigrationsMiddleware(MiddlewareMixin): + def process_request(self, request): + doc_url = """https://kiwitcms.readthedocs.io/en/latest/ +installing_docker.html#initial-configuration-of-running-container""" + executor = MigrationExecutor(connections[DEFAULT_DB_ALIAS]) + plan = executor.migration_plan(executor.loader.graph.leaf_nodes()) + if plan: + messages.add_message( + request, + messages.ERROR, + mark_safe( + _('You have %(unapplied_migration_count)s unapplied migration(s). ' + 'See documentation') % { + "unapplied_migration_count": len(plan), + "doc_url": doc_url, + } + ) + ) diff --git a/tcms/core/tests/test_middleware.py b/tcms/core/tests/test_middleware.py new file mode 100644 index 0000000000..5eb3df1358 --- /dev/null +++ b/tcms/core/tests/test_middleware.py @@ -0,0 +1,18 @@ +import os +import unittest +from django import test +from django.core.management import call_command + + +@unittest.skipUnless( + os.getenv('TEST_CHECK_UNAPPLIED_MIGRATIONS_MIDDLEWARE'), + 'CheckUnappliedMigrationsMiddleware testing not enabled') +class TestCheckUnappliedMigrationsMiddleware(test.TransactionTestCase): + def test_unapplied_migrations(self): + call_command('migrate', 'bugs', 'zero', verbosity=2, interactive=False) + unapplied_migration_message = 'unapplied migrations(s). See '\ + 'documentation' + response = self.client.get('/', follow=True) + self.assertContains(response, unapplied_migration_message) diff --git a/tcms/settings/common.py b/tcms/settings/common.py index c9933ccc45..30b7179c2c 100644 --- a/tcms/settings/common.py +++ b/tcms/settings/common.py @@ -130,6 +130,7 @@ 'global_login_required.GlobalLoginRequiredMiddleware', 'simple_history.middleware.HistoryRequestMiddleware', 'tcms.core.middleware.CheckSettingsMiddleware', + 'tcms.core.middleware.CheckUnappliedMigrationsMiddleware', ] diff --git a/tcms/settings/test/migrations_tests.py b/tcms/settings/test/migrations_tests.py new file mode 100644 index 0000000000..2627fb22ec --- /dev/null +++ b/tcms/settings/test/migrations_tests.py @@ -0,0 +1,9 @@ +from tcms.settings.test import * # noqa: F401,F403 + +INSTALLED_APPS = [ + 'django.contrib.sites', + 'django.contrib.auth', + 'django.contrib.sessions', + 'django.contrib.contenttypes', + 'attachments', +]