Skip to content

Commit 5c7ed92

Browse files
Use WorkflowReplayer for proper replay determinism tests
Previously the tests just ran workflows forward. Now they capture the event history after execution and replay it with WorkflowReplayer.replayWorkflowExecution(), which will throw NonDeterministicException if the workflow code generates different commands on replay. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 4fd80ec commit 5c7ed92

File tree

1 file changed

+21
-12
lines changed

1 file changed

+21
-12
lines changed

temporal-spring-ai/src/test/java/io/temporal/springai/WorkflowDeterminismTest.java

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,15 @@
44

55
import io.temporal.client.WorkflowClient;
66
import io.temporal.client.WorkflowOptions;
7+
import io.temporal.client.WorkflowStub;
8+
import io.temporal.common.WorkflowExecutionHistory;
79
import io.temporal.springai.activity.ChatModelActivityImpl;
810
import io.temporal.springai.chat.TemporalChatClient;
911
import io.temporal.springai.model.ActivityChatModel;
1012
import io.temporal.springai.tool.DeterministicTool;
1113
import io.temporal.springai.tool.SideEffectTool;
1214
import io.temporal.testing.TestWorkflowEnvironment;
15+
import io.temporal.testing.WorkflowReplayer;
1316
import io.temporal.worker.Worker;
1417
import io.temporal.workflow.WorkflowInterface;
1518
import io.temporal.workflow.WorkflowMethod;
@@ -26,8 +29,8 @@
2629
import org.springframework.ai.tool.annotation.Tool;
2730

2831
/**
29-
* Verifies that workflows using ActivityChatModel with tools execute without non-determinism
30-
* errors.
32+
* Verifies that workflows using ActivityChatModel with tools are deterministic by running them to
33+
* completion and then replaying from the captured history.
3134
*/
3235
class WorkflowDeterminismTest {
3336

@@ -48,13 +51,11 @@ void tearDown() {
4851
}
4952

5053
@Test
51-
void workflowWithChatModel_completesSuccessfully() {
54+
void workflowWithChatModel_replaysDeterministically() throws Exception {
5255
Worker worker = testEnv.newWorker(TASK_QUEUE);
5356
worker.registerWorkflowImplementationTypes(ChatWorkflowImpl.class);
54-
55-
// Register a ChatModelActivityImpl backed by a mock model that returns a canned response
56-
ChatModel mockModel = new StubChatModel("Hello from the model!");
57-
worker.registerActivitiesImplementations(new ChatModelActivityImpl(mockModel));
57+
worker.registerActivitiesImplementations(
58+
new ChatModelActivityImpl(new StubChatModel("Hello from the model!")));
5859

5960
testEnv.start();
6061

@@ -64,16 +65,19 @@ void workflowWithChatModel_completesSuccessfully() {
6465

6566
String result = workflow.chat("Hi");
6667
assertEquals("Hello from the model!", result);
68+
69+
// Capture history and replay — any non-determinism throws here
70+
WorkflowExecutionHistory history =
71+
client.fetchHistory(WorkflowStub.fromTyped(workflow).getExecution().getWorkflowId());
72+
WorkflowReplayer.replayWorkflowExecution(history, ChatWorkflowImpl.class);
6773
}
6874

6975
@Test
70-
void workflowWithDeterministicTool_completesSuccessfully() {
76+
void workflowWithTools_replaysDeterministically() throws Exception {
7177
Worker worker = testEnv.newWorker(TASK_QUEUE);
7278
worker.registerWorkflowImplementationTypes(ChatWithToolsWorkflowImpl.class);
73-
74-
// Model returns a simple response (no tool calls)
75-
ChatModel mockModel = new StubChatModel("I used the tools!");
76-
worker.registerActivitiesImplementations(new ChatModelActivityImpl(mockModel));
79+
worker.registerActivitiesImplementations(
80+
new ChatModelActivityImpl(new StubChatModel("I used the tools!")));
7781

7882
testEnv.start();
7983

@@ -83,6 +87,11 @@ void workflowWithDeterministicTool_completesSuccessfully() {
8387

8488
String result = workflow.chat("Use tools");
8589
assertEquals("I used the tools!", result);
90+
91+
// Capture history and replay
92+
WorkflowExecutionHistory history =
93+
client.fetchHistory(WorkflowStub.fromTyped(workflow).getExecution().getWorkflowId());
94+
WorkflowReplayer.replayWorkflowExecution(history, ChatWithToolsWorkflowImpl.class);
8695
}
8796

8897
// --- Workflow interfaces and implementations ---

0 commit comments

Comments
 (0)