70 lines
2.3 KiB
Go
70 lines
2.3 KiB
Go
package mssql
|
|
|
|
import (
|
|
"database/sql"
|
|
"errors"
|
|
"fmt"
|
|
"os"
|
|
"testing"
|
|
"time"
|
|
|
|
"git.warky.dev/wdevs/relspecgo/pkg/models"
|
|
"git.warky.dev/wdevs/relspecgo/pkg/writers"
|
|
)
|
|
|
|
func TestLive_ExecutionFailureModes(t *testing.T) {
|
|
connection := os.Getenv("RELSPEC_TEST_MSSQL_CONN")
|
|
if connection == "" {
|
|
t.Skip("RELSPEC_TEST_MSSQL_CONN not set")
|
|
}
|
|
conn, err := sql.Open("mssql", connection)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer conn.Close()
|
|
for _, mode := range []string{"stop", "continue", "atomic"} {
|
|
t.Run(mode, func(t *testing.T) {
|
|
prefix := fmt.Sprintf("audit_%d_", time.Now().UnixNano())
|
|
db := models.InitDatabase("audit")
|
|
schema := models.InitSchema("dbo")
|
|
for _, name := range []string{"first", "bad", "last"} {
|
|
table := models.InitTable(prefix+name, "dbo")
|
|
col := models.InitColumn("id", table.Name, "dbo")
|
|
col.Type = "integer"
|
|
if name == "bad" {
|
|
duplicate := models.InitColumn("id", table.Name, "dbo")
|
|
duplicate.Type = "integer"
|
|
table.Columns["duplicate"] = duplicate
|
|
}
|
|
table.Columns[col.Name] = col
|
|
schema.Tables = append(schema.Tables, table)
|
|
}
|
|
db.Schemas = append(db.Schemas, schema)
|
|
t.Cleanup(func() {
|
|
for _, name := range []string{"first", "bad", "last"} {
|
|
_, _ = conn.Exec("DROP TABLE IF EXISTS dbo." + prefix + name)
|
|
}
|
|
})
|
|
opts := &writers.WriterOptions{ContinueOnError: mode == "continue", AtomicExecution: mode == "atomic", Metadata: map[string]interface{}{"connection_string": connection}}
|
|
err := NewWriter(opts).WriteDatabase(db)
|
|
var failure *writers.ExecutionFailure
|
|
if !errors.As(err, &failure) || failure.Report.FailedStatements == 0 {
|
|
t.Fatalf("expected structured error: %v", err)
|
|
}
|
|
for _, name := range []string{"first", "last"} {
|
|
var count int
|
|
if err := conn.QueryRow("SELECT count(*) FROM sys.tables WHERE name=?", prefix+name).Scan(&count); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
want := mode != "atomic" && (name == "first" || mode == "continue")
|
|
if (count == 1) != want {
|
|
t.Fatalf("%s exists=%v want=%v", name, count == 1, want)
|
|
}
|
|
}
|
|
if mode == "atomic" && (failure.Report.Outcome != "rolled_back" || failure.Report.RolledBackStatements == 0 || failure.Report.ExecutedStatements != 0) {
|
|
t.Fatalf("incorrect rollback report: %+v", failure.Report)
|
|
}
|
|
})
|
|
}
|
|
}
|