- Add Workspace domain (entity, repository, service, handler, DTO) - Add multi-tenant K8s client with tenant binding and quota management - Add K8s diagnostics client (instance diagnostics) - Add authorization middleware (authz package) - Restructure frontend to feature-based architecture (features/) - Add User Management page in configuration - Add AccessDenied page and route guards - Refactor shared components (form inputs, layout, UI) - Update Tailwind config for new design system - Add comprehensive documentation (docs/, tasks/, plans) - Improve cluster service with better kubeconfig handling - Add tests for crypto, config, helm client, tenant binding
397 lines
11 KiB
Bash
Executable File
397 lines
11 KiB
Bash
Executable File
#!/bin/bash
|
||
|
||
# ==================================================
|
||
# OCDP Backend - 三种模式测试脚本
|
||
# ==================================================
|
||
# 测试三种部署模式:
|
||
# 1. Mock 模式(无 docker compose,backend 热重载)
|
||
# 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..."
|
||
|
||
# 测试注册
|
||
local test_username="testuser$RANDOM"
|
||
local test_password="test123"
|
||
register_response=$(curl -s -X POST http://localhost:8080/api/v1/auth/register \
|
||
-H "Content-Type: application/json" \
|
||
-d '{"username":"'"$test_username"'","password":"'"$test_password"'","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":"'"$test_username"'","password":"'"$test_password"'"}')
|
||
|
||
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 compose,backend 热重载)
|
||
# ==================================================
|
||
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
|