diff --git a/NEWS b/NEWS index 7355607bf..7d6a1146a 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,6 @@ 1.2.7.dev0 * Use Black code formatter and Flake8 code checker as part of running automated tests. + * Add an end-to-end automated test that actually integrates with Borg. 1.2.6 * Fix generated configuration to also include a "keep_daily" value so pruning works out of the diff --git a/README.md b/README.md index f2c2c8e74..a5c8fd4aa 100644 --- a/README.md +++ b/README.md @@ -453,6 +453,19 @@ following: tox -e black ``` +### 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 slow and require Docker. If you would like to run them, first +install Docker, and make sure that it's executable by the current user. Then: + +```bash +tox -e end-to-end +``` + +That builds a test container with your local borgmatic source, and runs +end-to-end tests within it. ## Troubleshooting diff --git a/tests/end-to-end/Dockerfile b/tests/end-to-end/Dockerfile new file mode 100644 index 000000000..33f8ea65b --- /dev/null +++ b/tests/end-to-end/Dockerfile @@ -0,0 +1,17 @@ +FROM b3vis/borgmatic + +# Starting from an existing borgmatic image, install the local source on top of +# it so that we can test any local changes. +RUN adduser -h /home -D app +COPY test_requirements.txt /app/ +RUN pip3 install --upgrade --requirement /app/test_requirements.txt +COPY . /app +RUN rm -fr /app/.tox /app/.git \ + && pip3 install --upgrade /app \ + && chown -R app /app + +USER app +WORKDIR /app +ENV BORG_CACHE_DIR "/app/.cache/borg" + +CMD ["py.test"] diff --git a/tests/end-to-end/__init__.py b/tests/end-to-end/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/end-to-end/test_borgmatic.py b/tests/end-to-end/test_borgmatic.py new file mode 100644 index 000000000..a677b5291 --- /dev/null +++ b/tests/end-to-end/test_borgmatic.py @@ -0,0 +1,39 @@ +import json +import os +import subprocess +import sys + + +def generate_configuration(): + subprocess.check_call('generate-borgmatic-config --destination test.yaml'.split(' ')) + config = ( + open('test.yaml') + .read() + .replace('user@backupserver:sourcehostname.borg', 'test.borg') + .replace('- /etc', '- /app') + .replace('- /var/log/syslog*', '') + ) + config_file = open('test.yaml', 'w') + config_file.write(config) + config_file.close() + + +def test_borgmatic_command(): + # Create a Borg repository. + subprocess.check_call( + 'borg init --encryption repokey test.borg'.split(' '), + env={'BORG_PASSPHRASE': '', **os.environ}, + ) + + # Generate borgmatic configuration, and update the defaults so as to work for this test. + generate_configuration() + + # Run borgmatic to generate a backup archive, and then list it to make sure it exists. + subprocess.check_call('borgmatic --config test.yaml'.split(' ')) + output = subprocess.check_output( + 'borgmatic --config test.yaml --list --json'.split(' '), encoding=sys.stdout.encoding + ) + parsed_output = json.loads(output) + + assert len(parsed_output) == 1 + assert len(parsed_output[0]['archives']) == 1 diff --git a/tox.ini b/tox.ini index 558911e79..4444d45e4 100644 --- a/tox.ini +++ b/tox.ini @@ -1,20 +1,29 @@ [tox] -envlist=py3 -skipsdist=True +envlist = py3 +skipsdist = True [testenv] -usedevelop=True -deps=-rtest_requirements.txt +usedevelop = True +deps = -rtest_requirements.txt commands = - py.test --cov-report term-missing:skip-covered --cov=borgmatic tests [] + py.test --cov-report term-missing:skip-covered --cov=borgmatic --ignore=tests/end-to-end \ + tests [] black --skip-string-normalization --line-length 100 --check . flake8 . [testenv:black] -basepython=python3.7 +basepython = python3.7 commands = black --skip-string-normalization --line-length 100 . +[testenv:end-to-end] +whitelist_externals = docker +skip_install = true +deps = +commands = + docker build --file tests/end-to-end/Dockerfile --tag borgmatic-test . + docker run --rm borgmatic-test py.test tests/end-to-end [] + [flake8] -ignore=E501,W503 -exclude=*.*/* +ignore = E501,W503 +exclude = *.*/*