#!/usr/bin/env bash # 一鍵 E2E:全新 Docker → index → seed → 起 Gateway → 跑測試 → 關閉並清 volume # # 環境變數: # E2E_KEEP_DOCKER=1 跑完不 docker compose down -v(方便查 Mongo/Redis) # E2E_WITH_SMTP=1 額外起 MailHog(http://localhost:8025)方便肉眼看寄信 # E2E_CONFIG=... 預設 test/e2e/fixtures/e2e.yaml # E2E_TEST_PATTERN 第一輪 go test -run pattern set -euo pipefail ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" # shellcheck source=scripts/e2e-lib.sh source "${ROOT}/scripts/e2e-lib.sh" cd "$ROOT" E2E_CONFIG="${E2E_CONFIG:-test/e2e/fixtures/e2e.yaml}" E2E_STATE="${E2E_STATE:-${ROOT}/test/e2e/fixtures/state.json}" E2E_MODE="${E2E_MODE:-contract}" # contract / journey E2E_TEST_PATTERN="${E2E_TEST_PATTERN:-Test(Auth_|Health|Member|Permission)}" E2E_TEST_PATTERN_ZZZ="${E2E_TEST_PATTERN_ZZZ:-TestZZZ_AuthTokenRefreshAndLogout}" GATEWAY_PORT="${GATEWAY_PORT:-18888}" PID_FILE="${PID_FILE:-${ROOT}/test/e2e/fixtures/gateway.pid}" E2E_WITH_SMTP="${E2E_WITH_SMTP:-}" cleanup() { e2e_stop_gateway "${GATEWAY_PORT}" "${PID_FILE}" if [[ "${E2E_KEEP_DOCKER:-}" != "1" ]]; then e2e_info "docker compose down -v(如要保留資料:E2E_KEEP_DOCKER=1)" docker compose down -v >/dev/null 2>&1 || docker compose --profile smtp down -v >/dev/null 2>&1 || true else e2e_warn "E2E_KEEP_DOCKER=1:容器繼續運行" fi } trap cleanup EXIT TOTAL_STEPS=6 e2e_step "1/${TOTAL_STEPS}" "fresh docker compose(mongo + redis$( [[ "$E2E_WITH_SMTP" == "1" ]] && echo " + mailhog" ))" docker compose down -v >/dev/null 2>&1 || true if [[ "$E2E_WITH_SMTP" == "1" ]]; then docker compose --profile smtp up -d mongo redis mailhog else docker compose up -d mongo redis fi e2e_step "2/${TOTAL_STEPS}" "wait for healthcheck" for i in $(seq 1 60); do if docker compose ps mongo 2>/dev/null | grep -q "(healthy)" && docker compose ps redis 2>/dev/null | grep -q "(healthy)"; then e2e_ok "mongo / redis healthy(${i}s)" break fi sleep 1 if [[ "$i" -eq 60 ]]; then echo "timeout waiting for docker health" >&2 docker compose ps >&2 exit 1 fi done e2e_step "3/${TOTAL_STEPS}" "建立 Mongo 索引(cmd/mongo-index)" go run ./cmd/mongo-index -f "${E2E_CONFIG}" e2e_ok "indexes ready" e2e_step "4/${TOTAL_STEPS}" "seed tenant + member + permission + JWT(cmd/e2e-seed)" rm -f "${E2E_STATE}" seed_args=(-f "${E2E_CONFIG}" -out "${E2E_STATE}") if [[ -n "${E2E_ROLE:-}" ]]; then seed_args+=(-role "${E2E_ROLE}") fi go run ./cmd/e2e-seed "${seed_args[@]}" e2e_ok "state.json written → ${E2E_STATE}" e2e_step "5/${TOTAL_STEPS}" "啟動 Gateway(:${GATEWAY_PORT})" e2e_start_gateway "${ROOT}" "${E2E_CONFIG}" "${GATEWAY_PORT}" "${PID_FILE}" >/dev/null e2e_wait_gateway "${GATEWAY_PORT}" e2e_ok "gateway up" e2e_print_services "$E2E_WITH_SMTP" case "${E2E_MODE}" in journey) step6_title="跑 E2E user journeys(每步驟印 ▶ [J-x.y] 中文情境,斷一步停整 journey)" ;; *) step6_title="跑 E2E contract tests(每個測試印 ▶ [ID] METHOD path — 中文情境)" ;; esac e2e_step "6/${TOTAL_STEPS}" "${step6_title}" e2e_info "第一輪:pattern=${E2E_TEST_PATTERN}" GATEWAY_E2E=1 E2E_STATE_FILE="${E2E_STATE}" E2E_BASE_URL="http://127.0.0.1:${GATEWAY_PORT}" \ go test -tags=e2e -v -count=1 ./test/e2e/... -run "${E2E_TEST_PATTERN}" e2e_info "第二輪:pattern=${E2E_TEST_PATTERN_ZZZ}(會撤銷 JWT,故最後跑)" GATEWAY_E2E=1 E2E_STATE_FILE="${E2E_STATE}" E2E_BASE_URL="http://127.0.0.1:${GATEWAY_PORT}" \ go test -tags=e2e -v -count=1 ./test/e2e/... -run "${E2E_TEST_PATTERN_ZZZ}" echo e2e_ok "E2E OK"