-
Notifications
You must be signed in to change notification settings - Fork 9
Expand file tree
/
Copy pathrollback_condition_parallel_test.go
More file actions
112 lines (94 loc) · 3.39 KB
/
Copy pathrollback_condition_parallel_test.go
File metadata and controls
112 lines (94 loc) · 3.39 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
package floxy
import (
"context"
"encoding/json"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestRollbackConditionInParallelBranches(t *testing.T) {
if testing.Short() {
t.Skip("skipping test in short mode.")
}
store, txManager, cleanup := setupTestStore(t)
t.Cleanup(cleanup)
ctx := context.Background()
engine := NewEngine(nil,
WithEngineStore(store),
WithEngineTxManager(txManager),
WithEngineCancelInterval(time.Minute),
)
defer engine.Shutdown()
// Register handlers
engine.RegisterHandler(&SimpleTestHandler{})
engine.RegisterHandler(&FailingHandler{})
// Create workflow with condition in parallel branch
workflowDef, err := NewBuilder("rollback_parallel", 1).
Step("start", "simple-test", WithStepMaxRetries(1)).
Fork("parallel_branch", func(branch1 *Builder) {
branch1.Step("branch1_step1", "simple-test", WithStepMaxRetries(1)).
Condition("branch1_condition", "{{ gt .count 5 }}", func(elseBranch *Builder) {
elseBranch.Step("branch1_else", "simple-test", WithStepMaxRetries(1))
}).
Then("branch1_next", "simple-test", WithStepMaxRetries(1))
}, func(branch2 *Builder) {
branch2.Step("branch2_step1", "simple-test", WithStepMaxRetries(1)).
Condition("branch2_condition", "{{ lt .count 3 }}", func(elseBranch *Builder) {
elseBranch.Step("branch2_else", "failing-handler", WithStepMaxRetries(1)) // This will fail
}).
Then("branch2_next", "simple-test", WithStepMaxRetries(1))
}).
Join("join", JoinStrategyAll).
Then("final", "simple-test", WithStepMaxRetries(1)).
Build()
require.NoError(t, err)
err = engine.RegisterWorkflow(ctx, workflowDef)
require.NoError(t, err)
// Start with count = 6 (branch1: true -> next, branch2: false -> else which fails)
input := json.RawMessage(`{"count": 6}`)
instanceID, err := engine.Start(ctx, "rollback_parallel-v1", input)
require.NoError(t, err)
// Process workflow until completion or failure
for i := 0; i < 20; i++ {
empty, err := engine.ExecuteNext(ctx, "worker1")
require.NoError(t, err)
if empty {
break
}
time.Sleep(10 * time.Millisecond)
}
// Check final status
status, err := engine.GetStatus(ctx, instanceID)
require.NoError(t, err)
// Check steps
steps, err := engine.GetSteps(ctx, instanceID)
require.NoError(t, err)
stepNames := make([]string, len(steps))
stepStatuses := make(map[string]StepStatus)
for i, step := range steps {
stepNames[i] = step.StepName
stepStatuses[step.StepName] = step.Status
}
t.Logf("Final status: %s", status)
t.Logf("Executed steps: %v", stepNames)
t.Logf("Step statuses: %v", stepStatuses)
// Expected execution path with count = 6:
// - start (completed)
// - parallel_branch (completed)
// - branch1_step1 (completed)
// - branch1_condition (completed, true -> next)
// - branch1_next (completed)
// - branch2_step1 (completed)
// - branch2_condition (completed, false -> else)
// - branch2_else (failed) -> triggers rollback
// - All steps should be rolled_back due to failure
// The key test: verify that when one branch fails, the entire workflow fails
// and all steps are rolled back
// Verify that the workflow failed
assert.Equal(t, StatusFailed, status, "Workflow should fail when one branch fails")
// Verify that all steps are rolled back
for _, step := range steps {
assert.Equal(t, StepStatusRolledBack, step.Status, "All steps should be rolled back")
}
}