Skip to content

Commit 9cc8453

Browse files
Tests for Continue as New and one additional scenario (#1313)
* replay test sequential * Add replay test case for problematic continue-as-new case * fix * Made minor comment fixes and expected error handling --------- Co-authored-by: taylan isikdemir <[email protected]>
1 parent 10ebf6b commit 9cc8453

6 files changed

+445
-1
lines changed

test/replaytests/branch_workflow.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ func sampleBranchWorkflow2(ctx workflow.Context) error {
7272
}
7373
ctx = workflow.WithActivityOptions(ctx, ao)
7474

75-
for i := 1; i <= 4; i++ {
75+
for i := 1; i <= 2; i++ {
7676
activityInput := fmt.Sprintf("branch %d of 4", i)
7777
future := workflow.ExecuteActivity(ctx, sampleActivity, activityInput)
7878
futures = append(futures, future)

test/replaytests/continue_as_new.json

+90
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
[
2+
{
3+
"eventId": 1,
4+
"timestamp": 1699856700704442400,
5+
"eventType": "WorkflowExecutionStarted",
6+
"version": 4,
7+
"taskId": 882931375,
8+
"workflowExecutionStartedEventAttributes": {
9+
"workflowType": {
10+
"name": "fx.SimpleSignalWorkflow"
11+
},
12+
"taskList": {
13+
"name": "fx-worker"
14+
},
15+
"executionStartToCloseTimeoutSeconds": 600,
16+
"taskStartToCloseTimeoutSeconds": 10,
17+
"continuedExecutionRunId": "a664f402-bfe9-4739-945c-9cbc637548f1",
18+
"initiator": "CronSchedule",
19+
"continuedFailureReason": "cadenceInternal:Timeout START_TO_CLOSE",
20+
"originalExecutionRunId": "d0baf930-6a83-4740-b773-71aaa696eed1",
21+
"firstExecutionRunId": "e85fa1b9-8899-40ce-8af9-7e0f93ed7ae5",
22+
"firstScheduleTimeNano": "2023-05-22T15:45:26.535595761-07:00",
23+
"cronSchedule": "* * * * *",
24+
"firstDecisionTaskBackoffSeconds": 60,
25+
"PartitionConfig": {
26+
"isolation-group": "dca11"
27+
}
28+
}
29+
},
30+
{
31+
"eventId": 2,
32+
"timestamp": 1699856760713586608,
33+
"eventType": "DecisionTaskScheduled",
34+
"version": 4,
35+
"taskId": 882931383,
36+
"decisionTaskScheduledEventAttributes": {
37+
"taskList": {
38+
"name": "fx-worker"
39+
},
40+
"startToCloseTimeoutSeconds": 10
41+
}
42+
},
43+
{
44+
"eventId": 3,
45+
"timestamp": 1699856760741837021,
46+
"eventType": "DecisionTaskStarted",
47+
"version": 4,
48+
"taskId": 882931387,
49+
"decisionTaskStartedEventAttributes": {
50+
"scheduledEventId": 2,
51+
"identity": "202@dca50-7q@fx-worker@db443597-5124-483a-b1a5-4b1ff35a0ed4",
52+
"requestId": "bb0ee926-13d1-4af4-9f9c-51433333ad04"
53+
}
54+
},
55+
{
56+
"eventId": 4,
57+
"timestamp": 1699856760773459755,
58+
"eventType": "DecisionTaskCompleted",
59+
"version": 4,
60+
"taskId": 882931391,
61+
"decisionTaskCompletedEventAttributes": {
62+
"scheduledEventId": 2,
63+
"startedEventId": 3,
64+
"identity": "202@dca50-7q@fx-worker@db443597-5124-483a-b1a5-4b1ff35a0ed4",
65+
"binaryChecksum": "uDeploy:dc3e318b30a49e8bb88f462a50fe3a01dd210a3a"
66+
}
67+
},
68+
{
69+
"eventId": 5,
70+
"timestamp": 1699857360713649962,
71+
"eventType": "WorkflowExecutionContinuedAsNew",
72+
"version": 4,
73+
"taskId": 882931394,
74+
"workflowExecutionContinuedAsNewEventAttributes": {
75+
"newExecutionRunId": "06c2468c-2d2d-44f7-ac7a-ff3c383f6e90",
76+
"workflowType": {
77+
"name": "fx.SimpleSignalWorkflow"
78+
},
79+
"taskList": {
80+
"name": "fx-worker"
81+
},
82+
"executionStartToCloseTimeoutSeconds": 600,
83+
"taskStartToCloseTimeoutSeconds": 10,
84+
"decisionTaskCompletedEventId": -23,
85+
"backoffStartIntervalInSeconds": 60,
86+
"initiator": "CronSchedule",
87+
"failureReason": "cadenceInternal:Timeout START_TO_CLOSE"
88+
}
89+
}
90+
]
+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package replaytests
2+
3+
import (
4+
"go.uber.org/cadence/workflow"
5+
"go.uber.org/zap"
6+
)
7+
8+
// ContinueAsNewWorkflow is a sample Cadence workflows that can receive a signal
9+
func ContinueAsNewWorkflow(ctx workflow.Context) error {
10+
selector := workflow.NewSelector(ctx)
11+
var signalResult string
12+
signalName := "helloWorldSignal"
13+
for {
14+
signalChan := workflow.GetSignalChannel(ctx, signalName)
15+
selector.AddReceive(signalChan, func(c workflow.Channel, more bool) {
16+
c.Receive(ctx, &signalResult)
17+
workflow.GetLogger(ctx).Info("Received age signalResult from signal!", zap.String("signal", signalName), zap.String("value", signalResult))
18+
})
19+
workflow.GetLogger(ctx).Info("Waiting for signal on channel.. " + signalName)
20+
// Wait for signal
21+
selector.Select(ctx)
22+
if signalResult == "kill" {
23+
return nil
24+
}
25+
}
26+
}

test/replaytests/replay_test.go

+21
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,17 @@ func TestBranchWorkflowWithExtraBranch(t *testing.T) {
151151
assert.ErrorContains(t, err, "nondeterministic workflow")
152152
}
153153

154+
// TestSequentialStepsWorkflow replays a history with 2 sequential activity calls and runs it against new version of the workflow code which only calls 1 activity.
155+
// This should be considered as non-determinism error.
156+
func TestSequentialStepsWorkflow(t *testing.T) {
157+
replayer := worker.NewWorkflowReplayer()
158+
159+
replayer.RegisterWorkflowWithOptions(replayerHelloWorldWorkflow, workflow.RegisterOptions{Name: "fx.ReplayerHelloWorldWorkflow"})
160+
replayer.RegisterActivityWithOptions(replayerHelloWorldActivity, activity.RegisterOptions{Name: "replayerhello"})
161+
err := replayer.ReplayWorkflowHistoryFromJSONFile(zaptest.NewLogger(t), "sequential.json")
162+
assert.NoError(t, err)
163+
}
164+
154165
func TestParallel(t *testing.T) {
155166
replayer := worker.NewWorkflowReplayer()
156167

@@ -170,3 +181,13 @@ func TestParallel2(t *testing.T) {
170181
err := replayer.ReplayWorkflowHistoryFromJSONFile(zaptest.NewLogger(t), "branch2.json")
171182
require.NoError(t, err)
172183
}
184+
185+
// Runs a history which ends with WorkflowExecutionContinuedAsNew. Replay fails because of the additional checks done
186+
// for continue as new case by replayWorkflowHistory().
187+
// This should not have any error because it's a valid continue as new case.
188+
func TestContinueAsNew(t *testing.T) {
189+
replayer := worker.NewWorkflowReplayer()
190+
replayer.RegisterWorkflowWithOptions(ContinueAsNewWorkflow, workflow.RegisterOptions{Name: "fx.SimpleSignalWorkflow"})
191+
err := replayer.ReplayWorkflowHistoryFromJSONFile(zaptest.NewLogger(t), "continue_as_new.json")
192+
assert.ErrorContains(t, err, "missing replay decision for WorkflowExecutionContinuedAsNew")
193+
}

test/replaytests/sequential.json

+231
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,231 @@
1+
[
2+
{
3+
"eventId": 1,
4+
"timestamp": 1697648630382933224,
5+
"eventType": "WorkflowExecutionStarted",
6+
"taskId": 3145798,
7+
"workflowExecutionStartedEventAttributes": {
8+
"workflowType": {
9+
"name": "fx.ReplayerHelloWorldWorkflow"
10+
},
11+
"taskList": {
12+
"name": "fx-worker"
13+
},
14+
"input": "eyJNZXNzYWdlIjoiaGVsbG8gcmVwbGF5ZXIifQ==",
15+
"executionStartToCloseTimeoutSeconds": 60,
16+
"taskStartToCloseTimeoutSeconds": 60,
17+
"originalExecutionRunId": "dadbe958-4159-4762-88e7-6b352b4cccff",
18+
"identity": "cadence-cli@taylan-trial",
19+
"firstExecutionRunId": "dadbe958-4159-4762-88e7-6b352b4cccff",
20+
"firstDecisionTaskBackoffSeconds": 0,
21+
"PartitionConfig": null
22+
}
23+
},
24+
{
25+
"eventId": 2,
26+
"timestamp": 1697648630382957815,
27+
"eventType": "DecisionTaskScheduled",
28+
"taskId": 3145799,
29+
"decisionTaskScheduledEventAttributes": {
30+
"taskList": {
31+
"name": "fx-worker"
32+
},
33+
"startToCloseTimeoutSeconds": 60
34+
}
35+
},
36+
{
37+
"eventId": 3,
38+
"timestamp": 1697648630401121943,
39+
"eventType": "DecisionTaskStarted",
40+
"taskId": 3145804,
41+
"decisionTaskStartedEventAttributes": {
42+
"scheduledEventId": 2,
43+
"identity": "2126702@taylan-trial@fx-worker@b25ed4e0-0864-41ed-843d-29265e3c6401",
44+
"requestId": "20ca16c3-b13e-4c72-85f9-bd79384d430e"
45+
}
46+
},
47+
{
48+
"eventId": 4,
49+
"timestamp": 1697648630412706912,
50+
"eventType": "DecisionTaskCompleted",
51+
"taskId": 3145807,
52+
"decisionTaskCompletedEventAttributes": {
53+
"scheduledEventId": 2,
54+
"startedEventId": 3,
55+
"identity": "2126702@taylan-trial@fx-worker@b25ed4e0-0864-41ed-843d-29265e3c6401",
56+
"binaryChecksum": "uDeploy:"
57+
}
58+
},
59+
{
60+
"eventId": 5,
61+
"timestamp": 1697648630412753262,
62+
"eventType": "ActivityTaskScheduled",
63+
"taskId": 3145808,
64+
"activityTaskScheduledEventAttributes": {
65+
"activityId": "0",
66+
"activityType": {
67+
"name": "replayerhello"
68+
},
69+
"taskList": {
70+
"name": "fx-worker"
71+
},
72+
"input": "eyJNZXNzYWdlIjoiaGVsbG8gcmVwbGF5ZXIifQo=",
73+
"scheduleToCloseTimeoutSeconds": 60,
74+
"scheduleToStartTimeoutSeconds": 60,
75+
"startToCloseTimeoutSeconds": 60,
76+
"heartbeatTimeoutSeconds": 0,
77+
"decisionTaskCompletedEventId": 4,
78+
"header": {}
79+
}
80+
},
81+
{
82+
"eventId": 6,
83+
"timestamp": 1697648630412771832,
84+
"eventType": "ActivityTaskStarted",
85+
"taskId": 3145809,
86+
"activityTaskStartedEventAttributes": {
87+
"scheduledEventId": 5,
88+
"identity": "2126702@taylan-trial@fx-worker@b25ed4e0-0864-41ed-843d-29265e3c6401",
89+
"requestId": "6adca0b2-bd1e-4877-ac44-c3fdf45784c6",
90+
"lastFailureReason": ""
91+
}
92+
},
93+
{
94+
"eventId": 7,
95+
"timestamp": 1697648630422944301,
96+
"eventType": "ActivityTaskCompleted",
97+
"taskId": 3145812,
98+
"activityTaskCompletedEventAttributes": {
99+
"result": "IkhlbGxvLCBoZWxsbyByZXBsYXllciEiCg==",
100+
"scheduledEventId": 5,
101+
"startedEventId": 6,
102+
"identity": "2126702@taylan-trial@fx-worker@b25ed4e0-0864-41ed-843d-29265e3c6401"
103+
}
104+
},
105+
{
106+
"eventId": 8,
107+
"timestamp": 1697648630422957221,
108+
"eventType": "DecisionTaskScheduled",
109+
"taskId": 3145814,
110+
"decisionTaskScheduledEventAttributes": {
111+
"taskList": {
112+
"name": "taylan-trial:4037e064-7565-4716-8169-e97eb2449f32"
113+
},
114+
"startToCloseTimeoutSeconds": 60
115+
}
116+
},
117+
{
118+
"eventId": 9,
119+
"timestamp": 1697648630432583300,
120+
"eventType": "DecisionTaskStarted",
121+
"taskId": 3145818,
122+
"decisionTaskStartedEventAttributes": {
123+
"scheduledEventId": 8,
124+
"identity": "2126702@taylan-trial@fx-worker@b25ed4e0-0864-41ed-843d-29265e3c6401",
125+
"requestId": "6eea9a40-e738-4a9b-9de3-30cc30af3597"
126+
}
127+
},
128+
{
129+
"eventId": 10,
130+
"timestamp": 1697648630442893019,
131+
"eventType": "DecisionTaskCompleted",
132+
"taskId": 3145821,
133+
"decisionTaskCompletedEventAttributes": {
134+
"scheduledEventId": 8,
135+
"startedEventId": 9,
136+
"identity": "2126702@taylan-trial@fx-worker@b25ed4e0-0864-41ed-843d-29265e3c6401",
137+
"binaryChecksum": "uDeploy:"
138+
}
139+
},
140+
{
141+
"eventId": 11,
142+
"timestamp": 1697648630442935059,
143+
"eventType": "ActivityTaskScheduled",
144+
"taskId": 3145822,
145+
"activityTaskScheduledEventAttributes": {
146+
"activityId": "1",
147+
"activityType": {
148+
"name": "replayerhello"
149+
},
150+
"taskList": {
151+
"name": "fx-worker"
152+
},
153+
"input": "eyJNZXNzYWdlIjoiaGVsbG8gcmVwbGF5ZXIifQo=",
154+
"scheduleToCloseTimeoutSeconds": 60,
155+
"scheduleToStartTimeoutSeconds": 60,
156+
"startToCloseTimeoutSeconds": 60,
157+
"heartbeatTimeoutSeconds": 0,
158+
"decisionTaskCompletedEventId": 10,
159+
"header": {}
160+
}
161+
},
162+
{
163+
"eventId": 12,
164+
"timestamp": 1697648630442953489,
165+
"eventType": "ActivityTaskStarted",
166+
"taskId": 3145823,
167+
"activityTaskStartedEventAttributes": {
168+
"scheduledEventId": 11,
169+
"identity": "2126702@taylan-trial@fx-worker@b25ed4e0-0864-41ed-843d-29265e3c6401",
170+
"requestId": "f44f0ef6-b40a-479f-96e2-3a5093433996",
171+
"lastFailureReason": ""
172+
}
173+
},
174+
{
175+
"eventId": 13,
176+
"timestamp": 1697648630451389698,
177+
"eventType": "ActivityTaskCompleted",
178+
"taskId": 3145826,
179+
"activityTaskCompletedEventAttributes": {
180+
"result": "IkhlbGxvLCBoZWxsbyByZXBsYXllciEiCg==",
181+
"scheduledEventId": 11,
182+
"startedEventId": 12,
183+
"identity": "2126702@taylan-trial@fx-worker@b25ed4e0-0864-41ed-843d-29265e3c6401"
184+
}
185+
},
186+
{
187+
"eventId": 14,
188+
"timestamp": 1697648630451401018,
189+
"eventType": "DecisionTaskScheduled",
190+
"taskId": 3145828,
191+
"decisionTaskScheduledEventAttributes": {
192+
"taskList": {
193+
"name": "taylan-trial:4037e064-7565-4716-8169-e97eb2449f32"
194+
},
195+
"startToCloseTimeoutSeconds": 60
196+
}
197+
},
198+
{
199+
"eventId": 15,
200+
"timestamp": 1697648630460950187,
201+
"eventType": "DecisionTaskStarted",
202+
"taskId": 3145832,
203+
"decisionTaskStartedEventAttributes": {
204+
"scheduledEventId": 14,
205+
"identity": "2126702@taylan-trial@fx-worker@b25ed4e0-0864-41ed-843d-29265e3c6401",
206+
"requestId": "51123563-8c56-442a-9583-5f6b2ae46643"
207+
}
208+
},
209+
{
210+
"eventId": 16,
211+
"timestamp": 1697648630471749886,
212+
"eventType": "DecisionTaskCompleted",
213+
"taskId": 3145835,
214+
"decisionTaskCompletedEventAttributes": {
215+
"scheduledEventId": 14,
216+
"startedEventId": 15,
217+
"identity": "2126702@taylan-trial@fx-worker@b25ed4e0-0864-41ed-843d-29265e3c6401",
218+
"binaryChecksum": "uDeploy:"
219+
}
220+
},
221+
{
222+
"eventId": 17,
223+
"timestamp": 1697648630471777786,
224+
"eventType": "WorkflowExecutionCompleted",
225+
"taskId": 3145836,
226+
"workflowExecutionCompletedEventAttributes": {
227+
"decisionTaskCompletedEventId": 16
228+
}
229+
}
230+
]
231+

0 commit comments

Comments
 (0)