Files
zclaw_openfang/scripts/tests/real-integration-test.sh
iven 0d4fa96b82
Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
refactor: 统一项目名称从OpenFang到ZCLAW
重构所有代码和文档中的项目名称,将OpenFang统一更新为ZCLAW。包括:
- 配置文件中的项目名称
- 代码注释和文档引用
- 环境变量和路径
- 类型定义和接口名称
- 测试用例和模拟数据

同时优化部分代码结构,移除未使用的模块,并更新相关依赖项。
2026-03-27 07:36:03 +08:00

480 lines
15 KiB
Bash
Raw Permalink 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.

#!/bin/bash
# ZCLAW 真实环境集成测试
# 连接真实 ZCLAW Kernel 验证完整数据流
#
# 使用方法:
# 1. 确保 ZCLAW Kernel 正在运行: zclaw start
# 2. 设置 API Key: export ZHIPU_API_KEY=your_key
# 3. 运行测试: ./scripts/tests/real-integration-test.sh
set -e
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
# 配置
GATEWAY_HOST="${GATEWAY_HOST:-127.0.0.1}"
GATEWAY_PORT="${GATEWAY_PORT:-50051}"
GATEWAY_URL="http://$GATEWAY_HOST:$GATEWAY_PORT"
RESULTS_DIR="test-results/integration"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
LOG_FILE="$RESULTS_DIR/integration_$TIMESTAMP.log"
# 测试计数器
TESTS_RUN=0
TESTS_PASSED=0
TESTS_FAILED=0
TESTS_SKIPPED=0
# 创建结果目录
mkdir -p "$RESULTS_DIR"
# 日志函数
log() {
echo -e "$1" | tee -a "$LOG_FILE"
}
log_test() {
local id="$1"
local description="$2"
local status="$3"
local details="${4:-}"
TESTS_RUN=$((TESTS_RUN + 1))
case "$status" in
PASS)
TESTS_PASSED=$((TESTS_PASSED + 1))
log "${GREEN}✅ [$id] $description${NC}"
;;
FAIL)
TESTS_FAILED=$((TESTS_FAILED + 1))
log "${RED}❌ [$id] $description${NC}"
;;
SKIP)
TESTS_SKIPPED=$((TESTS_SKIPPED + 1))
log "${YELLOW}⏭️ [$id] $description (跳过)${NC}"
;;
esac
if [ -n "$details" ]; then
echo " $details" | tee -a "$LOG_FILE"
fi
}
# 检查命令是否存在
check_command() {
command -v "$1" >/dev/null 2>&1
}
# HTTP 请求辅助函数
http_get() {
curl -s -w "\n%{http_code}" "$1" 2>/dev/null
}
http_post() {
curl -s -w "\n%{http_code}" -X POST -H "Content-Type: application/json" -d "$2" "$1" 2>/dev/null
}
# =============================================================================
# 测试开始
# =============================================================================
log "${BLUE}========================================${NC}"
log "${BLUE} ZCLAW 真实环境集成测试${NC}"
log "${BLUE}========================================${NC}"
log ""
log "测试时间: $(date)"
log "Gateway URL: $GATEWAY_URL"
log "日志文件: $LOG_FILE"
log ""
# =============================================================================
# 1. 环境检查
# =============================================================================
log "${YELLOW}[1. 环境检查]${NC}"
# RI-ENV-01: 检查 curl
if check_command curl; then
log_test "RI-ENV-01" "curl 可用" "PASS"
else
log_test "RI-ENV-01" "curl 可用" "FAIL" "需要安装 curl"
exit 1
fi
# RI-ENV-02: 检查 jq (可选,用于 JSON 解析)
if check_command jq; then
log_test "RI-ENV-02" "jq 可用" "PASS"
HAS_JQ=true
else
log_test "RI-ENV-02" "jq 可用" "SKIP" "建议安装 jq 以获得更好的 JSON 解析"
HAS_JQ=false
fi
# RI-ENV-03: 检查 Node.js
if check_command node; then
NODE_VERSION=$(node -v)
log_test "RI-ENV-03" "Node.js 可用 ($NODE_VERSION)" "PASS"
else
log_test "RI-ENV-03" "Node.js 可用" "FAIL" "需要安装 Node.js"
exit 1
fi
log ""
# =============================================================================
# 2. Gateway 连接测试
# =============================================================================
log "${YELLOW}[2. Gateway 连接测试]${NC}"
# RI-GW-01: 检查端口可达性
if check_command nc; then
if nc -z -w5 "$GATEWAY_HOST" "$GATEWAY_PORT" 2>/dev/null; then
log_test "RI-GW-01" "Gateway 端口 $GATEWAY_PORT 可达" "PASS"
else
log_test "RI-GW-01" "Gateway 端口 $GATEWAY_PORT 可达" "FAIL" "请确保 ZCLAW 正在运行: zclaw start"
fi
else
log_test "RI-GW-01" "Gateway 端口可达性" "SKIP" "nc 命令不可用"
fi
# RI-GW-02: Health 端点
RESPONSE=$(http_get "$GATEWAY_URL/api/health")
HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
BODY=$(echo "$RESPONSE" | sed '$d')
if [ "$HTTP_CODE" = "200" ]; then
log_test "RI-GW-02" "Health 端点返回 200" "PASS" "响应: $BODY"
else
log_test "RI-GW-02" "Health 端点返回 200" "FAIL" "HTTP $HTTP_CODE"
fi
# RI-GW-03: Health 响应结构
if [ "$HTTP_CODE" = "200" ]; then
if echo "$BODY" | grep -q '"status"'; then
log_test "RI-GW-03" "Health 响应包含 status 字段" "PASS"
else
log_test "RI-GW-03" "Health 响应包含 status 字段" "FAIL" "响应: $BODY"
fi
fi
log ""
# =============================================================================
# 3. 模型配置测试
# =============================================================================
log "${YELLOW}[3. 模型配置测试]${NC}"
# RI-MOD-01: 获取可用模型列表
RESPONSE=$(http_get "$GATEWAY_URL/api/models")
HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
BODY=$(echo "$RESPONSE" | sed '$d')
if [ "$HTTP_CODE" = "200" ]; then
log_test "RI-MOD-01" "Models 端点返回 200" "PASS"
# 检查是否有模型
if echo "$BODY" | grep -q '"id"'; then
MODEL_COUNT=$(echo "$BODY" | grep -o '"id"' | wc -l)
log_test "RI-MOD-02" "检测到 $MODEL_COUNT 个可用模型" "PASS"
else
log_test "RI-MOD-02" "检测到可用模型" "FAIL" "响应: $BODY"
fi
else
log_test "RI-MOD-01" "Models 端点返回 200" "FAIL" "HTTP $HTTP_CODE"
log_test "RI-MOD-02" "检测到可用模型" "SKIP"
fi
# RI-MOD-03: 检查中文模型配置
if [ -f "config/chinese-providers.toml" ]; then
log_test "RI-MOD-03" "中文模型配置文件存在" "PASS"
else
log_test "RI-MOD-03" "中文模型配置文件存在" "FAIL" "缺少 config/chinese-providers.toml"
fi
log ""
# =============================================================================
# 4. Agent 管理测试
# =============================================================================
log "${YELLOW}[4. Agent 管理测试]${NC}"
# RI-AGT-01: 获取 Agent 列表
RESPONSE=$(http_get "$GATEWAY_URL/api/agents")
HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
BODY=$(echo "$RESPONSE" | sed '$d')
if [ "$HTTP_CODE" = "200" ]; then
log_test "RI-AGT-01" "Agents 端点返回 200" "PASS"
else
log_test "RI-AGT-01" "Agents 端点返回 200" "FAIL" "HTTP $HTTP_CODE"
fi
# RI-AGT-02: 检查默认 Agent
if [ "$HTTP_CODE" = "200" ]; then
if echo "$BODY" | grep -q '"id"\|"name"'; then
log_test "RI-AGT-02" "检测到 Agent 配置" "PASS"
else
log_test "RI-AGT-02" "检测到 Agent 配置" "FAIL" "响应: $BODY"
fi
fi
log ""
# =============================================================================
# 5. API Key 验证测试
# =============================================================================
log "${YELLOW}[5. API Key 验证测试]${NC}"
# RI-KEY-01: 检查智谱 API Key
if [ -n "$ZHIPU_API_KEY" ]; then
log_test "RI-KEY-01" "智谱 API Key 已设置" "PASS" "长度: ${#ZHIPU_API_KEY} 字符"
else
log_test "RI-KEY-01" "智谱 API Key 已设置" "FAIL" "请设置: export ZHIPU_API_KEY=your_key"
fi
# RI-KEY-02: 检查通义千问 API Key
if [ -n "$DASHSCOPE_API_KEY" ]; then
log_test "RI-KEY-02" "通义千问 API Key 已设置" "PASS"
else
log_test "RI-KEY-02" "通义千问 API Key 已设置" "SKIP" "可选: export DASHSCOPE_API_KEY=your_key"
fi
# RI-KEY-03: 检查 Kimi API Key
if [ -n "$MOONSHOT_API_KEY" ]; then
log_test "RI-KEY-03" "Kimi API Key 已设置" "PASS"
else
log_test "RI-KEY-03" "Kimi API Key 已设置" "SKIP" "可选: export MOONSHOT_API_KEY=your_key"
fi
log ""
# =============================================================================
# 6. 对话功能测试(需要 API Key
# =============================================================================
log "${YELLOW}[6. 对话功能测试]${NC}"
if [ -n "$ZHIPU_API_KEY" ]; then
# RI-CHAT-01: 发送测试消息
TEST_MESSAGE="你好,这是一个测试消息。请简短回复。"
CHAT_PAYLOAD="{\"messages\":[{\"role\":\"user\",\"content\":\"$TEST_MESSAGE\"}],\"model\":\"glm-4-flash\",\"stream\":false}"
log "发送测试消息: $TEST_MESSAGE"
RESPONSE=$(http_post "$GATEWAY_URL/api/chat" "$CHAT_PAYLOAD")
HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
BODY=$(echo "$RESPONSE" | sed '$d')
if [ "$HTTP_CODE" = "200" ]; then
log_test "RI-CHAT-01" "对话请求成功" "PASS"
# 检查响应内容
if echo "$BODY" | grep -q '"content"\|"text"\|"message"'; then
log_test "RI-CHAT-02" "对话响应包含内容" "PASS"
# 显示响应摘要
if [ "$HAS_JQ" = true ]; then
CONTENT=$(echo "$BODY" | jq -r '.content // .text // .message // .choices[0].message.content // empty' 2>/dev/null | head -c 100)
if [ -n "$CONTENT" ]; then
log " 响应摘要: ${CONTENT}..."
fi
fi
else
log_test "RI-CHAT-02" "对话响应包含内容" "FAIL" "响应: $BODY"
fi
else
log_test "RI-CHAT-01" "对话请求成功" "FAIL" "HTTP $HTTP_CODE, 响应: $BODY"
log_test "RI-CHAT-02" "对话响应包含内容" "SKIP"
fi
else
log_test "RI-CHAT-01" "对话请求成功" "SKIP" "需要设置 ZHIPU_API_KEY"
log_test "RI-CHAT-02" "对话响应包含内容" "SKIP"
fi
log ""
# =============================================================================
# 7. Hands 触发测试
# =============================================================================
log "${YELLOW}[7. Hands 触发测试]${NC}"
# RI-HAND-01: 获取可用 Hands
RESPONSE=$(http_get "$GATEWAY_URL/api/hands")
HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
BODY=$(echo "$RESPONSE" | sed '$d')
if [ "$HTTP_CODE" = "200" ]; then
log_test "RI-HAND-01" "Hands 端点返回 200" "PASS"
# 检查可用的 Hands
if echo "$BODY" | grep -q '"name"\|"id"'; then
HAND_COUNT=$(echo "$BODY" | grep -o '"name"' | wc -l)
log_test "RI-HAND-02" "检测到 $HAND_COUNT 个可用 Hands" "PASS"
else
log_test "RI-HAND-02" "检测到可用 Hands" "SKIP" "无 Hands 配置"
fi
else
log_test "RI-HAND-01" "Hands 端点返回 200" "FAIL" "HTTP $HTTP_CODE (端点可能未实现)"
log_test "RI-HAND-02" "检测到可用 Hands" "SKIP"
fi
log ""
# =============================================================================
# 8. 记忆持久化测试
# =============================================================================
log "${YELLOW}[8. 记忆持久化测试]${NC}"
# RI-MEM-01: 检查记忆存储目录
MEMORY_DIR="$HOME/.zclaw/data/memory"
if [ -d "$MEMORY_DIR" ]; then
log_test "RI-MEM-01" "记忆存储目录存在" "PASS"
# 检查记忆文件
MEMORY_COUNT=$(find "$MEMORY_DIR" -name "*.json" 2>/dev/null | wc -l)
if [ "$MEMORY_COUNT" -gt 0 ]; then
log_test "RI-MEM-02" "检测到 $MEMORY_COUNT 个记忆文件" "PASS"
else
log_test "RI-MEM-02" "检测到记忆文件" "SKIP" "尚无记忆数据"
fi
else
log_test "RI-MEM-01" "记忆存储目录存在" "FAIL" "目录: $MEMORY_DIR"
log_test "RI-MEM-02" "检测到记忆文件" "SKIP"
fi
log ""
# =============================================================================
# 9. 配置验证测试
# =============================================================================
log "${YELLOW}[9. 配置验证测试]${NC}"
# RI-CFG-01: 主配置文件
if [ -f "config/config.toml" ]; then
log_test "RI-CFG-01" "主配置文件存在" "PASS"
else
log_test "RI-CFG-01" "主配置文件存在" "FAIL"
fi
# RI-CFG-02: 检查配置文件语法
if [ -f "config/config.toml" ] && check_command node; then
if node -e "const fs = require('fs'); const content = fs.readFileSync('config/config.toml', 'utf-8'); if (content.includes('[') && content.includes('=')) process.exit(0); else process.exit(1);" 2>/dev/null; then
log_test "RI-CFG-02" "主配置文件语法正确" "PASS"
else
log_test "RI-CFG-02" "主配置文件语法正确" "FAIL"
fi
else
log_test "RI-CFG-02" "主配置文件语法正确" "SKIP"
fi
# RI-CFG-03: ZCLAW 配置文件
ZCLAW_CONFIG="$HOME/.zclaw/config.toml"
if [ -f "$ZCLAW_CONFIG" ]; then
log_test "RI-CFG-03" "ZCLAW 配置文件存在" "PASS"
else
log_test "RI-CFG-03" "ZCLAW 配置文件存在" "FAIL" "请运行: zclaw init"
fi
log ""
# =============================================================================
# 10. WebSocket 连接测试
# =============================================================================
log "${YELLOW}[10. WebSocket 连接测试]${NC}"
# RI-WS-01: WebSocket 升级检查
WS_RESPONSE=$(curl -s -i -N \
-H "Connection: Upgrade" \
-H "Upgrade: websocket" \
-H "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==" \
-H "Sec-WebSocket-Version: 13" \
"$GATEWAY_URL/ws" 2>/dev/null | head -1)
if echo "$WS_RESPONSE" | grep -q "101"; then
log_test "RI-WS-01" "WebSocket 升级返回 101" "PASS"
else
log_test "RI-WS-01" "WebSocket 升级返回 101" "SKIP" "可能需要特定端点"
fi
log ""
# =============================================================================
# 11. 前端构建测试
# =============================================================================
log "${YELLOW}[11. 前端构建测试]${NC}"
# RI-UI-01: 检查前端依赖
if [ -d "desktop/node_modules" ]; then
log_test "RI-UI-01" "前端依赖已安装" "PASS"
else
log_test "RI-UI-01" "前端依赖已安装" "FAIL" "请运行: cd desktop && pnpm install"
fi
# RI-UI-02: 检查 Tauri 配置
if [ -f "desktop/src-tauri/tauri.conf.json" ]; then
log_test "RI-UI-02" "Tauri 配置文件存在" "PASS"
else
log_test "RI-UI-02" "Tauri 配置文件存在" "FAIL"
fi
log ""
# =============================================================================
# 测试总结
# =============================================================================
log "${BLUE}========================================${NC}"
log "${BLUE} 测试总结${NC}"
log "${BLUE}========================================${NC}"
log ""
log "总测试数: $TESTS_RUN"
log "${GREEN}通过: $TESTS_PASSED${NC}"
log "${RED}失败: $TESTS_FAILED${NC}"
log "${YELLOW}跳过: $TESTS_SKIPPED${NC}"
log ""
# 生成 JSON 报告
REPORT_FILE="$RESULTS_DIR/report_$TIMESTAMP.json"
cat > "$REPORT_FILE" << EOF
{
"timestamp": "$(date -Iseconds)",
"gateway_url": "$GATEWAY_URL",
"summary": {
"total": $TESTS_RUN,
"passed": $TESTS_PASSED,
"failed": $TESTS_FAILED,
"skipped": $TESTS_SKIPPED
},
"success_rate": $(echo "scale=2; $TESTS_PASSED * 100 / $TESTS_RUN" | bc 2>/dev/null || echo "0"),
"log_file": "$LOG_FILE"
}
EOF
log "报告已保存到: $REPORT_FILE"
log "日志已保存到: $LOG_FILE"
log ""
# 退出码
if [ $TESTS_FAILED -gt 0 ]; then
log "${RED}存在失败的测试,请检查上述详情${NC}"
exit 1
else
log "${GREEN}所有测试通过!${NC}"
exit 0
fi