Files
bot-bottle/tests/integration/test_pipelock_sidecar_smoke.sh
T

88 lines
3.0 KiB
Bash
Executable File

#!/usr/bin/env bash
# Integration: full sidecar smoke test. Boots a pipelock container the
# same way cli.sh does (docker create + docker cp YAML + docker start),
# then probes /health. Catches regressions in:
# - the YAML-cp path (the /etc/pipelock.yaml vs /etc/pipelock/ bug)
# - argv shape (the `run --listen 0.0.0.0:N` invocation)
# - YAML structural validity (pipelock would refuse to start on a bad config)
TEST_NAME="pipelock_sidecar_smoke"
. "$(dirname "$0")/../lib/common.sh"
# shellcheck source=../../lib/log.sh
. "${REPO_ROOT}/lib/log.sh"
# shellcheck source=../../lib/pipelock.sh
. "${REPO_ROOT}/lib/pipelock.sh"
skip_test_if_no_docker
# Use a distinct name so concurrent runs don't collide.
name="cb-test-pipelock-smoke-$$"
work_dir="$(mktemp -d)"
yaml="${work_dir}/pipelock.yaml"
cleanup() {
docker rm -f "$name" >/dev/null 2>&1 || true
rm -rf "$work_dir"
}
trap cleanup EXIT
# Generate a real config from a fixture manifest.
m="$(write_fixture fixture_minimal)"
pipelock_write_yaml "$m" dev "$yaml"
rm -f "$m"
# Same lifecycle as lib/pipelock.sh's pipelock_start, minus the
# network-attach steps (we just need a port we can curl).
docker create --name "$name" -p 0:8888 \
"$CLAUDE_BOTTLE_PIPELOCK_IMAGE" \
run --config /etc/pipelock.yaml --listen "0.0.0.0:8888" \
>/dev/null 2>&1 \
|| { _fail "docker create failed"; test_summary; }
# This is the exact cp path that broke before — guard against
# regressing to a /etc/pipelock/ subdirectory destination.
if ! docker cp "$yaml" "${name}:/etc/pipelock.yaml" >/dev/null 2>&1; then
_fail "docker cp to /etc/pipelock.yaml failed (parent dir must already exist in image)"
test_summary
fi
if ! docker start "$name" >/dev/null 2>&1; then
_fail "docker start failed; check that argv 'run --listen 0.0.0.0:8888' still matches image"
test_summary
fi
# Find the host-side port docker mapped 8888 to.
hostport="$(docker port "$name" 8888 2>/dev/null | head -1 | awk -F: '{print $NF}')"
if [ -z "$hostport" ]; then
_fail "could not determine published port" "docker port output: $(docker port "$name" 2>&1)"
test_summary
fi
# Wait up to 15 seconds for /health to come up.
healthy=0
for _ in $(seq 1 15); do
if curl -fsS "http://127.0.0.1:${hostport}/health" >/dev/null 2>&1; then
healthy=1
break
fi
sleep 1
done
if [ "$healthy" -eq 1 ]; then
_pass "sidecar /health responded"
else
_fail "sidecar /health did not respond within 15s" "logs:" "$(docker logs "$name" 2>&1 | tail -20)"
test_summary
fi
# Body should mention the version we pinned. We don't pin the exact
# version string here because the digest we test against is one
# release; the next release will change the version field but should
# keep the schema. Keep the assertion at "field is present and has
# a numeric-dotted shape".
body="$(curl -fsS "http://127.0.0.1:${hostport}/health" 2>&1)"
assert_contains "$body" '"status":"healthy"' "/health body status:healthy"
assert_match "$body" '"version":"[0-9]+\.[0-9]+\.[0-9]+"' "/health body has version field"
test_summary