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) } }) } }