Skip to content
Snippets Groups Projects
Commit b5c27f1c authored by Julian's avatar Julian
Browse files

Cleanup CI tests

Turns check_migrations.py into a normal test case. Speeds up pipeline by
making html5validator use the artifacts from tests:buster:sqlite instead of
running the tests on its own.
parent 91ba4a6f
No related branches found
No related tags found
No related merge requests found
...@@ -47,19 +47,6 @@ db_migrations_updated: ...@@ -47,19 +47,6 @@ db_migrations_updated:
- FLASK_APP=uffd FLASK_ENV=testing flask db upgrade - FLASK_APP=uffd FLASK_ENV=testing flask db upgrade
- FLASK_APP=uffd FLASK_ENV=testing flask db migrate 2>&1 | grep -q 'No changes in schema detected' - FLASK_APP=uffd FLASK_ENV=testing flask db migrate 2>&1 | grep -q 'No changes in schema detected'
test_db_migrations:sqlite:
stage: test
needs: []
script:
- python3 check_migrations.py sqlite
test_db_migrations:mysql:
stage: test
needs: []
script:
- service mysql start
- python3 check_migrations.py mysql
linter:buster: linter:buster:
image: registry.git.cccv.de/uffd/docker-images/buster image: registry.git.cccv.de/uffd/docker-images/buster
stage: test stage: test
...@@ -88,12 +75,16 @@ linter:bullseye: ...@@ -88,12 +75,16 @@ linter:bullseye:
reports: reports:
codequality: codeclimate.json codequality: codeclimate.json
unittests:buster:sqlite: tests:buster:sqlite:
image: registry.git.cccv.de/uffd/docker-images/buster image: registry.git.cccv.de/uffd/docker-images/buster
stage: test stage: test
needs: [] needs: []
script: script:
- python3-coverage run --include 'uffd/*.py' -m pytest --junitxml=report.xml || touch failed - rm -rf pages
- mkdir -p pages
- cp -r uffd/static pages/static
- DUMP_PAGES=pages python3-coverage run --include 'uffd/*.py' -m pytest --junitxml=report.xml || touch failed
- sed -i -e 's/href="\/static\//href=".\/static\//g' -e 's/src="\/static\//src=".\/static\//g' pages/*.html || true
- python3-coverage report -m - python3-coverage report -m
- python3-coverage html - python3-coverage html
- python3-coverage xml - python3-coverage xml
...@@ -103,6 +94,7 @@ unittests:buster:sqlite: ...@@ -103,6 +94,7 @@ unittests:buster:sqlite:
paths: paths:
- htmlcov/index.html - htmlcov/index.html
- htmlcov - htmlcov
- pages
expose_as: 'Coverage Report' expose_as: 'Coverage Report'
reports: reports:
coverage_report: coverage_report:
...@@ -111,7 +103,7 @@ unittests:buster:sqlite: ...@@ -111,7 +103,7 @@ unittests:buster:sqlite:
junit: report.xml junit: report.xml
coverage: '/^TOTAL.*\s+(\d+\%)$/' coverage: '/^TOTAL.*\s+(\d+\%)$/'
unittests:buster:mysql: tests:buster:mysql:
image: registry.git.cccv.de/uffd/docker-images/buster image: registry.git.cccv.de/uffd/docker-images/buster
stage: test stage: test
needs: [] needs: []
...@@ -123,7 +115,7 @@ unittests:buster:mysql: ...@@ -123,7 +115,7 @@ unittests:buster:mysql:
reports: reports:
junit: report.xml junit: report.xml
unittests:bullseye:sqlite: tests:bullseye:sqlite:
image: registry.git.cccv.de/uffd/docker-images/bullseye image: registry.git.cccv.de/uffd/docker-images/bullseye
stage: test stage: test
needs: [] needs: []
...@@ -134,7 +126,7 @@ unittests:bullseye:sqlite: ...@@ -134,7 +126,7 @@ unittests:bullseye:sqlite:
reports: reports:
junit: report.xml junit: report.xml
unittests:bullseye:mysql: tests:bullseye:mysql:
image: registry.git.cccv.de/uffd/docker-images/bullseye image: registry.git.cccv.de/uffd/docker-images/bullseye
stage: test stage: test
needs: [] needs: []
...@@ -148,13 +140,9 @@ unittests:bullseye:mysql: ...@@ -148,13 +140,9 @@ unittests:bullseye:mysql:
html5validator: html5validator:
stage: test stage: test
needs: [] needs:
- job: tests:buster:sqlite
script: script:
- rm -rf pages
- mkdir -p pages
- cp -r uffd/static pages/static
- DUMP_PAGES=pages python3 -m unittest discover tests/views
- sed -i -e 's/href="\/static\//href=".\/static\//g' -e 's/src="\/static\//src=".\/static\//g' pages/*.html
- html5validator --root pages 2>&1 | tee html5validator.log - html5validator --root pages 2>&1 | tee html5validator.log
artifacts: artifacts:
when: on_failure when: on_failure
...@@ -176,18 +164,18 @@ trans_de: ...@@ -176,18 +164,18 @@ trans_de:
test:package:pip:buster: test:package:pip:buster:
image: registry.git.cccv.de/uffd/docker-images/buster image: registry.git.cccv.de/uffd/docker-images/buster
stage: test stage: test
needs:
- job: build:pip
script: script:
- pip3 install dist/*.tar.gz - pip3 install dist/*.tar.gz
dependencies:
- build:pip
test:package:pip:bullseye: test:package:pip:bullseye:
image: registry.git.cccv.de/uffd/docker-images/bullseye image: registry.git.cccv.de/uffd/docker-images/bullseye
stage: test stage: test
needs:
- job: build:pip
script: script:
- pip3 install dist/*.tar.gz - pip3 install dist/*.tar.gz
dependencies:
- build:pip
# Since we want to test if the package installs correctly on a fresh Debian # Since we want to test if the package installs correctly on a fresh Debian
# install (has correct dependencies, etc.), we don't use uffd/docker-images # install (has correct dependencies, etc.), we don't use uffd/docker-images
...@@ -195,6 +183,8 @@ test:package:pip:bullseye: ...@@ -195,6 +183,8 @@ test:package:pip:bullseye:
test:package:apt:buster: test:package:apt:buster:
image: ${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX}/debian:buster image: ${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX}/debian:buster
stage: test stage: test
needs:
- job: build:apt
before_script: [] before_script: []
script: script:
- apt -y update - apt -y update
...@@ -204,12 +194,12 @@ test:package:apt:buster: ...@@ -204,12 +194,12 @@ test:package:apt:buster:
- service nginx start || ( service nginx status; nginx -t; exit 1; ) - service nginx start || ( service nginx status; nginx -t; exit 1; )
- uffd-admin routes - uffd-admin routes
- curl -Lv 127.0.0.1:5000 - curl -Lv 127.0.0.1:5000
dependencies:
- build:apt
test:package:apt:bullseye: test:package:apt:bullseye:
image: ${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX}/debian:bullseye image: ${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX}/debian:bullseye
stage: test stage: test
needs:
- job: build:apt
before_script: [] before_script: []
script: script:
- apt -y update - apt -y update
...@@ -219,8 +209,6 @@ test:package:apt:bullseye: ...@@ -219,8 +209,6 @@ test:package:apt:bullseye:
- service nginx start || ( service nginx status; nginx -t; exit 1; ) - service nginx start || ( service nginx status; nginx -t; exit 1; )
- uffd-admin routes - uffd-admin routes
- curl -Lv 127.0.0.1:5000 - curl -Lv 127.0.0.1:5000
dependencies:
- build:apt
.publish: .publish:
stage: deploy stage: deploy
......
#!/usr/bin/python3
import os import os
import sys import sys
import logging
import datetime import datetime
import flask_migrate from uffd.database import db
from uffd import create_app, db
from uffd.models import ( from uffd.models import (
User, UserEmail, Group, User, UserEmail, Group,
RecoveryCodeMethod, TOTPMethod, WebauthnMethod, RecoveryCodeMethod, TOTPMethod, WebauthnMethod,
...@@ -19,37 +15,32 @@ from uffd.models import ( ...@@ -19,37 +15,32 @@ from uffd.models import (
PasswordToken, PasswordToken,
) )
def run_test(dburi, revision): from tests.utils import MigrationTestCase
config = {
'TESTING': True, class TestFuzzy(MigrationTestCase):
'DEBUG': True, def setUpApp(self):
'SQLALCHEMY_DATABASE_URI': dburi, self.app.config['LDAP_SERVICE_MOCK'] = True
'SECRET_KEY': 'DEBUGKEY', self.app.config['OAUTH2_CLIENTS'] = {
'MAIL_SKIP_SEND': True,
'SELF_SIGNUP': True,
'ENABLE_INVITE': True,
'ENABLE_PASSWORDRESET': True,
'LDAP_SERVICE_MOCK': True,
'OAUTH2_CLIENTS': {
'test': { 'test': {
'service_name': 'test', 'service_name': 'test',
'client_secret': 'testsecret', 'client_secret': 'testsecret',
'redirect_uris': ['http://localhost:5004/oauthproxy/callback'], 'redirect_uris': ['http://localhost:5004/oauthproxy/callback'],
'logout_urls': ['http://localhost:5004/oauthproxy/logout'] 'logout_urls': ['http://localhost:5004/oauthproxy/logout']
} }
}, }
'API_CLIENTS_2': { self.app.config['API_CLIENTS_2'] = {
'test': { 'test': {
'service_name': 'test', 'service_name': 'test',
'client_secret': 'testsecret', 'client_secret': 'testsecret',
'scopes': ['checkpassword', 'getusers', 'getmails'] 'scopes': ['checkpassword', 'getusers', 'getmails']
}, },
},
} }
app = create_app(config)
with app.test_request_context(): # Runs every upgrade/downgrade script with data. To do this we first upgrade
flask_migrate.upgrade(revision='head') # to head, create data, then downgrade, upgrade, downgrade for every revision.
# Add a few rows to all tables to make sure that the migrations work with data def test_migrations_fuzzy(self):
self.upgrade('head')
# Users and groups were created by 878b25c4fae7_ldap_to_db because we set LDAP_SERVICE_MOCK to True
user = User.query.first() user = User.query.first()
group = Group.query.first() group = Group.query.first()
db.session.add(RecoveryCodeMethod(user=user)) db.session.add(RecoveryCodeMethod(user=user))
...@@ -74,44 +65,8 @@ def run_test(dburi, revision): ...@@ -74,44 +65,8 @@ def run_test(dburi, revision):
db.session.add(OAuth2DeviceLoginInitiation(client=oauth2_client, confirmations=[DeviceLoginConfirmation(user=user)])) db.session.add(OAuth2DeviceLoginInitiation(client=oauth2_client, confirmations=[DeviceLoginConfirmation(user=user)]))
db.session.add(PasswordToken(user=user)) db.session.add(PasswordToken(user=user))
db.session.commit() db.session.commit()
flask_migrate.downgrade(revision=revision) revs = [s.split('_', 1)[0] for s in os.listdir('uffd/migrations/versions') if '_' in s and s.endswith('.py')]
flask_migrate.upgrade(revision='head')
if __name__ == '__main__':
if len(sys.argv) != 2 or sys.argv[1] not in ['sqlite', 'mysql']:
print('usage: check_migrations.py {sqlite|mysql}')
exit(1)
dbtype = sys.argv[1]
revs = [s.split('_', 1)[0] for s in os.listdir('uffd/migrations/versions') if '_' in s and s.endswith('.py')] + ['base']
logging.getLogger().setLevel(logging.INFO)
failures = 0
for rev in revs: for rev in revs:
logging.info(f'Testing "upgrade to head, add objects, downgrade to {rev}, upgrade to head"') self.downgrade('-1')
# Cleanup/drop database self.upgrade('+1')
if dbtype == 'sqlite': self.downgrade('-1')
try:
os.remove('/tmp/uffd_check_migrations_db.sqlite3')
except FileNotFoundError:
pass
dburi = 'sqlite:////tmp/uffd_check_migrations_db.sqlite3'
elif dbtype == 'mysql':
import MySQLdb
conn = MySQLdb.connect(user='root', unix_socket='/var/run/mysqld/mysqld.sock')
cur = conn.cursor()
try:
cur.execute('DROP DATABASE uffd_tests')
except:
pass
cur.execute('CREATE DATABASE uffd_tests CHARACTER SET utf8mb4 COLLATE utf8mb4_nopad_bin')
conn.close()
dburi = 'mysql+mysqldb:///uffd_tests?unix_socket=/var/run/mysqld/mysqld.sock&charset=utf8mb4'
try:
run_test(dburi, rev)
except Exception as ex:
failures += 1
logging.error('Test failed', exc_info=ex)
if failures:
logging.info(f'{failures} tests failed')
exit(1)
logging.info('All tests succeeded')
exit(0)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment