Skip to content

Commit 2f5fdf1

Browse files
Test continue as new in an update (#1917)
1 parent 503cae7 commit 2f5fdf1

File tree

1 file changed

+162
-0
lines changed

1 file changed

+162
-0
lines changed
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
/*
2+
* Copyright (C) 2022 Temporal Technologies, Inc. All Rights Reserved.
3+
*
4+
* Copyright (C) 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5+
*
6+
* Modifications copyright (C) 2017 Uber Technologies, Inc.
7+
*
8+
* Licensed under the Apache License, Version 2.0 (the "License");
9+
* you may not use this material except in compliance with the License.
10+
* You may obtain a copy of the License at
11+
*
12+
* http://www.apache.org/licenses/LICENSE-2.0
13+
*
14+
* Unless required by applicable law or agreed to in writing, software
15+
* distributed under the License is distributed on an "AS IS" BASIS,
16+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17+
* See the License for the specific language governing permissions and
18+
* limitations under the License.
19+
*/
20+
21+
package io.temporal.workflow.updateTest;
22+
23+
import static org.junit.Assert.assertEquals;
24+
import static org.junit.Assert.assertThrows;
25+
26+
import io.temporal.activity.Activity;
27+
import io.temporal.activity.ActivityInterface;
28+
import io.temporal.activity.ActivityMethod;
29+
import io.temporal.activity.ActivityOptions;
30+
import io.temporal.api.common.v1.WorkflowExecution;
31+
import io.temporal.client.*;
32+
import io.temporal.testing.internal.SDKTestOptions;
33+
import io.temporal.testing.internal.SDKTestWorkflowRule;
34+
import io.temporal.worker.WorkerOptions;
35+
import io.temporal.workflow.CompletablePromise;
36+
import io.temporal.workflow.Workflow;
37+
import io.temporal.workflow.shared.TestActivities;
38+
import io.temporal.workflow.shared.TestWorkflows.WorkflowWithUpdate;
39+
import java.time.Duration;
40+
import java.util.ArrayList;
41+
import java.util.List;
42+
import java.util.Optional;
43+
import java.util.UUID;
44+
import org.junit.Rule;
45+
import org.junit.Test;
46+
import org.slf4j.Logger;
47+
import org.slf4j.LoggerFactory;
48+
49+
public class UpdateTestContinueAsNew {
50+
51+
private static final Logger log = LoggerFactory.getLogger(UpdateTestContinueAsNew.class);
52+
53+
@Rule
54+
public SDKTestWorkflowRule testWorkflowRule =
55+
SDKTestWorkflowRule.newBuilder()
56+
.setWorkerOptions(WorkerOptions.newBuilder().build())
57+
.setWorkflowTypes(TestUpdateWorkflowImpl.class)
58+
.setActivityImplementations(new ActivityImpl())
59+
.build();
60+
61+
@Test
62+
public void testContinueAsNewInAUpdate() {
63+
String workflowId = UUID.randomUUID().toString();
64+
WorkflowClient workflowClient = testWorkflowRule.getWorkflowClient();
65+
WorkflowOptions options =
66+
SDKTestOptions.newWorkflowOptionsWithTimeouts(testWorkflowRule.getTaskQueue()).toBuilder()
67+
.setWorkflowId(workflowId)
68+
.build();
69+
WorkflowWithUpdate workflow = workflowClient.newWorkflowStub(WorkflowWithUpdate.class, options);
70+
// To execute workflow client.execute() would do. But we want to start workflow and immediately
71+
// return.
72+
WorkflowExecution execution = WorkflowClient.start(workflow::execute);
73+
74+
SDKTestWorkflowRule.waitForOKQuery(workflow);
75+
assertEquals("initial", workflow.getState());
76+
77+
assertEquals(workflowId, execution.getWorkflowId());
78+
79+
assertEquals("Execute-Hello Update", workflow.update(0, "Hello Update"));
80+
assertEquals("Execute-Hello Update 2", workflow.update(0, "Hello Update 2"));
81+
// Complete should fail since we have not continued as new yet
82+
assertThrows(WorkflowUpdateException.class, () -> workflow.complete());
83+
84+
// Send an update to continue as new, must be async since the update won't complete
85+
WorkflowStub workflowStub = WorkflowStub.fromTyped(workflow);
86+
workflowStub.startUpdate("update", String.class, 0, "");
87+
88+
testWorkflowRule.waitForTheEndOfWFT(execution.getWorkflowId());
89+
testWorkflowRule.invalidateWorkflowCache();
90+
91+
assertEquals("Execute-Hello Update", workflow.update(0, "Hello Update"));
92+
assertEquals("Execute-Hello Update 2", workflow.update(0, "Hello Update 2"));
93+
94+
workflow.complete();
95+
96+
String result =
97+
testWorkflowRule
98+
.getWorkflowClient()
99+
.newUntypedWorkflowStub(execution, Optional.empty())
100+
.getResult(String.class);
101+
assertEquals("Execute-Hello Update Execute-Hello Update 2", result);
102+
}
103+
104+
public static class TestUpdateWorkflowImpl implements WorkflowWithUpdate {
105+
String state = "initial";
106+
List<String> updates = new ArrayList<>();
107+
CompletablePromise<Void> promise = Workflow.newPromise();
108+
private final TestActivities.TestActivity1 activity =
109+
Workflow.newActivityStub(
110+
TestActivities.TestActivity1.class,
111+
ActivityOptions.newBuilder().setScheduleToCloseTimeout(Duration.ofHours(1)).build());
112+
113+
@Override
114+
public String execute() {
115+
promise.get();
116+
return updates.get(0) + " " + updates.get(1);
117+
}
118+
119+
@Override
120+
public String getState() {
121+
return state;
122+
}
123+
124+
@Override
125+
public String update(Integer index, String value) {
126+
if (value.isEmpty()) {
127+
Workflow.newContinueAsNewStub(WorkflowWithUpdate.class).execute();
128+
}
129+
String result = activity.execute(value);
130+
updates.add(result);
131+
return result;
132+
}
133+
134+
@Override
135+
public void updateValidator(Integer index, String value) {}
136+
137+
@Override
138+
public void complete() {
139+
promise.complete(null);
140+
}
141+
142+
@Override
143+
public void completeValidator() {
144+
if (updates.size() < 2 || !Workflow.getInfo().getContinuedExecutionRunId().isPresent()) {
145+
throw new RuntimeException("Workflow not ready to complete");
146+
}
147+
}
148+
}
149+
150+
@ActivityInterface
151+
public interface GreetingActivities {
152+
@ActivityMethod
153+
String hello(String input);
154+
}
155+
156+
public static class ActivityImpl implements TestActivities.TestActivity1 {
157+
@Override
158+
public String execute(String input) {
159+
return Activity.getExecutionContext().getInfo().getActivityType() + "-" + input;
160+
}
161+
}
162+
}

0 commit comments

Comments
 (0)