Scert/backend/internal/database/migration_history_test.go

99 lines
3.0 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 (
"fmt"
"strings"
"testing"
)
func TestMigrateRejectsInvalidHistoryWithoutChangingDatabase(t *testing.T) {
newerHistory := make([]int, latestMigrationVersion+1)
for index := range newerHistory {
newerHistory[index] = index + 1
}
cases := []struct {
name string
versions []int
message string
}{
{"newer_database", newerHistory, "高于当前程序支持"},
{"missing_first", []int{2}, "迁移历史不连续"},
{"missing_middle", []int{1, 3}, "迁移历史不连续"},
{"zero", []int{0}, "迁移历史不连续"},
{"negative", []int{-1}, "迁移历史不连续"},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
db, err := Open(t.Context(), sqliteBusinessUpgradeConfig(t))
if err != nil {
t.Fatal(err)
}
defer db.Close()
if _, err := db.DB.ExecContext(t.Context(), migrationTableSQL("sqlite")); err != nil {
t.Fatal(err)
}
for _, version := range tc.versions {
if _, err := db.DB.ExecContext(t.Context(), "INSERT INTO schema_migrations (version) VALUES (?)", version); err != nil {
t.Fatal(err)
}
}
if _, err := db.DB.ExecContext(t.Context(), "CREATE TABLE preserved_data (value TEXT); INSERT INTO preserved_data VALUES ('unchanged')"); err != nil {
t.Fatal(err)
}
err = Migrate(t.Context(), db.DB, "sqlite")
if err == nil || !strings.Contains(err.Error(), tc.message) {
t.Fatalf("未拒绝异常迁移历史:%v", err)
}
var count int
if err := db.DB.QueryRow("SELECT COUNT(*) FROM schema_migrations").Scan(&count); err != nil {
t.Fatal(err)
}
if count != len(tc.versions) {
t.Fatalf("拒绝迁移后版本记录被修改:%d", count)
}
if err := db.DB.QueryRow("SELECT COUNT(*) FROM sqlite_master WHERE type = 'table'").Scan(&count); err != nil {
t.Fatal(err)
}
if count != 2 {
t.Fatalf("拒绝迁移后创建了业务表:%d", count)
}
var value string
if err := db.DB.QueryRow("SELECT value FROM preserved_data").Scan(&value); err != nil {
t.Fatal(err)
}
if value != "unchanged" {
t.Fatal("拒绝迁移后原数据被修改")
}
})
}
}
func TestSQLiteUpgradeFromEverySupportedVersion(t *testing.T) {
for version := 0; version <= latestMigrationVersion; version++ {
t.Run(fmt.Sprintf("version_%d", version), func(t *testing.T) {
db, err := Open(t.Context(), sqliteBusinessUpgradeConfig(t))
if err != nil {
t.Fatal(err)
}
defer db.Close()
if _, err := db.DB.ExecContext(t.Context(), migrationTableSQL("sqlite")); err != nil {
t.Fatal(err)
}
for next := 1; next <= version; next++ {
if err := applyMigration(t.Context(), db.DB, "sqlite", next); err != nil {
t.Fatal(err)
}
}
for repeat := 0; repeat < 2; repeat++ {
if err := Migrate(t.Context(), db.DB, "sqlite"); err != nil {
t.Fatal(err)
}
}
actual, err := currentMigrationVersion(t.Context(), db.DB)
if err != nil || actual != latestMigrationVersion {
t.Fatalf("迁移历史不完整:%d:%v", actual, err)
}
})
}
}