Scert/backend/internal/database/sqlite_replacement_migration_test.go

57 lines
3.4 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 "testing"
func TestSQLiteResourceProjectReplacementMigrationRollback(t *testing.T) {
cases := []struct{ name, setup, repair string }{
{"version_record", `CREATE TRIGGER fail_replacement_version BEFORE INSERT ON schema_migrations WHEN new.version = 12 BEGIN SELECT RAISE(ABORT, 'test-only'); END`, `DROP TRIGGER fail_replacement_version`},
{"trigger_collision", `CREATE TRIGGER scert_servers_replace_update_guard BEFORE UPDATE ON servers BEGIN SELECT 1; END`, `DROP TRIGGER scert_servers_replace_update_guard`},
{"orphan_binding", `INSERT OR REPLACE INTO domains (rowid, id, name, certificate_type, sans_json, status) SELECT rowid, 'replacement', 'replacement.example.test', certificate_type, sans_json, status FROM domains WHERE id = 'domain'`, `UPDATE domains SET id = 'domain' WHERE id = 'replacement'`},
{"orphan_server", `INSERT OR REPLACE INTO servers (rowid, id, name, address, port, username, private_key_ref, host_key_fingerprint, certificate_path, private_key_path, certificate_chain_path, web_server, reload_command_json) SELECT rowid, 'replacement', name, address, port, username, private_key_ref, host_key_fingerprint, certificate_path, private_key_path, certificate_chain_path, web_server, reload_command_json FROM servers WHERE id = 'server'`, `UPDATE servers SET id = 'server' WHERE id = 'replacement'`},
{"missing_project", `INSERT OR REPLACE INTO projects (rowid, id, name, description) SELECT rowid, 'replacement', name, description FROM projects WHERE id = 'default'`, `UPDATE projects SET id = 'default' WHERE id = 'replacement'`},
}
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()
db.DB.SetMaxOpenConns(1)
createSQLiteHistoricalBusiness(t, db.DB, 11)
if _, err := db.DB.ExecContext(t.Context(), "PRAGMA recursive_triggers = 0"); err != nil {
t.Fatal(err)
}
if _, err := db.DB.ExecContext(t.Context(), tc.setup); err != nil {
t.Fatal(err)
}
before := snapshotSQLiteReplacementState(t, db.DB)
schemaQuery := `SELECT type, name, sql FROM sqlite_master ORDER BY name`
schema := snapshotSQLiteUpgradeQuery(t, db.DB, schemaQuery)
if err := Migrate(t.Context(), db.DB, "sqlite"); err == nil {
t.Fatal("资源替换保护迁移未拒绝故障")
}
assertSQLiteHistoricalBusiness(t, db.DB, before)
if actual := snapshotSQLiteUpgradeQuery(t, db.DB, schemaQuery); actual != schema {
t.Fatal("迁移失败未完整回滚原模式")
}
version, err := currentMigrationVersion(t.Context(), db.DB)
if err != nil || version != 11 {
t.Fatalf("失败迁移错误登记版本:%d,%v", version, err)
}
if _, err := db.DB.ExecContext(t.Context(), tc.repair); err != nil {
t.Fatal(err)
}
for round := 0; round < 2; round++ {
if err := Migrate(t.Context(), db.DB, "sqlite"); err != nil {
t.Fatal(err)
}
}
var count int
if err := db.DB.QueryRowContext(t.Context(), `SELECT COUNT(*) FROM sqlite_master WHERE type = 'trigger' AND name IN ('scert_domains_replace_update_guard', 'scert_domains_replace_insert_guard', 'scert_servers_replace_update_guard', 'scert_servers_replace_insert_guard', 'scert_project_replace_insert_guard', 'scert_project_replace_update_guard', 'scert_project_replace_reference_guard')`).Scan(&count); err != nil || count != 7 {
t.Fatalf("重试未完整建立七项保护:%d,%v", count, err)
}
})
}
}