mirror of
https://github.com/lobaro/restic-backup-docker.git
synced 2026-11-13 07:45:22 +00:00
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>
This commit is contained in:
1 parent
c65537c013
commit
a6c83de07e
5 files changed
+72
-23
No files matched your search
+2
-2
@@ -32,9 +32,9 @@ tasks:
|
||||
- task: test:features
|
||||
|
||||
test:structure:
|
||||
desc: Run container-structure-test against the image
|
||||
desc: Run container-structure-test against the image and remove its containers and volumes
|
||||
cmds:
|
||||
- container-structure-test test --image {{.IMAGE}} --config test/structure.yml
|
||||
- uv run python tests/structure.py
|
||||
|
||||
test:compat:
|
||||
desc: Run the compat tests
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
# Optional features that MUST be present in the built image.
|
||||
#
|
||||
# One gate name per line. Known gates and the pull request that introduces
|
||||
# them (see test/features.sh):
|
||||
#
|
||||
# stream stream backups via RESTIC_STREAM PR #109
|
||||
# docker-cli docker cli inside the container PR #99
|
||||
# bash bash for pre/post hooks PR #99
|
||||
# msmtp mail relay via msmtp PR #84
|
||||
#
|
||||
# While a gate is NOT listed here its tests are reported as SKIP when the
|
||||
# feature is absent, so an open pull request does not turn master red.
|
||||
#
|
||||
# When you merge a feature, add its gate name below. From then on the feature
|
||||
# tests are mandatory and a feature that silently disappears from the image
|
||||
# fails the build.
|
||||
#
|
||||
# Empty on purpose: master currently ships none of the optional features.
|
||||
@@ -1,5 +1,17 @@
|
||||
# Optional features that MUST be present in the built image.
|
||||
#
|
||||
# One gate name per line. Known gates: stream, docker-cli, bash, msmtp.
|
||||
# A listed feature that is absent turns its skip into a failure.
|
||||
# Empty on purpose: master currently ships none of the optional features.
|
||||
# One gate name per line. Known gates and the pull request that introduces
|
||||
# them (see tests/test_features.py):
|
||||
#
|
||||
# stream stream backups via RESTIC_STREAM PR #109
|
||||
# docker-cli docker cli inside the container PR #99
|
||||
# bash bash for pre/post hooks PR #99
|
||||
# msmtp mail relay via msmtp PR #84
|
||||
#
|
||||
# While a gate is NOT listed here its tests are reported as SKIP when the
|
||||
# feature is absent, so an open pull request does not turn master red.
|
||||
#
|
||||
# When you merge a feature, add its gate name below. From then on the feature
|
||||
# tests are mandatory and a feature that silently disappears from the image
|
||||
# fails the build.
|
||||
#
|
||||
@@ -0,0 +1,55 @@
|
||||
"""Run container-structure-test without leaking Docker volumes.
|
||||
|
||||
container-structure-test starts one container per test and never removes it. The image
|
||||
declares `VOLUME /data`, so every container drags an anonymous volume along that outlives
|
||||
`docker rm`. With `--save` the containers are kept, and this wrapper removes the ones the
|
||||
run created, together with their volumes (`remove(v=True)`). Run with `task test:structure`.
|
||||
|
||||
Exit code: the one of container-structure-test.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import signal
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
import docker
|
||||
|
||||
CONFIG = Path(__file__).with_name("structure.yml")
|
||||
|
||||
|
||||
def _raise_interrupt(signum: int, _frame: object) -> None:
|
||||
raise KeyboardInterrupt(f"received {signal.Signals(signum).name}")
|
||||
|
||||
|
||||
def main() -> int:
|
||||
image = os.environ.get("IMAGE", "restic-backup-docker:test")
|
||||
signal.signal(signal.SIGTERM, _raise_interrupt)
|
||||
client = docker.from_env()
|
||||
before = {c.id for c in client.containers.list(all=True)}
|
||||
try:
|
||||
return subprocess.run(
|
||||
[
|
||||
"container-structure-test",
|
||||
"test",
|
||||
"--save",
|
||||
"--image",
|
||||
image,
|
||||
"--config",
|
||||
str(CONFIG),
|
||||
],
|
||||
check=False,
|
||||
).returncode
|
||||
finally:
|
||||
signal.signal(signal.SIGINT, signal.SIG_IGN)
|
||||
for container in client.containers.list(all=True):
|
||||
if container.id not in before:
|
||||
container.remove(v=True, force=True)
|
||||
signal.signal(signal.SIGINT, signal.default_int_handler)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
File renamed without changes.
Reference in new issue
Block a user