order sagas
Build and Publish / BuildAndDeployArm64 (push) Failing after 5s
Build and Publish / BuildAndDeployAmd64 (push) Has been cancelled

This commit is contained in:
2026-06-21 11:33:20 +02:00
parent 484f2364fb
commit 1a365de071
25 changed files with 4224 additions and 1 deletions
+91
View File
@@ -0,0 +1,91 @@
package flow
import (
"context"
"encoding/json"
"fmt"
"testing"
)
func TestRunRecordsOrderAndHooks(t *testing.T) {
reg := NewRegistry()
var trace []string
reg.Action("a", func(_ context.Context, _ *State, _ json.RawMessage) error {
trace = append(trace, "a")
return nil
})
reg.Action("b", func(_ context.Context, _ *State, _ json.RawMessage) error {
trace = append(trace, "b")
return nil
})
reg.Hook("rec", func(_ context.Context, _ *State, info HookInfo, _ json.RawMessage) error {
trace = append(trace, string(info.Phase)+":"+info.Step)
return nil
})
def := &Definition{Name: "t", Steps: []Step{
{Name: "s1", Action: "a", Hooks: Hooks{Before: []HookRef{{Type: "rec"}}, After: []HookRef{{Type: "rec"}}}},
{Name: "s2", Action: "b"},
}}
res, err := NewEngine(reg, nil).Run(context.Background(), def, NewState(1, nil))
if err != nil {
t.Fatal(err)
}
if res.Failed || len(res.Steps) != 2 {
t.Fatalf("unexpected result %+v", res)
}
want := []string{"before:s1", "a", "after:s1", "b"}
if fmt.Sprint(trace) != fmt.Sprint(want) {
t.Fatalf("trace = %v, want %v", trace, want)
}
}
func TestPredicateSkipsStep(t *testing.T) {
reg := NewRegistry()
ran := false
reg.Action("a", func(_ context.Context, _ *State, _ json.RawMessage) error { ran = true; return nil })
reg.Predicate("never", func(_ context.Context, _ *State) (bool, error) { return false, nil })
def := &Definition{Name: "t", Steps: []Step{{Name: "s1", Action: "a", When: "never"}}}
res, err := NewEngine(reg, nil).Run(context.Background(), def, NewState(1, nil))
if err != nil {
t.Fatal(err)
}
if ran {
t.Fatal("action ran despite predicate=false")
}
if !res.Steps[0].Skipped {
t.Fatal("step not marked skipped")
}
}
func TestContinueOnError(t *testing.T) {
reg := NewRegistry()
reg.Action("boom", func(_ context.Context, _ *State, _ json.RawMessage) error { return fmt.Errorf("x") })
reg.Action("ok", func(_ context.Context, _ *State, _ json.RawMessage) error { return nil })
def := &Definition{Name: "t", Steps: []Step{
{Name: "s1", Action: "boom", ContinueOnError: true},
{Name: "s2", Action: "ok"},
}}
res, err := NewEngine(reg, nil).Run(context.Background(), def, NewState(1, nil))
if err != nil {
t.Fatalf("continue-on-error should not abort: %v", err)
}
if res.Steps[0].Error == "" || res.Steps[1].Error != "" {
t.Fatalf("unexpected step results %+v", res.Steps)
}
}
func TestValidateCatchesUnknownRefs(t *testing.T) {
reg := NewRegistry()
reg.Action("a", func(_ context.Context, _ *State, _ json.RawMessage) error { return nil })
eng := NewEngine(reg, nil)
if err := eng.Validate(&Definition{Name: "t", Steps: []Step{{Name: "s", Action: "missing"}}}); err == nil {
t.Fatal("expected unknown-action error")
}
if err := eng.Validate(&Definition{Name: "t", Steps: []Step{{Name: "s", Action: "a"}}}); err != nil {
t.Fatalf("valid def rejected: %v", err)
}
}