mirror of
https://github.com/lobaro/restic-backup-docker.git
synced 2026-11-15 16:06:40 +00:00
test: move container test suites to pytest (#112)
* test: scaffold pytest suite with mise, uv and Task Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * ci: run the pytest suite via mise and task Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * fix: make test cleanup survive repeated SIGINT A group Ctrl-C reaches pytest a second time via task and uv while the session fixture tears down, aborting the volume cleanup. Ignore SIGINT and SIGTERM during cleanup, remove volumes in finally, and tolerate already-removed objects. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * fix: pin Python 3.13 for uv without mise Add .python-version (read by mise and uv) and cap requires-python at <3.14 so bare uv uses 3.13 or fails instead of picking 3.14. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * fix: clean up test containers on SIGTERM Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * test: port compat tests to pytest Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * test: assert the success message first in the corruption test Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * test: assert the empty-tag snapshot carries no tags Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * test: remove anonymous volumes with short-lived test containers Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * test: port feature-gated tests to pytest Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * test: port sabotage self-test to task test:sabotage Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * fix: create parent directories in put_file Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * test: move structure.yml to tests and remove cst volume leak container-structure-test left one anonymous volume per test container. tests/structure.py runs it with --save and removes the new containers with their volumes afterwards. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * test: remove the Bash suite Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * ci: run only the Python suite in the test job Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * docs: describe the Python test suite Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * test: isolate scenario steps, share helpers, use restore_latest, HEAD dir probe Scenario fixtures record each step; a failing step fails only the tests that assert on it. running() and raise_interrupt() live in helpers.py. put_file probes parent directories with a HEAD request instead of a get_archive stream. stream_run uses restore_latest and asserts its result. Docstrings no longer refer to the removed Bash suite. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * test: sabotage check rejects errors and malformed reports Only <failure> of the expected tests counts as red; errors in them and a malformed JUnit report exit 2 (invalid) instead of passing or exiting 1. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * test: structure wrapper removes only its own containers Restrict cleanup to containers of the image under test without the rbd-test-run label and ignore NotFound. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * build: run all test suites and aggregate the exit code task test no longer stops at the first failing suite. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * fix: sabotage check treats failed scenario steps as INVALID StepFailed is no AssertionError any more; sabotage.py counts a JUnit failure named StepFailed as error, so an expected-red test only counts when its own assertion fails. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * fix: hard timeout for container-structure-test CST_TIMEOUT (default 300 s) kills a hanging run; existing cleanup removes the containers; exit code 124 with a clear message. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * fix: shorten sabotage message for lint Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * fix: handle JUnit failures without message in sabotage check Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
31f06b5d9b
commit
be7d426f78
21 files changed
+1692
-958
No files matched your search
@@ -0,0 +1,64 @@
|
||||
schemaVersion: '2.0.0'
|
||||
|
||||
# Structural contract of the image. Everything asserted here is something a
|
||||
# user can reach from outside: a binary they call from a hook, a path they
|
||||
# mount, or the way the container is started.
|
||||
|
||||
commandTests:
|
||||
- name: 'restic is installed'
|
||||
command: 'restic'
|
||||
args: ['version']
|
||||
expectedOutput: ['restic \d+\.\d+\.\d+.*']
|
||||
- name: 'rclone is installed'
|
||||
command: 'rclone'
|
||||
args: ['--version']
|
||||
expectedOutput: ['rclone v.*']
|
||||
- name: 'curl is installed, used for Teams notifications'
|
||||
command: 'curl'
|
||||
args: ['--version']
|
||||
expectedOutput: ['curl \d+\..*']
|
||||
- name: 'mail is installed, used for mail notifications'
|
||||
command: 'sh'
|
||||
args: ['-c', 'command -v mail']
|
||||
expectedOutput: ['/usr/bin/mail']
|
||||
- name: 'crond is available'
|
||||
command: 'sh'
|
||||
args: ['-c', 'command -v crond']
|
||||
expectedOutput: ['/usr/sbin/crond']
|
||||
- name: 'flock is available, the cron jobs depend on it'
|
||||
command: 'sh'
|
||||
args: ['-c', 'test -x /usr/bin/flock && echo ok']
|
||||
expectedOutput: ['ok']
|
||||
|
||||
fileExistenceTests:
|
||||
- name: 'backup script'
|
||||
path: '/bin/backup'
|
||||
shouldExist: true
|
||||
permissions: '-rwxr-xr-x'
|
||||
- name: 'check script'
|
||||
path: '/bin/check'
|
||||
shouldExist: true
|
||||
permissions: '-rwxr-xr-x'
|
||||
- name: 'entrypoint'
|
||||
path: '/entry.sh'
|
||||
shouldExist: true
|
||||
permissions: '-rwxr-xr-x'
|
||||
- name: 'default repository mount point'
|
||||
path: '/mnt/restic'
|
||||
shouldExist: true
|
||||
- name: 'cron log file'
|
||||
path: '/var/log/cron.log'
|
||||
shouldExist: true
|
||||
- name: 'crontab directory'
|
||||
path: '/var/spool/cron/crontabs'
|
||||
shouldExist: true
|
||||
|
||||
metadataTest:
|
||||
volumes: ['/data']
|
||||
entrypoint: ['/entry.sh']
|
||||
cmd: ['tail', '-fn0', '/var/log/cron.log']
|
||||
envVars:
|
||||
- key: 'RESTIC_REPOSITORY'
|
||||
value: '/mnt/restic'
|
||||
- key: 'BACKUP_CRON'
|
||||
value: '0 */6 * * *'
|
||||
Reference in new issue
Block a user