From 464ff2fe96868b7a17f4c27c7cb0fa8d89acf068 Mon Sep 17 00:00:00 2001 From: Dan Helfman Date: Wed, 11 Dec 2019 16:43:01 -0800 Subject: [PATCH] Run end-to-end tests on developer machines with Docker Compose for approximate parity with continuous integration tests. --- .drone.yml | 35 ++++++++++++++++++++++++---- NEWS | 5 ++-- docs/how-to/develop-on-borgmatic.md | 16 +++++++++---- scripts/run-full-dev-tests | 13 +++++++++++ scripts/run-full-tests | 19 +++++++++++++++ scripts/run-tests | 13 ----------- tests/end-to-end/docker-compose.yaml | 23 ++++++++++++++++++ tests/end-to-end/test_database.py | 5 ++++ tox.ini | 2 +- 9 files changed, 106 insertions(+), 25 deletions(-) create mode 100755 scripts/run-full-dev-tests create mode 100755 scripts/run-full-tests delete mode 100755 scripts/run-tests create mode 100644 tests/end-to-end/docker-compose.yaml diff --git a/.drone.yml b/.drone.yml index 57ba82cf..89987e3e 100644 --- a/.drone.yml +++ b/.drone.yml @@ -8,13 +8,18 @@ services: environment: POSTGRES_PASSWORD: test POSTGRES_DB: test + - name: mysql + image: mariadb:10.3 + environment: + MYSQL_ROOT_PASSWORD: test + MYSQL_DATABASE: test steps: - name: build image: python:3.5-alpine3.10 pull: always commands: - - scripts/run-tests + - scripts/run-full-tests --- kind: pipeline name: python-3-6-alpine-3-10 @@ -25,13 +30,18 @@ services: environment: POSTGRES_PASSWORD: test POSTGRES_DB: test + - name: mysql + image: mariadb:10.3 + environment: + MYSQL_ROOT_PASSWORD: test + MYSQL_DATABASE: test steps: - name: build image: python:3.6-alpine3.10 pull: always commands: - - scripts/run-tests + - scripts/run-full-tests --- kind: pipeline name: python-3-7-alpine-3-10 @@ -42,13 +52,18 @@ services: environment: POSTGRES_PASSWORD: test POSTGRES_DB: test + - name: mysql + image: mariadb:10.3 + environment: + MYSQL_ROOT_PASSWORD: test + MYSQL_DATABASE: test steps: - name: build image: python:3.7-alpine3.10 pull: always commands: - - scripts/run-tests + - scripts/run-full-tests --- kind: pipeline name: python-3-7-alpine-3-7 @@ -59,13 +74,18 @@ services: environment: POSTGRES_PASSWORD: test POSTGRES_DB: test + - name: mysql + image: mariadb:10.1 + environment: + MYSQL_ROOT_PASSWORD: test + MYSQL_DATABASE: test steps: - name: build image: python:3.7-alpine3.7 pull: always commands: - - scripts/run-tests + - scripts/run-full-tests --- kind: pipeline name: python-3-8-alpine-3-10 @@ -76,13 +96,18 @@ services: environment: POSTGRES_PASSWORD: test POSTGRES_DB: test + - name: mysql + image: mariadb:10.3 + environment: + MYSQL_ROOT_PASSWORD: test + MYSQL_DATABASE: test steps: - name: build image: python:3.8-alpine3.10 pull: always commands: - - scripts/run-tests + - scripts/run-full-tests --- kind: pipeline name: documentation diff --git a/NEWS b/NEWS index fc24cd3d..a0eac709 100644 --- a/NEWS +++ b/NEWS @@ -3,8 +3,9 @@ in location configuration section. * #271: Support piping "borgmatic list" output to grep by logging certain log levels to console stdout and others to stderr. - * Retain colored output when piping or redirecting output in an interactive terminal. - * Add end-to-end tests for database dump and restore. + * Retain colored output when piping or redirecting in an interactive terminal. + * Add end-to-end tests for database dump and restore. These are run on developer machines with + Docker Compose for approximate parity with continuous integration tests. 1.4.18 * Fix "--repository" flag to accept relative paths. diff --git a/docs/how-to/develop-on-borgmatic.md b/docs/how-to/develop-on-borgmatic.md index 5a52352e..9e9fee72 100644 --- a/docs/how-to/develop-on-borgmatic.md +++ b/docs/how-to/develop-on-borgmatic.md @@ -75,14 +75,22 @@ tox -e isort ### End-to-end tests borgmatic additionally includes some end-to-end tests that integration test -with Borg for a few representative scenarios. These tests don't run by default -because they're relatively slow and depend on Borg. If you would like to run -them: +with Borg and supported databases for a few representative scenarios. These +tests don't run by default when running `tox`, because they're relatively slow +and depend on Docker containers for runtime dependencies. These tests tests do +run on the continuous integration (CI) server, and running them on your +developer machine is the closest thing to CI test parity. + +If you would like to run the full test suite, first install Docker and [Docker +Compose](https://docs.docker.com/compose/install/). Then run: ```bash -tox -e end-to-end +scripts/run-full-dev-tests ``` +Note that this scripts assumes you have permission to run Docker. If you +don't, then you may need to run with `sudo`. + ## Code style Start with [PEP 8](https://www.python.org/dev/peps/pep-0008/). But then, apply diff --git a/scripts/run-full-dev-tests b/scripts/run-full-dev-tests new file mode 100755 index 00000000..2c69a09f --- /dev/null +++ b/scripts/run-full-dev-tests @@ -0,0 +1,13 @@ +#!/bin/sh + +# This script is for running all tests, including end-to-end tests, on a developer machine. It sets +# up database containers to run tests against, runs the tests, and then tears down the containers. +# +# Run this script from the root directory of the borgmatic source. +# +# For more information, see: +# https://torsion.org/borgmatic/docs/how-to/develop-on-borgmatic/ + +set -e + +docker-compose --file tests/end-to-end/docker-compose.yaml up --abort-on-container-exit diff --git a/scripts/run-full-tests b/scripts/run-full-tests new file mode 100755 index 00000000..04c77c9d --- /dev/null +++ b/scripts/run-full-tests @@ -0,0 +1,19 @@ +#!/bin/sh + +# This script installs test dependencies and runs all tests, including end-to-end tests. It +# is designed to run inside a test container, and presumes that other test infrastructure like +# databases are already running. Therefore, on a developer machine, you should not run this script +# directly. Instead, run scripts/run-full-dev-tests +# +# For more information, see: +# https://torsion.org/borgmatic/docs/how-to/develop-on-borgmatic/ + +set -e + +python -m pip install --upgrade pip==19.3.1 +pip install tox==3.14.0 +tox +apk add --no-cache borgbackup postgresql-client mariadb-client +working_directory="$PWD" +adduser --disabled-password tests +su - tests --command "cd $working_directory && tox --workdir /tmp -e end-to-end" diff --git a/scripts/run-tests b/scripts/run-tests deleted file mode 100755 index ec0901a9..00000000 --- a/scripts/run-tests +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/sh - -# This script is intended to be run from the continuous integration build -# server, and not on a developer machine. For that, see: -# https://torsion.org/borgmatic/docs/how-to/develop-on-borgmatic/ - -set -e - -python -m pip install --upgrade pip==19.3.1 -pip install tox==3.14.0 -tox -apk add --no-cache borgbackup postgresql-client -tox -e end-to-end diff --git a/tests/end-to-end/docker-compose.yaml b/tests/end-to-end/docker-compose.yaml new file mode 100644 index 00000000..1e7ad582 --- /dev/null +++ b/tests/end-to-end/docker-compose.yaml @@ -0,0 +1,23 @@ +version: '3' +services: + postgresql: + image: postgres:11.6-alpine + environment: + POSTGRES_PASSWORD: test + POSTGRES_DB: test + mysql: + image: mariadb:10.4 + environment: + MYSQL_ROOT_PASSWORD: test + MYSQL_DATABASE: test + tests: + image: python:3.7-alpine3.10 + volumes: + - "../..:/app" + tty: true + working_dir: /app + command: + - /app/scripts/run-full-tests + depends_on: + - postgresql + - mysql diff --git a/tests/end-to-end/test_database.py b/tests/end-to-end/test_database.py index 83c9e949..a011c6f3 100644 --- a/tests/end-to-end/test_database.py +++ b/tests/end-to-end/test_database.py @@ -29,6 +29,11 @@ hooks: hostname: postgresql username: postgres password: test + mysql_databases: + - name: test + hostname: mysql + username: root + password: test '''.format( config_path, repository_path, borgmatic_source_directory ) diff --git a/tox.ini b/tox.ini index 92c3a33f..8d453c21 100644 --- a/tox.ini +++ b/tox.ini @@ -11,7 +11,7 @@ whitelist_externals = find sh commands_pre = - find {toxinidir} -type f -not -path '{toxinidir}/.tox/*' -path '*/__pycache__/*' -name '*.py[c|o]' -delete + find {envdir} -type f -not -path '*/__pycache__/*' -name '*.py[c|o]' -delete commands = pytest {posargs} py36,py37,py38: black --check .