Files
ystp/scripts/run_external_state_tests.sh
237899745 cdec19977c
Some checks failed
CI / verify (push) Has been cancelled
ci: require all external state tests
2026-07-26 10:54:22 +08:00

153 lines
4.8 KiB
Bash

#!/usr/bin/env bash
set -Eeuo pipefail
EXPECTED_EXTERNAL_TESTS="${EXPECTED_EXTERNAL_TESTS:-13}"
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."