Files
cmautobuy/admin/repository/mysql_db_integration_test.go
T

80 lines
2.1 KiB
Go

package repository
import (
"database/sql"
"fmt"
"os"
"strings"
"testing"
"cmautobuy/admin/config"
)
// TestMySQLMigrate_真实MySQL8 只在显式提供隔离测试库时运行。
// 库名必须以 _test 结尾,防止测试清理误碰生产库。
func TestMySQLMigrate_真实MySQL8(t *testing.T) {
if os.Getenv("CMAUTOBUY_MYSQL_TEST") != "1" {
t.Skip("未启用真实 MySQL 8 集成测试")
}
cfg, err := config.LoadDatabaseFromEnv()
if err != nil {
t.Fatal(err)
}
if !strings.HasSuffix(cfg.Name, "_test") {
t.Fatalf("拒绝清理非测试数据库 %q:库名必须以 _test 结尾", cfg.Name)
}
db, err := OpenMySQL(cfg)
if err != nil {
t.Fatal(err)
}
defer db.Close()
cleanMySQLTestSchema(t, db)
defer cleanMySQLTestSchema(t, db)
if err := MigrateMySQL(db); err != nil {
t.Fatalf("首次建立 MySQL schema 失败: %v", err)
}
if err := MigrateMySQL(db); err != nil {
t.Fatalf("重复迁移应该无副作用: %v", err)
}
var version int
if err := db.QueryRow(`SELECT MAX(version) FROM schema_migrations`).Scan(&version); err != nil {
t.Fatal(err)
}
if version != mysqlSchemaVersion {
t.Fatalf("schema 版本=%d,期望 %d", version, mysqlSchemaVersion)
}
}
func cleanMySQLTestSchema(t *testing.T, db *sql.DB) {
t.Helper()
rows, err := db.Query(`SELECT table_name FROM information_schema.tables
WHERE table_schema = DATABASE() AND table_type = 'BASE TABLE'`)
if err != nil {
t.Fatal(err)
}
var tables []string
for rows.Next() {
var table string
if err := rows.Scan(&table); err != nil {
rows.Close()
t.Fatal(err)
}
tables = append(tables, table)
}
if err := rows.Close(); err != nil {
t.Fatal(err)
}
if _, err := db.Exec(`SET FOREIGN_KEY_CHECKS = 0`); err != nil {
t.Fatal(err)
}
defer db.Exec(`SET FOREIGN_KEY_CHECKS = 1`)
for _, table := range tables {
// 表名只来自当前 _test 数据库的 information_schema,并对反引号转义。
quoted := "`" + strings.ReplaceAll(table, "`", "``") + "`"
if _, err := db.Exec("DROP TABLE " + quoted); err != nil {
t.Fatal(fmt.Errorf("清理 MySQL 测试表 %s 失败: %w", table, err))
}
}
}