57 lines
3.4 KiB
Go
57 lines
3.4 KiB
Go
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)
|
||
}
|
||
})
|
||
}
|
||
}
|