#!/bin/bash # ============================================ # 丹阳公益婚恋服务平台 — 生产上线冒烟测试(骨架) # ============================================ # 设计纪律(沿用项目「断言 ≠ 证据 / 不假绿」原则): # - 任一 FAIL 立即退出 1;脚本不做「skip 伪装通过」。 # - 需登录的核心链路默认不跑;提供 OPERATOR_TOKEN / USER_TOKEN 后才展开, # 未提供时明确打印「需人工真机验证」,不静默报绿。 # - 本脚本只覆盖「上线前可自动探活」的子集;13 项完整人工清单见 # docs/PHASE26-GO-LIVE-CHECKLIST.md。 set -uo pipefail BASE_URL="${BASE_URL:-https://match.danyang.gov.cn}" API="${BASE_URL%/}/api/v1" PASS=0 FAIL=0 WARN=0 # check_status NAME URL EXPECTED_CODE check_status() { local name="$1" url="$2" expected="$3" local code code=$(curl -sS -o /dev/null -w "%{http_code}" "${url}" 2>/dev/null || echo "000") if [ "$code" = "$expected" ]; then PASS=$((PASS + 1)); echo " ✅ $name (HTTP $code)" else FAIL=$((FAIL + 1)); echo " ❌ $name (期望 $expected, 实际 $code) — $url" fi } # check_auth_reject NAME URL — 未带凭证必须 401 check_auth_reject() { local name="$1" url="$2" local code code=$(curl -sS -o /dev/null -w "%{http_code}" "${url}" 2>/dev/null || echo "000") if [ "$code" = "401" ]; then PASS=$((PASS + 1)); echo " ✅ $name (未认证 401)" else FAIL=$((FAIL + 1)); echo " ❌ $name (期望 401, 实际 $code) — $url" fi } # guarded NAME URL TOKEN — 带 token 探活,期望 2xx guarded() { local name="$1" url="$2" token="$3" local code code=$(curl -fsS -H "Authorization: Bearer ${token}" -o /dev/null -w "%{http_code}" "${url}" 2>/dev/null || echo "000") if [ "$code" = "200" ]; then PASS=$((PASS + 1)); echo " ✅ $name (HTTP 200)" else FAIL=$((FAIL + 1)); echo " ❌ $name (期望 200, 实际 $code) — $url" fi } echo "============================================" echo " 丹阳公益婚恋平台 — 生产冒烟测试" echo " $(date '+%Y-%m-%d %H:%M:%S') BASE_URL=$BASE_URL" echo "============================================" echo "" echo "【1. 健康检查】" check_status "后端 live" "${API}/health/live" "200" check_status "后端 ready" "${API}/health/ready" "200" check_status "版本信息" "${BASE_URL%/}/version" "200" echo "" echo "【2. 匿名鉴权守卫(应 401)】" check_auth_reject "微信登录缺参" "${API}/auth/wechat/login" check_auth_reject "用户资料未认证" "${API}/me/profile" check_auth_reject "择偶条件未认证" "${API}/me/preferences" check_auth_reject "推荐列表未认证" "${API}/matches/recommendations" check_auth_reject "运营用户列表" "${API}/operator/users" check_auth_reject "举报提交" "${API}/risk/reports" echo "" echo "【3. 安全接口(应 401,不泄露)】" check_auth_reject "管理端统计" "${API}/operator/analytics/v11-dashboard" echo "" echo "【4. Nginx / 入口】" check_status "Nginx 根路径" "${BASE_URL%/}/" "200" check_status "管理端子路径" "${BASE_URL%/}/admin/" "200" # ---- 需登录链路:仅在提供 token 时展开 ---- if [ -n "${OPERATOR_TOKEN:-}" ]; then echo "" echo "【5. 运营端核心链路(已提供 OPERATOR_TOKEN)】" guarded "运营用户列表" "${API}/operator/users" "${OPERATOR_TOKEN}" guarded "管理端统计" "${API}/operator/analytics/v11-dashboard" "${OPERATOR_TOKEN}" else WARN=$((WARN + 1)) echo "" echo " ⚠️ 未提供 OPERATOR_TOKEN:运营端/用户端需登录链路(推荐·匹配·聊天·活动·咨询·红娘·内容·照片 presigned)" echo " 跳过自动探测,请按 docs/PHASE26-GO-LIVE-CHECKLIST.md 第 2~13 项真机/管理端人工验证。" fi if [ -n "${USER_TOKEN:-}" ]; then echo "" echo "【6. 用户端核心链路(已提供 USER_TOKEN)】" guarded "我的资料" "${API}/me/profile" "${USER_TOKEN}" guarded "择偶条件" "${API}/me/preferences" "${USER_TOKEN}" guarded "推荐列表" "${API}/matches/recommendations" "${USER_TOKEN}" else WARN=$((WARN + 1)) echo "" echo " ⚠️ 未提供 USER_TOKEN:用户端核心链路跳过(同上,需人工真机验证)。" fi echo "" echo "============================================" echo " 结果: PASS=${PASS} FAIL=${FAIL} WARN=${WARN}" echo "============================================" if [ "${FAIL}" -ne 0 ]; then echo "❌ 冒烟存在 ${FAIL} 个失败项,未通过" exit 1 fi if [ "${WARN}" -ne 0 ]; then echo "⚠️ 自动探活通过,但 ${WARN} 类需登录链路未覆盖(见上方 ⚠️),上线前须人工确认。" fi echo "✅ 冒烟自动探活通过" exit 0