|
23 | 23 | import static org.junit.Assert.*;
|
24 | 24 |
|
25 | 25 | import io.temporal.api.common.v1.WorkflowExecution;
|
| 26 | +import io.temporal.api.enums.v1.EventType; |
26 | 27 | import io.temporal.client.WorkflowClient;
|
27 | 28 | import io.temporal.client.WorkflowOptions;
|
| 29 | +import io.temporal.client.WorkflowUpdateException; |
28 | 30 | import io.temporal.testing.internal.SDKTestOptions;
|
29 | 31 | import io.temporal.testing.internal.SDKTestWorkflowRule;
|
30 | 32 | import io.temporal.worker.WorkerOptions;
|
@@ -89,6 +91,45 @@ public void testUpdateWithSignal() {
|
89 | 91 | workflow.execute());
|
90 | 92 | }
|
91 | 93 |
|
| 94 | + @Test |
| 95 | + public void testSpeculativeUpdateWithSignal() { |
| 96 | + String workflowId = UUID.randomUUID().toString(); |
| 97 | + WorkflowClient workflowClient = testWorkflowRule.getWorkflowClient(); |
| 98 | + WorkflowOptions options = |
| 99 | + SDKTestOptions.newWorkflowOptionsWithTimeouts(testWorkflowRule.getTaskQueue()).toBuilder() |
| 100 | + .setWorkflowId(workflowId) |
| 101 | + .build(); |
| 102 | + TestWorkflows.WorkflowWithUpdateAndSignal workflow = |
| 103 | + workflowClient.newWorkflowStub(TestWorkflows.WorkflowWithUpdateAndSignal.class, options); |
| 104 | + // To execute workflow client.execute() would do. But we want to start workflow and immediately |
| 105 | + // return. |
| 106 | + WorkflowExecution execution = WorkflowClient.start(workflow::execute); |
| 107 | + |
| 108 | + assertEquals(workflowId, execution.getWorkflowId()); |
| 109 | + |
| 110 | + SDKTestWorkflowRule.waitForOKQuery(workflow); |
| 111 | + assertEquals("initial", workflow.getState()); |
| 112 | + |
| 113 | + for (int i = 0; i < 5; i++) { |
| 114 | + assertThrows(WorkflowUpdateException.class, () -> workflow.update("")); |
| 115 | + } |
| 116 | + |
| 117 | + workflow.getState(); |
| 118 | + |
| 119 | + workflow.signal("signal 1"); |
| 120 | + |
| 121 | + assertEquals("update 1", workflow.update("update 1")); |
| 122 | + |
| 123 | + workflow.signal("signal 2"); |
| 124 | + |
| 125 | + workflow.complete(); |
| 126 | + |
| 127 | + assertEquals(Arrays.asList("signal 1", "update 1", "signal 2"), workflow.execute()); |
| 128 | + SDKTestWorkflowRule.assertNoHistoryEvent( |
| 129 | + workflowClient.fetchHistory(execution.getWorkflowId()).getHistory(), |
| 130 | + EventType.EVENT_TYPE_WORKFLOW_TASK_FAILED); |
| 131 | + } |
| 132 | + |
92 | 133 | public static class TestUpdateWithSignalWorkflowImpl
|
93 | 134 | implements TestWorkflows.WorkflowWithUpdateAndSignal {
|
94 | 135 | String state = "initial";
|
@@ -116,10 +157,18 @@ public void signal(String value) {
|
116 | 157 |
|
117 | 158 | @Override
|
118 | 159 | public String update(String value) {
|
| 160 | + Workflow.sleep(100); |
119 | 161 | updatesAndSignals.add(value);
|
120 | 162 | return value;
|
121 | 163 | }
|
122 | 164 |
|
| 165 | + @Override |
| 166 | + public void validator(String value) { |
| 167 | + if (value.isEmpty()) { |
| 168 | + throw new RuntimeException("Empty value"); |
| 169 | + } |
| 170 | + } |
| 171 | + |
123 | 172 | @Override
|
124 | 173 | public void complete() {
|
125 | 174 | promise.complete(null);
|
|
0 commit comments