#!/bin/bash # 全路径冒烟:register/login → token → 依次打全部接口,断言 HTTP 200 + code 符合预期 # 用法:bash scripts/smoke.sh # 约定:check_code 第三参 = 允许的降级 code 列表(逗号分隔,默认只许 0) set -e BASE="${BASE:-http://localhost:3007}" FAIL=0 say() { echo "[smoke] $*"; } fail() { echo "[smoke] FAIL: $*"; FAIL=1; } check_code() { local name="$1" body="$2" allow="$3" local code code=$(echo "$body" | python3 -c "import json,sys; print(json.load(sys.stdin).get('code','?'))" 2>/dev/null || echo "?") if [ "$code" = "0" ] || echo ",$allow," | grep -q ",$code,"; then say "OK: $name" else fail "$name: unexpected code=$code (allow: $allow) body=$(echo "$body" | head -c 200)" fi } # 1. 注册 + 登录拿 token USER="smoke_$(date +%s)" REG=$(curl -s -X POST "$BASE/user/register" -H 'Content-Type: application/json' -d "{\"account\":\"$USER\",\"password\":\"smoketest123\"}") say "register: $(echo "$REG" | head -c 120)" LOGIN=$(curl -s -X POST "$BASE/user/login" -H 'Content-Type: application/json' -d "{\"account\":\"$USER\",\"password\":\"smoketest123\"}") TOKEN=$(echo "$LOGIN" | python3 -c "import json,sys; print(json.load(sys.stdin).get('data',{}).get('token',''))" 2>/dev/null) if [ -z "$TOKEN" ]; then fail "login: no token in $(echo "$LOGIN" | head -c 200)" exit 1 fi say "login OK, token len=${#TOKEN}" AUTH="Authorization: Bearer $TOKEN" # 2. GET 接口(第三参允许的 code:50=未开通/降级/无数据) for item in \ "GET /user/profile 0" \ "GET /user-photo/list 0" \ "GET /wardrobe/list 0" \ "GET /body-measurement/get 0" \ "GET /avatar/get 0" \ "GET /hairstyle/list 0" \ "GET /outfit/task/status?task_id=0 50" \ "GET /outfit/plan/list 0" \ "GET /partner-store/list 0" \ "GET /member/plan/list 0" \ "GET /member/status 0" \ "GET /cps/category/list 0" \ "GET /cps/product/list?source=meituan_ota&category_code=beauty 0" \ "GET /cps/plan/recommend?plan_id=0&scene=haircut 50" \ "GET /cps/wardrobe/upgrade?item_id=0 50" \ "GET /cps/my/recent 0" ; do set -- $item METHOD="$1"; PATH_="$2"; ALLOW="${3:-0}" RESP=$(curl -s -X "$METHOD" "$BASE$PATH_" -H "$AUTH") check_code "$PATH_" "$RESP" "$ALLOW" done # 3. POST 接口 post_check() { local name="$1" json="$2" allow="${3:-0}" local resp resp=$(curl -s -X POST "$BASE$name" -H "$AUTH" -H 'Content-Type: application/json' -d "$json") check_code "$name" "$resp" "$allow" } post_check "/body-measurement/save" '{"height_cm":175,"weight_kg":65}' post_check "/outfit/plan/review" '{"plan_id":0,"action":"fav"}' "50" post_check "/member/order/create" '{"plan_id":1}' "50" post_check "/ad/reward/claim" '{"ad_type":"effect_extra"}' "50" post_check "/outfit/generate" '{"start_date":"2026-08-01","end_date":"2026-08-07","location":"上海"}' "50" post_check "/cps/product/link" '{"product_id":0,"scene":"item_buy"}' "50,51" post_check "/user/change-password" '{"old_password":"smoketest123","new_password":"smoketest456"}' # 4. 裸回调(无鉴权;no_order 预期返回 fail) NOTIFY=$(curl -s -X POST "$BASE/member/order/notify" -H 'Content-Type: application/x-www-form-urlencoded' -d 'out_trade_no=nonexist&trade_no=x&amount=0&status=paid') say "notify(no_order)=$NOTIFY" # 5. workspace 静态文件 WS=$(curl -s -o /dev/null -w "%{http_code}" "$BASE/workspace/nonexist.png" -H "$AUTH") say "workspace/404: $WS" if [ "$FAIL" = "0" ]; then say "ALL SMOKE PASS" else say "SMOKE HAS FAILURES" exit 1 fi