This commit is contained in:
mangomqy
2025-11-13 02:54:06 +00:00
commit c5e51ed069
254 changed files with 54901 additions and 0 deletions

395
backend/scripts/test-all-modes.sh Executable file
View File

@ -0,0 +1,395 @@
#!/bin/bash
# ==================================================
# OCDP Backend - 三种模式测试脚本
# ==================================================
# 测试三种部署模式:
# 1. Mock 模式(无 docker composebackend 热重载)
# 2. Production 模式docker compose 仅依赖服务backend 热重载)
# 3. Production 模式docker compose 包含 backend
# ==================================================
set -e # 遇到错误立即退出
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# 日志函数
log_info() {
echo -e "${BLUE} $1${NC}"
}
log_success() {
echo -e "${GREEN}$1${NC}"
}
log_error() {
echo -e "${RED}$1${NC}"
}
log_warning() {
echo -e "${YELLOW}⚠️ $1${NC}"
}
log_section() {
echo ""
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo -e "${BLUE} $1${NC}"
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo ""
}
# 等待服务启动
wait_for_service() {
local url=$1
local max_attempts=30
local attempt=1
log_info "等待服务启动: $url"
while [ $attempt -le $max_attempts ]; do
if curl -s -f "$url" > /dev/null 2>&1; then
log_success "服务已启动!"
return 0
fi
echo -n "."
sleep 1
attempt=$((attempt + 1))
done
log_error "服务启动超时"
return 1
}
# 测试健康检查
test_health() {
local mode=$1
log_info "测试健康检查..."
response=$(curl -s http://localhost:8080/health)
if echo "$response" | grep -q "healthy"; then
log_success "$mode 模式健康检查通过"
return 0
else
log_error "$mode 模式健康检查失败"
echo "响应: $response"
return 1
fi
}
# 测试 API
test_api() {
local mode=$1
log_info "测试 API..."
# 测试注册
register_response=$(curl -s -X POST http://localhost:8080/api/v1/auth/register \
-H "Content-Type: application/json" \
-d '{"username":"testuser'"$RANDOM"'","password":"test123","email":"test@example.com"}')
if echo "$register_response" | grep -q "id"; then
log_success "$mode 模式 API 注册测试通过"
else
log_warning "$mode 模式 API 注册测试失败(可能用户已存在)"
fi
# 测试登录
login_response=$(curl -s -X POST http://localhost:8080/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"admin123"}')
if echo "$login_response" | grep -q "accessToken"; then
log_success "$mode 模式 API 登录测试通过"
return 0
else
log_error "$mode 模式 API 登录测试失败"
echo "响应: $login_response"
return 1
fi
}
# 清理环境
cleanup() {
log_info "清理环境..."
# 停止所有容器
docker compose down --remove-orphans > /dev/null 2>&1 || true
docker compose --profile backend down --remove-orphans > /dev/null 2>&1 || true
docker compose --profile mock down --remove-orphans > /dev/null 2>&1 || true
# 停止可能在运行的本地进程
pkill -f "tmp/main" > /dev/null 2>&1 || true
pkill -f "cmd/api/main.go" > /dev/null 2>&1 || true
sleep 2
log_success "清理完成"
}
# ==================================================
# 测试 1: Mock 模式(无 docker composebackend 热重载)
# ==================================================
test_mode_1() {
log_section "测试模式 1: Mock 模式(本地运行,热重载)"
log_info "配置:"
log_info " • 运行方式: 本地 Go"
log_info " • 适配器: Mock内存存储"
log_info " • 数据库: 无需"
log_info " • 热重载: 支持Air"
# 检查 Air 是否安装
if ! command -v air &> /dev/null; then
log_error "Air 未安装,跳过热重载测试"
log_info "安装命令: go install github.com/air-verse/air@latest"
return 1
fi
# 启动 Mock 模式(后台)
log_info "启动 Mock 模式..."
export ADAPTER_MODE=mock
export PORT=8080
export JWT_SECRET=test-secret
# 在后台启动
nohup air -c .air.toml > /tmp/ocdp-mock.log 2>&1 &
local pid=$!
log_info "进程 PID: $pid"
# 等待服务启动
if wait_for_service "http://localhost:8080/health"; then
# 测试服务
test_health "Mock"
test_api "Mock"
# 停止服务
log_info "停止服务..."
kill $pid 2>/dev/null || true
pkill -f "tmp/main" 2>/dev/null || true
sleep 2
log_success "模式 1 测试完成"
return 0
else
log_error "服务启动失败,查看日志: /tmp/ocdp-mock.log"
kill $pid 2>/dev/null || true
return 1
fi
}
# ==================================================
# 测试 2: Production 模式docker compose 仅依赖backend 热重载)
# ==================================================
test_mode_2() {
log_section "测试模式 2: Docker Compose 仅依赖服务(本地 backend 热重载)"
log_info "配置:"
log_info " • 数据库: Docker (PostgreSQL)"
log_info " • Backend: 本地 Go"
log_info " • 适配器: Production"
log_info " • 热重载: 支持Air"
# 检查 Air 是否安装
if ! command -v air &> /dev/null; then
log_error "Air 未安装,跳过热重载测试"
return 1
fi
# 启动 PostgreSQL
log_info "启动 PostgreSQL 容器..."
docker compose up -d postgres
# 等待数据库就绪
log_info "等待 PostgreSQL 启动..."
sleep 10
# 检查数据库健康状态
if ! docker compose exec -T postgres pg_isready -U postgres > /dev/null 2>&1; then
log_error "PostgreSQL 未就绪"
docker compose logs postgres
return 1
fi
log_success "PostgreSQL 已启动"
# 启动 Backend后台
log_info "启动 Backend (本地)..."
export ADAPTER_MODE=production
export PORT=8080
export JWT_SECRET=test-secret
export ENCRYPTION_KEY=12345678901234567890123456789012
export DATABASE_URL="postgresql://postgres:postgres@localhost:5432/ocdp?sslmode=disable"
# 在后台启动
nohup air -c .air.toml > /tmp/ocdp-real.log 2>&1 &
local pid=$!
log_info "进程 PID: $pid"
# 等待服务启动
if wait_for_service "http://localhost:8080/health"; then
# 测试服务
test_health "Production (本地 backend)"
test_api "Production (本地 backend)"
# 停止服务
log_info "停止 backend..."
kill $pid 2>/dev/null || true
pkill -f "tmp/main" 2>/dev/null || true
sleep 2
# 停止数据库
log_info "停止 PostgreSQL..."
docker compose down
log_success "模式 2 测试完成"
return 0
else
log_error "服务启动失败,查看日志: /tmp/ocdp-real.log"
kill $pid 2>/dev/null || true
docker compose down
return 1
fi
}
# ==================================================
# 测试 3: Production 模式docker compose 包含 backend
# ==================================================
test_mode_3() {
log_section "测试模式 3: Docker Compose 完整服务(包含 backend"
log_info "配置:"
log_info " • 数据库: Docker (PostgreSQL)"
log_info " • Backend: Docker 容器"
log_info " • 适配器: Production"
log_info " • 热重载: 不支持"
# 确保 .env 文件存在
if [ ! -f .env ]; then
log_info "创建 .env 文件..."
cp env.example .env
fi
# 启动完整服务
log_info "启动完整服务PostgreSQL + Backend..."
docker compose --profile backend up -d
# 等待服务启动
log_info "等待服务启动(可能需要构建镜像,请耐心等待)..."
# 检查容器状态
sleep 15
if ! docker compose ps | grep -q "ocdp-backend"; then
log_error "Backend 容器未启动"
docker compose logs backend
return 1
fi
# 等待健康检查通过
if wait_for_service "http://localhost:8080/health"; then
# 测试服务
test_health "Production (Docker)"
test_api "Production (Docker)"
# 查看容器状态
log_info "容器状态:"
docker compose ps
# 停止服务
log_info "停止服务..."
docker compose --profile backend down
log_success "模式 3 测试完成"
return 0
else
log_error "服务启动失败"
log_info "Backend 日志:"
docker compose logs backend
docker compose --profile backend down
return 1
fi
}
# ==================================================
# 主函数
# ==================================================
main() {
log_section "OCDP Backend - 三种模式自动化测试"
log_info "项目目录: $(pwd)"
log_info "测试时间: $(date)"
# 检查是否在项目根目录
if [ ! -f "docker-compose.yml" ]; then
log_error "请在项目根目录运行此脚本"
exit 1
fi
# 初始清理
cleanup
# 运行测试
local failed=0
# 测试模式 1
if test_mode_1; then
log_success "✅ 模式 1 测试通过"
else
log_error "❌ 模式 1 测试失败"
failed=$((failed + 1))
fi
cleanup
sleep 3
# 测试模式 2
if test_mode_2; then
log_success "✅ 模式 2 测试通过"
else
log_error "❌ 模式 2 测试失败"
failed=$((failed + 1))
fi
cleanup
sleep 3
# 测试模式 3
if test_mode_3; then
log_success "✅ 模式 3 测试通过"
else
log_error "❌ 模式 3 测试失败"
failed=$((failed + 1))
fi
cleanup
# 总结
log_section "测试总结"
if [ $failed -eq 0 ]; then
log_success "🎉 所有测试通过!"
log_info ""
log_info "三种部署模式总结:"
log_info ""
log_info "1⃣ Mock 模式(开发)"
log_info " 命令: make dev-mock"
log_info " 特点: 无需数据库,快速启动,热重载"
log_info ""
log_info "2⃣ Real 模式(开发 + 数据库)"
log_info " 命令: docker compose up -d && make dev-real"
log_info " 特点: PostgreSQL 容器Backend 本地热重载"
log_info ""
log_info "3⃣ Production 模式(生产)"
log_info " 命令: docker compose --profile backend up -d"
log_info " 特点: 完全容器化,适合生产环境"
exit 0
else
log_error "$failed 个测试失败"
exit 1
fi
}
# 执行主函数
main