#!/usr/bin/env bash set -euo pipefail DEFAULT_BASE_URL="http://localhost:${BACKEND_PORT:-8000}" BASE_URL="${SMOKE_BASE_URL:-$DEFAULT_BASE_URL}" GLOBAL_TOKEN="${SMOKE_TOKEN:-}" USER_A="${SMOKE_USER_A:-admin}" PASS_A="${SMOKE_PASSWORD_A:-admin123}" USER_B="${SMOKE_USER_B:-boss}" PASS_B="${SMOKE_PASSWORD_B:-boss123}" login_token() { local user="$1" local pass="$2" local raw raw="$(curl -fsS -X POST "$BASE_URL/auth/login" \ -H 'Content-Type: application/x-www-form-urlencoded' \ --data "username=${user}&password=${pass}")" echo "$raw" | sed -n 's/.*"access_token":"\([^"]*\)".*/\1/p' } ask_with_token() { local token="$1" local question="$2" curl -fsS -X POST "$BASE_URL/rag/ask" \ -H "Authorization: Bearer $token" \ -H 'Content-Type: application/json' \ -d "{\"question\":\"$question\",\"asked_via\":\"pmflow\"}" } if [[ -n "$GLOBAL_TOKEN" ]]; then TOKEN_A="$GLOBAL_TOKEN" TOKEN_B="$GLOBAL_TOKEN" else TOKEN_A="$(login_token "$USER_A" "$PASS_A")" TOKEN_B="$(login_token "$USER_B" "$PASS_B")" fi if [[ -z "${TOKEN_A:-}" || -z "${TOKEN_B:-}" ]]; then echo "[FAIL] login/token missing" exit 2 fi # 链路 A:项目 count -> 项目 list q1="$(ask_with_token "$TOKEN_A" '目前系统里面有多少个项目')" q2="$(ask_with_token "$TOKEN_A" '分别是什么')" # 链路 B:项目信号 count -> 信号 list q3="$(ask_with_token "$TOKEN_B" '健身食谱项目里面有多少个信号源')" q4="$(ask_with_token "$TOKEN_B" '分别什么信号源')" assert_contains() { local text="$1" local pattern="$2" local label="$3" if ! echo "$text" | grep -q "$pattern"; then echo "[FAIL] $label missing pattern: $pattern" echo "$text" | head -c 400 exit 2 fi } assert_contains "$q1" '"query_type":"count"' 'q1' assert_contains "$q1" '项目总数' 'q1' assert_contains "$q2" '"query_type":"list"' 'q2' assert_contains "$q2" '项目列表' 'q2' assert_contains "$q3" '"query_type":"count"' 'q3' assert_contains "$q3" '信号' 'q3' assert_contains "$q4" '"query_type":"list"' 'q4' assert_contains "$q4" '信号' 'q4' echo '[OK] rag followup smoke passed'