Skip to content

Commit 5ead824

Browse files
authored
Add the change in branch number case(test) to replayersuite (#1236)
* Fixed the spelling of replay_test file. * Added the Activity Registration required failure scenario to replayer test suite * Documentation change * Added test cases for branch workflow * Added change in number of branches scenario to replayer * Added copyright info * Update replay_test.go * Fixed merge issues * Added assertion * Updated assretion
1 parent f53f72d commit 5ead824

File tree

3 files changed

+376
-0
lines changed

3 files changed

+376
-0
lines changed

test/replaytests/branch.json

Lines changed: 265 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,265 @@
1+
[
2+
{
3+
"eventId": 1,
4+
"timestamp": 1679416555872012261,
5+
"eventType": "WorkflowExecutionStarted",
6+
"version": 0,
7+
"taskId": 5242880,
8+
"workflowExecutionStartedEventAttributes": {
9+
"workflowType": {
10+
"name": "branch"
11+
},
12+
"taskList": {
13+
"name": "branchGroup"
14+
},
15+
"executionStartToCloseTimeoutSeconds": 60,
16+
"taskStartToCloseTimeoutSeconds": 60,
17+
"continuedExecutionRunId": "",
18+
"originalExecutionRunId": "691e424f-453e-46d5-ad6e-b5fe44ea905b",
19+
"identity": "68502@agautam-NV709R969P@@e83a1347-9ee8-4554-8db5-0aba8e654bd5",
20+
"firstExecutionRunId": "691e424f-453e-46d5-ad6e-b5fe44ea905b",
21+
"attempt": 0,
22+
"cronSchedule": "",
23+
"firstDecisionTaskBackoffSeconds": 0,
24+
"header": {}
25+
}
26+
},
27+
{
28+
"eventId": 2,
29+
"timestamp": 1679416555874434594,
30+
"eventType": "DecisionTaskScheduled",
31+
"version": 0,
32+
"taskId": 5242881,
33+
"decisionTaskScheduledEventAttributes": {
34+
"taskList": {
35+
"name": "branchGroup"
36+
},
37+
"startToCloseTimeoutSeconds": 60,
38+
"attempt": 0
39+
}
40+
},
41+
{
42+
"eventId": 3,
43+
"timestamp": 1679416555977722803,
44+
"eventType": "DecisionTaskStarted",
45+
"version": 0,
46+
"taskId": 5242886,
47+
"decisionTaskStartedEventAttributes": {
48+
"scheduledEventId": 2,
49+
"identity": "68471@agautam-NV709R969P@branchGroup@9b8601e8-1ed4-438b-bd03-9b7a7382595b",
50+
"requestId": "b8596d8f-3d2c-427a-8e21-10505fdff896"
51+
}
52+
},
53+
{
54+
"eventId": 4,
55+
"timestamp": 1679416556030277261,
56+
"eventType": "DecisionTaskCompleted",
57+
"version": 0,
58+
"taskId": 5242889,
59+
"decisionTaskCompletedEventAttributes": {
60+
"scheduledEventId": 2,
61+
"startedEventId": 3,
62+
"identity": "68471@agautam-NV709R969P@branchGroup@9b8601e8-1ed4-438b-bd03-9b7a7382595b",
63+
"binaryChecksum": "bbf90d59747791397fd7d18d98635ee0"
64+
}
65+
},
66+
{
67+
"eventId": 5,
68+
"timestamp": 1679416556032126428,
69+
"eventType": "ActivityTaskScheduled",
70+
"version": 0,
71+
"taskId": 5242890,
72+
"activityTaskScheduledEventAttributes": {
73+
"activityId": "0",
74+
"activityType": {
75+
"name": "main.sampleActivity"
76+
},
77+
"taskList": {
78+
"name": "branchGroup"
79+
},
80+
"input": "ImJyYW5jaCAxIG9mIDMuIgo=",
81+
"scheduleToCloseTimeoutSeconds": 60,
82+
"scheduleToStartTimeoutSeconds": 60,
83+
"startToCloseTimeoutSeconds": 60,
84+
"heartbeatTimeoutSeconds": 20,
85+
"decisionTaskCompletedEventId": 4,
86+
"header": {}
87+
}
88+
},
89+
{
90+
"eventId": 6,
91+
"timestamp": 1679416556034048386,
92+
"eventType": "ActivityTaskScheduled",
93+
"version": 0,
94+
"taskId": 5242891,
95+
"activityTaskScheduledEventAttributes": {
96+
"activityId": "1",
97+
"activityType": {
98+
"name": "main.sampleActivity"
99+
},
100+
"taskList": {
101+
"name": "branchGroup"
102+
},
103+
"input": "ImJyYW5jaCAyIG9mIDMuIgo=",
104+
"scheduleToCloseTimeoutSeconds": 60,
105+
"scheduleToStartTimeoutSeconds": 60,
106+
"startToCloseTimeoutSeconds": 60,
107+
"heartbeatTimeoutSeconds": 20,
108+
"decisionTaskCompletedEventId": 4,
109+
"header": {}
110+
}
111+
},
112+
{
113+
"eventId": 7,
114+
"timestamp": 1679416556034178470,
115+
"eventType": "ActivityTaskScheduled",
116+
"version": 0,
117+
"taskId": 5242892,
118+
"activityTaskScheduledEventAttributes": {
119+
"activityId": "2",
120+
"activityType": {
121+
"name": "main.sampleActivity"
122+
},
123+
"taskList": {
124+
"name": "branchGroup"
125+
},
126+
"input": "ImJyYW5jaCAzIG9mIDMuIgo=",
127+
"scheduleToCloseTimeoutSeconds": 60,
128+
"scheduleToStartTimeoutSeconds": 60,
129+
"startToCloseTimeoutSeconds": 60,
130+
"heartbeatTimeoutSeconds": 20,
131+
"decisionTaskCompletedEventId": 4,
132+
"header": {}
133+
}
134+
},
135+
{
136+
"eventId": 8,
137+
"timestamp": 1679416556033170928,
138+
"eventType": "ActivityTaskStarted",
139+
"version": 0,
140+
"taskId": 5242893,
141+
"activityTaskStartedEventAttributes": {
142+
"scheduledEventId": 5,
143+
"identity": "68471@agautam-NV709R969P@branchGroup@9b8601e8-1ed4-438b-bd03-9b7a7382595b",
144+
"requestId": "5004df63-0a58-4a16-8466-67ee0997de68",
145+
"attempt": 0,
146+
"lastFailureReason": ""
147+
}
148+
},
149+
{
150+
"eventId": 9,
151+
"timestamp": 1679416556034104428,
152+
"eventType": "ActivityTaskStarted",
153+
"version": 0,
154+
"taskId": 5242894,
155+
"activityTaskStartedEventAttributes": {
156+
"scheduledEventId": 6,
157+
"identity": "68471@agautam-NV709R969P@branchGroup@9b8601e8-1ed4-438b-bd03-9b7a7382595b",
158+
"requestId": "e8e5ec37-925e-49f6-b59d-80935c3b01b0",
159+
"attempt": 0,
160+
"lastFailureReason": ""
161+
}
162+
},
163+
{
164+
"eventId": 10,
165+
"timestamp": 1679416556068643803,
166+
"eventType": "ActivityTaskStarted",
167+
"version": 0,
168+
"taskId": 5242898,
169+
"activityTaskStartedEventAttributes": {
170+
"scheduledEventId": 7,
171+
"identity": "68471@agautam-NV709R969P@branchGroup@9b8601e8-1ed4-438b-bd03-9b7a7382595b",
172+
"requestId": "d0a68205-7a41-4749-854a-acef7bc5a912",
173+
"attempt": 0,
174+
"lastFailureReason": ""
175+
}
176+
},
177+
{
178+
"eventId": 11,
179+
"timestamp": 1679416556089305720,
180+
"eventType": "ActivityTaskCompleted",
181+
"version": 0,
182+
"taskId": 5242900,
183+
"activityTaskCompletedEventAttributes": {
184+
"result": "IlJlc3VsdF9zYW1wbGVBY3Rpdml0eSIK",
185+
"scheduledEventId": 6,
186+
"startedEventId": 9,
187+
"identity": "68471@agautam-NV709R969P@branchGroup@9b8601e8-1ed4-438b-bd03-9b7a7382595b"
188+
}
189+
},
190+
{
191+
"eventId": 12,
192+
"timestamp": 1679416556089691970,
193+
"eventType": "DecisionTaskScheduled",
194+
"version": 0,
195+
"taskId": 5242902,
196+
"decisionTaskScheduledEventAttributes": {
197+
"taskList": {
198+
"name": "agautam-NV709R969P:2ffead12-7907-4ead-8b80-ee294165ff88"
199+
},
200+
"startToCloseTimeoutSeconds": 60,
201+
"attempt": 0
202+
}
203+
},
204+
{
205+
"eventId": 13,
206+
"timestamp": 1679416556103261761,
207+
"eventType": "ActivityTaskCompleted",
208+
"version": 0,
209+
"taskId": 5242906,
210+
"activityTaskCompletedEventAttributes": {
211+
"result": "IlJlc3VsdF9zYW1wbGVBY3Rpdml0eSIK",
212+
"scheduledEventId": 5,
213+
"startedEventId": 8,
214+
"identity": "68471@agautam-NV709R969P@branchGroup@9b8601e8-1ed4-438b-bd03-9b7a7382595b"
215+
}
216+
},
217+
{
218+
"eventId": 14,
219+
"timestamp": 1679416556114646970,
220+
"eventType": "ActivityTaskCompleted",
221+
"version": 0,
222+
"taskId": 5242909,
223+
"activityTaskCompletedEventAttributes": {
224+
"result": "IlJlc3VsdF9zYW1wbGVBY3Rpdml0eSIK",
225+
"scheduledEventId": 7,
226+
"startedEventId": 10,
227+
"identity": "68471@agautam-NV709R969P@branchGroup@9b8601e8-1ed4-438b-bd03-9b7a7382595b"
228+
}
229+
},
230+
{
231+
"eventId": 15,
232+
"timestamp": 1679416556128525803,
233+
"eventType": "DecisionTaskStarted",
234+
"version": 0,
235+
"taskId": 5242911,
236+
"decisionTaskStartedEventAttributes": {
237+
"scheduledEventId": 12,
238+
"identity": "68471@agautam-NV709R969P@branchGroup@9b8601e8-1ed4-438b-bd03-9b7a7382595b",
239+
"requestId": "773d5cd4-626c-4ce5-b340-503007a9c80f"
240+
}
241+
},
242+
{
243+
"eventId": 16,
244+
"timestamp": 1679416556152007511,
245+
"eventType": "DecisionTaskCompleted",
246+
"version": 0,
247+
"taskId": 5242914,
248+
"decisionTaskCompletedEventAttributes": {
249+
"scheduledEventId": 12,
250+
"startedEventId": 15,
251+
"identity": "68471@agautam-NV709R969P@branchGroup@9b8601e8-1ed4-438b-bd03-9b7a7382595b",
252+
"binaryChecksum": "bbf90d59747791397fd7d18d98635ee0"
253+
}
254+
},
255+
{
256+
"eventId": 17,
257+
"timestamp": 1679416556152617636,
258+
"eventType": "WorkflowExecutionCompleted",
259+
"version": 0,
260+
"taskId": 5242915,
261+
"workflowExecutionCompletedEventAttributes": {
262+
"decisionTaskCompletedEventId": 16
263+
}
264+
}
265+
]

test/replaytests/branch_workflow.go

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
// Copyright (c) 2017 Uber Technologies, Inc.
2+
//
3+
// Permission is hereby granted, free of charge, to any person obtaining a copy
4+
// of this software and associated documentation files (the "Software"), to deal
5+
// in the Software without restriction, including without limitation the rights
6+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
// copies of the Software, and to permit persons to whom the Software is
8+
// furnished to do so, subject to the following conditions:
9+
//
10+
// The above copyright notice and this permission notice shall be included in
11+
// all copies or substantial portions of the Software.
12+
//
13+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19+
// THE SOFTWARE.
20+
21+
package replaytests
22+
23+
import (
24+
"fmt"
25+
"go.uber.org/cadence/workflow"
26+
"time"
27+
)
28+
29+
/**
30+
* This sample workflow executes multiple branches in parallel. The number of branches is controlled by passed in parameter.
31+
*/
32+
33+
// sampleBranchWorkflow workflow decider
34+
func sampleBranchWorkflow(ctx workflow.Context) error {
35+
var futures []workflow.Future
36+
// starts activities in parallel
37+
ao := workflow.ActivityOptions{
38+
ScheduleToStartTimeout: time.Minute,
39+
StartToCloseTimeout: time.Minute,
40+
HeartbeatTimeout: time.Second * 20,
41+
}
42+
ctx = workflow.WithActivityOptions(ctx, ao)
43+
44+
for i := 1; i <= 3; i++ {
45+
activityInput := fmt.Sprintf("branch %d of 3", i)
46+
future := workflow.ExecuteActivity(ctx, sampleActivity, activityInput)
47+
futures = append(futures, future)
48+
}
49+
50+
// wait until all futures are done
51+
for _, future := range futures {
52+
if err := future.Get(ctx, nil); err != nil {
53+
return err
54+
}
55+
}
56+
57+
workflow.GetLogger(ctx).Info("Workflow completed.")
58+
59+
return nil
60+
}
61+
62+
// SampleBranchWorkflow2 run a workflow with different number of branch.
63+
// If the number of expected branches is changed the replayer should catch it as a non deterministic error.
64+
func sampleBranchWorkflow2(ctx workflow.Context) error {
65+
var futures []workflow.Future
66+
// starts activities in parallel
67+
ao := workflow.ActivityOptions{
68+
ScheduleToStartTimeout: time.Minute,
69+
StartToCloseTimeout: time.Minute,
70+
HeartbeatTimeout: time.Second * 20,
71+
}
72+
ctx = workflow.WithActivityOptions(ctx, ao)
73+
74+
for i := 1; i <= 4; i++ {
75+
activityInput := fmt.Sprintf("branch %d of 4", i)
76+
future := workflow.ExecuteActivity(ctx, sampleActivity, activityInput)
77+
futures = append(futures, future)
78+
}
79+
80+
// wait until all futures are done
81+
for _, future := range futures {
82+
if err := future.Get(ctx, nil); err != nil {
83+
return err
84+
}
85+
}
86+
87+
workflow.GetLogger(ctx).Info("Workflow completed.")
88+
89+
return nil
90+
}

test/replaytests/replay_test.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
package replaytests
2222

2323
import (
24+
"github.com/stretchr/testify/assert"
2425
"strings"
2526
"testing"
2627

@@ -99,6 +100,26 @@ func TestGreetingsWorkflow2(t *testing.T) {
99100
require.Error(t, err)
100101
}
101102

103+
func TestBranchWorkflow(t *testing.T) {
104+
replayer := worker.NewWorkflowReplayer()
105+
106+
replayer.RegisterWorkflowWithOptions(sampleBranchWorkflow, workflow.RegisterOptions{Name: "branch"})
107+
108+
err := replayer.ReplayWorkflowHistoryFromJSONFile(zaptest.NewLogger(t), "branch.json")
109+
require.NoError(t, err)
110+
}
111+
112+
// Fails with a non deterministic error because there was an additional unexpected branch. Decreasing the number of branches will
113+
// also fail the test because the history expects the same number of branches executing the activity.
114+
func TestBranchWorkflowWithExtraBranch(t *testing.T) {
115+
replayer := worker.NewWorkflowReplayer()
116+
117+
replayer.RegisterWorkflowWithOptions(sampleBranchWorkflow2, workflow.RegisterOptions{Name: "branch"})
118+
119+
err := replayer.ReplayWorkflowHistoryFromJSONFile(zaptest.NewLogger(t), "branch.json")
120+
assert.ErrorContains(t, err, "nondeterministic workflow")
121+
}
122+
102123
func TestParallel(t *testing.T) {
103124
replayer := worker.NewWorkflowReplayer()
104125

0 commit comments

Comments
 (0)