Files
tbd/script/integration-test
ajet 343a759d7d
CI / Unit tests (push) Successful in 27s
CI / Integration tests + coverage (push) Failing after 10s
fix CI
2026-09-19 05:56:52 -09:00

78 lines
2.7 KiB
Bash
Executable File

#!/usr/bin/env bash
# Run the dockerized integration tests in isolation: builds the app image, starts it on a
# random port, runs the suite against it, then tears everything down and exits with the
# suite's exit code.
#
# With COVERAGE=1 (see script/integration-coverage) the app runs under Cloverage
# (docker-compose.coverage.yml); after the suite finishes the app is stopped gracefully so
# it writes its report, which is copied to target/coverage/integration.
set -euo pipefail
cd "$(dirname "$0")/.."
root=$PWD
source script/lib/docker.sh
# Picks a random port in [lo, hi] that's currently free on this host; retries on
# collision since another process could grab it first.
free_port_in_range() {
local lo=$1 hi=$2 port attempt
for attempt in $(seq 20); do
port=$((lo + RANDOM % (hi - lo + 1)))
# A successful connect means something is already listening.
if ! (exec 3<>"/dev/tcp/127.0.0.1/$port") 2>/dev/null; then
echo "$port"
return 0
fi
done
echo "no free port found in range $lo-$hi" >&2
return 1
}
port=$(free_port_in_range 30000 40000)
echo "[test] starting vibe-app on random port $port${COVERAGE:+ (under coverage instrumentation)}"
compose=(docker compose)
if [[ -n "${COVERAGE:-}" ]]; then
compose+=(-f docker-compose.yml -f docker-compose.coverage.yml)
fi
use_builder
cd integration-test
export VIBE_PORT=$port
teardown() {
local status=$?
trap - EXIT
"${compose[@]}" down -v || true
exit "$status"
}
trap teardown EXIT
trap 'exit 130' INT
trap 'exit 143' TERM
# Build vibe-app explicitly: `run --build integration-test` only builds the named service
# (not its dependencies), and integration-test is image-only, so compose hands bake an
# empty definition ("failed to find target default") and vibe-app never gets built or started.
"${compose[@]}" --ansi never --progress plain build vibe-app
# `run` returns the test container's own exit code; `up --abort-on-container-exit` can leak
# the app's SIGTERM exit (143) during teardown instead.
status=0
"${compose[@]}" --ansi never run --rm integration-test || status=$?
if [[ -n "${COVERAGE:-}" ]]; then
# SIGTERM is what makes Cloverage write its report, so stop (not kill) the app and pull
# the report out of the stopped container before `down` removes it.
out_dir=$root/target/coverage
echo "[test] stopping vibe-app to flush coverage report"
"${compose[@]}" stop -t 120 vibe-app || true
rm -rf "$out_dir/integration"
mkdir -p "$out_dir"
if ! "${compose[@]}" cp vibe-app:/app/target/coverage/integration "$out_dir" \
|| [[ ! -f $out_dir/integration/lcov.info ]]; then
echo "[test] WARNING: no integration coverage report was produced"
fi
fi
exit "$status"