From 353d65f5775bfba2b6416df0db81f6567f3401cd Mon Sep 17 00:00:00 2001 From: Jason Woltje Date: Fri, 23 Oct 2026 06:00:49 -0500 Subject: [PATCH] row 305 (#1812, Vikunja 591) draft: per-run COMPOSE_PROJECT_NAME, exit trap removes that one network, one absent-network check per suite; for Mos through Sage before the build (mos-1272) --- scripts/test-release.sh | 27 ++++++++++++++++++++++++++- scripts/test-task.sh | 27 ++++++++++++++++++++++++++- 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/scripts/test-release.sh b/scripts/test-release.sh index 1ac5bc8d9..2179a50f6 100755 --- a/scripts/test-release.sh +++ b/scripts/test-release.sh @@ -12,7 +12,22 @@ RELEASE_BACKUP="$(mktemp)" cp RELEASE "$RELEASE_BACKUP" # One exit trap: the repo RELEASE is ALWAYS restored from the backup, # regardless of how the test run ends. -trap 'cp "$RELEASE_BACKUP" RELEASE 2>/dev/null; rm -rf "$SANDBOX" "$RELEASE_BACKUP"' EXIT +# Compose names the project after the checkout directory unless told otherwise, +# and `compose run --rm` leaves the project's _default network behind. +# Every run gets its own project, and the exit trap removes that one network +# (row 305). It never runs `compose down` and never touches another network. +COMPOSE_ID="$(basename "$SANDBOX")" +COMPOSE_ID="$(printf '%s' "${COMPOSE_ID##*.}" | tr -cd '[:alnum:]' | tr '[:upper:]' '[:lower:]')" +export COMPOSE_PROJECT_NAME="mosaic-test-release-$COMPOSE_ID" +remove_compose_network() { # absent is fine; any other failure is one stderr line, never a status + command -v docker >/dev/null 2>&1 || return 0 + local net="${COMPOSE_PROJECT_NAME}_default" err + err="$(docker network rm "$net" 2>&1 >/dev/null)" && return 0 + case "$err" in *"not found"*|*"No such network"*) return 0 ;; esac + echo "test-release: could not remove network $net: ${err%%$'\n'*}" >&2 + return 0 +} +trap 'cp "$RELEASE_BACKUP" RELEASE 2>/dev/null; rm -rf "$SANDBOX" "$RELEASE_BACKUP"; remove_compose_network' EXIT # Compose mounts PI_AUTH_FILE. Point it at a fixture so no activation reaches # the host's pi credential (row 244). chmod after the write: umask-proof (row 243). { mkdir -p "$SANDBOX/pi" && printf '{}' > "$SANDBOX/pi/auth.json" && chmod 600 "$SANDBOX/pi/auth.json"; } \ @@ -108,6 +123,16 @@ else echo "skip state-machine cases (docker daemon unavailable)" fi +# The compose network goes with the run (row 305): the trap's cleanup leaves no +# network under this run's project name. +if docker info >/dev/null 2>&1; then + remove_compose_network + NETS="$(docker network ls -q --filter "name=^${COMPOSE_PROJECT_NAME}_default\$")" && [ -z "$NETS" ] \ + && check "compose network removed after the run" 0 || check "compose network removed after the run" 1 +else + echo "skip compose network check (docker daemon unavailable)" +fi + echo echo "selftest: $PASS passed, $FAIL failed" [ "$FAIL" -eq 0 ] diff --git a/scripts/test-task.sh b/scripts/test-task.sh index 35b0c1412..ac65dbbb8 100755 --- a/scripts/test-task.sh +++ b/scripts/test-task.sh @@ -8,7 +8,22 @@ set -uo pipefail cd "$(dirname "$0")/.." SANDBOX="$(mktemp -d)" -trap 'rm -rf "$SANDBOX"' EXIT +# Compose names the project after the checkout directory unless told otherwise, +# and `compose run --rm` leaves the project's _default network behind. +# Every run gets its own project, and the exit trap removes that one network +# (row 305). It never runs `compose down` and never touches another network. +COMPOSE_ID="$(basename "$SANDBOX")" +COMPOSE_ID="$(printf '%s' "${COMPOSE_ID##*.}" | tr -cd '[:alnum:]' | tr '[:upper:]' '[:lower:]')" +export COMPOSE_PROJECT_NAME="mosaic-test-task-$COMPOSE_ID" +remove_compose_network() { # absent is fine; any other failure is one stderr line, never a status + command -v docker >/dev/null 2>&1 || return 0 + local net="${COMPOSE_PROJECT_NAME}_default" err + err="$(docker network rm "$net" 2>&1 >/dev/null)" && return 0 + case "$err" in *"not found"*|*"No such network"*) return 0 ;; esac + echo "test-task: could not remove network $net: ${err%%$'\n'*}" >&2 + return 0 +} +trap 'rm -rf "$SANDBOX"; remove_compose_network' EXIT # Real-model cases need the operator's credential and a billed provider call, # so they run only on request (row 244, sage-2061). The gate lane never passes # MOSAIC_LIVE_PROVIDER through. @@ -558,6 +573,16 @@ fi git -C "$SANDBOX/repo" rev-parse >/dev/null 2>&1 || true unset MOSAIC_CONFIG +# The compose network goes with the run (row 305): the trap's cleanup leaves no +# network under this run's project name. +if docker info >/dev/null 2>&1; then + remove_compose_network + NETS="$(docker network ls -q --filter "name=^${COMPOSE_PROJECT_NAME}_default\$")" && [ -z "$NETS" ] \ + && check "compose network removed after the run" 0 || check "compose network removed after the run" 1 +else + echo "skip compose network check (docker daemon unavailable)" +fi + echo echo "selftest: $PASS passed, $FAIL failed" [ "$FAIL" -eq 0 ]