153 lines
4.8 KiB
Bash
153 lines
4.8 KiB
Bash
#!/usr/bin/env bash
|
|
set -Eeuo pipefail
|
|
|
|
EXPECTED_EXTERNAL_TESTS="${EXPECTED_EXTERNAL_TESTS:-10}"
|
|
WORK_DIR="$(mktemp -d)"
|
|
POSTGRES_CONTAINER=""
|
|
REDIS_CONTAINER=""
|
|
MINIO_PID=""
|
|
|
|
cleanup() {
|
|
local status=$?
|
|
trap - EXIT INT TERM
|
|
set +e
|
|
if [[ -n "$MINIO_PID" ]]; then
|
|
kill "$MINIO_PID" 2>/dev/null
|
|
wait "$MINIO_PID" 2>/dev/null
|
|
fi
|
|
if [[ -n "$POSTGRES_CONTAINER" ]]; then
|
|
docker rm -f "$POSTGRES_CONTAINER" >/dev/null 2>&1
|
|
fi
|
|
if [[ -n "$REDIS_CONTAINER" ]]; then
|
|
docker rm -f "$REDIS_CONTAINER" >/dev/null 2>&1
|
|
fi
|
|
rm -rf "$WORK_DIR"
|
|
exit "$status"
|
|
}
|
|
trap cleanup EXIT INT TERM
|
|
|
|
wait_for_command() {
|
|
local description=$1
|
|
shift
|
|
for _ in $(seq 1 60); do
|
|
if "$@" >/dev/null 2>&1; then
|
|
return 0
|
|
fi
|
|
sleep 1
|
|
done
|
|
echo "Timed out waiting for ${description}" >&2
|
|
return 1
|
|
}
|
|
|
|
if [[ -z "${IMAGEFORGE_TEST_DATABASE_URL:-}" || -z "${IMAGEFORGE_TEST_REDIS_URL:-}" ]]; then
|
|
if ! command -v docker >/dev/null 2>&1; then
|
|
echo "Set IMAGEFORGE_TEST_DATABASE_URL and IMAGEFORGE_TEST_REDIS_URL, or install Docker." >&2
|
|
exit 1
|
|
fi
|
|
|
|
suffix="$$-${RANDOM}"
|
|
postgres_port="${IMAGEFORGE_TEST_POSTGRES_PORT:-25432}"
|
|
redis_port="${IMAGEFORGE_TEST_REDIS_PORT:-26379}"
|
|
POSTGRES_CONTAINER="imageforge-test-postgres-${suffix}"
|
|
REDIS_CONTAINER="imageforge-test-redis-${suffix}"
|
|
|
|
docker run -d \
|
|
--label imageforge.external-tests=true \
|
|
--name "$POSTGRES_CONTAINER" \
|
|
-e POSTGRES_PASSWORD=codex_test \
|
|
-e POSTGRES_DB=imageforge_test \
|
|
-p "127.0.0.1:${postgres_port}:5432" \
|
|
postgres:16-alpine >/dev/null
|
|
docker run -d \
|
|
--label imageforge.external-tests=true \
|
|
--name "$REDIS_CONTAINER" \
|
|
-p "127.0.0.1:${redis_port}:6379" \
|
|
redis:7-alpine >/dev/null
|
|
|
|
wait_for_command PostgreSQL docker exec "$POSTGRES_CONTAINER" \
|
|
pg_isready -U postgres -d imageforge_test
|
|
wait_for_command Redis docker exec "$REDIS_CONTAINER" redis-cli ping
|
|
|
|
export IMAGEFORGE_TEST_DATABASE_URL="postgres://postgres:codex_test@127.0.0.1:${postgres_port}/imageforge_test"
|
|
export IMAGEFORGE_TEST_REDIS_URL="redis://127.0.0.1:${redis_port}/"
|
|
fi
|
|
|
|
arch="$(uname -m)"
|
|
case "$arch" in
|
|
x86_64) minio_arch=amd64 ;;
|
|
aarch64|arm64) minio_arch=arm64 ;;
|
|
*) echo "Unsupported MinIO architecture: ${arch}" >&2; exit 1 ;;
|
|
esac
|
|
|
|
default_minio_bin="${WORK_DIR}/minio"
|
|
default_mc_bin="${WORK_DIR}/mc"
|
|
if command -v minio >/dev/null 2>&1; then
|
|
default_minio_bin="$(command -v minio)"
|
|
fi
|
|
if command -v mc >/dev/null 2>&1; then
|
|
default_mc_bin="$(command -v mc)"
|
|
fi
|
|
MINIO_BIN="${MINIO_BIN:-${default_minio_bin}}"
|
|
MC_BIN="${MC_BIN:-${default_mc_bin}}"
|
|
|
|
download_tool() {
|
|
local url=$1
|
|
local output=$2
|
|
local partial="${output}.part"
|
|
curl --fail --silent --show-error --location \
|
|
--retry 10 --retry-all-errors --retry-delay 2 --connect-timeout 20 \
|
|
--continue-at - --output "$partial" "$url"
|
|
mv "$partial" "$output"
|
|
chmod +x "$output"
|
|
}
|
|
|
|
if [[ ! -x "$MINIO_BIN" ]]; then
|
|
download_tool \
|
|
"https://dl.min.io/server/minio/release/linux-${minio_arch}/minio" \
|
|
"$MINIO_BIN"
|
|
fi
|
|
if [[ ! -x "$MC_BIN" ]]; then
|
|
download_tool \
|
|
"https://dl.min.io/client/mc/release/linux-${minio_arch}/mc" \
|
|
"$MC_BIN"
|
|
fi
|
|
|
|
export IMAGEFORGE_TEST_S3_ENDPOINT="${IMAGEFORGE_TEST_S3_ENDPOINT:-http://127.0.0.1:19000}"
|
|
export IMAGEFORGE_TEST_S3_BUCKET="${IMAGEFORGE_TEST_S3_BUCKET:-imageforge-test}"
|
|
export IMAGEFORGE_TEST_S3_ACCESS_KEY="${IMAGEFORGE_TEST_S3_ACCESS_KEY:-codexminio}"
|
|
export IMAGEFORGE_TEST_S3_SECRET_KEY="${IMAGEFORGE_TEST_S3_SECRET_KEY:-codexminio123}"
|
|
|
|
if [[ "$IMAGEFORGE_TEST_S3_ENDPOINT" == "http://127.0.0.1:19000" ]]; then
|
|
MINIO_ROOT_USER="$IMAGEFORGE_TEST_S3_ACCESS_KEY" \
|
|
MINIO_ROOT_PASSWORD="$IMAGEFORGE_TEST_S3_SECRET_KEY" \
|
|
"$MINIO_BIN" server "${WORK_DIR}/minio-data" \
|
|
--address 127.0.0.1:19000 >"${WORK_DIR}/minio.log" 2>&1 &
|
|
MINIO_PID=$!
|
|
wait_for_command MinIO curl --fail --silent \
|
|
"${IMAGEFORGE_TEST_S3_ENDPOINT}/minio/health/ready"
|
|
fi
|
|
|
|
"$MC_BIN" alias set imageforge-test \
|
|
"$IMAGEFORGE_TEST_S3_ENDPOINT" \
|
|
"$IMAGEFORGE_TEST_S3_ACCESS_KEY" \
|
|
"$IMAGEFORGE_TEST_S3_SECRET_KEY" >/dev/null
|
|
"$MC_BIN" mb --ignore-existing \
|
|
"imageforge-test/${IMAGEFORGE_TEST_S3_BUCKET}" >/dev/null
|
|
|
|
export DATABASE_URL="$IMAGEFORGE_TEST_DATABASE_URL"
|
|
export REDIS_URL="$IMAGEFORGE_TEST_REDIS_URL"
|
|
export JWT_SECRET="${JWT_SECRET:-imageforge-external-test-jwt-secret}"
|
|
export API_KEY_PEPPER="${API_KEY_PEPPER:-imageforge-external-test-api-key-pepper}"
|
|
|
|
test_log="${WORK_DIR}/external-tests.log"
|
|
cargo test --all-targets --locked -- \
|
|
--ignored --test-threads=1 --nocapture 2>&1 | tee "$test_log"
|
|
|
|
expected_summary="test result: ok. ${EXPECTED_EXTERNAL_TESTS} passed; 0 failed; 0 ignored;"
|
|
if ! grep --fixed-strings --quiet "$expected_summary" "$test_log"; then
|
|
echo "External-state test count mismatch; expected: ${expected_summary}" >&2
|
|
exit 1
|
|
fi
|
|
|
|
echo "External-state gate passed: ${EXPECTED_EXTERNAL_TESTS} passed, 0 failed, 0 ignored."
|