test: replace legacy workspace deployment fixtures
This commit is contained in:
@@ -6,6 +6,7 @@ set -euo pipefail
|
||||
|
||||
root="$(cd "$(dirname "$0")/.." && pwd -P)"
|
||||
tmp="$(mktemp -d "${TMPDIR:-/tmp}/thoth-workspace-registry-smoke.XXXXXX")"
|
||||
tmp="$(cd "$tmp" && pwd -P)"
|
||||
tmp_slug="$(basename "$tmp" | tr '[:upper:]._' '[:lower:]--' | tr -cd 'a-z0-9-')"
|
||||
project="thoth-workspace-registry-smoke-${tmp_slug}-$$"
|
||||
image="thothii-workspace-registry-smoke:${project}"
|
||||
@@ -15,20 +16,128 @@ branch="workspace-registry-smoke"
|
||||
core_remote="/fixtures/remote.git"
|
||||
|
||||
cleanup_smoke_image() {
|
||||
docker image rm -f "$image" >/dev/null 2>&1 || true
|
||||
local inspect_status listed list_status
|
||||
docker image inspect --format '{{.Id}}' "$image" >/dev/null 2>&1
|
||||
inspect_status=$?
|
||||
if [[ "$inspect_status" -eq 0 ]]; then
|
||||
docker image rm -f "$image" >/dev/null 2>&1
|
||||
return $?
|
||||
fi
|
||||
|
||||
listed="$(docker image ls --quiet --no-trunc "$image" 2>/dev/null)"
|
||||
list_status=$?
|
||||
[[ "$list_status" -eq 0 && -z "$listed" ]]
|
||||
}
|
||||
|
||||
workspace_registry_smoke_leftovers() {
|
||||
{
|
||||
docker ps -a --filter "label=com.docker.compose.project=$project" -q
|
||||
docker volume ls --filter "label=com.docker.compose.project=$project" -q
|
||||
docker network ls --filter "label=com.docker.compose.project=$project" -q
|
||||
docker image inspect --format '{{.Id}}' "$image" 2>/dev/null || true
|
||||
} | sed '/^$/d'
|
||||
local output status=0
|
||||
if output="$(docker ps -a --filter "label=com.docker.compose.project=$project" -q)"; then
|
||||
printf '%s\n' "$output"
|
||||
else
|
||||
status=1
|
||||
fi
|
||||
if output="$(docker volume ls --filter "label=com.docker.compose.project=$project" -q)"; then
|
||||
printf '%s\n' "$output"
|
||||
else
|
||||
status=1
|
||||
fi
|
||||
if output="$(docker network ls --filter "label=com.docker.compose.project=$project" -q)"; then
|
||||
printf '%s\n' "$output"
|
||||
else
|
||||
status=1
|
||||
fi
|
||||
if output="$(docker image inspect --format '{{.Id}}' "$image" 2>/dev/null)"; then
|
||||
printf '%s\n' "$output"
|
||||
elif output="$(docker image ls --quiet --no-trunc "$image" 2>/dev/null)"; then
|
||||
printf '%s\n' "$output"
|
||||
else
|
||||
status=1
|
||||
fi
|
||||
return "$status"
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
local body_status=$?
|
||||
local down_status image_status enumeration_status rm_status=0 cleanup_incomplete=0 final_status
|
||||
local leftovers
|
||||
trap - EXIT HUP INT TERM
|
||||
set +e
|
||||
|
||||
compose down --volumes --remove-orphans >/dev/null 2>&1
|
||||
down_status=$?
|
||||
cleanup_smoke_image
|
||||
image_status=$?
|
||||
leftovers="$(workspace_registry_smoke_leftovers)"
|
||||
enumeration_status=$?
|
||||
leftovers="$(printf '%s\n' "$leftovers" | sed '/^$/d')"
|
||||
|
||||
if [[ "$down_status" -ne 0 || "$image_status" -ne 0 || "$enumeration_status" -ne 0 || -n "$leftovers" ]]; then
|
||||
cleanup_incomplete=1
|
||||
else
|
||||
rm -rf "$tmp"
|
||||
rm_status=$?
|
||||
[[ "$rm_status" -eq 0 ]] || cleanup_incomplete=1
|
||||
fi
|
||||
|
||||
if [[ "$cleanup_incomplete" -ne 0 ]]; then
|
||||
echo "workspace registry cleanup incomplete: compose down status=$down_status, image cleanup status=$image_status, enumeration status=$enumeration_status, temp cleanup status=$rm_status." >&2
|
||||
if [[ -n "$leftovers" ]]; then
|
||||
echo "workspace registry cleanup left owned Docker resources:" >&2
|
||||
printf '%s\n' "$leftovers" >&2
|
||||
fi
|
||||
echo "workspace registry smoke recovery path retained: $tmp" >&2
|
||||
if [[ "$body_status" -ne 0 ]]; then
|
||||
final_status=$body_status
|
||||
else
|
||||
final_status=1
|
||||
fi
|
||||
else
|
||||
echo "workspace registry cleanup proof: no compose containers, volumes, networks, image, or temporary path remain for $project."
|
||||
final_status=$body_status
|
||||
fi
|
||||
exit "$final_status"
|
||||
}
|
||||
|
||||
compose() {
|
||||
SMOKE_ROOT="$root" \
|
||||
SMOKE_IMAGE="$image" \
|
||||
SMOKE_REMOTE="$remote" \
|
||||
SMOKE_BRANCH="$branch" \
|
||||
SMOKE_CORE_REMOTE="$core_remote" \
|
||||
docker compose --project-name "$project" -f - "$@" <<'COMPOSE_YAML'
|
||||
services:
|
||||
core:
|
||||
build:
|
||||
context: "${SMOKE_ROOT:?}"
|
||||
dockerfile: docker/core.Dockerfile
|
||||
image: "${SMOKE_IMAGE:?}"
|
||||
environment:
|
||||
HOST: 0.0.0.0
|
||||
PORT: "8787"
|
||||
AUTH_MODE: none
|
||||
THT_HARNESS_DIR: /app/harness
|
||||
THT_BIN: /opt/venv/bin/tht
|
||||
SETTINGS_FILE: /tmp/settings.json
|
||||
THT_WORKSPACE_REGISTRY_ROOT: /data/workspace-registry
|
||||
THT_WORKSPACE_GIT_REMOTE: "${SMOKE_CORE_REMOTE:?}"
|
||||
THT_WORKSPACE_GIT_BRANCH: "${SMOKE_BRANCH:?}"
|
||||
THT_WORKSPACE_INSTALLATION_ID: smoke
|
||||
THT_WORKSPACE_SECRET_ROOTS: /run/secrets
|
||||
volumes:
|
||||
- type: volume
|
||||
source: workspace-registry
|
||||
target: /data/workspace-registry
|
||||
- type: bind
|
||||
source: "${SMOKE_REMOTE:?}"
|
||||
target: /fixtures/remote.git
|
||||
read_only: true
|
||||
volumes:
|
||||
workspace-registry: {}
|
||||
COMPOSE_YAML
|
||||
}
|
||||
|
||||
workspace_registry_smoke_self_test_image_cleanup_identity() {
|
||||
local calls exact_image foreign_project foreign_tag leftovers
|
||||
local calls exact_image foreign_project foreign_tag leftovers removed=0
|
||||
calls="$(mktemp "${TMPDIR:-/tmp}/thoth-workspace-registry-smoke-image-contract.XXXXXX")"
|
||||
project="thoth-workspace-registry-smoke-selftest-123"
|
||||
exact_image="thothii-workspace-registry-smoke:${project}"
|
||||
@@ -39,19 +148,19 @@ workspace_registry_smoke_self_test_image_cleanup_identity() {
|
||||
docker() {
|
||||
printf '%s\n' "docker $*" >>"$calls"
|
||||
case "$1 $2" in
|
||||
"image rm")
|
||||
[[ "$3" == "-f" ]] || return 41
|
||||
[[ "$4" == "$exact_image" ]] || return 42
|
||||
return 0
|
||||
;;
|
||||
"image inspect")
|
||||
[[ "$3" == "--format" ]] || return 43
|
||||
[[ "$5" == "$exact_image" ]] || return 44
|
||||
return 1
|
||||
[[ "$3" == "--format" && "$5" == "$exact_image" ]] || return 43
|
||||
[[ "$removed" -eq 0 ]]
|
||||
;;
|
||||
"image rm")
|
||||
[[ "$3" == "-f" && "$4" == "$exact_image" ]] || return 42
|
||||
removed=1
|
||||
;;
|
||||
"image ls")
|
||||
[[ "$3" == "--quiet" && "$4" == "--no-trunc" && "$5" == "$exact_image" ]] || return 47
|
||||
;;
|
||||
"ps -a"|"volume ls"|"network ls")
|
||||
[[ "$*" == *"label=com.docker.compose.project=$project"* ]] || return 45
|
||||
return 0
|
||||
;;
|
||||
*)
|
||||
return 46
|
||||
@@ -61,7 +170,7 @@ workspace_registry_smoke_self_test_image_cleanup_identity() {
|
||||
|
||||
cleanup_smoke_image
|
||||
leftovers="$(workspace_registry_smoke_leftovers)"
|
||||
[[ -z "$leftovers" ]] || {
|
||||
[[ -z "$(printf '%s\n' "$leftovers" | sed '/^$/d')" ]] || {
|
||||
echo "self-test observed leftovers for the per-run image" >&2
|
||||
printf '%s\n' "$leftovers" >&2
|
||||
return 1
|
||||
@@ -72,62 +181,95 @@ workspace_registry_smoke_self_test_image_cleanup_identity() {
|
||||
echo "self-test cleanup touched a foreign workspace-registry smoke image reference" >&2
|
||||
return 1
|
||||
fi
|
||||
rm -f "$calls"
|
||||
echo "workspace registry smoke image cleanup identity self-test passed"
|
||||
}
|
||||
|
||||
if [[ "${WORKSPACE_REGISTRY_SMOKE_SELF_TEST:-}" == "image-cleanup-identity" ]]; then
|
||||
workspace_registry_smoke_self_test_image_cleanup_identity
|
||||
exit 0
|
||||
fi
|
||||
workspace_registry_smoke_self_test_compose_config() {
|
||||
local special_root rendered
|
||||
special_root="$tmp/compose config path # colon: fixture"
|
||||
root="$special_root/root context"
|
||||
remote="$special_root/remote repo # fixture.git"
|
||||
branch="workspace registry # branch"
|
||||
core_remote="/fixtures/remote repo # fixture.git"
|
||||
image="thothii-workspace-registry-smoke:compose-config-selftest"
|
||||
project="thoth-workspace-registry-smoke-compose-config-selftest-$$"
|
||||
rendered="$special_root/rendered.yaml"
|
||||
mkdir -p "$root" "$remote"
|
||||
|
||||
cleanup() {
|
||||
local cleanup_status=$?
|
||||
compose down --volumes --remove-orphans >/dev/null 2>&1 || true
|
||||
cleanup_smoke_image
|
||||
if [[ "$cleanup_status" -eq 0 ]]; then
|
||||
local leftovers
|
||||
leftovers="$(workspace_registry_smoke_leftovers)"
|
||||
if [[ -n "$leftovers" ]]; then
|
||||
echo "workspace registry cleanup left owned Docker resources:" >&2
|
||||
printf '%s\n' "$leftovers" >&2
|
||||
cleanup_status=1
|
||||
else
|
||||
echo "workspace registry cleanup proof: no compose containers, volumes, networks, or image remain for $project."
|
||||
fi
|
||||
fi
|
||||
compose config --quiet
|
||||
compose config --format json >"$rendered"
|
||||
grep -Fq "$root" "$rendered"
|
||||
grep -Fq "$remote" "$rendered"
|
||||
grep -Fq "$branch" "$rendered"
|
||||
grep -Fq "$core_remote" "$rendered"
|
||||
grep -Fq '"read_only": true' "$rendered"
|
||||
rm -rf "$tmp"
|
||||
exit "$cleanup_status"
|
||||
echo "workspace registry smoke Compose config special-path self-test passed"
|
||||
}
|
||||
trap cleanup EXIT HUP INT TERM
|
||||
|
||||
compose() {
|
||||
docker compose --project-name "$project" -f - "$@" <<EOF
|
||||
services:
|
||||
core:
|
||||
build:
|
||||
context: $root
|
||||
dockerfile: docker/core.Dockerfile
|
||||
image: $image
|
||||
environment:
|
||||
HOST: 0.0.0.0
|
||||
PORT: "8787"
|
||||
AUTH_MODE: none
|
||||
THT_HARNESS_DIR: /app/harness
|
||||
THT_BIN: /opt/venv/bin/tht
|
||||
SETTINGS_FILE: /tmp/settings.json
|
||||
THT_WORKSPACE_REGISTRY_ROOT: /data/workspace-registry
|
||||
THT_WORKSPACE_GIT_REMOTE: $core_remote
|
||||
THT_WORKSPACE_GIT_BRANCH: $branch
|
||||
THT_WORKSPACE_INSTALLATION_ID: smoke
|
||||
THT_WORKSPACE_SECRET_ROOTS: /run/secrets
|
||||
volumes:
|
||||
- workspace-registry:/data/workspace-registry
|
||||
- $remote:/fixtures/remote.git:ro
|
||||
volumes:
|
||||
workspace-registry: {}
|
||||
EOF
|
||||
workspace_registry_smoke_self_test_cleanup_failure_path() {
|
||||
local fixture_root retained calls output status
|
||||
fixture_root="$tmp/cleanup failure # fixture"
|
||||
retained="$fixture_root/retained smoke path"
|
||||
calls="$fixture_root/calls.log"
|
||||
mkdir -p "$retained"
|
||||
|
||||
set +e
|
||||
output="$(
|
||||
(
|
||||
tmp="$retained"
|
||||
project="thoth-workspace-registry-smoke-cleanup-failure-selftest"
|
||||
image="thothii-workspace-registry-smoke:cleanup-failure-selftest"
|
||||
compose() { printf '%s\n' "compose $*" >>"$calls"; return 71; }
|
||||
cleanup_smoke_image() { printf '%s\n' 'image cleanup' >>"$calls"; return 72; }
|
||||
workspace_registry_smoke_leftovers() { printf '%s\n' 'owned-resource-selftest'; printf '%s\n' 'enumerate leftovers' >>"$calls"; return 73; }
|
||||
trap cleanup EXIT
|
||||
exit 37
|
||||
) 2>&1
|
||||
)"
|
||||
status=$?
|
||||
set -e
|
||||
|
||||
[[ "$status" -eq 37 ]] || { echo "cleanup self-test did not preserve body status 37 (got $status)" >&2; return 1; }
|
||||
grep -Fq 'compose down --volumes --remove-orphans' "$calls"
|
||||
grep -Fq 'image cleanup' "$calls"
|
||||
grep -Fq 'enumerate leftovers' "$calls"
|
||||
grep -Fq 'cleanup incomplete: compose down status=71, image cleanup status=72, enumeration status=73' <<<"$output"
|
||||
grep -Fq 'owned-resource-selftest' <<<"$output"
|
||||
grep -Fq "recovery path retained: $retained" <<<"$output"
|
||||
[[ -d "$retained" ]] || { echo "cleanup self-test did not retain its recovery path" >&2; return 1; }
|
||||
rm -rf "$tmp"
|
||||
echo "workspace registry smoke cleanup failure-path self-test passed"
|
||||
}
|
||||
|
||||
case "${WORKSPACE_REGISTRY_SMOKE_SELF_TEST:-}" in
|
||||
"") ;;
|
||||
image-cleanup-identity)
|
||||
workspace_registry_smoke_self_test_image_cleanup_identity
|
||||
rm -rf "$tmp"
|
||||
exit 0
|
||||
;;
|
||||
compose-config-contract)
|
||||
workspace_registry_smoke_self_test_compose_config
|
||||
exit 0
|
||||
;;
|
||||
cleanup-failure-path)
|
||||
workspace_registry_smoke_self_test_cleanup_failure_path
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "unknown workspace registry smoke self-test: ${WORKSPACE_REGISTRY_SMOKE_SELF_TEST}" >&2
|
||||
rm -rf "$tmp"
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
|
||||
trap cleanup EXIT
|
||||
trap 'exit 129' HUP
|
||||
trap 'exit 130' INT
|
||||
trap 'exit 143' TERM
|
||||
|
||||
wait_for_core() {
|
||||
local attempt
|
||||
for attempt in $(seq 1 30); do
|
||||
@@ -149,9 +291,8 @@ echo "== Seed isolated workspace registry =="
|
||||
git init --bare --initial-branch=main "$remote" >/dev/null
|
||||
git clone "$remote" "$seed" >/dev/null
|
||||
git -C "$seed" checkout -b "$branch" >/dev/null
|
||||
npm --prefix "$root/backend" run build >/dev/null
|
||||
node "$root/backend/dist/workspaces/migrate-legacy.js" \
|
||||
--input "$root/harness/workspaces/local.yaml" --output "$seed" --collection local >/dev/null
|
||||
mkdir -p "$seed/workspaces"
|
||||
cp "$root/scripts/fixtures/workspace-registry-smoke.yaml" "$seed/workspaces/local.yaml"
|
||||
git -C "$seed" add workspaces/local.yaml
|
||||
git -C "$seed" -c user.name='Workspace Registry Smoke' -c user.email='workspace-registry-smoke@example.invalid' \
|
||||
commit -m 'Seed workspace registry smoke' >/dev/null
|
||||
|
||||
Reference in New Issue
Block a user