Scert/backend/internal/database/project_mysql_test.go

73 lines
2.9 KiB
Go
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.

package database
import (
"strings"
"testing"
)
func TestMySQLRealProjectMigrationRetry(t *testing.T) {
fixture := startRealMySQL(t)
db := fixture.database(t)
ctx := t.Context()
if _, err := db.DB.ExecContext(ctx, migrationTableSQL("mysql")); err != nil {
t.Fatal(err)
}
for version := 1; version <= 9; version++ {
if err := applyMigration(ctx, db.DB, "mysql", version); err != nil {
t.Fatal(err)
}
}
if _, err := db.DB.ExecContext(ctx, `INSERT INTO tasks (id, domain_id, task_type, status, message)
VALUES ('historical-task', 'historical-domain', 'deploy', 'success', '保留历史任务')`); err != nil {
t.Fatal(err)
}
// MySQL 的 DDL 不会随事务回滚,必须验证建表后版本登记失败可安全重试。
var schema string
if err := db.DB.QueryRowContext(ctx, "SELECT DATABASE()").Scan(&schema); err != nil {
t.Fatal(err)
}
schema = "`" + strings.ReplaceAll(schema, "`", "``") + "`"
// 故障注入仅使用隔离实例管理连接,不给产品连接增加全局权限。
if _, err := fixture.admin.ExecContext(ctx, `CREATE TRIGGER `+schema+`.fail_project_version BEFORE INSERT ON `+schema+`.schema_migrations
FOR EACH ROW SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'test-only'`); err != nil {
t.Fatal(err)
}
if err := Migrate(ctx, db.DB, "mysql"); err == nil {
t.Fatal("版本登记故障未阻断 MySQL 迁移")
}
version, err := currentMigrationVersion(ctx, db.DB)
if err != nil || version != 9 {
t.Fatalf("失败迁移错误登记版本:%d,%v", version, err)
}
var name string
if err := db.DB.QueryRowContext(ctx, "SELECT name FROM projects WHERE id = 'default'").Scan(&name); err != nil || name != "默认项目" {
t.Fatalf("MySQL 部分迁移的默认项目缺失:%q,%v", name, err)
}
if _, err := db.DB.ExecContext(ctx, "UPDATE projects SET name = '保留用户调整' WHERE id = 'default'"); err != nil {
t.Fatal(err)
}
if _, err := fixture.admin.ExecContext(ctx, "DROP TRIGGER "+schema+".fail_project_version"); err != nil {
t.Fatal(err)
}
for repeat := 0; repeat < 2; repeat++ {
if err := Migrate(ctx, db.DB, "mysql"); err != nil {
t.Fatal(err)
}
}
var count int
if err := db.DB.QueryRowContext(ctx, "SELECT COUNT(*) FROM projects").Scan(&count); err != nil || count != 1 {
t.Fatalf("重试后项目数量错误:%d,%v", count, err)
}
if err := db.DB.QueryRowContext(ctx, "SELECT name FROM projects WHERE id = 'default'").Scan(&name); err != nil || name != "保留用户调整" {
t.Fatalf("重试覆盖已有默认项目:%q,%v", name, err)
}
var message string
if err := db.DB.QueryRowContext(ctx, "SELECT message FROM tasks WHERE id = 'historical-task'").Scan(&message); err != nil || message != "保留历史任务" {
t.Fatalf("迁移影响历史任务:%q,%v", message, err)
}
version, err = currentMigrationVersion(ctx, db.DB)
if err != nil || version != latestMigrationVersion {
t.Fatalf("重试后迁移版本不完整:%d,%v", version, err)
}
}