Files
AIRegulation-Deployment/scripts/07_smoke_test.sh
2026-04-23 09:58:47 +08:00

184 lines
7.8 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env bash
# ══════════════════════════════════════════════════
# 07_smoke_test.sh
# 端到端冒烟测试:验证三条业务闭环
# 用法bash scripts/07_smoke_test.sh
# ══════════════════════════════════════════════════
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
cd "$PROJECT_DIR"
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; BLUE='\033[0;34m'; NC='\033[0m'
info() { echo -e "${BLUE}[INFO]${NC} $*"; }
ok() { echo -e "${GREEN}[✓]${NC} $*"; }
fail() { echo -e "${RED}[✗]${NC} $*"; FAILED=$((FAILED+1)); }
warn() { echo -e "${YELLOW}[~]${NC} $*"; }
FAILED=0
API_BASE="http://localhost"
echo ""
echo -e "${BLUE}══════════════════════════════════════════${NC}"
echo -e "${BLUE} AI合规智能中枢 端到端冒烟测试${NC}"
echo -e "${BLUE}══════════════════════════════════════════${NC}"
echo ""
# ── 基础健康检查 ────────────────────────────────
info "=== 基础设施健康检查 ==="
check_service() {
local name=$1; local url=$2
if curl -sf "$url" > /dev/null 2>&1; then
ok "$name"
else
fail "$name$url 不可达)"
fi
}
check_service "API 网关 (Nginx)" "http://localhost/health"
check_service "业务后端 (FastAPI)" "http://localhost:8000/health"
check_service "嵌入服务 (BGE-M3)" "http://localhost:8010/health"
check_service "解析服务 (MinerU)" "http://localhost:8011/health"
check_service "Milvus HTTP" "http://localhost:9091/healthz"
check_service "Neo4j Browser" "http://localhost:7474"
echo ""
# ── 嵌入服务测试 ────────────────────────────────
info "=== 嵌入服务测试 ==="
EMBED_RESP=$(curl -sf -X POST http://localhost:8010/embed \
-H "Content-Type: application/json" \
-d '{"texts": ["GB 18384 电动汽车碰撞安全要求"], "batch_size": 1}' 2>/dev/null || echo "{}")
if echo "$EMBED_RESP" | python3 -c "import sys,json; d=json.load(sys.stdin); assert len(d.get('dense',[])[0])==1024" 2>/dev/null; then
ok "BGE-M3 嵌入:返回 1024 维向量"
else
fail "BGE-M3 嵌入失败,响应:${EMBED_RESP:0:200}"
fi
echo ""
# ── 创建测试 PDF ────────────────────────────────
info "=== 创建测试文档 ==="
TEST_PDF="$PROJECT_DIR/data/uploads/test_regulation.txt"
cat > "$TEST_PDF" << 'EOF'
GB 18384-2020 电动汽车安全要求
第一章 总则
本标准规定了电动汽车的安全要求适用于M1类纯电动汽车。
第二章 电气安全
2.1 绝缘电阻要求
直流电路绝缘电阻不得低于100Ω/V。
2.2 碰撞安全
车辆碰撞后,高压电系统应自动断电。
碰撞后5秒内高压系统电压应降至60V以下。
第三章 防水要求
高压系统防护等级应达到IP67。
EOF
ok "测试文档创建:$TEST_PDF"
echo ""
# ── 闭环①:文件上传 → 向量化 → 问答 ───────────
info "=== 闭环①:法规入库 → 检索问答 ==="
# 创建工作空间
WORKSPACE_RESP=$(curl -sf -X POST "$API_BASE/api/kb/workspaces" \
-H "Content-Type: application/json" \
-d '{"name": "测试法规库", "domain": "vehicle_safety"}' 2>/dev/null || echo "{}")
WS_ID=$(echo "$WORKSPACE_RESP" | python3 -c "import sys,json; print(json.load(sys.stdin).get('id',''))" 2>/dev/null || echo "")
if [[ -n "$WS_ID" ]]; then
ok "工作空间创建:$WS_ID"
else
warn "工作空间创建失败(可能接口未完全实现),跳过后续上传测试"
WS_ID="test-workspace"
fi
# 上传文件
UPLOAD_RESP=$(curl -sf -X POST "$API_BASE/api/kb/files/upload" \
-F "file=@$TEST_PDF" \
-F "workspace_id=$WS_ID" 2>/dev/null || echo "{}")
TASK_ID=$(echo "$UPLOAD_RESP" | python3 -c "import sys,json; print(json.load(sys.stdin).get('task_id',''))" 2>/dev/null || echo "")
if [[ -n "$TASK_ID" ]]; then
ok "文件上传任务已创建:$TASK_ID"
# 轮询任务状态最多等待120秒
info "等待向量化完成..."
for i in {1..24}; do
TASK_STATUS=$(curl -sf "$API_BASE/api/kb/tasks/$TASK_ID" 2>/dev/null | \
python3 -c "import sys,json; print(json.load(sys.stdin).get('status','unknown'))" 2>/dev/null || echo "unknown")
if [[ "$TASK_STATUS" == "completed" ]]; then
ok "向量化完成(${i}×5s"
break
elif [[ "$TASK_STATUS" == "failed" ]]; then
fail "向量化失败"
break
fi
echo -n "."
sleep 5
done
echo ""
# 检索问答
QA_RESP=$(curl -sf -X POST "$API_BASE/api/kb/qa" \
-H "Content-Type: application/json" \
-d "{\"query\": \"碰撞后高压系统电压要求\", \"workspace_id\": \"$WS_ID\", \"top_k\": 3}" 2>/dev/null || echo "{}")
ANSWER=$(echo "$QA_RESP" | python3 -c "import sys,json; print(json.load(sys.stdin).get('answer','')[:100])" 2>/dev/null || echo "")
if [[ -n "$ANSWER" ]]; then
ok "问答成功:${ANSWER}..."
else
warn "问答返回空LLM API 可能未配置或响应缓慢)"
fi
else
warn "文件上传失败(接口可能未实现)"
fi
echo ""
# ── 闭环②:合规审查 ────────────────────────────
info "=== 闭环②:文档上传 → 合规审查 ==="
CHECK_RESP=$(curl -sf -X POST "$API_BASE/api/compliance/check" \
-H "Content-Type: application/json" \
-d '{"query": "供应商文件是否符合GB 18384碰撞安全要求", "domains": ["vehicle_safety"]}' 2>/dev/null || echo "{}")
RISK=$(echo "$CHECK_RESP" | python3 -c "import sys,json; print(json.load(sys.stdin).get('risk_level','unknown'))" 2>/dev/null || echo "unknown")
if [[ "$RISK" != "unknown" && -n "$RISK" ]]; then
ok "合规审查完成,风险等级:$RISK"
else
warn "合规审查接口返回空(功能可能未完全实现)"
fi
echo ""
# ── 闭环③:法规监控 ────────────────────────────
info "=== 闭环③:法规监控源配置 ==="
SOURCE_RESP=$(curl -sf -X POST "$API_BASE/api/regulation/sources" \
-H "Content-Type: application/json" \
-d '{"name": "测试监控源", "url": "https://std.samr.gov.cn", "domain": "vehicle_safety"}' 2>/dev/null || echo "{}")
SOURCE_ID=$(echo "$SOURCE_RESP" | python3 -c "import sys,json; print(json.load(sys.stdin).get('id',''))" 2>/dev/null || echo "")
if [[ -n "$SOURCE_ID" ]]; then
ok "监控源配置成功:$SOURCE_ID"
else
warn "监控源配置返回空(功能可能未完全实现)"
fi
echo ""
# ── 汇总 ────────────────────────────────────────
echo ""
echo -e "${BLUE}══════════════════════════════════════════${NC}"
if [[ $FAILED -eq 0 ]]; then
echo -e "${GREEN} 全部检查通过!${NC}"
else
echo -e "${YELLOW} 完成,${FAILED} 项失败${NC}(部分功能可能尚未实现)"
fi
echo -e "${BLUE}══════════════════════════════════════════${NC}"
echo ""
echo "查看服务日志:"
echo " docker compose logs -f compliance-backend"
echo " docker compose logs -f celery-worker"