- 创建完整的迁移框架 (pkg/migration/) - 版本管理系统,时间戳版本号 (YYYYMMDD_HHMMSS) - 事务安全的上下迁移机制 (Up/Down) - 迁移状态跟踪和记录 (migration_records 表) - 命令行迁移工具 (cmd/migrate/main.go) - 生产环境迁移脚本 (scripts/production-migrate.sh) - 生产环境初始化脚本 (scripts/init-production-db.sh) - 迁移测试脚本 (scripts/test-migration.sh) - Makefile 集成 (migrate-up, migrate-down, migrate-status) - 5个预定义迁移 (基础表、默认数据、元数据、收藏、用户资料) - 自动备份机制、预览模式、详细日志 - 完整文档 (docs/DATABASE_MIGRATION.md) 任务13完成,项目完成率达到42.5%
343 lines
7.9 KiB
Bash
Executable File
343 lines
7.9 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# 迁移系统测试脚本
|
|
# 用于验证迁移系统的正确性
|
|
|
|
set -e
|
|
|
|
# 配置
|
|
TEST_DB="test_migration.db"
|
|
CONFIG_FILE="etc/photographyapi-api.yaml"
|
|
TEMP_CONFIG="test_migration_config.yaml"
|
|
|
|
# 颜色定义
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
NC='\033[0m'
|
|
|
|
# 日志函数
|
|
log() {
|
|
echo -e "${BLUE}[TEST]${NC} $1"
|
|
}
|
|
|
|
error() {
|
|
echo -e "${RED}[ERROR]${NC} $1"
|
|
}
|
|
|
|
success() {
|
|
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
|
}
|
|
|
|
warning() {
|
|
echo -e "${YELLOW}[WARNING]${NC} $1"
|
|
}
|
|
|
|
# 清理函数
|
|
cleanup() {
|
|
log "清理测试环境..."
|
|
rm -f "$TEST_DB" "$TEMP_CONFIG"
|
|
rm -f migration_test.log
|
|
}
|
|
|
|
# 创建测试配置
|
|
create_test_config() {
|
|
log "创建测试配置..."
|
|
|
|
cat > "$TEMP_CONFIG" << EOF
|
|
Name: photography-api-test
|
|
Host: 0.0.0.0
|
|
Port: 8081
|
|
|
|
database:
|
|
driver: sqlite
|
|
file_path: ./$TEST_DB
|
|
|
|
auth:
|
|
access_secret: test-secret
|
|
access_expire: 3600
|
|
|
|
file_upload:
|
|
max_size: 10485760
|
|
upload_dir: ./test_uploads
|
|
allowed_types:
|
|
- image/jpeg
|
|
- image/png
|
|
EOF
|
|
}
|
|
|
|
# 测试数据库连接
|
|
test_database_connection() {
|
|
log "测试数据库连接..."
|
|
|
|
# 创建简单的测试数据库
|
|
sqlite3 "$TEST_DB" "CREATE TABLE IF NOT EXISTS test_table (id INTEGER PRIMARY KEY);"
|
|
|
|
if [[ -f "$TEST_DB" ]]; then
|
|
success "数据库连接正常"
|
|
rm -f "$TEST_DB" # 清理测试数据库
|
|
else
|
|
error "数据库连接失败"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# 测试迁移状态
|
|
test_migration_status() {
|
|
log "测试迁移状态..."
|
|
|
|
if go run cmd/migrate/main.go -f "$TEMP_CONFIG" -c status; then
|
|
success "迁移状态命令正常"
|
|
else
|
|
error "迁移状态命令失败"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# 测试迁移执行
|
|
test_migration_up() {
|
|
log "测试迁移执行..."
|
|
|
|
if go run cmd/migrate/main.go -f "$TEMP_CONFIG" -c up; then
|
|
success "迁移执行成功"
|
|
else
|
|
error "迁移执行失败"
|
|
exit 1
|
|
fi
|
|
|
|
# 验证表是否创建
|
|
if sqlite3 "$TEST_DB" ".tables" | grep -q "user"; then
|
|
success "用户表创建成功"
|
|
else
|
|
error "用户表创建失败"
|
|
exit 1
|
|
fi
|
|
|
|
if sqlite3 "$TEST_DB" ".tables" | grep -q "schema_migrations"; then
|
|
success "迁移记录表创建成功"
|
|
else
|
|
error "迁移记录表创建失败"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# 测试数据插入
|
|
test_data_insertion() {
|
|
log "测试数据插入..."
|
|
|
|
# 检查默认用户是否存在
|
|
local user_count=$(sqlite3 "$TEST_DB" "SELECT COUNT(*) FROM user;")
|
|
if [[ "$user_count" -gt 0 ]]; then
|
|
success "默认用户数据插入成功 ($user_count 个用户)"
|
|
else
|
|
warning "没有找到默认用户数据"
|
|
fi
|
|
|
|
# 检查默认分类是否存在
|
|
local category_count=$(sqlite3 "$TEST_DB" "SELECT COUNT(*) FROM category;")
|
|
if [[ "$category_count" -gt 0 ]]; then
|
|
success "默认分类数据插入成功 ($category_count 个分类)"
|
|
else
|
|
warning "没有找到默认分类数据"
|
|
fi
|
|
}
|
|
|
|
# 测试迁移回滚
|
|
test_migration_down() {
|
|
log "测试迁移回滚..."
|
|
|
|
# 获取当前迁移数量
|
|
local applied_count=$(sqlite3 "$TEST_DB" "SELECT COUNT(*) FROM schema_migrations WHERE applied = 1;")
|
|
log "当前已应用迁移数量: $applied_count"
|
|
|
|
if [[ "$applied_count" -gt 0 ]]; then
|
|
# 回滚一步
|
|
if go run cmd/migrate/main.go -f "$TEMP_CONFIG" -c down -s 1; then
|
|
success "迁移回滚成功"
|
|
|
|
# 验证回滚后的状态
|
|
local new_applied_count=$(sqlite3 "$TEST_DB" "SELECT COUNT(*) FROM schema_migrations WHERE applied = 1;")
|
|
log "回滚后已应用迁移数量: $new_applied_count"
|
|
|
|
if [[ "$new_applied_count" -eq $((applied_count - 1)) ]]; then
|
|
success "回滚状态验证成功"
|
|
else
|
|
error "回滚状态验证失败"
|
|
exit 1
|
|
fi
|
|
else
|
|
error "迁移回滚失败"
|
|
exit 1
|
|
fi
|
|
else
|
|
warning "没有可回滚的迁移"
|
|
fi
|
|
}
|
|
|
|
# 测试迁移版本
|
|
test_migration_version() {
|
|
log "测试迁移版本..."
|
|
|
|
if go run cmd/migrate/main.go -f "$TEMP_CONFIG" -c version; then
|
|
success "迁移版本命令正常"
|
|
else
|
|
error "迁移版本命令失败"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# 测试 Makefile 集成
|
|
test_makefile_integration() {
|
|
log "测试 Makefile 集成..."
|
|
|
|
# 备份原配置
|
|
if [[ -f "$CONFIG_FILE" ]]; then
|
|
cp "$CONFIG_FILE" "${CONFIG_FILE}.backup"
|
|
fi
|
|
|
|
# 使用测试配置
|
|
cp "$TEMP_CONFIG" "$CONFIG_FILE"
|
|
|
|
# 测试 Makefile 命令
|
|
if make migrate-status; then
|
|
success "Makefile 迁移状态命令正常"
|
|
else
|
|
error "Makefile 迁移状态命令失败"
|
|
exit 1
|
|
fi
|
|
|
|
# 恢复原配置
|
|
if [[ -f "${CONFIG_FILE}.backup" ]]; then
|
|
mv "${CONFIG_FILE}.backup" "$CONFIG_FILE"
|
|
fi
|
|
}
|
|
|
|
# 测试生产脚本
|
|
test_production_script() {
|
|
log "测试生产脚本..."
|
|
|
|
# 测试状态检查
|
|
if ./scripts/production-migrate.sh -c "$TEMP_CONFIG" status; then
|
|
success "生产脚本状态检查正常"
|
|
else
|
|
error "生产脚本状态检查失败"
|
|
exit 1
|
|
fi
|
|
|
|
# 测试系统检查
|
|
if ./scripts/production-migrate.sh -c "$TEMP_CONFIG" check; then
|
|
success "生产脚本系统检查正常"
|
|
else
|
|
warning "生产脚本系统检查有警告"
|
|
fi
|
|
}
|
|
|
|
# 性能测试
|
|
performance_test() {
|
|
log "执行性能测试..."
|
|
|
|
local start_time=$(date +%s)
|
|
|
|
# 重新运行迁移
|
|
go run cmd/migrate/main.go -f "$TEMP_CONFIG" -c up > /dev/null 2>&1
|
|
|
|
local end_time=$(date +%s)
|
|
local duration=$((end_time - start_time))
|
|
|
|
log "迁移执行时间: ${duration}秒"
|
|
|
|
if [[ $duration -lt 10 ]]; then
|
|
success "迁移性能正常"
|
|
else
|
|
warning "迁移执行时间较长: ${duration}秒"
|
|
fi
|
|
}
|
|
|
|
# 数据完整性测试
|
|
data_integrity_test() {
|
|
log "测试数据完整性..."
|
|
|
|
# 检查外键约束
|
|
sqlite3 "$TEST_DB" "PRAGMA foreign_keys = ON;"
|
|
|
|
# 尝试插入测试数据
|
|
if sqlite3 "$TEST_DB" "INSERT INTO photo (title, description, file_path, user_id, category_id) VALUES ('test', 'test', '/test.jpg', 1, 1);"; then
|
|
success "外键约束正常"
|
|
|
|
# 清理测试数据
|
|
sqlite3 "$TEST_DB" "DELETE FROM photo WHERE title = 'test';"
|
|
else
|
|
error "外键约束失败"
|
|
exit 1
|
|
fi
|
|
|
|
# 检查索引
|
|
local index_count=$(sqlite3 "$TEST_DB" "SELECT COUNT(*) FROM sqlite_master WHERE type='index' AND name NOT LIKE 'sqlite_%';")
|
|
log "自定义索引数量: $index_count"
|
|
|
|
if [[ "$index_count" -gt 0 ]]; then
|
|
success "索引创建正常"
|
|
else
|
|
warning "没有找到自定义索引"
|
|
fi
|
|
}
|
|
|
|
# 主测试函数
|
|
main() {
|
|
log "开始迁移系统测试..."
|
|
|
|
# 清理之前的测试
|
|
cleanup
|
|
|
|
# 创建测试环境
|
|
create_test_config
|
|
|
|
# 执行测试
|
|
test_database_connection
|
|
test_migration_status
|
|
test_migration_up
|
|
test_data_insertion
|
|
test_migration_version
|
|
test_migration_down
|
|
test_makefile_integration
|
|
test_production_script
|
|
performance_test
|
|
data_integrity_test
|
|
|
|
# 清理测试环境
|
|
cleanup
|
|
|
|
success "所有测试通过!"
|
|
|
|
cat << EOF
|
|
|
|
🎉 迁移系统测试完成!
|
|
|
|
测试结果:
|
|
✅ 数据库连接正常
|
|
✅ 迁移状态查询正常
|
|
✅ 迁移执行成功
|
|
✅ 数据插入正常
|
|
✅ 迁移回滚成功
|
|
✅ 版本管理正常
|
|
✅ Makefile 集成正常
|
|
✅ 生产脚本正常
|
|
✅ 性能测试通过
|
|
✅ 数据完整性验证通过
|
|
|
|
迁移系统已就绪,可以安全使用!
|
|
|
|
下一步:
|
|
1. 在开发环境运行: make migrate-up
|
|
2. 检查迁移状态: make migrate-status
|
|
3. 阅读文档: docs/DATABASE_MIGRATION.md
|
|
|
|
EOF
|
|
}
|
|
|
|
# 错误处理
|
|
trap cleanup EXIT
|
|
|
|
# 运行测试
|
|
main "$@" |