From d04a03c96c4ec2bcb2fc15974b15dbd8ccc16fa6 Mon Sep 17 00:00:00 2001 From: Anthony Ting Date: Tue, 16 Dec 2025 16:15:39 -0800 Subject: [PATCH 01/14] fix(sdk): fix race condition when checkpoint completion happens before waitForStatusChange is called --- .../serdes/wait-for-callback-serdes.test.ts | 3 + .../checkpoint-central-termination.test.ts | 451 ++++++++++++++++++ .../utils/checkpoint/checkpoint-manager.ts | 21 + 3 files changed, 475 insertions(+) diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/serdes/wait-for-callback-serdes.test.ts b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/serdes/wait-for-callback-serdes.test.ts index 7102488b..8c2eb49b 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/serdes/wait-for-callback-serdes.test.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/serdes/wait-for-callback-serdes.test.ts @@ -9,6 +9,9 @@ import { createTests } from "../../../utils/test-helper"; createTests({ handler, invocationType: InvocationType.Event, + localRunnerConfig: { + skipTime: false, + }, tests: (runner) => { it("should handle waitForCallback with custom serdes configuration", async () => { const executionPromise = runner.run(); diff --git a/packages/aws-durable-execution-sdk-js/src/utils/checkpoint/checkpoint-central-termination.test.ts b/packages/aws-durable-execution-sdk-js/src/utils/checkpoint/checkpoint-central-termination.test.ts index ed7b918f..879b9a63 100644 --- a/packages/aws-durable-execution-sdk-js/src/utils/checkpoint/checkpoint-central-termination.test.ts +++ b/packages/aws-durable-execution-sdk-js/src/utils/checkpoint/checkpoint-central-termination.test.ts @@ -4,6 +4,7 @@ import { TerminationReason } from "../../termination-manager/types"; import { OperationLifecycleState, OperationSubType } from "../../types"; import { OperationType } from "@aws-sdk/client-lambda"; import { EventEmitter } from "events"; +import { hashId } from "../step-id-utils/step-id-utils"; jest.mock("../logger/logger"); @@ -199,6 +200,233 @@ describe("CheckpointManager - Centralized Termination", () => { await expect(promise).resolves.toBeUndefined(); }); + + describe("terminal status instant resolution", () => { + it.each([ + { status: "SUCCEEDED", operationStatus: "SUCCEEDED" }, + { status: "CANCELLED", operationStatus: "CANCELLED" }, + { status: "FAILED", operationStatus: "FAILED" }, + { status: "STOPPED", operationStatus: "STOPPED" }, + { status: "TIMED_OUT", operationStatus: "TIMED_OUT" }, + ])( + "should instantly resolve when status is $status", + async ({ operationStatus }) => { + const stepId = "step-1"; + + // Create operation in RETRY_WAITING state + checkpointManager.markOperationState( + stepId, + OperationLifecycleState.RETRY_WAITING, + { + metadata: { + stepId, + type: OperationType.STEP, + subType: OperationSubType.STEP, + }, + endTimestamp: new Date(Date.now() + 5000), + }, + ); + + // Set up stepData with terminal status + const hashedStepId = hashId(stepId); + (checkpointManager as any).stepData[hashedStepId] = { + Id: hashedStepId, + Status: operationStatus, + }; + + jest.clearAllTimers(); + + // Call waitForRetryTimer - should resolve immediately + const promise = checkpointManager.waitForRetryTimer(stepId); + + await expect(promise).resolves.toBeUndefined(); + + // Verify no polling was set up + const ops = checkpointManager.getAllOperations(); + const op = ops.get(stepId); + expect(op?.timer).toBeUndefined(); + expect(op?.resolver).toBeUndefined(); + expect(op?.pollCount).toBeUndefined(); + expect(op?.pollStartTime).toBeUndefined(); + + // Verify no timers were scheduled + expect(jest.getTimerCount()).toBe(0); + }, + ); + + it("should instantly resolve when status is terminal even with future endTimestamp", async () => { + const stepId = "step-1"; + + // Create operation with future endTimestamp + checkpointManager.markOperationState( + stepId, + OperationLifecycleState.RETRY_WAITING, + { + metadata: { + stepId, + type: OperationType.STEP, + subType: OperationSubType.STEP, + }, + endTimestamp: new Date(Date.now() + 10000), // 10 seconds in future + }, + ); + + // Set up stepData with terminal status + const hashedStepId = hashId(stepId); + (checkpointManager as any).stepData[hashedStepId] = { + Id: hashedStepId, + Status: "SUCCEEDED", + }; + + jest.clearAllTimers(); + + // Call waitForRetryTimer - should resolve immediately despite future endTimestamp + const promise = checkpointManager.waitForRetryTimer(stepId); + + await expect(promise).resolves.toBeUndefined(); + + // Verify no polling was set up + const ops = checkpointManager.getAllOperations(); + const op = ops.get(stepId); + expect(op?.timer).toBeUndefined(); + expect(op?.resolver).toBeUndefined(); + expect(op?.pollCount).toBeUndefined(); + expect(op?.pollStartTime).toBeUndefined(); + + // Verify no timers were scheduled + expect(jest.getTimerCount()).toBe(0); + }); + + it("should set up polling when status is not terminal", async () => { + const stepId = "step-1"; + + // Create operation in RETRY_WAITING state + checkpointManager.markOperationState( + stepId, + OperationLifecycleState.RETRY_WAITING, + { + metadata: { + stepId, + type: OperationType.STEP, + subType: OperationSubType.STEP, + }, + endTimestamp: new Date(Date.now() + 5000), + }, + ); + + // Set up stepData with non-terminal status + const hashedStepId = hashId(stepId); + (checkpointManager as any).stepData[hashedStepId] = { + Id: hashedStepId, + Status: "STARTED", // Non-terminal status + }; + + jest.clearAllTimers(); + + // Call waitForRetryTimer - should set up polling + const promise = checkpointManager.waitForRetryTimer(stepId); + + // Verify polling was set up + const ops = checkpointManager.getAllOperations(); + const op = ops.get(stepId); + expect(op?.timer).toBeDefined(); + expect(op?.resolver).toBeDefined(); + expect(op?.pollCount).toBe(0); + expect(op?.pollStartTime).toBeDefined(); + + // Verify timer was scheduled + expect(jest.getTimerCount()).toBeGreaterThan(0); + + // Clean up by resolving the operation + op?.resolver?.(); + await promise; + }); + + it("should set up polling when stepData is missing", async () => { + const stepId = "step-1"; + + // Create operation in RETRY_WAITING state + checkpointManager.markOperationState( + stepId, + OperationLifecycleState.RETRY_WAITING, + { + metadata: { + stepId, + type: OperationType.STEP, + subType: OperationSubType.STEP, + }, + endTimestamp: new Date(Date.now() + 5000), + }, + ); + + // Don't set up stepData - should be missing/undefined + + jest.clearAllTimers(); + + // Call waitForRetryTimer - should set up polling + const promise = checkpointManager.waitForRetryTimer(stepId); + + // Verify polling was set up + const ops = checkpointManager.getAllOperations(); + const op = ops.get(stepId); + expect(op?.timer).toBeDefined(); + expect(op?.resolver).toBeDefined(); + expect(op?.pollCount).toBe(0); + expect(op?.pollStartTime).toBeDefined(); + + // Verify timer was scheduled + expect(jest.getTimerCount()).toBeGreaterThan(0); + + // Clean up by resolving the operation + op?.resolver?.(); + await promise; + }); + + it("should set up polling when stepData status is undefined", async () => { + const stepId = "step-1"; + + // Create operation in RETRY_WAITING state + checkpointManager.markOperationState( + stepId, + OperationLifecycleState.RETRY_WAITING, + { + metadata: { + stepId, + type: OperationType.STEP, + subType: OperationSubType.STEP, + }, + endTimestamp: new Date(Date.now() + 5000), + }, + ); + + // Set up stepData without status + const hashedStepId = hashId(stepId); + (checkpointManager as any).stepData[hashedStepId] = { + Id: hashedStepId, + // Status is undefined + }; + + jest.clearAllTimers(); + + // Call waitForRetryTimer - should set up polling + const promise = checkpointManager.waitForRetryTimer(stepId); + + // Verify polling was set up + const ops = checkpointManager.getAllOperations(); + const op = ops.get(stepId); + expect(op?.timer).toBeDefined(); + expect(op?.resolver).toBeDefined(); + expect(op?.pollCount).toBe(0); + expect(op?.pollStartTime).toBeDefined(); + + // Verify timer was scheduled + expect(jest.getTimerCount()).toBeGreaterThan(0); + + // Clean up by resolving the operation + op?.resolver?.(); + await promise; + }); + }); }); describe("waitForStatusChange", () => { @@ -252,6 +480,229 @@ describe("CheckpointManager - Centralized Termination", () => { await expect(promise).resolves.toBeUndefined(); }); + + describe("terminal status instant resolution", () => { + it.each([ + { status: "SUCCEEDED", operationStatus: "SUCCEEDED" }, + { status: "CANCELLED", operationStatus: "CANCELLED" }, + { status: "FAILED", operationStatus: "FAILED" }, + { status: "STOPPED", operationStatus: "STOPPED" }, + { status: "TIMED_OUT", operationStatus: "TIMED_OUT" }, + ])( + "should instantly resolve when status is $status", + async ({ operationStatus }) => { + const stepId = "step-1"; + + // Create operation in IDLE_AWAITED state + checkpointManager.markOperationState( + stepId, + OperationLifecycleState.IDLE_AWAITED, + { + metadata: { + stepId, + type: OperationType.STEP, + subType: OperationSubType.WAIT, + }, + }, + ); + + // Set up stepData with terminal status + const hashedStepId = hashId(stepId); + (checkpointManager as any).stepData[hashedStepId] = { + Id: hashedStepId, + Status: operationStatus, + }; + + jest.clearAllTimers(); + + // Call waitForStatusChange - should resolve immediately + const promise = checkpointManager.waitForStatusChange(stepId); + + await expect(promise).resolves.toBeUndefined(); + + // Verify no polling was set up + const ops = checkpointManager.getAllOperations(); + const op = ops.get(stepId); + expect(op?.timer).toBeUndefined(); + expect(op?.resolver).toBeUndefined(); + expect(op?.pollCount).toBeUndefined(); + expect(op?.pollStartTime).toBeUndefined(); + + // Verify no timers were scheduled + expect(jest.getTimerCount()).toBe(0); + }, + ); + + it("should instantly resolve when status is terminal even with endTimestamp", async () => { + const stepId = "step-1"; + + // Create operation with future endTimestamp + checkpointManager.markOperationState( + stepId, + OperationLifecycleState.IDLE_AWAITED, + { + metadata: { + stepId, + type: OperationType.STEP, + subType: OperationSubType.WAIT, + }, + endTimestamp: new Date(Date.now() + 10000), // 10 seconds in future + }, + ); + + // Set up stepData with terminal status + const hashedStepId = hashId(stepId); + (checkpointManager as any).stepData[hashedStepId] = { + Id: hashedStepId, + Status: "SUCCEEDED", + }; + + jest.clearAllTimers(); + + // Call waitForStatusChange - should resolve immediately despite endTimestamp + const promise = checkpointManager.waitForStatusChange(stepId); + + await expect(promise).resolves.toBeUndefined(); + + // Verify no polling was set up + const ops = checkpointManager.getAllOperations(); + const op = ops.get(stepId); + expect(op?.timer).toBeUndefined(); + expect(op?.resolver).toBeUndefined(); + expect(op?.pollCount).toBeUndefined(); + expect(op?.pollStartTime).toBeUndefined(); + + // Verify no timers were scheduled + expect(jest.getTimerCount()).toBe(0); + }); + + it("should set up polling when status is not terminal", async () => { + const stepId = "step-1"; + + // Create operation in IDLE_AWAITED state + checkpointManager.markOperationState( + stepId, + OperationLifecycleState.IDLE_AWAITED, + { + metadata: { + stepId, + type: OperationType.STEP, + subType: OperationSubType.WAIT, + }, + }, + ); + + // Set up stepData with non-terminal status + const hashedStepId = hashId(stepId); + (checkpointManager as any).stepData[hashedStepId] = { + Id: hashedStepId, + Status: "STARTED", // Non-terminal status + }; + + jest.clearAllTimers(); + + // Call waitForStatusChange - should set up polling + const promise = checkpointManager.waitForStatusChange(stepId); + + // Verify polling was set up + const ops = checkpointManager.getAllOperations(); + const op = ops.get(stepId); + expect(op?.timer).toBeDefined(); + expect(op?.resolver).toBeDefined(); + expect(op?.pollCount).toBe(0); + expect(op?.pollStartTime).toBeDefined(); + + // Verify timer was scheduled + expect(jest.getTimerCount()).toBeGreaterThan(0); + + // Clean up by resolving the operation + op?.resolver?.(); + await promise; + }); + + it("should set up polling when stepData is missing", async () => { + const stepId = "step-1"; + + // Create operation in IDLE_AWAITED state + checkpointManager.markOperationState( + stepId, + OperationLifecycleState.IDLE_AWAITED, + { + metadata: { + stepId, + type: OperationType.STEP, + subType: OperationSubType.WAIT, + }, + }, + ); + + // Don't set up stepData - should be missing/undefined + + jest.clearAllTimers(); + + // Call waitForStatusChange - should set up polling + const promise = checkpointManager.waitForStatusChange(stepId); + + // Verify polling was set up + const ops = checkpointManager.getAllOperations(); + const op = ops.get(stepId); + expect(op?.timer).toBeDefined(); + expect(op?.resolver).toBeDefined(); + expect(op?.pollCount).toBe(0); + expect(op?.pollStartTime).toBeDefined(); + + // Verify timer was scheduled + expect(jest.getTimerCount()).toBeGreaterThan(0); + + // Clean up by resolving the operation + op?.resolver?.(); + await promise; + }); + + it("should set up polling when stepData status is undefined", async () => { + const stepId = "step-1"; + + // Create operation in IDLE_AWAITED state + checkpointManager.markOperationState( + stepId, + OperationLifecycleState.IDLE_AWAITED, + { + metadata: { + stepId, + type: OperationType.STEP, + subType: OperationSubType.WAIT, + }, + }, + ); + + // Set up stepData without status + const hashedStepId = hashId(stepId); + (checkpointManager as any).stepData[hashedStepId] = { + Id: hashedStepId, + // Status is undefined + }; + + jest.clearAllTimers(); + + // Call waitForStatusChange - should set up polling + const promise = checkpointManager.waitForStatusChange(stepId); + + // Verify polling was set up + const ops = checkpointManager.getAllOperations(); + const op = ops.get(stepId); + expect(op?.timer).toBeDefined(); + expect(op?.resolver).toBeDefined(); + expect(op?.pollCount).toBe(0); + expect(op?.pollStartTime).toBeDefined(); + + // Verify timer was scheduled + expect(jest.getTimerCount()).toBeGreaterThan(0); + + // Clean up by resolving the operation + op?.resolver?.(); + await promise; + }); + }); }); describe("termination cooldown", () => { diff --git a/packages/aws-durable-execution-sdk-js/src/utils/checkpoint/checkpoint-manager.ts b/packages/aws-durable-execution-sdk-js/src/utils/checkpoint/checkpoint-manager.ts index 6d526e50..979458af 100644 --- a/packages/aws-durable-execution-sdk-js/src/utils/checkpoint/checkpoint-manager.ts +++ b/packages/aws-durable-execution-sdk-js/src/utils/checkpoint/checkpoint-manager.ts @@ -2,6 +2,7 @@ import { CheckpointDurableExecutionRequest, OperationUpdate, Operation, + OperationStatus, } from "@aws-sdk/client-lambda"; import { DurableExecutionClient } from "../../types/durable-execution"; import { log } from "../logger/logger"; @@ -23,6 +24,14 @@ import { export const STEP_DATA_UPDATED_EVENT = "stepDataUpdated"; +const TERMINAL_STATUSES: OperationStatus[] = [ + OperationStatus.SUCCEEDED, + OperationStatus.CANCELLED, + OperationStatus.FAILED, + OperationStatus.STOPPED, + OperationStatus.TIMED_OUT, +]; + interface QueuedCheckpoint { stepId: string; data: Partial; @@ -494,6 +503,12 @@ export class CheckpointManager implements Checkpoint { ); } + // Resolve immediately if the step was completed already + const stepData = this.stepData[hashId(stepId)]; + if (stepData?.Status && TERMINAL_STATUSES.includes(stepData.Status)) { + return Promise.resolve(); + } + // Start timer with polling this.startTimerWithPolling(stepId, op.endTimestamp); @@ -515,6 +530,12 @@ export class CheckpointManager implements Checkpoint { ); } + // Resolve immediately if the step was completed already + const stepData = this.stepData[hashId(stepId)]; + if (stepData?.Status && TERMINAL_STATUSES.includes(stepData.Status)) { + return Promise.resolve(); + } + // Start timer with polling this.startTimerWithPolling(stepId, op.endTimestamp); From 41c9cac6dad4767f1617f8c5848b1319860cdd41 Mon Sep 17 00:00:00 2001 From: Anthony Ting Date: Tue, 16 Dec 2025 17:17:45 -0800 Subject: [PATCH 02/14] add a separate test file instead of reusing serdes test --- ...wait-for-callback-quick-completion.test.ts | 37 +++++++++++++++++++ .../wait-for-callback-quick-completion.ts | 29 +++++++++++++++ .../serdes/wait-for-callback-serdes.test.ts | 3 -- 3 files changed, 66 insertions(+), 3 deletions(-) create mode 100644 packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/quick-completion/wait-for-callback-quick-completion.test.ts create mode 100644 packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/quick-completion/wait-for-callback-quick-completion.ts diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/quick-completion/wait-for-callback-quick-completion.test.ts b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/quick-completion/wait-for-callback-quick-completion.test.ts new file mode 100644 index 00000000..26775d42 --- /dev/null +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/quick-completion/wait-for-callback-quick-completion.test.ts @@ -0,0 +1,37 @@ +import { InvocationType } from "@aws-sdk/client-lambda"; +import { handler } from "./wait-for-callback-quick-completion"; +import { createTests } from "../../../utils/test-helper"; + +createTests({ + handler, + invocationType: InvocationType.Event, + localRunnerConfig: { + skipTime: false, + }, + tests: (runner, { isCloud }) => { + it("should handle waitForCallback when callback completes before ", async () => { + const callbackOp = runner.getOperationByIndex(0); + + const executionPromise = runner.run({ + payload: isCloud + ? { + submitterDelay: 5, + } + : {}, + }); + + // only wait for started status + await callbackOp.waitForData(); + + await callbackOp.sendCallbackSuccess("{}"); + + const result = await executionPromise; + + expect(result.getResult()).toEqual({ + callbackResult: "{}", + success: true, + }); + expect(result.getInvocations().length).toBe(1); + }); + }, +}); diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/quick-completion/wait-for-callback-quick-completion.ts b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/quick-completion/wait-for-callback-quick-completion.ts new file mode 100644 index 00000000..0f8e3201 --- /dev/null +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/quick-completion/wait-for-callback-quick-completion.ts @@ -0,0 +1,29 @@ +import { + DurableContext, + withDurableExecution, +} from "@aws/durable-execution-sdk-js"; +import { ExampleConfig } from "../../../types"; + +export const config: ExampleConfig = { + name: "Wait for Callback - Quick Completion", + description: + "Demonstrates waitForCallback invocation-level completion scenario", +}; + +export const handler = withDurableExecution( + async (event: { submitterDelay: number }, context: DurableContext) => { + const result = await context.waitForCallback(async () => { + if (event.submitterDelay) { + await new Promise((resolve) => + setTimeout(resolve, event.submitterDelay * 1000), + ); + } + return Promise.resolve(); + }); + + return { + callbackResult: result, + success: true, + }; + }, +); diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/serdes/wait-for-callback-serdes.test.ts b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/serdes/wait-for-callback-serdes.test.ts index 8c2eb49b..7102488b 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/serdes/wait-for-callback-serdes.test.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/serdes/wait-for-callback-serdes.test.ts @@ -9,9 +9,6 @@ import { createTests } from "../../../utils/test-helper"; createTests({ handler, invocationType: InvocationType.Event, - localRunnerConfig: { - skipTime: false, - }, tests: (runner) => { it("should handle waitForCallback with custom serdes configuration", async () => { const executionPromise = runner.run(); From b66aa9a434f5b3d1952c11bf4bd0d221dfbc3adf Mon Sep 17 00:00:00 2001 From: Anthony Ting Date: Tue, 16 Dec 2025 13:33:55 -0800 Subject: [PATCH 03/14] fix(testing-sdk): support PENDING status reinvocation and execution failure --- ...-for-callback-multiple-invocations.test.ts | 3 + .../__tests__/execution-handlers.test.ts | 10 +- .../handlers/execution-handlers.ts | 5 +- .../checkpoint-manager-dirty.test.ts | 9 + .../__tests__/execution-manager.test.ts | 96 ++- .../storage/checkpoint-manager.ts | 4 + .../storage/execution-manager.ts | 12 +- .../worker-api/worker-api-response.ts | 7 +- .../__tests__/checkpoint-worker.test.ts | 10 +- ...tion-orchestrator-invocation-order.test.ts | 34 +- ...ion-orchestrator-pending-rejection.test.ts | 765 ++++++++++++++++++ .../test-execution-orchestrator.test.ts | 11 +- .../local/api-client/checkpoint-api-client.ts | 5 +- .../checkpoint-worker-api-client.ts | 5 +- .../__tests__/invocation-tracker.test.ts | 15 +- .../local/operations/invocation-tracker.ts | 5 +- .../local/test-execution-orchestrator.ts | 94 ++- 17 files changed, 1032 insertions(+), 58 deletions(-) create mode 100644 packages/aws-durable-execution-sdk-js-testing/src/test-runner/local/__tests__/test-execution-orchestrator-pending-rejection.test.ts diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/multiple-invocations/wait-for-callback-multiple-invocations.test.ts b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/multiple-invocations/wait-for-callback-multiple-invocations.test.ts index 97d114b9..92e6bc4b 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/multiple-invocations/wait-for-callback-multiple-invocations.test.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/multiple-invocations/wait-for-callback-multiple-invocations.test.ts @@ -8,6 +8,9 @@ import { createTests } from "../../../utils/test-helper"; createTests({ handler, invocationType: InvocationType.Event, + localRunnerConfig: { + skipTime: false, + }, tests: (runner) => { it("should handle multiple invocations tracking with waitForCallback operations", async () => { // Get operations for verification diff --git a/packages/aws-durable-execution-sdk-js-testing/src/checkpoint-server/handlers/__tests__/execution-handlers.test.ts b/packages/aws-durable-execution-sdk-js-testing/src/checkpoint-server/handlers/__tests__/execution-handlers.test.ts index f525e888..7846f6e1 100644 --- a/packages/aws-durable-execution-sdk-js-testing/src/checkpoint-server/handlers/__tests__/execution-handlers.test.ts +++ b/packages/aws-durable-execution-sdk-js-testing/src/checkpoint-server/handlers/__tests__/execution-handlers.test.ts @@ -141,7 +141,10 @@ describe("execution handlers", () => { Error: { Payload: undefined }, }, }; - completeInvocationSpy.mockReturnValue(mockEvent); + completeInvocationSpy.mockReturnValue({ + event: mockEvent, + hasDirtyOperations: false, + }); const errorObject: ErrorObject = { ErrorType: "TestError", @@ -160,7 +163,10 @@ describe("execution handlers", () => { invocationId, errorObject, ); - expect(result).toEqual(mockEvent); + expect(result).toEqual({ + event: mockEvent, + hasDirtyOperations: false, + }); }); }); }); diff --git a/packages/aws-durable-execution-sdk-js-testing/src/checkpoint-server/handlers/execution-handlers.ts b/packages/aws-durable-execution-sdk-js-testing/src/checkpoint-server/handlers/execution-handlers.ts index d7722f5a..8aa41033 100644 --- a/packages/aws-durable-execution-sdk-js-testing/src/checkpoint-server/handlers/execution-handlers.ts +++ b/packages/aws-durable-execution-sdk-js-testing/src/checkpoint-server/handlers/execution-handlers.ts @@ -1,4 +1,4 @@ -import { ErrorObject, Event } from "@aws-sdk/client-lambda"; +import { ErrorObject } from "@aws-sdk/client-lambda"; import { createExecutionId, ExecutionId, @@ -12,6 +12,7 @@ import { StartDurableExecutionRequest, StartInvocationRequest, } from "../worker-api/worker-api-request"; +import { CompleteInvocationResponse } from "../worker-api/worker-api-response"; /** * Starts a durable execution. Returns the data needed for the handler invocation event. @@ -42,6 +43,6 @@ export function processCompleteInvocation( invocationId: InvocationId, error: ErrorObject | undefined, executionManager: ExecutionManager, -): Event { +): CompleteInvocationResponse { return executionManager.completeInvocation(executionId, invocationId, error); } diff --git a/packages/aws-durable-execution-sdk-js-testing/src/checkpoint-server/storage/__tests__/checkpoint-manager-dirty.test.ts b/packages/aws-durable-execution-sdk-js-testing/src/checkpoint-server/storage/__tests__/checkpoint-manager-dirty.test.ts index 0ac1349b..6b42a30b 100644 --- a/packages/aws-durable-execution-sdk-js-testing/src/checkpoint-server/storage/__tests__/checkpoint-manager-dirty.test.ts +++ b/packages/aws-durable-execution-sdk-js-testing/src/checkpoint-server/storage/__tests__/checkpoint-manager-dirty.test.ts @@ -36,6 +36,7 @@ describe("CheckpointManager dirty operation tracking", () => { const dirtyOperations = storage.getDirtyOperations(); expect(dirtyOperations).toEqual([]); + expect(storage.hasDirtyOperations()).toBe(false); }); it("should return dirty operations and clear the dirty set", () => { @@ -51,8 +52,11 @@ describe("CheckpointManager dirty operation tracking", () => { expect(firstCall).toHaveLength(1); expect(firstCall[0].Id).toBe("dirty-step"); + expect(storage.hasDirtyOperations()).toBe(false); + const secondCall = storage.getDirtyOperations(); expect(secondCall).toEqual([]); + expect(storage.hasDirtyOperations()).toBe(false); }); it("should return multiple dirty operations in correct order", () => { @@ -86,6 +90,7 @@ describe("CheckpointManager dirty operation tracking", () => { "second-op", "third-op", ]); + expect(storage.hasDirtyOperations()).toBe(false); }); }); @@ -100,16 +105,20 @@ describe("CheckpointManager dirty operation tracking", () => { storage.registerUpdate(stepUpdate); // Verify operation is dirty before invocation + expect(storage.hasDirtyOperations()).toBe(true); const dirtyBefore = storage.getDirtyOperations(); expect(dirtyBefore).toHaveLength(1); + expect(storage.hasDirtyOperations()).toBe(false); // Start new invocation should clear dirty set const invocationId = createInvocationId("test-invocation"); storage.startInvocation(invocationId); + expect(storage.hasDirtyOperations()).toBe(false); // Verify dirty set is cleared after invocation const dirtyAfter = storage.getDirtyOperations(); expect(dirtyAfter).toEqual([]); + expect(storage.hasDirtyOperations()).toBe(false); }); it("should return all operations from startInvocation", () => { diff --git a/packages/aws-durable-execution-sdk-js-testing/src/checkpoint-server/storage/__tests__/execution-manager.test.ts b/packages/aws-durable-execution-sdk-js-testing/src/checkpoint-server/storage/__tests__/execution-manager.test.ts index f4ffb69b..065d2c0f 100644 --- a/packages/aws-durable-execution-sdk-js-testing/src/checkpoint-server/storage/__tests__/execution-manager.test.ts +++ b/packages/aws-durable-execution-sdk-js-testing/src/checkpoint-server/storage/__tests__/execution-manager.test.ts @@ -4,6 +4,7 @@ import { OperationType, EventType, ErrorObject, + OperationAction, } from "@aws-sdk/client-lambda"; import { ExecutionManager, StartExecutionParams } from "../execution-manager"; import { CheckpointManager } from "../checkpoint-manager"; @@ -520,7 +521,10 @@ describe("execution-manager", () => { ); // Verify the result - expect(result).toBe(mockHistoryEvent); + expect(result).toEqual({ + event: mockHistoryEvent, + hasDirtyOperations: false, + }); // Verify CheckpointManager.completeInvocation was called expect(completeInvocationSpy).toHaveBeenCalledWith(invocationId); @@ -593,7 +597,10 @@ describe("execution-manager", () => { ); // Verify the result - expect(result).toBe(mockHistoryEvent); + expect(result).toEqual({ + event: mockHistoryEvent, + hasDirtyOperations: false, + }); // Verify CheckpointManager.completeInvocation was called expect(completeInvocationSpy).toHaveBeenCalledWith(invocationId); @@ -642,6 +649,91 @@ describe("execution-manager", () => { // Verify CheckpointManager.completeInvocation was called expect(completeInvocationSpy).toHaveBeenCalledWith(invocationId); }); + + it("should return hasDirtyOperations as true when checkpoint storage has dirty operations", () => { + // Create an execution first + const executionId = createExecutionId("test-execution-id"); + const invocationId = createInvocationId("test-invocation-id"); + executionManager.startExecution({ executionId, invocationId }); + + const storage = executionManager.getCheckpointsByExecution(executionId); + expect(storage).toBeDefined(); + + // Register an operation to make the storage dirty + const stepUpdate = { + Id: "test-step-operation", + Type: OperationType.STEP, + Action: OperationAction.START, + }; + storage!.registerUpdate(stepUpdate); + + // Mock the completeInvocation method on CheckpointManager + const mockTimestamps = { + startTimestamp: new Date("2023-01-01T00:00:00.000Z"), + endTimestamp: new Date("2023-01-01T00:01:00.000Z"), + }; + + const completeInvocationSpy = jest + .spyOn(storage!, "completeInvocation") + .mockReturnValue(mockTimestamps); + + // Mock the eventProcessor.createHistoryEvent method + const mockHistoryEvent = { + EventType: EventType.InvocationCompleted, + Timestamp: new Date(), + InvocationCompletedDetails: { + StartTimestamp: mockTimestamps.startTimestamp, + EndTimestamp: mockTimestamps.endTimestamp, + Error: { + Payload: undefined, + }, + RequestId: invocationId, + }, + }; + + const createHistoryEventSpy = jest + .spyOn(storage!.eventProcessor, "createHistoryEvent") + .mockReturnValue(mockHistoryEvent); + + // Mock hasDirtyOperations to return true + const hasDirtyOperationsSpy = jest + .spyOn(storage!, "hasDirtyOperations") + .mockReturnValue(true); + + // Call the method + const result = executionManager.completeInvocation( + executionId, + invocationId, + undefined, + ); + + // Verify the result shows dirty operations exist + expect(result).toEqual({ + event: mockHistoryEvent, + hasDirtyOperations: true, + }); + + // Verify CheckpointManager.completeInvocation was called + expect(completeInvocationSpy).toHaveBeenCalledWith(invocationId); + + // Verify hasDirtyOperations was called + expect(hasDirtyOperationsSpy).toHaveBeenCalled(); + + // Verify eventProcessor.createHistoryEvent was called with correct parameters + expect(createHistoryEventSpy).toHaveBeenCalledWith( + EventType.InvocationCompleted, + undefined, + "InvocationCompletedDetails", + { + StartTimestamp: mockTimestamps.startTimestamp, + EndTimestamp: mockTimestamps.endTimestamp, + Error: { + Payload: undefined, + }, + RequestId: invocationId, + }, + ); + }); }); }); }); diff --git a/packages/aws-durable-execution-sdk-js-testing/src/checkpoint-server/storage/checkpoint-manager.ts b/packages/aws-durable-execution-sdk-js-testing/src/checkpoint-server/storage/checkpoint-manager.ts index b4f66e53..e9b14aec 100644 --- a/packages/aws-durable-execution-sdk-js-testing/src/checkpoint-server/storage/checkpoint-manager.ts +++ b/packages/aws-durable-execution-sdk-js-testing/src/checkpoint-server/storage/checkpoint-manager.ts @@ -50,6 +50,10 @@ export class CheckpointManager { return this.operationDataMap; } + hasDirtyOperations(): boolean { + return !!this.dirtyOperationIds.size; + } + getDirtyOperations(): Operation[] { const dirtyOperations = Array.from(this.dirtyOperationIds).map((id) => { const operationEvents = this.operationDataMap.get(id); diff --git a/packages/aws-durable-execution-sdk-js-testing/src/checkpoint-server/storage/execution-manager.ts b/packages/aws-durable-execution-sdk-js-testing/src/checkpoint-server/storage/execution-manager.ts index f0d602c9..d18bcc2d 100644 --- a/packages/aws-durable-execution-sdk-js-testing/src/checkpoint-server/storage/execution-manager.ts +++ b/packages/aws-durable-execution-sdk-js-testing/src/checkpoint-server/storage/execution-manager.ts @@ -9,11 +9,12 @@ import { CallbackId, CheckpointToken } from "../utils/tagged-strings"; import { ExecutionId, InvocationId } from "../utils/tagged-strings"; import { decodeCallbackId } from "../utils/callback-id"; import { OperationEvents } from "../../test-runner/common/operations/operation-with-data"; -import { ErrorObject, EventType, Event } from "@aws-sdk/client-lambda"; +import { ErrorObject, EventType } from "@aws-sdk/client-lambda"; import { StartDurableExecutionRequest, StartInvocationRequest, } from "../worker-api/worker-api-request"; +import { CompleteInvocationResponse } from "../worker-api/worker-api-response"; export interface InvocationResult { checkpointToken: CheckpointToken; @@ -105,7 +106,7 @@ export class ExecutionManager { executionId: ExecutionId, invocationId: InvocationId, error: ErrorObject | undefined, - ): Event { + ): CompleteInvocationResponse { const checkpointStorage = this.executions.get(executionId); if (!checkpointStorage) { @@ -115,7 +116,7 @@ export class ExecutionManager { const { startTimestamp, endTimestamp } = checkpointStorage.completeInvocation(invocationId); - return checkpointStorage.eventProcessor.createHistoryEvent( + const event = checkpointStorage.eventProcessor.createHistoryEvent( EventType.InvocationCompleted, undefined, "InvocationCompletedDetails", @@ -128,6 +129,11 @@ export class ExecutionManager { RequestId: invocationId, }, ); + + return { + event, + hasDirtyOperations: checkpointStorage.hasDirtyOperations(), + }; } /** diff --git a/packages/aws-durable-execution-sdk-js-testing/src/checkpoint-server/worker-api/worker-api-response.ts b/packages/aws-durable-execution-sdk-js-testing/src/checkpoint-server/worker-api/worker-api-response.ts index ecd80d99..90804aaf 100644 --- a/packages/aws-durable-execution-sdk-js-testing/src/checkpoint-server/worker-api/worker-api-response.ts +++ b/packages/aws-durable-execution-sdk-js-testing/src/checkpoint-server/worker-api/worker-api-response.ts @@ -16,10 +16,15 @@ export interface PollCheckpointDataResponse { operations: CheckpointOperation[]; } +export interface CompleteInvocationResponse { + event: Event; + hasDirtyOperations: boolean; +} + export interface WorkerApiResponseMapping { [ApiType.StartDurableExecution]: InvocationResult; [ApiType.StartInvocation]: InvocationResult; - [ApiType.CompleteInvocation]: Event; + [ApiType.CompleteInvocation]: CompleteInvocationResponse; [ApiType.UpdateCheckpointData]: Record; [ApiType.PollCheckpointData]: Promise; [ApiType.GetDurableExecutionState]: GetDurableExecutionStateResponse; diff --git a/packages/aws-durable-execution-sdk-js-testing/src/checkpoint-server/worker/__tests__/checkpoint-worker.test.ts b/packages/aws-durable-execution-sdk-js-testing/src/checkpoint-server/worker/__tests__/checkpoint-worker.test.ts index 922ef715..83373a7b 100644 --- a/packages/aws-durable-execution-sdk-js-testing/src/checkpoint-server/worker/__tests__/checkpoint-worker.test.ts +++ b/packages/aws-durable-execution-sdk-js-testing/src/checkpoint-server/worker/__tests__/checkpoint-worker.test.ts @@ -306,7 +306,10 @@ describe("CheckpointWorker", () => { Timestamp: new Date(), Type: "InvocationComplete", }; - mockApiHandlerInstance.performApiCall.mockReturnValue(mockEvent); + mockApiHandlerInstance.performApiCall.mockReturnValue({ + event: mockEvent, + hasDirtyOperations: false, + }); messageHandler(command); @@ -318,7 +321,10 @@ describe("CheckpointWorker", () => { data: { type: ApiType.CompleteInvocation, requestId: "complete-request-456", - response: mockEvent, + response: { + event: mockEvent, + hasDirtyOperations: false, + }, }, }); }); diff --git a/packages/aws-durable-execution-sdk-js-testing/src/test-runner/local/__tests__/test-execution-orchestrator-invocation-order.test.ts b/packages/aws-durable-execution-sdk-js-testing/src/test-runner/local/__tests__/test-execution-orchestrator-invocation-order.test.ts index 4a85a048..bb9fefee 100644 --- a/packages/aws-durable-execution-sdk-js-testing/src/test-runner/local/__tests__/test-execution-orchestrator-invocation-order.test.ts +++ b/packages/aws-durable-execution-sdk-js-testing/src/test-runner/local/__tests__/test-execution-orchestrator-invocation-order.test.ts @@ -25,6 +25,7 @@ import { ILocalDurableTestRunnerFactory } from "../interfaces/durable-test-runne import { DurableApiClient } from "../../common/create-durable-api-client"; import { CheckpointApiClient } from "../api-client/checkpoint-api-client"; import { InvocationResult } from "../../../checkpoint-server/storage/execution-manager"; +import { CompleteInvocationResponse } from "../../../checkpoint-server/worker-api/worker-api-response"; // Mock dependencies jest.mock("../operations/local-operation-storage"); @@ -75,15 +76,20 @@ describe("TestExecutionOrchestrator - Invocation History Ordering", () => { // Tracking arrays for call order verification let callOrder: string[]; let addHistoryEventSpy: jest.SpyInstance; - let completeInvocationSpy: jest.SpyInstance; - - const mockInvocationCompletedEvent: Event = { - EventType: EventType.InvocationCompleted, - InvocationCompletedDetails: { - RequestId: "invocation-request-id", - StartTimestamp: new Date(), - EndTimestamp: new Date(), + let completeInvocationSpy: jest.SpyInstance< + Promise + >; + + const mockInvocationCompletedEvent: CompleteInvocationResponse = { + event: { + EventType: EventType.InvocationCompleted, + InvocationCompletedDetails: { + RequestId: "invocation-request-id", + StartTimestamp: new Date(), + EndTimestamp: new Date(), + }, }, + hasDirtyOperations: false, }; const nonResolvingPromise = new Promise(() => { @@ -135,7 +141,10 @@ describe("TestExecutionOrchestrator - Invocation History Ordering", () => { }), completeInvocation: jest.fn().mockImplementation(() => { callOrder.push("completeInvocation"); - return Promise.resolve(mockInvocationCompletedEvent); + return Promise.resolve({ + event: mockInvocationCompletedEvent, + hasDirtyOperations: false, + }); }), }; @@ -509,8 +518,11 @@ describe("TestExecutionOrchestrator - Invocation History Ordering", () => { invocationCount++; callOrder.push(`completeInvocation${invocationCount}`); return Promise.resolve({ - ...mockInvocationCompletedEvent, - EventId: invocationCount, + event: { + ...mockInvocationCompletedEvent, + EventId: invocationCount, + }, + hasDirtyOperations: false, }); }); diff --git a/packages/aws-durable-execution-sdk-js-testing/src/test-runner/local/__tests__/test-execution-orchestrator-pending-rejection.test.ts b/packages/aws-durable-execution-sdk-js-testing/src/test-runner/local/__tests__/test-execution-orchestrator-pending-rejection.test.ts new file mode 100644 index 00000000..b6802458 --- /dev/null +++ b/packages/aws-durable-execution-sdk-js-testing/src/test-runner/local/__tests__/test-execution-orchestrator-pending-rejection.test.ts @@ -0,0 +1,765 @@ +import { TestExecutionOrchestrator } from "../test-execution-orchestrator"; +import { LocalOperationStorage } from "../operations/local-operation-storage"; +import { + createCheckpointToken, + createExecutionId, +} from "../../../checkpoint-server/utils/tagged-strings"; +import { InvocationStatus } from "@aws/durable-execution-sdk-js"; +import { + Event, + EventType, + OperationAction, + OperationStatus, + OperationType, +} from "@aws-sdk/client-lambda"; +import { OperationWaitManager } from "../operations/operation-wait-manager"; +import { IndexedOperations } from "../../common/indexed-operations"; +import { OperationEvents } from "../../common/operations/operation-with-data"; +import { FunctionStorage } from "../operations/function-storage"; +import { ILocalDurableTestRunnerFactory } from "../interfaces/durable-test-runner-factory"; +import { DurableApiClient } from "../../common/create-durable-api-client"; +import { CheckpointApiClient } from "../api-client/checkpoint-api-client"; + +// Mock dependencies +jest.mock("../operations/local-operation-storage"); + +const mockInvoke = jest.fn(); + +jest.mock("../invoke-handler", () => ({ + InvokeHandler: jest.fn().mockImplementation(() => ({ + invoke: mockInvoke, + })), +})); + +/** + * Test suite focused on verifying that the TestExecutionOrchestrator correctly rejects + * executions with the error "Cannot return pending status with no operations" when a handler + * returns PENDING status but there are no pending operations or scheduled functions to justify + * continuing execution. + */ +describe("TestExecutionOrchestrator - Pending Status Rejection", () => { + const mockHandlerFunction = jest.fn(); + const mockExecutionId = createExecutionId("test-execution-id"); + const mockCheckpointToken = createCheckpointToken("test-checkpoint-token"); + + const mockExecutionOperationEvents: OperationEvents[] = [ + { + events: [ + { + Id: "execution-id", + EventId: 1, + EventType: EventType.ExecutionStarted, + }, + ], + operation: { + Id: "execution-id", + StartTimestamp: new Date(), + Status: OperationStatus.STARTED, + Type: OperationType.EXECUTION, + ExecutionDetails: {}, + }, + }, + ]; + + let orchestrator: TestExecutionOrchestrator; + let mockOperationStorage: jest.Mocked; + let checkpointApi: CheckpointApiClient; + let mockFunctionStorage: FunctionStorage; + let mockDurableApiClient: DurableApiClient; + + const mockInvocationCompletedEvent: Event = { + EventType: EventType.InvocationCompleted, + InvocationCompletedDetails: { + RequestId: "invocation-request-id", + StartTimestamp: new Date(), + EndTimestamp: new Date(), + }, + }; + + const nonResolvingPromise = new Promise(() => { + // never resolve + }); + + beforeEach(() => { + jest.clearAllMocks(); + mockInvoke.mockReset(); + + mockDurableApiClient = { + sendCallbackFailure: jest.fn(), + sendCallbackSuccess: jest.fn(), + sendCallbackHeartbeat: jest.fn(), + }; + + const indexedOperations = new IndexedOperations([]); + + // Mock OperationStorage + mockOperationStorage = new LocalOperationStorage( + new OperationWaitManager(indexedOperations), + indexedOperations, + mockDurableApiClient, + jest.fn(), + ) as jest.Mocked; + + mockOperationStorage.populateOperations = jest.fn(); + mockOperationStorage.addHistoryEvent = jest.fn(); + + checkpointApi = { + startDurableExecution: jest.fn().mockResolvedValue({ + executionId: mockExecutionId, + checkpointToken: mockCheckpointToken, + operationEvents: mockExecutionOperationEvents, + }), + pollCheckpointData: jest.fn().mockReturnValue(nonResolvingPromise), + updateCheckpointData: jest.fn().mockResolvedValue(undefined), + startInvocation: jest.fn().mockResolvedValue({ + checkpointToken: mockCheckpointToken, + executionId: mockExecutionId, + operationEvents: [], + }), + completeInvocation: jest.fn().mockResolvedValue({ + hasDirtyOperations: false, + event: mockInvocationCompletedEvent, + }), + }; + + // Create a mock factory for FunctionStorage + const mockFactory: ILocalDurableTestRunnerFactory = { + createRunner: jest.fn().mockReturnValue({ + run: jest.fn().mockResolvedValue({ + getStatus: () => "SUCCEEDED", + getResult: () => ({}), + }), + }), + }; + + mockFunctionStorage = new FunctionStorage(mockFactory); + + orchestrator = new TestExecutionOrchestrator( + mockHandlerFunction, + mockOperationStorage, + checkpointApi, + mockFunctionStorage, + { + enabled: false, + }, + ); + }); + + describe("Single operation type pending scenarios", () => { + it("should not reject when only invoke operation is pending", async () => { + const invokeOperationId = "pending-invoke-op"; + + // Set up complete polling sequence upfront + jest + .spyOn(checkpointApi, "pollCheckpointData") + .mockResolvedValueOnce({ + operations: [ + { + operation: { + Id: invokeOperationId, + StartTimestamp: new Date(), + Status: OperationStatus.STARTED, + Type: OperationType.CHAINED_INVOKE, + ChainedInvokeDetails: {}, + }, + update: { + Id: invokeOperationId, + Type: OperationType.CHAINED_INVOKE, + Action: OperationAction.START, + ChainedInvokeOptions: { + FunctionName: "test-function", + }, + Payload: "{}", + }, + events: [], + }, + ], + }) + // Then complete the invoke operation + .mockResolvedValueOnce({ + operations: [ + { + operation: { + Id: invokeOperationId, + StartTimestamp: new Date(), + Status: OperationStatus.SUCCEEDED, + Type: OperationType.CHAINED_INVOKE, + ChainedInvokeDetails: { + Result: JSON.stringify({ invoke: "success" }), + }, + }, + update: { + Id: invokeOperationId, + Type: OperationType.CHAINED_INVOKE, + Action: OperationAction.SUCCEED, + }, + events: [], + }, + ], + }) + .mockReturnValue(nonResolvingPromise); + + // Mock function storage to complete the invoke + jest.spyOn(mockFunctionStorage, "runHandler").mockResolvedValue({ + result: JSON.stringify({ invoke: "success" }), + error: undefined, + }); + + // Handler returns PENDING but there's a pending invoke operation + mockInvoke + .mockResolvedValueOnce({ + Status: InvocationStatus.PENDING, + }) + .mockResolvedValueOnce({ + Status: InvocationStatus.SUCCEEDED, + Result: JSON.stringify({ success: true }), + }); + + const executePromise = orchestrator.executeHandler({ + payload: { input: "test-pending-invoke" }, + }); + + const result = await executePromise; + + // Should succeed, not reject with pending status error + expect(result.status).toBe(OperationStatus.SUCCEEDED); + expect(result.result).toBe(JSON.stringify({ success: true })); + }); + + it("should not reject when only callback operation is pending", async () => { + const callbackOperationId = "pending-callback-op"; + + // Set up complete polling sequence upfront + jest + .spyOn(checkpointApi, "pollCheckpointData") + .mockResolvedValueOnce({ + operations: [ + { + operation: { + Id: callbackOperationId, + StartTimestamp: new Date(), + Status: OperationStatus.STARTED, + Type: OperationType.CALLBACK, + CallbackDetails: {}, + }, + update: undefined, // No update for started callback operations + events: [], + }, + ], + }) + // Then complete the callback operation + .mockResolvedValueOnce({ + operations: [ + { + operation: { + Id: callbackOperationId, + StartTimestamp: new Date(), + Status: OperationStatus.SUCCEEDED, + Type: OperationType.CALLBACK, + CallbackDetails: { Result: "{}" }, + }, + update: { + Id: callbackOperationId, + Type: OperationType.CALLBACK, + Action: OperationAction.SUCCEED, + }, + events: [], + }, + ], + }) + .mockReturnValue(nonResolvingPromise); + + // Handler returns PENDING but there's a pending callback operation + mockInvoke + .mockResolvedValueOnce({ + Status: InvocationStatus.PENDING, + }) + .mockResolvedValueOnce({ + Status: InvocationStatus.SUCCEEDED, + Result: JSON.stringify({ success: true }), + }); + + const executePromise = orchestrator.executeHandler({ + payload: { input: "test-pending-callback" }, + }); + + const result = await executePromise; + + // Should succeed, not reject with pending status error + expect(result.status).toBe(OperationStatus.SUCCEEDED); + expect(result.result).toBe(JSON.stringify({ success: true })); + }); + + it("should reject when handler returns PENDING with no operations", async () => { + // Set up empty polling response - no operations + jest + .spyOn(checkpointApi, "pollCheckpointData") + .mockReturnValue(nonResolvingPromise); + + // Handler returns PENDING but there are no pending operations or scheduled functions + mockInvoke.mockResolvedValue({ + Status: InvocationStatus.PENDING, + }); + + const executePromise = orchestrator.executeHandler({ + payload: { input: "test-no-operations" }, + }); + + await expect(executePromise).rejects.toEqual({ + error: { + ErrorType: "InvalidParameterValueException", + ErrorMessage: + "Cannot return PENDING status with no pending operations.", + }, + status: "FAILED", + }); + }); + + it("should not reject when there are pending operations, but dirty operations exist", async () => { + // Set up empty polling response - no operations + jest + .spyOn(checkpointApi, "pollCheckpointData") + .mockReturnValue(nonResolvingPromise); + + // Set up dirty operations + jest.spyOn(checkpointApi, "completeInvocation").mockResolvedValue({ + hasDirtyOperations: true, + event: mockInvocationCompletedEvent, + }); + + // Handler returns PENDING but there are no pending operations or scheduled functions + mockInvoke + .mockResolvedValue({ + Status: InvocationStatus.PENDING, + }) + .mockResolvedValueOnce({ + Status: InvocationStatus.SUCCEEDED, + Result: JSON.stringify({ success: true }), + }); + + const result = await orchestrator.executeHandler({ + payload: { input: "test-no-operations" }, + }); + + expect(result.status).toBe(OperationStatus.SUCCEEDED); + expect(result.result).toBe(JSON.stringify({ success: true })); + }); + }); + + describe("Scheduled function scenarios", () => { + it("should not reject when scheduled functions are pending", async () => { + const waitOperationId = "scheduled-wait-op"; + const futureTimestamp = new Date(Date.now() + 100); + + jest + .spyOn(checkpointApi, "pollCheckpointData") + .mockResolvedValueOnce({ + operations: [ + { + operation: { + Id: waitOperationId, + StartTimestamp: new Date(), + Status: OperationStatus.STARTED, + Type: OperationType.WAIT, + WaitDetails: { + ScheduledEndTimestamp: futureTimestamp, + }, + }, + update: { + Id: waitOperationId, + Type: OperationType.WAIT, + Action: OperationAction.START, + }, + events: [], + }, + ], + }) + // Then complete the wait operation + .mockResolvedValueOnce({ + operations: [ + { + operation: { + Id: waitOperationId, + StartTimestamp: new Date(), + Status: OperationStatus.SUCCEEDED, + Type: OperationType.WAIT, + WaitDetails: { ScheduledEndTimestamp: futureTimestamp }, + }, + update: { + Id: waitOperationId, + Type: OperationType.WAIT, + Action: OperationAction.SUCCEED, + }, + events: [], + }, + ], + }) + .mockReturnValue(nonResolvingPromise); + + // Handler returns PENDING but there's a scheduled wait operation + mockInvoke + .mockResolvedValueOnce({ + Status: InvocationStatus.PENDING, + }) + .mockResolvedValueOnce({ + Status: InvocationStatus.SUCCEEDED, + Result: JSON.stringify({ success: true }), + }); + + const executePromise = orchestrator.executeHandler({ + payload: { input: "test-scheduled-wait" }, + }); + + const result = await executePromise; + + expect(result.status).toBe(OperationStatus.SUCCEEDED); + expect(result.result).toBe(JSON.stringify({ success: true })); + }); + + it("should not immediately re-invoke when there are dirty operations but scheduled functions exist", async () => { + // Set up empty polling response - no operations + jest + .spyOn(checkpointApi, "pollCheckpointData") + .mockReturnValue(nonResolvingPromise); + + // Set up dirty operations + jest.spyOn(checkpointApi, "completeInvocation").mockResolvedValue({ + hasDirtyOperations: true, + event: mockInvocationCompletedEvent, + }); + + // Handler returns PENDING but there are no pending operations or scheduled functions + mockInvoke + .mockResolvedValue({ + Status: InvocationStatus.PENDING, + }) + .mockResolvedValueOnce({ + Status: InvocationStatus.SUCCEEDED, + Result: JSON.stringify({ success: true }), + }); + + const result = await orchestrator.executeHandler({ + payload: { input: "test-no-operations" }, + }); + + expect(result.status).toBe(OperationStatus.SUCCEEDED); + expect(result.result).toBe(JSON.stringify({ success: true })); + }); + }); + + describe("Operations completed scenarios", () => { + it("should reject when operations were created but are no longer pending", async () => { + const completedInvokeId = "completed-invoke-op"; + const completedCallbackId = "completed-callback-op"; + + // Mock polling to return already completed operations + jest + .spyOn(checkpointApi, "pollCheckpointData") + .mockResolvedValueOnce({ + operations: [ + { + operation: { + Id: completedInvokeId, + StartTimestamp: new Date(), + Status: OperationStatus.SUCCEEDED, + Type: OperationType.CHAINED_INVOKE, + ChainedInvokeDetails: { Result: "{}" }, + }, + update: { + Id: completedInvokeId, + Type: OperationType.CHAINED_INVOKE, + Action: OperationAction.SUCCEED, + }, + events: [], + }, + { + operation: { + Id: completedCallbackId, + StartTimestamp: new Date(), + Status: OperationStatus.SUCCEEDED, + Type: OperationType.CALLBACK, + CallbackDetails: { Result: "{}" }, + }, + update: { + Id: completedCallbackId, + Type: OperationType.CALLBACK, + Action: OperationAction.SUCCEED, + }, + events: [], + }, + ], + }) + .mockReturnValue(nonResolvingPromise); + + // Handler returns PENDING, but all operations are already completed + mockInvoke.mockResolvedValue({ + Status: InvocationStatus.PENDING, + }); + + const executePromise = orchestrator.executeHandler({ + payload: { input: "test-completed-operations" }, + }); + + // The handler still returns PENDING with no actual pending work + await expect(executePromise).rejects.toEqual({ + error: { + ErrorType: "InvalidParameterValueException", + ErrorMessage: + "Cannot return PENDING status with no pending operations.", + }, + status: "FAILED", + }); + }); + + it("should reject when callback completes between invocations leaving nothing pending", async () => { + const callbackOperationId = "completing-callback-op"; + + // First polling returns pending callback + jest + .spyOn(checkpointApi, "pollCheckpointData") + .mockResolvedValueOnce({ + operations: [ + { + operation: { + Id: callbackOperationId, + StartTimestamp: new Date(), + Status: OperationStatus.STARTED, + Type: OperationType.CALLBACK, + CallbackDetails: {}, + }, + update: undefined, + events: [], + }, + ], + }) + // Second polling returns completed callback + .mockResolvedValueOnce({ + operations: [ + { + operation: { + Id: callbackOperationId, + StartTimestamp: new Date(), + Status: OperationStatus.SUCCEEDED, + Type: OperationType.CALLBACK, + CallbackDetails: { Result: "{}" }, + }, + update: { + Id: callbackOperationId, + Type: OperationType.CALLBACK, + Action: OperationAction.SUCCEED, + }, + events: [], + }, + ], + }) + .mockReturnValue(nonResolvingPromise); + + // Handler returns PENDING on both invocations + mockInvoke.mockResolvedValue({ + Status: InvocationStatus.PENDING, + }); + + const executePromise = orchestrator.executeHandler({ + payload: { input: "test-completing-callback" }, + }); + + // Should reject on the second invocation when callback completes but handler still returns PENDING + await expect(executePromise).rejects.toEqual({ + error: { + ErrorType: "InvalidParameterValueException", + ErrorMessage: + "Cannot return PENDING status with no pending operations.", + }, + status: "FAILED", + }); + }); + }); + + describe("Edge cases and error conditions", () => { + it("should handle mixed scenarios with some operations completing while others remain pending", async () => { + const invokeOperationId = "completing-invoke-op"; + const callbackOperationId = "pending-callback-op"; + + // First polling: both operations pending, then complete both + jest + .spyOn(checkpointApi, "pollCheckpointData") + .mockResolvedValueOnce({ + operations: [ + { + operation: { + Id: invokeOperationId, + StartTimestamp: new Date(), + Status: OperationStatus.STARTED, + Type: OperationType.CHAINED_INVOKE, + ChainedInvokeDetails: {}, + }, + update: { + Id: invokeOperationId, + Type: OperationType.CHAINED_INVOKE, + Action: OperationAction.START, + ChainedInvokeOptions: { + FunctionName: "test-function", + }, + Payload: "{}", + }, + events: [], + }, + { + operation: { + Id: callbackOperationId, + StartTimestamp: new Date(), + Status: OperationStatus.STARTED, + Type: OperationType.CALLBACK, + CallbackDetails: {}, + }, + update: undefined, + events: [], + }, + ], + }) + // Complete callback to finish execution + .mockResolvedValueOnce({ + operations: [ + { + operation: { + Id: callbackOperationId, + StartTimestamp: new Date(), + Status: OperationStatus.SUCCEEDED, + Type: OperationType.CALLBACK, + CallbackDetails: { Result: "{}" }, + }, + update: { + Id: callbackOperationId, + Type: OperationType.CALLBACK, + Action: OperationAction.SUCCEED, + }, + events: [], + }, + ], + }) + .mockReturnValue(nonResolvingPromise); + + // Mock function storage to complete invoke quickly + jest.spyOn(mockFunctionStorage, "runHandler").mockResolvedValue({ + result: JSON.stringify({ invoke: "completed" }), + error: undefined, + }); + + // Handler returns PENDING - should be valid with callback still pending + mockInvoke + .mockResolvedValueOnce({ + Status: InvocationStatus.PENDING, + }) + .mockResolvedValueOnce({ + Status: InvocationStatus.SUCCEEDED, + Result: JSON.stringify({ success: true }), + }); + + const executePromise = orchestrator.executeHandler({ + payload: { input: "test-mixed-completion" }, + }); + + const result = await executePromise; + + // Should succeed - callback was still pending when first PENDING was returned + expect(result.status).toBe(OperationStatus.SUCCEEDED); + expect(result.result).toBe(JSON.stringify({ success: true })); + }); + + it("should properly track pending operations across multiple polling cycles", async () => { + const firstCallbackId = "first-callback-op"; + const secondCallbackId = "second-callback-op"; + + // First polling: one callback, then first completes and second starts, then second completes + jest + .spyOn(checkpointApi, "pollCheckpointData") + .mockResolvedValueOnce({ + operations: [ + { + operation: { + Id: firstCallbackId, + StartTimestamp: new Date(), + Status: OperationStatus.STARTED, + Type: OperationType.CALLBACK, + CallbackDetails: {}, + }, + update: undefined, + events: [], + }, + ], + }) + // Second polling: first completes, second starts + .mockResolvedValueOnce({ + operations: [ + { + operation: { + Id: firstCallbackId, + StartTimestamp: new Date(), + Status: OperationStatus.SUCCEEDED, + Type: OperationType.CALLBACK, + CallbackDetails: { Result: "{}" }, + }, + update: { + Id: firstCallbackId, + Type: OperationType.CALLBACK, + Action: OperationAction.SUCCEED, + }, + events: [], + }, + { + operation: { + Id: secondCallbackId, + StartTimestamp: new Date(), + Status: OperationStatus.STARTED, + Type: OperationType.CALLBACK, + CallbackDetails: {}, + }, + update: undefined, + events: [], + }, + ], + }) + // Complete second callback + .mockResolvedValueOnce({ + operations: [ + { + operation: { + Id: secondCallbackId, + StartTimestamp: new Date(), + Status: OperationStatus.SUCCEEDED, + Type: OperationType.CALLBACK, + CallbackDetails: { Result: "{}" }, + }, + update: { + Id: secondCallbackId, + Type: OperationType.CALLBACK, + Action: OperationAction.SUCCEED, + }, + events: [], + }, + ], + }) + .mockReturnValue(nonResolvingPromise); + + // Handler returns PENDING on both invocations (valid in both cases) + mockInvoke + .mockResolvedValueOnce({ + Status: InvocationStatus.PENDING, + }) + .mockResolvedValueOnce({ + Status: InvocationStatus.SUCCEEDED, + Result: JSON.stringify({ success: true }), + }); + + const executePromise = orchestrator.executeHandler({ + payload: { input: "test-multiple-polling-cycles" }, + }); + + const result = await executePromise; + + // Should succeed - there was always at least one pending operation + expect(result.status).toBe(OperationStatus.SUCCEEDED); + expect(result.result).toBe(JSON.stringify({ success: true })); + }); + }); +}); diff --git a/packages/aws-durable-execution-sdk-js-testing/src/test-runner/local/__tests__/test-execution-orchestrator.test.ts b/packages/aws-durable-execution-sdk-js-testing/src/test-runner/local/__tests__/test-execution-orchestrator.test.ts index 30f11fe6..fa34533c 100644 --- a/packages/aws-durable-execution-sdk-js-testing/src/test-runner/local/__tests__/test-execution-orchestrator.test.ts +++ b/packages/aws-durable-execution-sdk-js-testing/src/test-runner/local/__tests__/test-execution-orchestrator.test.ts @@ -904,9 +904,14 @@ describe("TestExecutionOrchestrator", () => { ) .mockRejectedValue(new Error("Not implemented")); - mockInvoke.mockResolvedValue({ - Status: InvocationStatus.PENDING, - }); + mockInvoke + .mockResolvedValueOnce({ + Status: InvocationStatus.PENDING, + }) + .mockResolvedValueOnce({ + Status: InvocationStatus.SUCCEEDED, + Result: JSON.stringify({ success: true }), + }); const executePromise = orchestrator.executeHandler(); diff --git a/packages/aws-durable-execution-sdk-js-testing/src/test-runner/local/api-client/checkpoint-api-client.ts b/packages/aws-durable-execution-sdk-js-testing/src/test-runner/local/api-client/checkpoint-api-client.ts index d84b770d..4da3aef4 100644 --- a/packages/aws-durable-execution-sdk-js-testing/src/test-runner/local/api-client/checkpoint-api-client.ts +++ b/packages/aws-durable-execution-sdk-js-testing/src/test-runner/local/api-client/checkpoint-api-client.ts @@ -1,4 +1,4 @@ -import { ErrorObject, Operation, Event } from "@aws-sdk/client-lambda"; +import { ErrorObject, Operation } from "@aws-sdk/client-lambda"; import { CheckpointOperation } from "../../../checkpoint-server/storage/checkpoint-manager"; import { InvocationResult } from "../../../checkpoint-server/storage/execution-manager"; import { SerializedCheckpointOperation } from "../../../checkpoint-server/types/operation-event"; @@ -10,6 +10,7 @@ import { StartDurableExecutionRequest, StartInvocationRequest, } from "../../../checkpoint-server/worker-api/worker-api-request"; +import { CompleteInvocationResponse } from "../../../checkpoint-server/worker-api/worker-api-response"; export interface SerializedPollCheckpointResponse { operations: SerializedCheckpointOperation[]; @@ -62,5 +63,5 @@ export interface CheckpointApiClient { executionId: ExecutionId, invocationId: InvocationId, error: ErrorObject | undefined, - ): Promise; + ): Promise; } diff --git a/packages/aws-durable-execution-sdk-js-testing/src/test-runner/local/api-client/checkpoint-worker-api-client.ts b/packages/aws-durable-execution-sdk-js-testing/src/test-runner/local/api-client/checkpoint-worker-api-client.ts index 5eb65914..17e36ce2 100644 --- a/packages/aws-durable-execution-sdk-js-testing/src/test-runner/local/api-client/checkpoint-worker-api-client.ts +++ b/packages/aws-durable-execution-sdk-js-testing/src/test-runner/local/api-client/checkpoint-worker-api-client.ts @@ -1,4 +1,4 @@ -import { Operation, ErrorObject, Event } from "@aws-sdk/client-lambda"; +import { Operation, ErrorObject } from "@aws-sdk/client-lambda"; import { CheckpointOperation } from "../../../checkpoint-server/storage/checkpoint-manager"; import { InvocationResult } from "../../../checkpoint-server/storage/execution-manager"; import { @@ -12,6 +12,7 @@ import { StartDurableExecutionRequest, StartInvocationRequest, } from "../../../checkpoint-server/worker-api/worker-api-request"; +import { CompleteInvocationResponse } from "../../../checkpoint-server/worker-api/worker-api-response"; export class CheckpointWorkerApiClient implements CheckpointApiClient { constructor(private readonly workerManager: CheckpointWorkerManager) {} @@ -76,7 +77,7 @@ export class CheckpointWorkerApiClient implements CheckpointApiClient { executionId: ExecutionId, invocationId: InvocationId, error: ErrorObject | undefined, - ): Promise { + ): Promise { return this.workerManager.sendApiRequest(ApiType.CompleteInvocation, { executionId, invocationId, diff --git a/packages/aws-durable-execution-sdk-js-testing/src/test-runner/local/operations/__tests__/invocation-tracker.test.ts b/packages/aws-durable-execution-sdk-js-testing/src/test-runner/local/operations/__tests__/invocation-tracker.test.ts index e91cc82b..8c4084a7 100644 --- a/packages/aws-durable-execution-sdk-js-testing/src/test-runner/local/operations/__tests__/invocation-tracker.test.ts +++ b/packages/aws-durable-execution-sdk-js-testing/src/test-runner/local/operations/__tests__/invocation-tracker.test.ts @@ -19,14 +19,17 @@ describe("InvocationTracker", () => { startInvocation: jest.fn(), completeInvocation: jest.fn((_executionId, invocationId, error) => Promise.resolve({ - InvocationCompletedDetails: { - StartTimestamp: new Date(), - EndTimestamp: new Date(), - Error: { - Payload: error, + event: { + InvocationCompletedDetails: { + StartTimestamp: new Date(), + EndTimestamp: new Date(), + Error: { + Payload: error, + }, + RequestId: invocationId, }, - RequestId: invocationId, }, + hasDirtyOperations: false, }), ), }; diff --git a/packages/aws-durable-execution-sdk-js-testing/src/test-runner/local/operations/invocation-tracker.ts b/packages/aws-durable-execution-sdk-js-testing/src/test-runner/local/operations/invocation-tracker.ts index b3615ff2..f6a84a18 100644 --- a/packages/aws-durable-execution-sdk-js-testing/src/test-runner/local/operations/invocation-tracker.ts +++ b/packages/aws-durable-execution-sdk-js-testing/src/test-runner/local/operations/invocation-tracker.ts @@ -1,10 +1,11 @@ -import { ErrorObject, Event } from "@aws-sdk/client-lambda"; +import { ErrorObject } from "@aws-sdk/client-lambda"; import { createInvocationId, ExecutionId, InvocationId, } from "../../../checkpoint-server/utils/tagged-strings"; import { CheckpointApiClient } from "../api-client/checkpoint-api-client"; +import { CompleteInvocationResponse } from "../../../checkpoint-server/worker-api/worker-api-response"; /** * Manages tracking of invocations in local runner. @@ -49,7 +50,7 @@ export class InvocationTracker { executionId: ExecutionId, invocationId: InvocationId, error: ErrorObject | undefined, - ): Promise { + ): Promise { if (!this.invocations.has(invocationId)) { throw new Error(`Invocation with ID ${invocationId} not found`); } diff --git a/packages/aws-durable-execution-sdk-js-testing/src/test-runner/local/test-execution-orchestrator.ts b/packages/aws-durable-execution-sdk-js-testing/src/test-runner/local/test-execution-orchestrator.ts index d77c447e..5026468f 100644 --- a/packages/aws-durable-execution-sdk-js-testing/src/test-runner/local/test-execution-orchestrator.ts +++ b/packages/aws-durable-execution-sdk-js-testing/src/test-runner/local/test-execution-orchestrator.ts @@ -46,6 +46,7 @@ export class TestExecutionOrchestrator { private invokeHandlerInstance: InvokeHandler; private invocationTracker: InvocationTracker; private readonly scheduler: Scheduler; + private readonly pendingOperations = new Set(); constructor( private handlerFunction: DurableLambdaHandler, @@ -294,18 +295,21 @@ export class TestExecutionOrchestrator { ); } + const operationId = update.Id; + if (operationId === undefined) { + throw new Error("Missing operation id"); + } + + this.pendingOperations.add(operationId); + const { result, error } = await this.functionStorage.runHandler( functionName, update.Payload, ); - if (update.Id === undefined) { - throw new Error("Missing operation id"); - } - await this.checkpointApi.updateCheckpointData({ executionId, - operationId: update.Id, + operationId: operationId, operationData: { // todo: handle other operation types as well Status: result ? OperationStatus.SUCCEEDED : OperationStatus.FAILED, @@ -321,6 +325,11 @@ export class TestExecutionOrchestrator { (err) => { this.executionState.rejectWith(err); }, + undefined, + () => { + this.pendingOperations.delete(operationId); + return Promise.resolve(); + }, ); } @@ -444,7 +453,13 @@ export class TestExecutionOrchestrator { operation: Operation, executionId: ExecutionId, ): void { + const operationId = operation.Id; + if (!operationId) { + throw new Error("Missing operation id"); + } + if (operation.Status === OperationStatus.STARTED) { + this.pendingOperations.add(operationId); return; } @@ -453,6 +468,11 @@ export class TestExecutionOrchestrator { (err) => { this.executionState.rejectWith(err); }, + undefined, + () => { + this.pendingOperations.delete(operationId); + return Promise.resolve(); + }, ); } @@ -587,24 +607,59 @@ export class TestExecutionOrchestrator { value, ); - this.operationStorage.addHistoryEvent( + const { event, hasDirtyOperations } = await this.invocationTracker.completeInvocation( executionId, invocationId, "Error" in value ? value.Error : undefined, - ), - ); + ); + + this.operationStorage.addHistoryEvent(event); if (value.Status === InvocationStatus.SUCCEEDED) { this.executionState.resolveWith({ result: value.Result, status: OperationStatus.SUCCEEDED, }); - } else if (value.Status === InvocationStatus.FAILED) { + return; + } + + if (value.Status === InvocationStatus.FAILED) { this.executionState.resolveWith({ error: value.Error, status: OperationStatus.FAILED, }); + return; + } + + if (!this.scheduler.hasScheduledFunction() && hasDirtyOperations) { + defaultLogger.debug( + "Re-invoking handler since invocation completed with pending dirty operations", + ); + // Re-invoke the handler if its last checkpoint was not synchronized + // with the backend and there are pending dirty operations when the + // invocation completed. + this.scheduler.scheduleFunction( + () => this.invokeHandler(executionId), + (err) => { + this.executionState.rejectWith(err); + }, + ); + return; + } + + if ( + !this.scheduler.hasScheduledFunction() && + !this.pendingOperations.size + ) { + this.executionState.rejectWith({ + error: { + ErrorType: "InvalidParameterValueException", + ErrorMessage: + "Cannot return PENDING status with no pending operations.", + }, + status: ExecutionStatus.FAILED, + }); } } catch (err) { defaultLogger.debug( @@ -612,18 +667,17 @@ export class TestExecutionOrchestrator { err, ); - this.operationStorage.addHistoryEvent( - await this.invocationTracker.completeInvocation( - executionId, - invocationId, - { - ErrorMessage: err instanceof Error ? err.message : undefined, - ErrorType: err instanceof Error ? err.name : undefined, - StackTrace: - err instanceof Error ? err.stack?.split("\n") : undefined, - }, - ), + const { event } = await this.invocationTracker.completeInvocation( + executionId, + invocationId, + { + ErrorMessage: err instanceof Error ? err.message : undefined, + ErrorType: err instanceof Error ? err.name : undefined, + StackTrace: err instanceof Error ? err.stack?.split("\n") : undefined, + }, ); + + this.operationStorage.addHistoryEvent(event); this.executionState.rejectWith(err); } } From 8b9e5eba68ed35a7602523c2f01f76dddfa73564 Mon Sep 17 00:00:00 2001 From: Anthony Ting Date: Tue, 9 Dec 2025 16:27:53 -0800 Subject: [PATCH 04/14] ci: enable history tests for all remaining examples and update readme --- .../ADDING_EXAMPLES.md | 188 +++++- .../create-callback-concurrent.history.json | 124 ++++ .../create-callback-concurrent.test.ts | 4 +- .../create-callback-failures.history.json | 82 +++ .../failures/create-callback-failures.test.ts | 4 +- .../create-callback-heartbeat.history.json | 72 +++ .../create-callback-heartbeat.test.ts | 4 +- .../create-callback-mixed-ops.history.json | 118 ++++ .../create-callback-mixed-ops.test.ts | 4 +- .../create-callback-serdes.history.json | 72 +++ .../serdes/create-callback-serdes.test.ts | 4 +- ...te-callback-failure-undefined.history.json | 77 +++ .../create-callback-failure.history.json | 79 +++ ...te-callback-success-undefined.history.json | 63 ++ .../create-callback-success.history.json | 69 ++ .../simple/create-callback.test.ts | 10 +- .../create-callback-timeout.history.json | 82 +++ .../timeout/create-callback-timeout.test.ts | 6 +- .../force-checkpointing-callback.history.json | 209 ++++++ .../force-checkpointing-callback.test.ts | 4 +- .../force-checkpointing-invoke.history.json | 212 ++++++ .../invoke/force-checkpointing-invoke.test.ts | 4 +- .../step-retry/force-checkpointing.test.ts | 4 +- .../invoke-simple-basic-wait.history.json | 72 +++ .../invoke-simple-child-failure.history.json | 83 +++ ...ke-simple-non-durable-failure.history.json | 94 +++ ...ke-simple-non-durable-success.history.json | 72 +++ .../invoke-simple-step-payload.history.json | 72 +++ .../invoke/simple/invoke-simple.test.ts | 12 +- .../logger-after-callback.history.json | 69 ++ .../logger-after-callback.test.ts | 28 +- ...lure-threshold-exceeded-count.history.json | 473 ++++++++++++++ ...p-failure-threshold-exceeded-count.test.ts | 4 +- ...threshold-exceeded-percentage.history.json | 451 +++++++++++++ ...lure-threshold-exceeded-percentage.test.ts | 4 +- .../map-min-successful.history.json | 236 +++++++ .../min-successful/map-min-successful.test.ts | 2 + .../map-tolerated-failure-count.history.json | 350 ++++++++++ .../map-tolerated-failure-count.test.ts | 4 +- ...-tolerated-failure-percentage.history.json | 603 ++++++++++++++++++ .../map-tolerated-failure-percentage.test.ts | 4 +- .../parallel/basic/parallel-basic.test.ts | 11 +- ...lure-threshold-exceeded-count.history.json | 473 ++++++++++++++ ...l-failure-threshold-exceeded-count.test.ts | 4 +- ...threshold-exceeded-percentage.history.json | 451 +++++++++++++ ...lure-threshold-exceeded-percentage.test.ts | 4 +- ...allel-min-successful-callback.history.json | 165 +++++ .../parallel-min-successful-callback.test.ts | 4 +- .../parallel-min-successful.history.json | 216 +++++++ .../parallel-min-successful.test.ts | 4 +- ...allel-tolerated-failure-count.history.json | 350 ++++++++++ .../parallel-tolerated-failure-count.test.ts | 4 +- ...-tolerated-failure-percentage.history.json | 350 ++++++++++ ...allel-tolerated-failure-percentage.test.ts | 4 +- .../serde/basic/serde-basic.history.json | 113 ++++ .../examples/serde/basic/serde-basic.test.ts | 6 +- .../wait-for-callback-anonymous.history.json | 112 ++++ .../wait-for-callback-anonymous.test.ts | 4 +- .../wait-for-callback-failure.history.json | 128 ++++ .../wait-for-callback-success.history.json | 115 ++++ .../basic/wait-for-callback.test.ts | 8 +- ...it-for-callback-child-context.history.json | 253 ++++++++ .../wait-for-callback-child-context.test.ts | 4 +- .../wait-for-callback-failures.history.json | 118 ++++ .../wait-for-callback-failures.test.ts | 4 +- ...-for-callback-heartbeat-sends.history.json | 113 ++++ .../wait-for-callback-heartbeat-sends.test.ts | 4 +- .../wait-for-callback-mixed-ops.history.json | 228 +++++++ .../wait-for-callback-mixed-ops.test.ts | 4 +- ...callback-multiple-invocations.history.json | 273 ++++++++ ...-for-callback-multiple-invocations.test.ts | 4 +- .../wait-for-callback-nested.history.json | 358 +++++++++++ .../nested/wait-for-callback-nested.test.ts | 4 +- .../wait-for-callback-serdes.history.json | 189 ++++++ .../serdes/wait-for-callback-serdes.test.ts | 4 +- ...k-submitter-failure-catchable.history.json | 180 ++++++ ...llback-submitter-failure-catchable.test.ts | 14 +- ...lback-submitter-retry-success.history.json | 114 ++++ ...r-callback-submitter-retry-success.test.ts | 4 +- .../wait-for-callback-timeout.history.json | 118 ++++ .../timeout/wait-for-callback-timeout.test.ts | 4 +- .../src/utils/test-helper.ts | 33 +- 82 files changed, 8587 insertions(+), 94 deletions(-) create mode 100644 packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/concurrent/create-callback-concurrent.history.json create mode 100644 packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/failures/create-callback-failures.history.json create mode 100644 packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/heartbeat/create-callback-heartbeat.history.json create mode 100644 packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/mixed-ops/create-callback-mixed-ops.history.json create mode 100644 packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/serdes/create-callback-serdes.history.json create mode 100644 packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/simple/create-callback-failure-undefined.history.json create mode 100644 packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/simple/create-callback-failure.history.json create mode 100644 packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/simple/create-callback-success-undefined.history.json create mode 100644 packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/simple/create-callback-success.history.json create mode 100644 packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/timeout/create-callback-timeout.history.json create mode 100644 packages/aws-durable-execution-sdk-js-examples/src/examples/force-checkpointing/callback/force-checkpointing-callback.history.json create mode 100644 packages/aws-durable-execution-sdk-js-examples/src/examples/force-checkpointing/invoke/force-checkpointing-invoke.history.json create mode 100644 packages/aws-durable-execution-sdk-js-examples/src/examples/invoke/simple/invoke-simple-basic-wait.history.json create mode 100644 packages/aws-durable-execution-sdk-js-examples/src/examples/invoke/simple/invoke-simple-child-failure.history.json create mode 100644 packages/aws-durable-execution-sdk-js-examples/src/examples/invoke/simple/invoke-simple-non-durable-failure.history.json create mode 100644 packages/aws-durable-execution-sdk-js-examples/src/examples/invoke/simple/invoke-simple-non-durable-success.history.json create mode 100644 packages/aws-durable-execution-sdk-js-examples/src/examples/invoke/simple/invoke-simple-step-payload.history.json create mode 100644 packages/aws-durable-execution-sdk-js-examples/src/examples/logger-test/after-callback/logger-after-callback.history.json create mode 100644 packages/aws-durable-execution-sdk-js-examples/src/examples/map/failure-threshold-exceeded-count/map-failure-threshold-exceeded-count.history.json create mode 100644 packages/aws-durable-execution-sdk-js-examples/src/examples/map/failure-threshold-exceeded-percentage/map-failure-threshold-exceeded-percentage.history.json create mode 100644 packages/aws-durable-execution-sdk-js-examples/src/examples/map/min-successful/map-min-successful.history.json create mode 100644 packages/aws-durable-execution-sdk-js-examples/src/examples/map/tolerated-failure-count/map-tolerated-failure-count.history.json create mode 100644 packages/aws-durable-execution-sdk-js-examples/src/examples/map/tolerated-failure-percentage/map-tolerated-failure-percentage.history.json create mode 100644 packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/failure-threshold-exceeded-count/parallel-failure-threshold-exceeded-count.history.json create mode 100644 packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/failure-threshold-exceeded-percentage/parallel-failure-threshold-exceeded-percentage.history.json create mode 100644 packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/min-successful-with-callback/parallel-min-successful-callback.history.json create mode 100644 packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/min-successful/parallel-min-successful.history.json create mode 100644 packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/tolerated-failure-count/parallel-tolerated-failure-count.history.json create mode 100644 packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/tolerated-failure-percentage/parallel-tolerated-failure-percentage.history.json create mode 100644 packages/aws-durable-execution-sdk-js-examples/src/examples/serde/basic/serde-basic.history.json create mode 100644 packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/anonymous/wait-for-callback-anonymous.history.json create mode 100644 packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/basic/wait-for-callback-failure.history.json create mode 100644 packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/basic/wait-for-callback-success.history.json create mode 100644 packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/child-context/wait-for-callback-child-context.history.json create mode 100644 packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/failures/wait-for-callback-failures.history.json create mode 100644 packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/heartbeat-sends/wait-for-callback-heartbeat-sends.history.json create mode 100644 packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/mixed-ops/wait-for-callback-mixed-ops.history.json create mode 100644 packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/multiple-invocations/wait-for-callback-multiple-invocations.history.json create mode 100644 packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/nested/wait-for-callback-nested.history.json create mode 100644 packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/serdes/wait-for-callback-serdes.history.json create mode 100644 packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/submitter-failure-catchable/wait-for-callback-submitter-failure-catchable.history.json create mode 100644 packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/submitter-retry-success/wait-for-callback-submitter-retry-success.history.json create mode 100644 packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/timeout/wait-for-callback-timeout.history.json diff --git a/packages/aws-durable-execution-sdk-js-examples/ADDING_EXAMPLES.md b/packages/aws-durable-execution-sdk-js-examples/ADDING_EXAMPLES.md index e935db18..50ff30dd 100644 --- a/packages/aws-durable-execution-sdk-js-examples/ADDING_EXAMPLES.md +++ b/packages/aws-durable-execution-sdk-js-examples/ADDING_EXAMPLES.md @@ -87,21 +87,20 @@ Create a test file in the same directory: ```typescript import { handler } from "./{example-name}"; -import { createTests } from "../../shared/test-helper"; // For nested: "../../../shared/test-helper" +import { createTests } from "../../../utils/test-helper"; // For standalone: "../../utils/test-helper" createTests({ - name: "my-example test", - functionName: "{example-name}", handler, - tests: (runner) => { - it("should return expected result", async () => { + tests: (runner, { assertEventSignatures }) => { + it("should execute successfully with expected result and operations", async () => { const execution = await runner.run(); - expect(execution.getResult()).toEqual("example result"); - }); - it("should execute correct number of operations", async () => { - const execution = await runner.run(); + // Multiple assertions on the same execution + expect(execution.getResult()).toEqual("example result"); expect(execution.getOperations()).toHaveLength(2); // adjust based on your example + + // REQUIRED: Must call assertEventSignatures for every test + assertEventSignatures(execution); }); }, }); @@ -172,38 +171,147 @@ The `createTests` helper provides a unified interface: ```typescript createTests({ - name: string; // Test suite name - functionName: string; // Must match handler filename (without .ts) - handler: Function; // The handler function to test - invocationType?: string; // Optional: 'RequestResponse' | 'Event' - tests: (runner, isCloud) => void; // Test definitions + handler: DurableLambdaHandler; // The handler function to test + tests: TestCallback; // Test definitions + invocationType?: InvocationType; // Optional: 'RequestResponse' | 'Event' + localRunnerConfig?: LocalDurableTestRunnerSetupParameters; // Optional local test config }); ``` Inside `tests`, you have access to: - `runner`: Either `LocalDurableTestRunner` or `CloudDurableTestRunner` -- `isCloud`: Boolean indicating if running against real Lambda +- `testHelper`: Object containing: + - `assertEventSignatures`: **Required** function to validate execution history + - `isTimeSkipping`: Boolean indicating if time is being skipped in tests + - `isCloud`: Boolean indicating if running against real Lambda + - `functionNameMap`: Helper for resolving function names in tests + +## Event Signature Validation with `assertEventSignatures` + +**IMPORTANT**: Every test **MUST** call `assertEventSignatures(execution)` at the end. This validates that the execution produces the expected sequence of durable execution events. + +### How it Works + +1. **First Run**: When you first create a test, run it with `GENERATE_HISTORY=true` to create the history file: + + ```bash + GENERATE_HISTORY=true npm test + ``` + +2. **History File Creation**: This generates a `.history.json` file next to your test containing the expected event signatures. + +3. **Subsequent Runs**: Normal test runs compare the actual events against the stored history file. + +### Example Usage + +```typescript +createTests({ + handler, + tests: (runner, { assertEventSignatures }) => { + it("should complete workflow successfully", async () => { + const execution = await runner.run(); + + // Your test assertions + expect(execution.getResult()).toEqual("completed"); + expect(execution.getOperations()).toHaveLength(3); + + // REQUIRED: Validate event signatures + assertEventSignatures(execution); + }); + + it("should handle callback operations", async () => { + const callbackOp = runner.getOperation("my-callback"); + const executionPromise = runner.run(); + + await callbackOp.waitForData(); + await callbackOp.sendCallbackSuccess("result"); + + const execution = await executionPromise; + expect(execution.getResult()).toEqual("result"); + + // REQUIRED: Validate event signatures + assertEventSignatures(execution); + }); + }, +}); +``` + +### Multiple History Files + +For tests with multiple scenarios, you can create separate history files: + +```typescript +it("should handle success case", async () => { + const execution = await runner.run({ scenario: "success" }); + expect(execution.getResult()).toBe("success"); + + // Creates/uses example-name-success.history.json + assertEventSignatures(execution, "success"); +}); + +it("should handle failure case", async () => { + const execution = await runner.run({ scenario: "failure" }); + expect(execution.getError()).toBeDefined(); + + // Creates/uses example-name-failure.history.json + assertEventSignatures(execution, "failure"); +}); +``` ### Common Test Patterns ```typescript -tests: (runner, isCloud) => { - it("should return expected result", async () => { +tests: (runner, { assertEventSignatures, isCloud, isTimeSkipping }) => { + // Combine tests with identical setup (same runner.run() call) + it("should execute successfully with expected result and operations", async () => { const execution = await runner.run(); + + // Multiple assertions on the same execution expect(execution.getResult()).toEqual(expectedValue); - }); + expect(execution.getOperations()).toHaveLength(3); - it("should execute operations in order", async () => { - const execution = await runner.run(); + // Check operations in order const ops = execution.getOperations(); - expect(ops[0].name).toBe("step-1"); - expect(ops[1].name).toBe("step-2"); + expect(ops[0].getName()).toBe("step-1"); + expect(ops[1].getName()).toBe("step-2"); + + // REQUIRED + assertEventSignatures(execution); + }); + + // Separate test only when setup is different (different parameters, callbacks, etc.) + it("should handle callback operations", async () => { + const callbackOp = runner.getOperation("my-callback"); + const executionPromise = runner.run(); + + // Wait for callback to start + await callbackOp.waitForData(); + + // Send callback result + await callbackOp.sendCallbackSuccess("callback-result"); + + const execution = await executionPromise; + expect(execution.getResult()).toContain("callback-result"); + + // REQUIRED + assertEventSignatures(execution); }); - it("should execute correct number of operations", async () => { + // Environment-specific tests with different setups + it("should behave differently in cloud vs local", async () => { const execution = await runner.run(); - expect(execution.getOperations()).toHaveLength(3); + + if (isCloud) { + // Cloud-specific assertions + expect(execution.getInvocations().length).toBeGreaterThan(1); + } else { + // Local-specific assertions + expect(isTimeSkipping).toBe(true); + } + + // REQUIRED + assertEventSignatures(execution); }); }; ``` @@ -213,6 +321,9 @@ tests: (runner, isCloud) => { - [ ] Created example file in appropriate directory structure - [ ] Created test file in same directory - [ ] Used correct import paths for test-helper and types +- [ ] Added `assertEventSignatures` parameter to test callback +- [ ] Called `assertEventSignatures(execution)` in every test +- [ ] Generated history files with `GENERATE_HISTORY=true npm test` - [ ] Local tests pass (`npm test`) - [ ] Integration tests pass in CI/CD @@ -231,6 +342,31 @@ sam local execution history $DURABLE_EXECUTION_ARN ## Troubleshooting -**Test not found in integration run:** +### assertEventSignatures Issues + +**Error: "assertEventSignature was not called for test [name]"** + +- You forgot to call `assertEventSignatures(execution)` in one or more of your tests +- Make sure every `it()` test calls this function + +**Error: "History file [...].history.json does not exist"** + +- Run the test with `GENERATE_HISTORY=true npm test` to create the history file +- Make sure the file is committed to your repository + +**Error: Event signature mismatch** + +- The execution produced different events than expected +- If this is intentional (you changed the function), regenerate the history with `GENERATE_HISTORY=true npm test` +- If not intentional, check your function logic for unintended changes + +**TypeError: testResult.getHistoryEvents is not a function** + +- You're passing the wrong variable to `assertEventSignatures` +- Pass the `execution` result from `runner.run()`, not `execution.getResult()` + +### Test Setup Issues + +**Tests timing out:** -- Verify `functionName` in test matches the example name +- For local tests with time skipping disabled: make sure step retries are not longer than the timeout diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/concurrent/create-callback-concurrent.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/concurrent/create-callback-concurrent.history.json new file mode 100644 index 00000000..59efc1fe --- /dev/null +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/concurrent/create-callback-concurrent.history.json @@ -0,0 +1,124 @@ +[ + { + "EventType": "ExecutionStarted", + "EventId": 1, + "Id": "baad178f-c918-474e-932a-7d0f8868e4be", + "EventTimestamp": "2025-12-10T00:15:09.988Z", + "ExecutionStartedDetails": { + "Input": { + "Payload": "{}" + } + } + }, + { + "EventType": "CallbackStarted", + "SubType": "Callback", + "EventId": 2, + "Id": "c4ca4238a0b92382", + "Name": "api-call-1", + "EventTimestamp": "2025-12-10T00:15:10.018Z", + "CallbackStartedDetails": { + "CallbackId": "eyJleGVjdXRpb25JZCI6IjNlZWIyMjRlLWM2ZGMtNDMzZC04NjFhLWI2YzlhZTIzMjg3NSIsIm9wZXJhdGlvbklkIjoiYzRjYTQyMzhhMGI5MjM4MiIsInRva2VuIjoiM2RjNGQ0ZjAtZGM4OS00YThiLTgxZDgtMmExZDE2MTVhMGRkIn0=", + "Timeout": 300, + "Input": {} + } + }, + { + "EventType": "CallbackStarted", + "SubType": "Callback", + "EventId": 3, + "Id": "c81e728d9d4c2f63", + "Name": "api-call-2", + "EventTimestamp": "2025-12-10T00:15:10.039Z", + "CallbackStartedDetails": { + "CallbackId": "eyJleGVjdXRpb25JZCI6IjNlZWIyMjRlLWM2ZGMtNDMzZC04NjFhLWI2YzlhZTIzMjg3NSIsIm9wZXJhdGlvbklkIjoiYzgxZTcyOGQ5ZDRjMmY2MyIsInRva2VuIjoiMjAwMjczNzMtNWM0Zi00OGY2LTg0NTEtODc4MmM5Njg4ZTNiIn0=", + "Timeout": 300, + "Input": {} + } + }, + { + "EventType": "CallbackStarted", + "SubType": "Callback", + "EventId": 4, + "Id": "eccbc87e4b5ce2fe", + "Name": "api-call-3", + "EventTimestamp": "2025-12-10T00:15:10.067Z", + "CallbackStartedDetails": { + "CallbackId": "eyJleGVjdXRpb25JZCI6IjNlZWIyMjRlLWM2ZGMtNDMzZC04NjFhLWI2YzlhZTIzMjg3NSIsIm9wZXJhdGlvbklkIjoiZWNjYmM4N2U0YjVjZTJmZSIsInRva2VuIjoiZTAyMTdlNWItMDQyZS00MmRjLWEwNmEtZGFkMzQ4ZjgzNzQwIn0=", + "Timeout": 300, + "Input": {} + } + }, + { + "EventType": "CallbackSucceeded", + "SubType": "Callback", + "EventId": 5, + "Id": "c81e728d9d4c2f63", + "Name": "api-call-2", + "EventTimestamp": "2025-12-10T00:15:10.070Z", + "CallbackSucceededDetails": { + "Result": { + "Payload": "{\"id\":2,\"data\":\"second\"}" + } + } + }, + { + "EventType": "CallbackSucceeded", + "SubType": "Callback", + "EventId": 6, + "Id": "c4ca4238a0b92382", + "Name": "api-call-1", + "EventTimestamp": "2025-12-10T00:15:10.071Z", + "CallbackSucceededDetails": { + "Result": { + "Payload": "{\"id\":1,\"data\":\"first\"}" + } + } + }, + { + "EventType": "CallbackSucceeded", + "SubType": "Callback", + "EventId": 7, + "Id": "eccbc87e4b5ce2fe", + "Name": "api-call-3", + "EventTimestamp": "2025-12-10T00:15:10.075Z", + "CallbackSucceededDetails": { + "Result": { + "Payload": "{\"id\":3,\"data\":\"third\"}" + } + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 8, + "EventTimestamp": "2025-12-10T00:15:10.126Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:15:09.987Z", + "EndTimestamp": "2025-12-10T00:15:10.126Z", + "Error": {}, + "RequestId": "6f2132e4-4618-4e08-88c0-9819e79685ca" + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 9, + "EventTimestamp": "2025-12-10T00:15:10.146Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:15:10.146Z", + "EndTimestamp": "2025-12-10T00:15:10.146Z", + "Error": {}, + "RequestId": "7b23a50d-1b08-47d5-96ed-473f84c01ffd" + } + }, + { + "EventType": "ExecutionSucceeded", + "EventId": 10, + "Id": "baad178f-c918-474e-932a-7d0f8868e4be", + "EventTimestamp": "2025-12-10T00:15:10.147Z", + "ExecutionSucceededDetails": { + "Result": { + "Payload": "{\"results\":[\"{\\\"id\\\":1,\\\"data\\\":\\\"first\\\"}\",\"{\\\"id\\\":2,\\\"data\\\":\\\"second\\\"}\",\"{\\\"id\\\":3,\\\"data\\\":\\\"third\\\"}\"],\"allCompleted\":true}" + } + } + } +] diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/concurrent/create-callback-concurrent.test.ts b/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/concurrent/create-callback-concurrent.test.ts index 037a15f9..1c3400ac 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/concurrent/create-callback-concurrent.test.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/concurrent/create-callback-concurrent.test.ts @@ -9,7 +9,7 @@ import { createTests } from "../../../utils/test-helper"; createTests({ handler, invocationType: InvocationType.Event, - tests: (runner) => { + tests: (runner, { assertEventSignatures }) => { it("should handle multiple concurrent callback operations", async () => { // Get all callback operations const callback1 = runner.getOperation("api-call-1"); @@ -57,6 +57,8 @@ createTests({ (op) => op.getType() === OperationType.CALLBACK, ), ).toBe(true); + + assertEventSignatures(result); }); }, }); diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/failures/create-callback-failures.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/failures/create-callback-failures.history.json new file mode 100644 index 00000000..c39b63ba --- /dev/null +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/failures/create-callback-failures.history.json @@ -0,0 +1,82 @@ +[ + { + "EventType": "ExecutionStarted", + "EventId": 1, + "Id": "489831c7-988e-47fc-b01e-aea2d3d9916f", + "EventTimestamp": "2025-12-10T00:15:10.670Z", + "ExecutionStartedDetails": { + "Input": { + "Payload": "{\"shouldCatchError\":false}" + } + } + }, + { + "EventType": "CallbackStarted", + "SubType": "Callback", + "EventId": 2, + "Id": "c4ca4238a0b92382", + "Name": "failing-operation", + "EventTimestamp": "2025-12-10T00:15:10.702Z", + "CallbackStartedDetails": { + "CallbackId": "eyJleGVjdXRpb25JZCI6ImU3ODA2MWMwLTY1OTgtNDlhZi1iNTMzLTM1OWQwMjA3ZDc4MiIsIm9wZXJhdGlvbklkIjoiYzRjYTQyMzhhMGI5MjM4MiIsInRva2VuIjoiNTA4ZjUwMjUtN2JiNC00OTUwLTk2MGItNTMzZDJhOTU2MmNkIn0=", + "Input": {} + } + }, + { + "EventType": "CallbackFailed", + "SubType": "Callback", + "EventId": 3, + "Id": "c4ca4238a0b92382", + "Name": "failing-operation", + "EventTimestamp": "2025-12-10T00:15:10.703Z", + "CallbackFailedDetails": { + "Error": { + "Payload": { + "ErrorMessage": "External API failure", + "ErrorType": "APIException" + } + } + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 4, + "EventTimestamp": "2025-12-10T00:15:10.762Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:15:10.670Z", + "EndTimestamp": "2025-12-10T00:15:10.762Z", + "Error": {}, + "RequestId": "ec711523-276b-4d18-b7a9-a96053f58caa" + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 5, + "EventTimestamp": "2025-12-10T00:15:10.784Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:15:10.783Z", + "EndTimestamp": "2025-12-10T00:15:10.784Z", + "Error": { + "Payload": { + "ErrorType": "CallbackError", + "ErrorMessage": "External API failure" + } + }, + "RequestId": "562069c6-e606-4403-83b4-da93a5ab332c" + } + }, + { + "EventType": "ExecutionFailed", + "EventId": 6, + "Id": "489831c7-988e-47fc-b01e-aea2d3d9916f", + "EventTimestamp": "2025-12-10T00:15:10.784Z", + "ExecutionFailedDetails": { + "Error": { + "Payload": { + "ErrorType": "CallbackError", + "ErrorMessage": "External API failure" + } + } + } + } +] diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/failures/create-callback-failures.test.ts b/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/failures/create-callback-failures.test.ts index 91c5f98a..654b594e 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/failures/create-callback-failures.test.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/failures/create-callback-failures.test.ts @@ -8,7 +8,7 @@ import { createTests } from "../../../utils/test-helper"; createTests({ handler, invocationType: InvocationType.Event, - tests: (runner) => { + tests: (runner, { assertEventSignatures }) => { it("should handle callback operations with failure", async () => { const callbackOperation = runner.getOperation("failing-operation"); @@ -32,6 +32,8 @@ createTests({ errorType: "CallbackError", stackTrace: undefined, }); + + assertEventSignatures(result); }); }, }); diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/heartbeat/create-callback-heartbeat.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/heartbeat/create-callback-heartbeat.history.json new file mode 100644 index 00000000..499c4c50 --- /dev/null +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/heartbeat/create-callback-heartbeat.history.json @@ -0,0 +1,72 @@ +[ + { + "EventType": "ExecutionStarted", + "EventId": 1, + "Id": "70381ad4-7099-443f-8d6e-e7160b89ef72", + "EventTimestamp": "2025-12-10T00:12:25.149Z", + "ExecutionStartedDetails": { + "Input": { + "Payload": "{\"isCloud\":false}" + } + } + }, + { + "EventType": "CallbackStarted", + "SubType": "Callback", + "EventId": 2, + "Id": "c4ca4238a0b92382", + "Name": "long-running-task", + "EventTimestamp": "2025-12-10T00:12:25.154Z", + "CallbackStartedDetails": { + "CallbackId": "eyJleGVjdXRpb25JZCI6IjA3MzU0YzM3LTlkMzAtNDkzNC04NGRjLTkzMjVlNjRlZWRkMiIsIm9wZXJhdGlvbklkIjoiYzRjYTQyMzhhMGI5MjM4MiIsInRva2VuIjoiZDI4Njc4ZjctMTBmNS00NTY2LThlMjctYjczM2Y3NDdhY2U3In0=", + "HeartbeatTimeout": 1, + "Input": {} + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 3, + "EventTimestamp": "2025-12-10T00:12:25.205Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:12:25.149Z", + "EndTimestamp": "2025-12-10T00:12:25.205Z", + "Error": {}, + "RequestId": "d0f3a9b7-5015-48bb-b73d-5b405f4f4103" + } + }, + { + "EventType": "CallbackSucceeded", + "SubType": "Callback", + "EventId": 4, + "Id": "c4ca4238a0b92382", + "Name": "long-running-task", + "EventTimestamp": "2025-12-10T00:12:26.358Z", + "CallbackSucceededDetails": { + "Result": { + "Payload": "{\"processed\":1000,\"status\":\"completed\"}" + } + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 5, + "EventTimestamp": "2025-12-10T00:12:26.360Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:12:26.360Z", + "EndTimestamp": "2025-12-10T00:12:26.360Z", + "Error": {}, + "RequestId": "071ab60f-7282-4e3b-bedf-1477ade7d430" + } + }, + { + "EventType": "ExecutionSucceeded", + "EventId": 6, + "Id": "70381ad4-7099-443f-8d6e-e7160b89ef72", + "EventTimestamp": "2025-12-10T00:12:26.361Z", + "ExecutionSucceededDetails": { + "Result": { + "Payload": "{\"longTaskResult\":\"{\\\"processed\\\":1000,\\\"status\\\":\\\"completed\\\"}\"}" + } + } + } +] diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/heartbeat/create-callback-heartbeat.test.ts b/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/heartbeat/create-callback-heartbeat.test.ts index 0c0a709a..bfedcce6 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/heartbeat/create-callback-heartbeat.test.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/heartbeat/create-callback-heartbeat.test.ts @@ -5,7 +5,7 @@ import { InvocationType } from "@aws-sdk/client-lambda"; createTests({ handler, invocationType: InvocationType.Event, - tests: (runner, { isCloud }) => { + tests: (runner, { isCloud, assertEventSignatures }) => { it("should handle callback heartbeats during long-running tasks", async () => { const callbackOperation = runner.getOperation("long-running-task"); @@ -37,6 +37,8 @@ createTests({ expect(result.getResult()).toEqual({ longTaskResult: callbackResult, }); + + assertEventSignatures(result); }); }, }); diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/mixed-ops/create-callback-mixed-ops.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/mixed-ops/create-callback-mixed-ops.history.json new file mode 100644 index 00000000..9dfe103f --- /dev/null +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/mixed-ops/create-callback-mixed-ops.history.json @@ -0,0 +1,118 @@ +[ + { + "EventType": "ExecutionStarted", + "EventId": 1, + "Id": "6e7afd87-c2cd-4b0a-9d07-e40c3bf50842", + "EventTimestamp": "2025-12-10T00:12:39.173Z", + "ExecutionStartedDetails": { + "Input": { + "Payload": "{}" + } + } + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 2, + "Id": "c4ca4238a0b92382", + "Name": "fetch-data", + "EventTimestamp": "2025-12-10T00:12:39.177Z", + "StepStartedDetails": {} + }, + { + "EventType": "StepSucceeded", + "SubType": "Step", + "EventId": 3, + "Id": "c4ca4238a0b92382", + "Name": "fetch-data", + "EventTimestamp": "2025-12-10T00:12:39.177Z", + "StepSucceededDetails": { + "Result": { + "Payload": "{\"userId\":123,\"name\":\"John Doe\"}" + }, + "RetryDetails": {} + } + }, + { + "EventType": "CallbackStarted", + "SubType": "Callback", + "EventId": 4, + "Id": "c81e728d9d4c2f63", + "Name": "process-user", + "EventTimestamp": "2025-12-10T00:12:39.179Z", + "CallbackStartedDetails": { + "CallbackId": "eyJleGVjdXRpb25JZCI6ImM0M2MzNWYzLWRhMzMtNDkwZS05MDljLWMwNTU3ZjJkODQ3NCIsIm9wZXJhdGlvbklkIjoiYzgxZTcyOGQ5ZDRjMmY2MyIsInRva2VuIjoiYTMwNTU3NTMtNWJiMy00MzAyLWJkYjQtZGQ4NTQ0M2ZkMWIxIn0=", + "Timeout": 300, + "Input": {} + } + }, + { + "EventType": "CallbackSucceeded", + "SubType": "Callback", + "EventId": 5, + "Id": "c81e728d9d4c2f63", + "Name": "process-user", + "EventTimestamp": "2025-12-10T00:12:39.180Z", + "CallbackSucceededDetails": { + "Result": { + "Payload": "{\"processed\":true,\"timestamp\":1765325559179}" + } + } + }, + { + "EventType": "WaitStarted", + "SubType": "Wait", + "EventId": 6, + "Id": "eccbc87e4b5ce2fe", + "Name": "initial-wait", + "EventTimestamp": "2025-12-10T00:12:39.181Z", + "WaitStartedDetails": { + "Duration": 1, + "ScheduledEndTimestamp": "2025-12-10T00:12:40.181Z" + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 7, + "EventTimestamp": "2025-12-10T00:12:39.233Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:12:39.173Z", + "EndTimestamp": "2025-12-10T00:12:39.233Z", + "Error": {}, + "RequestId": "e7549444-7453-4869-b047-ee7feb42d122" + } + }, + { + "EventType": "WaitSucceeded", + "SubType": "Wait", + "EventId": 8, + "Id": "eccbc87e4b5ce2fe", + "Name": "initial-wait", + "EventTimestamp": "2025-12-10T00:12:40.183Z", + "WaitSucceededDetails": { + "Duration": 1 + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 9, + "EventTimestamp": "2025-12-10T00:12:40.184Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:12:40.183Z", + "EndTimestamp": "2025-12-10T00:12:40.184Z", + "Error": {}, + "RequestId": "20d6750d-4768-426c-ab8f-082b128d44de" + } + }, + { + "EventType": "ExecutionSucceeded", + "EventId": 10, + "Id": "6e7afd87-c2cd-4b0a-9d07-e40c3bf50842", + "EventTimestamp": "2025-12-10T00:12:40.184Z", + "ExecutionSucceededDetails": { + "Result": { + "Payload": "{\"stepResult\":{\"userId\":123,\"name\":\"John Doe\"},\"callbackResult\":\"{\\\"processed\\\":true,\\\"timestamp\\\":1765325559179}\",\"completed\":true}" + } + } + } +] diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/mixed-ops/create-callback-mixed-ops.test.ts b/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/mixed-ops/create-callback-mixed-ops.test.ts index f6e6d840..6f6d2a34 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/mixed-ops/create-callback-mixed-ops.test.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/mixed-ops/create-callback-mixed-ops.test.ts @@ -9,7 +9,7 @@ import { createTests } from "../../../utils/test-helper"; createTests({ handler, invocationType: InvocationType.Event, - tests: (runner) => { + tests: (runner, { assertEventSignatures }) => { it("should handle callback operations mixed with other operation types", async () => { const callbackOperation = runner.getOperation("process-user"); @@ -41,6 +41,8 @@ createTests({ expect(operationTypes).toContain(OperationType.WAIT); expect(operationTypes).toContain(OperationType.STEP); expect(operationTypes).toContain(OperationType.CALLBACK); + + assertEventSignatures(result); }); }, }); diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/serdes/create-callback-serdes.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/serdes/create-callback-serdes.history.json new file mode 100644 index 00000000..4af1a1c1 --- /dev/null +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/serdes/create-callback-serdes.history.json @@ -0,0 +1,72 @@ +[ + { + "EventType": "ExecutionStarted", + "EventId": 1, + "Id": "7e2007fa-3f78-424d-817a-47fb55e32436", + "EventTimestamp": "2025-12-10T00:15:10.549Z", + "ExecutionStartedDetails": { + "Input": { + "Payload": "{}" + } + } + }, + { + "EventType": "CallbackStarted", + "SubType": "Callback", + "EventId": 2, + "Id": "c4ca4238a0b92382", + "Name": "custom-serdes-callback", + "EventTimestamp": "2025-12-10T00:15:10.586Z", + "CallbackStartedDetails": { + "CallbackId": "eyJleGVjdXRpb25JZCI6ImMxMjEzYWM0LWVmY2QtNDlkZi1hMjdlLWJjNWQ3MGUzYTg0OCIsIm9wZXJhdGlvbklkIjoiYzRjYTQyMzhhMGI5MjM4MiIsInRva2VuIjoiYmQ0NjQyZGYtMzJiYi00MzE3LThlMTUtZThjYWM0NWE4MTUxIn0=", + "Timeout": 300, + "Input": {} + } + }, + { + "EventType": "CallbackSucceeded", + "SubType": "Callback", + "EventId": 3, + "Id": "c4ca4238a0b92382", + "Name": "custom-serdes-callback", + "EventTimestamp": "2025-12-10T00:15:10.587Z", + "CallbackSucceededDetails": { + "Result": { + "Payload": "{\"id\":42,\"message\":\"Hello World\",\"timestamp\":\"2025-01-01T00:00:00.000Z\"}" + } + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 4, + "EventTimestamp": "2025-12-10T00:15:10.646Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:15:10.549Z", + "EndTimestamp": "2025-12-10T00:15:10.646Z", + "Error": {}, + "RequestId": "9f7cbe60-1104-4ea4-b89a-af6ab03ba71a" + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 5, + "EventTimestamp": "2025-12-10T00:15:10.668Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:15:10.667Z", + "EndTimestamp": "2025-12-10T00:15:10.668Z", + "Error": {}, + "RequestId": "f0958925-e623-4e52-ba25-14b296c58b68" + } + }, + { + "EventType": "ExecutionSucceeded", + "EventId": 6, + "Id": "7e2007fa-3f78-424d-817a-47fb55e32436", + "EventTimestamp": "2025-12-10T00:15:10.668Z", + "ExecutionSucceededDetails": { + "Result": { + "Payload": "{\"receivedData\":{\"id\":42,\"message\":\"Hello World\",\"timestamp\":\"2025-01-01T00:00:00.000Z\"},\"isDateObject\":true}" + } + } + } +] diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/serdes/create-callback-serdes.test.ts b/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/serdes/create-callback-serdes.test.ts index e30fd6df..660493ab 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/serdes/create-callback-serdes.test.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/serdes/create-callback-serdes.test.ts @@ -30,7 +30,7 @@ const customSerdes = { createTests({ handler, invocationType: InvocationType.Event, - tests: (runner) => { + tests: (runner, { assertEventSignatures }) => { it("should handle callback operations with custom serdes", async () => { const callbackOperation = runner.getOperation("custom-serdes-callback"); const executionPromise = runner.run(); @@ -58,6 +58,8 @@ createTests({ }), ), ); + + assertEventSignatures(result); }); }, }); diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/simple/create-callback-failure-undefined.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/simple/create-callback-failure-undefined.history.json new file mode 100644 index 00000000..c10f4802 --- /dev/null +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/simple/create-callback-failure-undefined.history.json @@ -0,0 +1,77 @@ +[ + { + "EventType": "ExecutionStarted", + "EventId": 1, + "Id": "9dfc0ba2-68f6-4906-b673-e9fc7f730c35", + "EventTimestamp": "2025-12-10T00:15:09.336Z", + "ExecutionStartedDetails": { + "Input": { + "Payload": "{}" + } + } + }, + { + "EventType": "CallbackStarted", + "SubType": "Callback", + "EventId": 2, + "Id": "c4ca4238a0b92382", + "EventTimestamp": "2025-12-10T00:15:09.362Z", + "CallbackStartedDetails": { + "CallbackId": "eyJleGVjdXRpb25JZCI6ImYyNTVjNmY5LWRiNDQtNGI2Ni05M2IwLTg1YTE2NDZjNzlhOSIsIm9wZXJhdGlvbklkIjoiYzRjYTQyMzhhMGI5MjM4MiIsInRva2VuIjoiYjY2OTgyMzgtNTQ1OS00YThkLTkyNDgtZGQxOWNjNzY1M2Y3In0=", + "Input": {} + } + }, + { + "EventType": "CallbackFailed", + "SubType": "Callback", + "EventId": 3, + "Id": "c4ca4238a0b92382", + "EventTimestamp": "2025-12-10T00:15:09.362Z", + "CallbackFailedDetails": { + "Error": { + "Payload": {} + } + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 4, + "EventTimestamp": "2025-12-10T00:15:09.423Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:15:09.336Z", + "EndTimestamp": "2025-12-10T00:15:09.423Z", + "Error": {}, + "RequestId": "1e5ef3b2-7095-41f4-8558-3eb54813d2d8" + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 5, + "EventTimestamp": "2025-12-10T00:15:09.444Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:15:09.443Z", + "EndTimestamp": "2025-12-10T00:15:09.444Z", + "Error": { + "Payload": { + "ErrorType": "CallbackError", + "ErrorMessage": "Callback failed" + } + }, + "RequestId": "37732507-267a-411b-a1cd-654d05c66440" + } + }, + { + "EventType": "ExecutionFailed", + "EventId": 6, + "Id": "9dfc0ba2-68f6-4906-b673-e9fc7f730c35", + "EventTimestamp": "2025-12-10T00:15:09.445Z", + "ExecutionFailedDetails": { + "Error": { + "Payload": { + "ErrorType": "CallbackError", + "ErrorMessage": "Callback failed" + } + } + } + } +] diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/simple/create-callback-failure.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/simple/create-callback-failure.history.json new file mode 100644 index 00000000..25d901a5 --- /dev/null +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/simple/create-callback-failure.history.json @@ -0,0 +1,79 @@ +[ + { + "EventType": "ExecutionStarted", + "EventId": 1, + "Id": "36f807d8-a63f-42d8-a44d-ad73d36c78bc", + "EventTimestamp": "2025-12-10T00:15:08.867Z", + "ExecutionStartedDetails": { + "Input": { + "Payload": "{}" + } + } + }, + { + "EventType": "CallbackStarted", + "SubType": "Callback", + "EventId": 2, + "Id": "c4ca4238a0b92382", + "EventTimestamp": "2025-12-10T00:15:08.910Z", + "CallbackStartedDetails": { + "CallbackId": "eyJleGVjdXRpb25JZCI6ImQ0ODU1ZWRhLTlkOGUtNGQ3NC1hMmU5LTY1Yjg4MDNiMjc0OSIsIm9wZXJhdGlvbklkIjoiYzRjYTQyMzhhMGI5MjM4MiIsInRva2VuIjoiNzUzMjdjZGEtMDYxYy00YmM5LWEzOWEtNzljY2NiYWNlYWUxIn0=", + "Input": {} + } + }, + { + "EventType": "CallbackFailed", + "SubType": "Callback", + "EventId": 3, + "Id": "c4ca4238a0b92382", + "EventTimestamp": "2025-12-10T00:15:08.911Z", + "CallbackFailedDetails": { + "Error": { + "Payload": { + "ErrorMessage": "ERROR" + } + } + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 4, + "EventTimestamp": "2025-12-10T00:15:08.972Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:15:08.867Z", + "EndTimestamp": "2025-12-10T00:15:08.972Z", + "Error": {}, + "RequestId": "c547ab5d-6501-41ba-b720-bb7248c0af70" + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 5, + "EventTimestamp": "2025-12-10T00:15:08.994Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:15:08.993Z", + "EndTimestamp": "2025-12-10T00:15:08.994Z", + "Error": { + "Payload": { + "ErrorType": "CallbackError", + "ErrorMessage": "ERROR" + } + }, + "RequestId": "e99100a2-77c5-4a49-a696-6788e90e27d4" + } + }, + { + "EventType": "ExecutionFailed", + "EventId": 6, + "Id": "36f807d8-a63f-42d8-a44d-ad73d36c78bc", + "EventTimestamp": "2025-12-10T00:15:08.994Z", + "ExecutionFailedDetails": { + "Error": { + "Payload": { + "ErrorType": "CallbackError", + "ErrorMessage": "ERROR" + } + } + } + } +] diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/simple/create-callback-success-undefined.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/simple/create-callback-success-undefined.history.json new file mode 100644 index 00000000..f696c3c1 --- /dev/null +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/simple/create-callback-success-undefined.history.json @@ -0,0 +1,63 @@ +[ + { + "EventType": "ExecutionStarted", + "EventId": 1, + "Id": "aeb42be9-bb93-4a04-b845-42dcca430046", + "EventTimestamp": "2025-12-10T00:15:09.097Z", + "ExecutionStartedDetails": { + "Input": { + "Payload": "{}" + } + } + }, + { + "EventType": "CallbackStarted", + "SubType": "Callback", + "EventId": 2, + "Id": "c4ca4238a0b92382", + "EventTimestamp": "2025-12-10T00:15:09.141Z", + "CallbackStartedDetails": { + "CallbackId": "eyJleGVjdXRpb25JZCI6ImNhNDZkMTFhLTk2ZGQtNDk3NC04ODkyLWE4Njc3ZDJkZTcwNiIsIm9wZXJhdGlvbklkIjoiYzRjYTQyMzhhMGI5MjM4MiIsInRva2VuIjoiYzBiYjVmZGUtMjYzNi00ZGM0LTlhZDUtODE3ZjkwZjFlY2Q3In0=", + "Input": {} + } + }, + { + "EventType": "CallbackSucceeded", + "SubType": "Callback", + "EventId": 3, + "Id": "c4ca4238a0b92382", + "EventTimestamp": "2025-12-10T00:15:09.142Z", + "CallbackSucceededDetails": { + "Result": {} + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 4, + "EventTimestamp": "2025-12-10T00:15:09.202Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:15:09.097Z", + "EndTimestamp": "2025-12-10T00:15:09.202Z", + "Error": {}, + "RequestId": "3e069eec-4204-4aea-afc4-518db3d6fa93" + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 5, + "EventTimestamp": "2025-12-10T00:15:09.224Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:15:09.224Z", + "EndTimestamp": "2025-12-10T00:15:09.224Z", + "Error": {}, + "RequestId": "b27855c1-7ffd-4577-9185-60cee47f7607" + } + }, + { + "EventType": "ExecutionSucceeded", + "EventId": 6, + "Id": "aeb42be9-bb93-4a04-b845-42dcca430046", + "EventTimestamp": "2025-12-10T00:15:09.224Z", + "ExecutionSucceededDetails": {} + } +] diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/simple/create-callback-success.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/simple/create-callback-success.history.json new file mode 100644 index 00000000..474e1193 --- /dev/null +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/simple/create-callback-success.history.json @@ -0,0 +1,69 @@ +[ + { + "EventType": "ExecutionStarted", + "EventId": 1, + "Id": "e9657372-e8ef-4099-a5b5-6f3fb9e886da", + "EventTimestamp": "2025-12-10T00:15:08.642Z", + "ExecutionStartedDetails": { + "Input": { + "Payload": "{}" + } + } + }, + { + "EventType": "CallbackStarted", + "SubType": "Callback", + "EventId": 2, + "Id": "c4ca4238a0b92382", + "EventTimestamp": "2025-12-10T00:15:08.678Z", + "CallbackStartedDetails": { + "CallbackId": "eyJleGVjdXRpb25JZCI6IjM0ODU3NTUyLTNhMWMtNDgxYi05ZDNlLWUzZjM1ZjVhM2M3OCIsIm9wZXJhdGlvbklkIjoiYzRjYTQyMzhhMGI5MjM4MiIsInRva2VuIjoiMzlmOWU2ZTYtYWI0My00NjhhLTg5ZjQtMDBiZTNlOTQxZDMxIn0=", + "Input": {} + } + }, + { + "EventType": "CallbackSucceeded", + "SubType": "Callback", + "EventId": 3, + "Id": "c4ca4238a0b92382", + "EventTimestamp": "2025-12-10T00:15:08.679Z", + "CallbackSucceededDetails": { + "Result": { + "Payload": "successful" + } + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 4, + "EventTimestamp": "2025-12-10T00:15:08.739Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:15:08.642Z", + "EndTimestamp": "2025-12-10T00:15:08.739Z", + "Error": {}, + "RequestId": "76079409-2aa5-4ef4-b5fb-576798ed2d75" + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 5, + "EventTimestamp": "2025-12-10T00:15:08.761Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:15:08.760Z", + "EndTimestamp": "2025-12-10T00:15:08.761Z", + "Error": {}, + "RequestId": "3205c33a-2785-455f-be9e-f9490e91a69d" + } + }, + { + "EventType": "ExecutionSucceeded", + "EventId": 6, + "Id": "e9657372-e8ef-4099-a5b5-6f3fb9e886da", + "EventTimestamp": "2025-12-10T00:15:08.761Z", + "ExecutionSucceededDetails": { + "Result": { + "Payload": "\"successful\"" + } + } + } +] diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/simple/create-callback.test.ts b/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/simple/create-callback.test.ts index 82b26e44..68b86f16 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/simple/create-callback.test.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/simple/create-callback.test.ts @@ -8,7 +8,7 @@ import { createTests } from "../../../utils/test-helper"; createTests({ handler, invocationType: InvocationType.Event, - tests: (runner) => { + tests: (runner, { assertEventSignatures }) => { it("function completes when callback succeeds - happy case", async () => { const res = "successful"; const executionPromise = runner.run(); @@ -21,6 +21,8 @@ createTests({ expect(callbackOp.getCallbackDetails()?.result).toStrictEqual(res); expect(execution.getResult()).toStrictEqual(res); + + assertEventSignatures(execution, "success"); }); it("function completes when callback fails - happy case", async () => { @@ -34,6 +36,8 @@ createTests({ expect(callbackOp.getCallbackDetails()?.error).toBeDefined(); expect(execution.getError()).toBeDefined(); + + assertEventSignatures(execution, "failure"); }); it("function completes when callback succeeds with undefined - edge case", async () => { @@ -48,6 +52,8 @@ createTests({ expect(callbackOp.getCallbackDetails()?.result).toBeUndefined(); expect(callbackOp.getCallbackDetails()?.error).toBeUndefined(); expect(execution.getResult()).toBeUndefined(); + + assertEventSignatures(execution, "success-undefined"); }); it("function completes when callback fails with undefined error message - edge case", async () => { @@ -67,6 +73,8 @@ createTests({ stackTrace: undefined, }); expect(execution.getError()).toBeDefined(); + + assertEventSignatures(execution, "failure-undefined"); }); }, }); diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/timeout/create-callback-timeout.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/timeout/create-callback-timeout.history.json new file mode 100644 index 00000000..658150ad --- /dev/null +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/timeout/create-callback-timeout.history.json @@ -0,0 +1,82 @@ +[ + { + "EventType": "ExecutionStarted", + "EventId": 1, + "Id": "2a59b0ba-c037-4bf2-9659-a6e384d44356", + "EventTimestamp": "2025-12-10T00:12:21.428Z", + "ExecutionStartedDetails": { + "Input": { + "Payload": "{\"timeoutType\":\"heartbeat\"}" + } + } + }, + { + "EventType": "CallbackStarted", + "SubType": "Callback", + "EventId": 2, + "Id": "c4ca4238a0b92382", + "Name": "long-running-task", + "EventTimestamp": "2025-12-10T00:12:21.434Z", + "CallbackStartedDetails": { + "CallbackId": "eyJleGVjdXRpb25JZCI6IjJkM2NjMjRkLTA1MWEtNDdhOC1iMzNmLWE5ZmE5NGQ5MDUwOSIsIm9wZXJhdGlvbklkIjoiYzRjYTQyMzhhMGI5MjM4MiIsInRva2VuIjoiZDM5NDgwMmQtZjVjZC00ZmNmLWEwYjgtMGE1Nzc3MDYyZTlhIn0=", + "HeartbeatTimeout": 1, + "Input": {} + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 3, + "EventTimestamp": "2025-12-10T00:12:21.485Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:12:21.428Z", + "EndTimestamp": "2025-12-10T00:12:21.485Z", + "Error": {}, + "RequestId": "a083c5de-7d37-471a-a204-ce52a4ca54af" + } + }, + { + "EventType": "CallbackTimedOut", + "SubType": "Callback", + "EventId": 4, + "Id": "c4ca4238a0b92382", + "Name": "long-running-task", + "EventTimestamp": "2025-12-10T00:12:22.436Z", + "CallbackTimedOutDetails": { + "Error": { + "Payload": { + "ErrorMessage": "Callback timed out on heartbeat" + } + } + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 5, + "EventTimestamp": "2025-12-10T00:12:22.437Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:12:22.436Z", + "EndTimestamp": "2025-12-10T00:12:22.437Z", + "Error": { + "Payload": { + "ErrorType": "CallbackError", + "ErrorMessage": "Callback timed out on heartbeat" + } + }, + "RequestId": "292e244b-a3bd-416f-bc9a-55e5f5e78092" + } + }, + { + "EventType": "ExecutionFailed", + "EventId": 6, + "Id": "2a59b0ba-c037-4bf2-9659-a6e384d44356", + "EventTimestamp": "2025-12-10T00:12:22.437Z", + "ExecutionFailedDetails": { + "Error": { + "Payload": { + "ErrorType": "CallbackError", + "ErrorMessage": "Callback timed out on heartbeat" + } + } + } + } +] diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/timeout/create-callback-timeout.test.ts b/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/timeout/create-callback-timeout.test.ts index a3d3b080..f26d572d 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/timeout/create-callback-timeout.test.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/timeout/create-callback-timeout.test.ts @@ -3,7 +3,7 @@ import { createTests } from "../../../utils/test-helper"; createTests({ handler, - tests: (runner) => { + tests: (runner, { assertEventSignatures }) => { it("should time out if there are no callback heartbeats", async () => { const result = await runner.run({ payload: { timeoutType: "heartbeat" }, @@ -15,6 +15,8 @@ createTests({ errorType: "CallbackError", stackTrace: undefined, }); + + assertEventSignatures(result); }); it("should time out if callback times out", async () => { @@ -28,6 +30,8 @@ createTests({ errorType: "CallbackError", stackTrace: undefined, }); + + assertEventSignatures(result); }); }, }); diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/force-checkpointing/callback/force-checkpointing-callback.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/force-checkpointing/callback/force-checkpointing-callback.history.json new file mode 100644 index 00000000..f06141da --- /dev/null +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/force-checkpointing/callback/force-checkpointing-callback.history.json @@ -0,0 +1,209 @@ +[ + { + "EventType": "ExecutionStarted", + "EventId": 1, + "Id": "1354deb8-60cc-41f3-a469-e8bb11156808", + "EventTimestamp": "2025-12-10T00:12:09.158Z", + "ExecutionStartedDetails": { + "Input": { + "Payload": "{}" + } + } + }, + { + "EventType": "ContextStarted", + "SubType": "Parallel", + "EventId": 2, + "Id": "c4ca4238a0b92382", + "EventTimestamp": "2025-12-10T00:12:09.164Z", + "ContextStartedDetails": {} + }, + { + "EventType": "ContextStarted", + "SubType": "ParallelBranch", + "EventId": 3, + "Id": "ea66c06c1e1c05fa", + "Name": "parallel-branch-0", + "EventTimestamp": "2025-12-10T00:12:09.164Z", + "ParentId": "c4ca4238a0b92382", + "ContextStartedDetails": {} + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 4, + "Id": "2f221a18eb863803", + "Name": "long-running-step", + "EventTimestamp": "2025-12-10T00:12:09.164Z", + "ParentId": "ea66c06c1e1c05fa", + "StepStartedDetails": {} + }, + { + "EventType": "ContextStarted", + "SubType": "ParallelBranch", + "EventId": 5, + "Id": "98c6f2c2287f4c73", + "Name": "parallel-branch-1", + "EventTimestamp": "2025-12-10T00:12:09.164Z", + "ParentId": "c4ca4238a0b92382", + "ContextStartedDetails": {} + }, + { + "EventType": "CallbackStarted", + "SubType": "Callback", + "EventId": 6, + "Id": "6151f5ab282d90e4", + "Name": "callback-1", + "EventTimestamp": "2025-12-10T00:12:09.164Z", + "ParentId": "98c6f2c2287f4c73", + "CallbackStartedDetails": { + "CallbackId": "eyJleGVjdXRpb25JZCI6ImQ4NWMyMjM4LTU5NTYtNDdiYS05NTAyLWEwMDJhNWU5N2IzMCIsIm9wZXJhdGlvbklkIjoiNjE1MWY1YWIyODJkOTBlNCIsInRva2VuIjoiZmJiOTljNzMtYmYwOS00NzZkLWFlZDAtOTNkZDlmYTkyMmJjIn0=", + "Input": {} + } + }, + { + "EventType": "CallbackSucceeded", + "SubType": "Callback", + "EventId": 7, + "Id": "6151f5ab282d90e4", + "Name": "callback-1", + "EventTimestamp": "2025-12-10T00:12:09.165Z", + "ParentId": "98c6f2c2287f4c73", + "CallbackSucceededDetails": { + "Result": { + "Payload": "callback-1-done" + } + } + }, + { + "EventType": "CallbackStarted", + "SubType": "Callback", + "EventId": 8, + "Id": "e61730e6717b1787", + "Name": "callback-2", + "EventTimestamp": "2025-12-10T00:12:10.168Z", + "ParentId": "98c6f2c2287f4c73", + "CallbackStartedDetails": { + "CallbackId": "eyJleGVjdXRpb25JZCI6ImQ4NWMyMjM4LTU5NTYtNDdiYS05NTAyLWEwMDJhNWU5N2IzMCIsIm9wZXJhdGlvbklkIjoiZTYxNzMwZTY3MTdiMTc4NyIsInRva2VuIjoiY2Y4YzA5ZGQtM2YwYy00N2Y5LWI3OTAtYjU1MDQxN2NkNDdlIn0=", + "Input": {} + } + }, + { + "EventType": "CallbackSucceeded", + "SubType": "Callback", + "EventId": 9, + "Id": "e61730e6717b1787", + "Name": "callback-2", + "EventTimestamp": "2025-12-10T00:12:10.168Z", + "ParentId": "98c6f2c2287f4c73", + "CallbackSucceededDetails": { + "Result": { + "Payload": "callback-2-done" + } + } + }, + { + "EventType": "CallbackStarted", + "SubType": "Callback", + "EventId": 10, + "Id": "453e406dcee4d181", + "Name": "callback-3", + "EventTimestamp": "2025-12-10T00:12:11.173Z", + "ParentId": "98c6f2c2287f4c73", + "CallbackStartedDetails": { + "CallbackId": "eyJleGVjdXRpb25JZCI6ImQ4NWMyMjM4LTU5NTYtNDdiYS05NTAyLWEwMDJhNWU5N2IzMCIsIm9wZXJhdGlvbklkIjoiNDUzZTQwNmRjZWU0ZDE4MSIsInRva2VuIjoiM2Q4ZTZmYWYtOWQ2NS00MmRjLTk4YmUtNmFlNjhiOTUwZWZiIn0=", + "Input": {} + } + }, + { + "EventType": "CallbackSucceeded", + "SubType": "Callback", + "EventId": 11, + "Id": "453e406dcee4d181", + "Name": "callback-3", + "EventTimestamp": "2025-12-10T00:12:11.173Z", + "ParentId": "98c6f2c2287f4c73", + "CallbackSucceededDetails": { + "Result": { + "Payload": "callback-3-done" + } + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "ParallelBranch", + "EventId": 12, + "Id": "98c6f2c2287f4c73", + "Name": "parallel-branch-1", + "EventTimestamp": "2025-12-10T00:12:12.178Z", + "ParentId": "c4ca4238a0b92382", + "ContextSucceededDetails": { + "Result": { + "Payload": "\"callbacks-complete\"" + } + } + }, + { + "EventType": "StepSucceeded", + "SubType": "Step", + "EventId": 13, + "Id": "2f221a18eb863803", + "Name": "long-running-step", + "EventTimestamp": "2025-12-10T00:12:19.165Z", + "ParentId": "ea66c06c1e1c05fa", + "StepSucceededDetails": { + "Result": { + "Payload": "\"long-complete\"" + }, + "RetryDetails": {} + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "ParallelBranch", + "EventId": 14, + "Id": "ea66c06c1e1c05fa", + "Name": "parallel-branch-0", + "EventTimestamp": "2025-12-10T00:12:19.168Z", + "ParentId": "c4ca4238a0b92382", + "ContextSucceededDetails": { + "Result": { + "Payload": "\"long-complete\"" + } + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "Parallel", + "EventId": 15, + "Id": "c4ca4238a0b92382", + "EventTimestamp": "2025-12-10T00:12:19.168Z", + "ContextSucceededDetails": { + "Result": { + "Payload": "{\"all\":[{\"result\":\"long-complete\",\"index\":0,\"status\":\"SUCCEEDED\"},{\"result\":\"callbacks-complete\",\"index\":1,\"status\":\"SUCCEEDED\"}],\"completionReason\":\"ALL_COMPLETED\"}" + } + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 16, + "EventTimestamp": "2025-12-10T00:12:19.170Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:12:09.158Z", + "EndTimestamp": "2025-12-10T00:12:19.170Z", + "Error": {}, + "RequestId": "c21bfd3a-4123-4b55-a333-470e9a59a1e3" + } + }, + { + "EventType": "ExecutionSucceeded", + "EventId": 17, + "Id": "1354deb8-60cc-41f3-a469-e8bb11156808", + "EventTimestamp": "2025-12-10T00:12:19.170Z", + "ExecutionSucceededDetails": { + "Result": { + "Payload": "\"{\\\"all\\\":[{\\\"result\\\":\\\"long-complete\\\",\\\"index\\\":0,\\\"status\\\":\\\"SUCCEEDED\\\"},{\\\"result\\\":\\\"callbacks-complete\\\",\\\"index\\\":1,\\\"status\\\":\\\"SUCCEEDED\\\"}],\\\"completionReason\\\":\\\"ALL_COMPLETED\\\"}\"" + } + } + } +] diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/force-checkpointing/callback/force-checkpointing-callback.test.ts b/packages/aws-durable-execution-sdk-js-examples/src/examples/force-checkpointing/callback/force-checkpointing-callback.test.ts index b8443232..348c6852 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/force-checkpointing/callback/force-checkpointing-callback.test.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/force-checkpointing/callback/force-checkpointing-callback.test.ts @@ -9,7 +9,7 @@ import { createTests({ handler, invocationType: InvocationType.Event, - tests: (runner) => { + tests: (runner, { assertEventSignatures }) => { it("should complete with force checkpointing when one branch blocks termination with multiple callbacks", async () => { const startTime = Date.now(); @@ -56,6 +56,8 @@ createTests({ // Verify operations were tracked const operations = execution.getOperations(); expect(operations.length).toBeGreaterThan(0); + + assertEventSignatures(execution); }, 50000); }, }); diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/force-checkpointing/invoke/force-checkpointing-invoke.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/force-checkpointing/invoke/force-checkpointing-invoke.history.json new file mode 100644 index 00000000..286884b2 --- /dev/null +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/force-checkpointing/invoke/force-checkpointing-invoke.history.json @@ -0,0 +1,212 @@ +[ + { + "EventType": "ExecutionStarted", + "EventId": 1, + "Id": "b8ac939d-b10c-495b-9ed9-c5474d343820", + "EventTimestamp": "2025-12-10T00:12:07.577Z", + "ExecutionStartedDetails": { + "Input": { + "Payload": "{\"functionNames\":[\"wait\",\"step-basic\",\"wait\"]}" + } + } + }, + { + "EventType": "ContextStarted", + "SubType": "Parallel", + "EventId": 2, + "Id": "c4ca4238a0b92382", + "EventTimestamp": "2025-12-10T00:12:07.585Z", + "ContextStartedDetails": {} + }, + { + "EventType": "ContextStarted", + "SubType": "ParallelBranch", + "EventId": 3, + "Id": "ea66c06c1e1c05fa", + "Name": "parallel-branch-0", + "EventTimestamp": "2025-12-10T00:12:07.585Z", + "ParentId": "c4ca4238a0b92382", + "ContextStartedDetails": {} + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 4, + "Id": "2f221a18eb863803", + "Name": "long-running-step", + "EventTimestamp": "2025-12-10T00:12:07.585Z", + "ParentId": "ea66c06c1e1c05fa", + "StepStartedDetails": {} + }, + { + "EventType": "ContextStarted", + "SubType": "ParallelBranch", + "EventId": 5, + "Id": "98c6f2c2287f4c73", + "Name": "parallel-branch-1", + "EventTimestamp": "2025-12-10T00:12:07.585Z", + "ParentId": "c4ca4238a0b92382", + "ContextStartedDetails": {} + }, + { + "EventType": "ChainedInvokeStarted", + "SubType": "ChainedInvoke", + "EventId": 6, + "Id": "6151f5ab282d90e4", + "EventTimestamp": "2025-12-10T00:12:07.585Z", + "ParentId": "98c6f2c2287f4c73", + "ChainedInvokeStartedDetails": { + "FunctionName": "", + "Input": { + "Payload": "" + }, + "DurableExecutionArn": "" + } + }, + { + "EventType": "ChainedInvokeSucceeded", + "SubType": "ChainedInvoke", + "EventId": 7, + "Id": "6151f5ab282d90e4", + "EventTimestamp": "2025-12-10T00:12:09.694Z", + "ParentId": "98c6f2c2287f4c73", + "ChainedInvokeSucceededDetails": { + "Result": { + "Payload": "\"Function Completed\"" + } + } + }, + { + "EventType": "ChainedInvokeStarted", + "SubType": "ChainedInvoke", + "EventId": 8, + "Id": "e61730e6717b1787", + "EventTimestamp": "2025-12-10T00:12:11.595Z", + "ParentId": "98c6f2c2287f4c73", + "ChainedInvokeStartedDetails": { + "FunctionName": "", + "Input": { + "Payload": "" + }, + "DurableExecutionArn": "" + } + }, + { + "EventType": "ChainedInvokeSucceeded", + "SubType": "ChainedInvoke", + "EventId": 9, + "Id": "e61730e6717b1787", + "EventTimestamp": "2025-12-10T00:12:11.702Z", + "ParentId": "98c6f2c2287f4c73", + "ChainedInvokeSucceededDetails": { + "Result": { + "Payload": "\"step completed\"" + } + } + }, + { + "EventType": "ChainedInvokeStarted", + "SubType": "ChainedInvoke", + "EventId": 10, + "Id": "453e406dcee4d181", + "EventTimestamp": "2025-12-10T00:12:12.599Z", + "ParentId": "98c6f2c2287f4c73", + "ChainedInvokeStartedDetails": { + "FunctionName": "", + "Input": { + "Payload": "" + }, + "DurableExecutionArn": "" + } + }, + { + "EventType": "ChainedInvokeSucceeded", + "SubType": "ChainedInvoke", + "EventId": 11, + "Id": "453e406dcee4d181", + "EventTimestamp": "2025-12-10T00:12:14.704Z", + "ParentId": "98c6f2c2287f4c73", + "ChainedInvokeSucceededDetails": { + "Result": { + "Payload": "\"Function Completed\"" + } + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "ParallelBranch", + "EventId": 12, + "Id": "98c6f2c2287f4c73", + "Name": "parallel-branch-1", + "EventTimestamp": "2025-12-10T00:12:16.609Z", + "ParentId": "c4ca4238a0b92382", + "ContextSucceededDetails": { + "Result": { + "Payload": "\"invokes-complete\"" + } + } + }, + { + "EventType": "StepSucceeded", + "SubType": "Step", + "EventId": 13, + "Id": "2f221a18eb863803", + "Name": "long-running-step", + "EventTimestamp": "2025-12-10T00:12:27.585Z", + "ParentId": "ea66c06c1e1c05fa", + "StepSucceededDetails": { + "Result": { + "Payload": "\"long-complete\"" + }, + "RetryDetails": {} + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "ParallelBranch", + "EventId": 14, + "Id": "ea66c06c1e1c05fa", + "Name": "parallel-branch-0", + "EventTimestamp": "2025-12-10T00:12:27.587Z", + "ParentId": "c4ca4238a0b92382", + "ContextSucceededDetails": { + "Result": { + "Payload": "\"long-complete\"" + } + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "Parallel", + "EventId": 15, + "Id": "c4ca4238a0b92382", + "EventTimestamp": "2025-12-10T00:12:27.587Z", + "ContextSucceededDetails": { + "Result": { + "Payload": "{\"all\":[{\"result\":\"long-complete\",\"index\":0,\"status\":\"SUCCEEDED\"},{\"result\":\"invokes-complete\",\"index\":1,\"status\":\"SUCCEEDED\"}],\"completionReason\":\"ALL_COMPLETED\"}" + } + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 16, + "EventTimestamp": "2025-12-10T00:12:27.587Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:12:07.576Z", + "EndTimestamp": "2025-12-10T00:12:27.587Z", + "Error": {}, + "RequestId": "55467410-dbb1-4a06-ad2e-31a749af94bf" + } + }, + { + "EventType": "ExecutionSucceeded", + "EventId": 17, + "Id": "b8ac939d-b10c-495b-9ed9-c5474d343820", + "EventTimestamp": "2025-12-10T00:12:27.587Z", + "ExecutionSucceededDetails": { + "Result": { + "Payload": "\"{\\\"all\\\":[{\\\"result\\\":\\\"long-complete\\\",\\\"index\\\":0,\\\"status\\\":\\\"SUCCEEDED\\\"},{\\\"result\\\":\\\"invokes-complete\\\",\\\"index\\\":1,\\\"status\\\":\\\"SUCCEEDED\\\"}],\\\"completionReason\\\":\\\"ALL_COMPLETED\\\"}\"" + } + } + } +] diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/force-checkpointing/invoke/force-checkpointing-invoke.test.ts b/packages/aws-durable-execution-sdk-js-examples/src/examples/force-checkpointing/invoke/force-checkpointing-invoke.test.ts index 1cbdaa54..d404d747 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/force-checkpointing/invoke/force-checkpointing-invoke.test.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/force-checkpointing/invoke/force-checkpointing-invoke.test.ts @@ -9,7 +9,7 @@ import { handler as stepHandler } from "../../step/basic/step-basic"; createTests({ handler, - tests: (runner, { functionNameMap }) => { + tests: (runner, { functionNameMap, assertEventSignatures }) => { it("should complete with force checkpointing when one branch blocks termination with multiple invokes", async () => { // Register the invoked functions for local testing if (runner instanceof LocalDurableTestRunner) { @@ -58,6 +58,8 @@ createTests({ // Verify operations were tracked const operations = execution.getOperations(); expect(operations.length).toBeGreaterThan(0); + + assertEventSignatures(execution); }, 60000); // 60 second timeout }, }); diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/force-checkpointing/step-retry/force-checkpointing.test.ts b/packages/aws-durable-execution-sdk-js-examples/src/examples/force-checkpointing/step-retry/force-checkpointing.test.ts index f3956a68..8ea8ce27 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/force-checkpointing/step-retry/force-checkpointing.test.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/force-checkpointing/step-retry/force-checkpointing.test.ts @@ -4,7 +4,7 @@ import { ExecutionStatus } from "@aws/durable-execution-sdk-js-testing"; createTests({ handler, - tests: (runner) => { + tests: (runner, { assertEventSignatures }) => { it("should complete with force checkpointing when one branch blocks termination", async () => { const startTime = Date.now(); @@ -33,6 +33,8 @@ createTests({ // Verify operations were tracked const operations = execution.getOperations(); expect(operations.length).toBeGreaterThan(0); + + assertEventSignatures(execution); }, 20000); // 20 second timeout }, }); diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/invoke/simple/invoke-simple-basic-wait.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/invoke/simple/invoke-simple-basic-wait.history.json new file mode 100644 index 00000000..dcc14bd6 --- /dev/null +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/invoke/simple/invoke-simple-basic-wait.history.json @@ -0,0 +1,72 @@ +[ + { + "EventType": "ExecutionStarted", + "EventId": 1, + "Id": "c2ee5a66-7751-40e2-8c7b-8eb271518e37", + "EventTimestamp": "2025-12-10T00:12:22.591Z", + "ExecutionStartedDetails": { + "Input": { + "Payload": "{\"functionName\":\"wait-named\"}" + } + } + }, + { + "EventType": "ChainedInvokeStarted", + "SubType": "ChainedInvoke", + "EventId": 2, + "Id": "c4ca4238a0b92382", + "EventTimestamp": "2025-12-10T00:12:22.594Z", + "ChainedInvokeStartedDetails": { + "FunctionName": "", + "Input": { + "Payload": "" + }, + "DurableExecutionArn": "" + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 3, + "EventTimestamp": "2025-12-10T00:12:22.646Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:12:22.591Z", + "EndTimestamp": "2025-12-10T00:12:22.646Z", + "Error": {}, + "RequestId": "451009d0-39ae-4b25-8ce7-8d4254ae153c" + } + }, + { + "EventType": "ChainedInvokeSucceeded", + "SubType": "ChainedInvoke", + "EventId": 4, + "Id": "c4ca4238a0b92382", + "EventTimestamp": "2025-12-10T00:12:24.701Z", + "ChainedInvokeSucceededDetails": { + "Result": { + "Payload": "\"wait finished\"" + } + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 5, + "EventTimestamp": "2025-12-10T00:12:24.703Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:12:24.702Z", + "EndTimestamp": "2025-12-10T00:12:24.703Z", + "Error": {}, + "RequestId": "33341976-7210-4783-b505-9b4c61c6c274" + } + }, + { + "EventType": "ExecutionSucceeded", + "EventId": 6, + "Id": "c2ee5a66-7751-40e2-8c7b-8eb271518e37", + "EventTimestamp": "2025-12-10T00:12:24.703Z", + "ExecutionSucceededDetails": { + "Result": { + "Payload": "\"wait finished\"" + } + } + } +] diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/invoke/simple/invoke-simple-child-failure.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/invoke/simple/invoke-simple-child-failure.history.json new file mode 100644 index 00000000..9e31cbca --- /dev/null +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/invoke/simple/invoke-simple-child-failure.history.json @@ -0,0 +1,83 @@ +[ + { + "EventType": "ExecutionStarted", + "EventId": 1, + "Id": "7e80d670-4810-4737-8ad6-fc9c6b270f6d", + "EventTimestamp": "2025-12-10T00:12:25.024Z", + "ExecutionStartedDetails": { + "Input": { + "Payload": "{\"functionName\":\"handler-error\"}" + } + } + }, + { + "EventType": "ChainedInvokeStarted", + "SubType": "ChainedInvoke", + "EventId": 2, + "Id": "c4ca4238a0b92382", + "EventTimestamp": "2025-12-10T00:12:25.029Z", + "ChainedInvokeStartedDetails": { + "FunctionName": "", + "Input": { + "Payload": "" + }, + "DurableExecutionArn": "" + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 3, + "EventTimestamp": "2025-12-10T00:12:25.080Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:12:25.024Z", + "EndTimestamp": "2025-12-10T00:12:25.080Z", + "Error": {}, + "RequestId": "a902cbf1-ac57-48f7-ab93-3ebcb6bf18da" + } + }, + { + "EventType": "ChainedInvokeFailed", + "SubType": "ChainedInvoke", + "EventId": 4, + "Id": "c4ca4238a0b92382", + "EventTimestamp": "2025-12-10T00:12:25.136Z", + "ChainedInvokeFailedDetails": { + "Error": { + "Payload": { + "ErrorMessage": "Intentional handler failure", + "ErrorType": "Error" + } + } + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 5, + "EventTimestamp": "2025-12-10T00:12:25.139Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:12:25.138Z", + "EndTimestamp": "2025-12-10T00:12:25.139Z", + "Error": { + "Payload": { + "ErrorType": "InvokeError", + "ErrorMessage": "Intentional handler failure" + } + }, + "RequestId": "108e47a9-d884-4628-a1ec-fc170acfec7f" + } + }, + { + "EventType": "ExecutionFailed", + "EventId": 6, + "Id": "7e80d670-4810-4737-8ad6-fc9c6b270f6d", + "EventTimestamp": "2025-12-10T00:12:25.139Z", + "ExecutionFailedDetails": { + "Error": { + "Payload": { + "ErrorType": "InvokeError", + "ErrorMessage": "Intentional handler failure" + } + } + } + } +] diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/invoke/simple/invoke-simple-non-durable-failure.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/invoke/simple/invoke-simple-non-durable-failure.history.json new file mode 100644 index 00000000..2ba17f3e --- /dev/null +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/invoke/simple/invoke-simple-non-durable-failure.history.json @@ -0,0 +1,94 @@ +[ + { + "EventType": "ExecutionStarted", + "EventId": 1, + "Id": "35c882e2-c63d-4544-8cf8-ae18e1e868b9", + "EventTimestamp": "2025-12-10T00:15:10.766Z", + "ExecutionStartedDetails": { + "Input": { + "Payload": "{\"functionName\":\"non-durable\",\"payload\":{\"failure\":true}}" + } + } + }, + { + "EventType": "ChainedInvokeStarted", + "SubType": "ChainedInvoke", + "EventId": 2, + "Id": "c4ca4238a0b92382", + "EventTimestamp": "2025-12-10T00:15:10.814Z", + "ChainedInvokeStartedDetails": { + "FunctionName": "", + "Input": { + "Payload": "" + }, + "DurableExecutionArn": "" + } + }, + { + "EventType": "ChainedInvokeFailed", + "SubType": "ChainedInvoke", + "EventId": 3, + "Id": "c4ca4238a0b92382", + "EventTimestamp": "2025-12-10T00:15:10.839Z", + "ChainedInvokeFailedDetails": { + "Error": { + "Payload": { + "ErrorMessage": "This is a failure", + "ErrorType": "Error", + "StackTrace": [ + "Error: This is a failure", + " at handler (/Users/adting/workplace/lambda-durable-functions-sdk-js/packages/aws-durable-execution-sdk-js-examples/src/examples/non-durable/non-durable.ts:11:11)", + " at result (/Users/adting/workplace/lambda-durable-functions-sdk-js/packages/aws-durable-execution-sdk-js-testing/src/test-runner/local/operations/function-storage.ts:149:24)", + " at new Promise ()", + " at FunctionStorage.runHandler (/Users/adting/workplace/lambda-durable-functions-sdk-js/packages/aws-durable-execution-sdk-js-testing/src/test-runner/local/operations/function-storage.ts:148:28)", + " at TestExecutionOrchestrator.handleInvokeUpdate (/Users/adting/workplace/lambda-durable-functions-sdk-js/packages/aws-durable-execution-sdk-js-testing/src/test-runner/local/test-execution-orchestrator.ts:297:58)", + " at TestExecutionOrchestrator.processOperation (/Users/adting/workplace/lambda-durable-functions-sdk-js/packages/aws-durable-execution-sdk-js-testing/src/test-runner/local/test-execution-orchestrator.ts:272:14)", + " at TestExecutionOrchestrator.processOperations (/Users/adting/workplace/lambda-durable-functions-sdk-js/packages/aws-durable-execution-sdk-js-testing/src/test-runner/local/test-execution-orchestrator.ts:238:12)", + " at TestExecutionOrchestrator.pollForCheckpointData (/Users/adting/workplace/lambda-durable-functions-sdk-js/packages/aws-durable-execution-sdk-js-testing/src/test-runner/local/test-execution-orchestrator.ts:203:14)" + ] + } + } + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 4, + "EventTimestamp": "2025-12-10T00:15:10.880Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:15:10.766Z", + "EndTimestamp": "2025-12-10T00:15:10.880Z", + "Error": {}, + "RequestId": "fe13dfea-f8f4-424e-99ba-ad360f8afe42" + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 5, + "EventTimestamp": "2025-12-10T00:15:10.902Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:15:10.901Z", + "EndTimestamp": "2025-12-10T00:15:10.902Z", + "Error": { + "Payload": { + "ErrorType": "InvokeError", + "ErrorMessage": "This is a failure" + } + }, + "RequestId": "bc497243-73e1-47d2-a01a-7c3ef8c7b0b1" + } + }, + { + "EventType": "ExecutionFailed", + "EventId": 6, + "Id": "35c882e2-c63d-4544-8cf8-ae18e1e868b9", + "EventTimestamp": "2025-12-10T00:15:10.902Z", + "ExecutionFailedDetails": { + "Error": { + "Payload": { + "ErrorType": "InvokeError", + "ErrorMessage": "This is a failure" + } + } + } + } +] diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/invoke/simple/invoke-simple-non-durable-success.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/invoke/simple/invoke-simple-non-durable-success.history.json new file mode 100644 index 00000000..6360c8c4 --- /dev/null +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/invoke/simple/invoke-simple-non-durable-success.history.json @@ -0,0 +1,72 @@ +[ + { + "EventType": "ExecutionStarted", + "EventId": 1, + "Id": "5c002679-931c-4e9e-ac7a-62dbdf5a555d", + "EventTimestamp": "2025-12-10T00:12:25.242Z", + "ExecutionStartedDetails": { + "Input": { + "Payload": "{\"functionName\":\"non-durable\"}" + } + } + }, + { + "EventType": "ChainedInvokeStarted", + "SubType": "ChainedInvoke", + "EventId": 2, + "Id": "c4ca4238a0b92382", + "EventTimestamp": "2025-12-10T00:12:25.245Z", + "ChainedInvokeStartedDetails": { + "FunctionName": "", + "Input": { + "Payload": "" + }, + "DurableExecutionArn": "" + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 3, + "EventTimestamp": "2025-12-10T00:12:25.297Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:12:25.242Z", + "EndTimestamp": "2025-12-10T00:12:25.297Z", + "Error": {}, + "RequestId": "24a3700d-f1b9-402d-9efd-a2b01025069f" + } + }, + { + "EventType": "ChainedInvokeSucceeded", + "SubType": "ChainedInvoke", + "EventId": 4, + "Id": "c4ca4238a0b92382", + "EventTimestamp": "2025-12-10T00:12:26.247Z", + "ChainedInvokeSucceededDetails": { + "Result": { + "Payload": "{\"status\":200,\"body\":\"{\\\"message\\\":\\\"Hello from Lambda!\\\"}\"}" + } + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 5, + "EventTimestamp": "2025-12-10T00:12:26.251Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:12:26.249Z", + "EndTimestamp": "2025-12-10T00:12:26.251Z", + "Error": {}, + "RequestId": "02c671e7-0994-40d2-adbe-4056113fd00d" + } + }, + { + "EventType": "ExecutionSucceeded", + "EventId": 6, + "Id": "5c002679-931c-4e9e-ac7a-62dbdf5a555d", + "EventTimestamp": "2025-12-10T00:12:26.251Z", + "ExecutionSucceededDetails": { + "Result": { + "Payload": "{\"status\":200,\"body\":\"{\\\"message\\\":\\\"Hello from Lambda!\\\"}\"}" + } + } + } +] diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/invoke/simple/invoke-simple-step-payload.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/invoke/simple/invoke-simple-step-payload.history.json new file mode 100644 index 00000000..0e312f50 --- /dev/null +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/invoke/simple/invoke-simple-step-payload.history.json @@ -0,0 +1,72 @@ +[ + { + "EventType": "ExecutionStarted", + "EventId": 1, + "Id": "69ff2915-abb7-4ea8-9359-d32b14ac164a", + "EventTimestamp": "2025-12-10T00:12:24.808Z", + "ExecutionStartedDetails": { + "Input": { + "Payload": "{\"functionName\":\"step-named\",\"payload\":{\"data\":\"data from parent\"}}" + } + } + }, + { + "EventType": "ChainedInvokeStarted", + "SubType": "ChainedInvoke", + "EventId": 2, + "Id": "c4ca4238a0b92382", + "EventTimestamp": "2025-12-10T00:12:24.811Z", + "ChainedInvokeStartedDetails": { + "FunctionName": "", + "Input": { + "Payload": "" + }, + "DurableExecutionArn": "" + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 3, + "EventTimestamp": "2025-12-10T00:12:24.862Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:12:24.808Z", + "EndTimestamp": "2025-12-10T00:12:24.862Z", + "Error": {}, + "RequestId": "f0d4d2b8-a7bb-4d98-bae0-a0d17115b146" + } + }, + { + "EventType": "ChainedInvokeSucceeded", + "SubType": "ChainedInvoke", + "EventId": 4, + "Id": "c4ca4238a0b92382", + "EventTimestamp": "2025-12-10T00:12:24.915Z", + "ChainedInvokeSucceededDetails": { + "Result": { + "Payload": "\"processed: data from parent\"" + } + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 5, + "EventTimestamp": "2025-12-10T00:12:24.917Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:12:24.917Z", + "EndTimestamp": "2025-12-10T00:12:24.917Z", + "Error": {}, + "RequestId": "58de6169-edd8-4b1e-abe2-6f4e79f00614" + } + }, + { + "EventType": "ExecutionSucceeded", + "EventId": 6, + "Id": "69ff2915-abb7-4ea8-9359-d32b14ac164a", + "EventTimestamp": "2025-12-10T00:12:24.918Z", + "ExecutionSucceededDetails": { + "Result": { + "Payload": "\"processed: data from parent\"" + } + } + } +] diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/invoke/simple/invoke-simple.test.ts b/packages/aws-durable-execution-sdk-js-examples/src/examples/invoke/simple/invoke-simple.test.ts index bcae854b..983c6ac7 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/invoke/simple/invoke-simple.test.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/invoke/simple/invoke-simple.test.ts @@ -8,7 +8,7 @@ import { handler as namedStepHandler } from "../../step/named/step-named"; createTests({ handler, - tests: function (runner, { functionNameMap }) { + tests: function (runner, { functionNameMap, assertEventSignatures }) { it("should run invoke with basic wait state", async () => { if (runner instanceof LocalDurableTestRunner) { runner.registerDurableFunction( @@ -23,6 +23,8 @@ createTests({ }, }); expect(result.getResult()).toBe("wait finished"); + + assertEventSignatures(result, "basic-wait"); }); it("should run invoke with step and payload", async () => { @@ -42,6 +44,8 @@ createTests({ }, }); expect(result.getResult()).toEqual("processed: data from parent"); + + assertEventSignatures(result, "step-payload"); }); it("should run invoke with child function failure", async () => { @@ -61,6 +65,8 @@ createTests({ errorMessage: "Intentional handler failure", errorType: "InvokeError", }); + + assertEventSignatures(result, "child-failure"); }); it("should run invoke with non-durable function success", async () => { @@ -82,6 +88,8 @@ createTests({ message: "Hello from Lambda!", }), }); + + assertEventSignatures(result, "non-durable-success"); }); it("should run invoke with non-durable function failure", async () => { @@ -104,6 +112,8 @@ createTests({ errorMessage: "This is a failure", errorType: "InvokeError", }); + + assertEventSignatures(result, "non-durable-failure"); }); }, }); diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/logger-test/after-callback/logger-after-callback.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/logger-test/after-callback/logger-after-callback.history.json new file mode 100644 index 00000000..08feefef --- /dev/null +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/logger-test/after-callback/logger-after-callback.history.json @@ -0,0 +1,69 @@ +[ + { + "EventType": "ExecutionStarted", + "EventId": 1, + "Id": "f2fd8f7e-f233-4f2d-991a-0590a5f1fcc3", + "EventTimestamp": "2025-12-10T00:15:08.650Z", + "ExecutionStartedDetails": { + "Input": { + "Payload": "{\"logFilePath\":\"/var/folders/t8/39f5f5gj7kx35kt8s5bhqj6m0000gr/T/logger-test-9fad77ce-f12b-40c3-b098-46f751b54931.log\",\"modeAware\":true}" + } + } + }, + { + "EventType": "CallbackStarted", + "SubType": "Callback", + "EventId": 2, + "Id": "c4ca4238a0b92382", + "EventTimestamp": "2025-12-10T00:15:08.675Z", + "CallbackStartedDetails": { + "CallbackId": "eyJleGVjdXRpb25JZCI6ImU3ZTE3NGEwLWU5NjUtNGJmNC05ODMxLTk0YjE1Nzc0MTA1MSIsIm9wZXJhdGlvbklkIjoiYzRjYTQyMzhhMGI5MjM4MiIsInRva2VuIjoiYWUwYWFiZDctMjQwOS00MmMxLWJjYzctYzYyMDgxMThiMTNkIn0=", + "Input": {} + } + }, + { + "EventType": "CallbackSucceeded", + "SubType": "Callback", + "EventId": 3, + "Id": "c4ca4238a0b92382", + "EventTimestamp": "2025-12-10T00:15:08.676Z", + "CallbackSucceededDetails": { + "Result": { + "Payload": "test-result" + } + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 4, + "EventTimestamp": "2025-12-10T00:15:08.735Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:15:08.650Z", + "EndTimestamp": "2025-12-10T00:15:08.735Z", + "Error": {}, + "RequestId": "95ffa90f-3a62-4d70-b1be-d1404f0c386a" + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 5, + "EventTimestamp": "2025-12-10T00:15:08.757Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:15:08.756Z", + "EndTimestamp": "2025-12-10T00:15:08.757Z", + "Error": {}, + "RequestId": "81aed61d-f37b-43be-bd06-696fc313accf" + } + }, + { + "EventType": "ExecutionSucceeded", + "EventId": 6, + "Id": "f2fd8f7e-f233-4f2d-991a-0590a5f1fcc3", + "EventTimestamp": "2025-12-10T00:15:08.757Z", + "ExecutionSucceededDetails": { + "Result": { + "Payload": "{\"message\":\"Success\",\"callbackId\":\"eyJleGVjdXRpb25JZCI6ImU3ZTE3NGEwLWU5NjUtNGJmNC05ODMxLTk0YjE1Nzc0MTA1MSIsIm9wZXJhdGlvbklkIjoiYzRjYTQyMzhhMGI5MjM4MiIsInRva2VuIjoiYWUwYWFiZDctMjQwOS00MmMxLWJjYzctYzYyMDgxMThiMTNkIn0=\",\"result\":\"test-result\"}" + } + } + } +] diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/logger-test/after-callback/logger-after-callback.test.ts b/packages/aws-durable-execution-sdk-js-examples/src/examples/logger-test/after-callback/logger-after-callback.test.ts index a333a4ef..c3f8e9b2 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/logger-test/after-callback/logger-after-callback.test.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/logger-test/after-callback/logger-after-callback.test.ts @@ -12,7 +12,7 @@ import { randomUUID } from "crypto"; createTests({ handler, invocationType: InvocationType.Event, - tests: (runner, isCloud) => { + tests: (runner, { isCloud, assertEventSignatures }) => { if (!isCloud) { it("should log correctly with modeAware=true", async () => { const logFilePath = path.join( @@ -58,6 +58,8 @@ createTests({ // - "After createCallback" appears once (after callback resolves, in execution mode) expect(beforeCallbackLogs.length).toBe(1); expect(afterCallbackLogs.length).toBe(1); + + assertEventSignatures(execution); } finally { if (fs.existsSync(logFilePath)) { fs.unlinkSync(logFilePath); @@ -107,24 +109,28 @@ createTests({ // - "After createCallback" appears once (after callback resolves) expect(beforeCallbackLogs.length).toBe(2); expect(afterCallbackLogs.length).toBe(1); + + assertEventSignatures(execution); } finally { if (fs.existsSync(logFilePath)) { fs.unlinkSync(logFilePath); } } }); - } + } else { + it("should execute successfully", async () => { + const executionPromise = runner.run(); - it("should execute successfully", async () => { - const executionPromise = runner.run(); + const callbackOp = runner.getOperationByIndex(0); + await callbackOp.waitForData(WaitingOperationStatus.STARTED); + await callbackOp.sendCallbackSuccess("test-result"); - const callbackOp = runner.getOperationByIndex(0); - await callbackOp.waitForData(WaitingOperationStatus.STARTED); - await callbackOp.sendCallbackSuccess("test-result"); + const execution = await executionPromise; + const result = execution.getResult() as any; + expect(result.message).toBe("Success"); - const execution = await executionPromise; - const result = execution.getResult() as any; - expect(result.message).toBe("Success"); - }); + assertEventSignatures(execution); + }); + } }, }); diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/map/failure-threshold-exceeded-count/map-failure-threshold-exceeded-count.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/map/failure-threshold-exceeded-count/map-failure-threshold-exceeded-count.history.json new file mode 100644 index 00000000..7dcddb95 --- /dev/null +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/map/failure-threshold-exceeded-count/map-failure-threshold-exceeded-count.history.json @@ -0,0 +1,473 @@ +[ + { + "EventType": "ExecutionStarted", + "EventId": 1, + "Id": "dfeefa8f-8522-49d4-b8a0-0adb383962d6", + "EventTimestamp": "2025-12-10T00:14:18.046Z", + "ExecutionStartedDetails": { + "Input": { + "Payload": "{}" + } + } + }, + { + "EventType": "ContextStarted", + "SubType": "Map", + "EventId": 2, + "Id": "c4ca4238a0b92382", + "Name": "failure-threshold-items", + "EventTimestamp": "2025-12-10T00:14:18.080Z", + "ContextStartedDetails": {} + }, + { + "EventType": "ContextStarted", + "SubType": "MapIteration", + "EventId": 3, + "Id": "ea66c06c1e1c05fa", + "Name": "map-item-0", + "EventTimestamp": "2025-12-10T00:14:18.080Z", + "ParentId": "c4ca4238a0b92382", + "ContextStartedDetails": {} + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 4, + "Id": "2f221a18eb863803", + "Name": "process-0", + "EventTimestamp": "2025-12-10T00:14:18.080Z", + "ParentId": "ea66c06c1e1c05fa", + "StepStartedDetails": {} + }, + { + "EventType": "ContextStarted", + "SubType": "MapIteration", + "EventId": 5, + "Id": "98c6f2c2287f4c73", + "Name": "map-item-1", + "EventTimestamp": "2025-12-10T00:14:18.080Z", + "ParentId": "c4ca4238a0b92382", + "ContextStartedDetails": {} + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 6, + "Id": "6151f5ab282d90e4", + "Name": "process-1", + "EventTimestamp": "2025-12-10T00:14:18.080Z", + "ParentId": "98c6f2c2287f4c73", + "StepStartedDetails": {} + }, + { + "EventType": "ContextStarted", + "SubType": "MapIteration", + "EventId": 7, + "Id": "13cee27a2bd93915", + "Name": "map-item-2", + "EventTimestamp": "2025-12-10T00:14:18.080Z", + "ParentId": "c4ca4238a0b92382", + "ContextStartedDetails": {} + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 8, + "Id": "b425e0c75591aa8f", + "Name": "process-2", + "EventTimestamp": "2025-12-10T00:14:18.080Z", + "ParentId": "13cee27a2bd93915", + "StepStartedDetails": {} + }, + { + "EventType": "ContextStarted", + "SubType": "MapIteration", + "EventId": 9, + "Id": "3a170a9fe4f47efa", + "Name": "map-item-3", + "EventTimestamp": "2025-12-10T00:14:18.080Z", + "ParentId": "c4ca4238a0b92382", + "ContextStartedDetails": {} + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 10, + "Id": "a4e1cd317d54f087", + "Name": "process-3", + "EventTimestamp": "2025-12-10T00:14:18.080Z", + "ParentId": "3a170a9fe4f47efa", + "StepStartedDetails": {} + }, + { + "EventType": "ContextStarted", + "SubType": "MapIteration", + "EventId": 11, + "Id": "12426c956d1bc501", + "Name": "map-item-4", + "EventTimestamp": "2025-12-10T00:14:18.080Z", + "ParentId": "c4ca4238a0b92382", + "ContextStartedDetails": {} + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 12, + "Id": "0f42756e5788f9b0", + "Name": "process-4", + "EventTimestamp": "2025-12-10T00:14:18.080Z", + "ParentId": "12426c956d1bc501", + "StepStartedDetails": {} + }, + { + "EventType": "StepFailed", + "SubType": "Step", + "EventId": 13, + "Id": "2f221a18eb863803", + "Name": "process-0", + "EventTimestamp": "2025-12-10T00:14:18.080Z", + "ParentId": "ea66c06c1e1c05fa", + "StepFailedDetails": { + "Error": { + "Payload": { + "ErrorMessage": "Item 1 failed", + "ErrorType": "Error" + } + }, + "RetryDetails": { + "NextAttemptDelaySeconds": 2, + "CurrentAttempt": 1 + } + } + }, + { + "EventType": "StepFailed", + "SubType": "Step", + "EventId": 14, + "Id": "6151f5ab282d90e4", + "Name": "process-1", + "EventTimestamp": "2025-12-10T00:14:18.086Z", + "ParentId": "98c6f2c2287f4c73", + "StepFailedDetails": { + "Error": { + "Payload": { + "ErrorMessage": "Item 2 failed", + "ErrorType": "Error" + } + }, + "RetryDetails": { + "NextAttemptDelaySeconds": 1, + "CurrentAttempt": 1 + } + } + }, + { + "EventType": "StepFailed", + "SubType": "Step", + "EventId": 15, + "Id": "b425e0c75591aa8f", + "Name": "process-2", + "EventTimestamp": "2025-12-10T00:14:18.086Z", + "ParentId": "13cee27a2bd93915", + "StepFailedDetails": { + "Error": { + "Payload": { + "ErrorMessage": "Item 3 failed", + "ErrorType": "Error" + } + }, + "RetryDetails": { + "NextAttemptDelaySeconds": 2, + "CurrentAttempt": 1 + } + } + }, + { + "EventType": "StepSucceeded", + "SubType": "Step", + "EventId": 16, + "Id": "a4e1cd317d54f087", + "Name": "process-3", + "EventTimestamp": "2025-12-10T00:14:18.086Z", + "ParentId": "3a170a9fe4f47efa", + "StepSucceededDetails": { + "Result": { + "Payload": "8" + }, + "RetryDetails": {} + } + }, + { + "EventType": "StepSucceeded", + "SubType": "Step", + "EventId": 17, + "Id": "0f42756e5788f9b0", + "Name": "process-4", + "EventTimestamp": "2025-12-10T00:14:18.086Z", + "ParentId": "12426c956d1bc501", + "StepSucceededDetails": { + "Result": { + "Payload": "10" + }, + "RetryDetails": {} + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "MapIteration", + "EventId": 18, + "Id": "3a170a9fe4f47efa", + "Name": "map-item-3", + "EventTimestamp": "2025-12-10T00:14:18.090Z", + "ParentId": "c4ca4238a0b92382", + "ContextSucceededDetails": { + "Result": { + "Payload": "8" + } + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "MapIteration", + "EventId": 19, + "Id": "12426c956d1bc501", + "Name": "map-item-4", + "EventTimestamp": "2025-12-10T00:14:18.090Z", + "ParentId": "c4ca4238a0b92382", + "ContextSucceededDetails": { + "Result": { + "Payload": "10" + } + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 20, + "EventTimestamp": "2025-12-10T00:14:18.139Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:14:18.046Z", + "EndTimestamp": "2025-12-10T00:14:18.139Z", + "Error": {}, + "RequestId": "d63bf0b3-dc58-4aa8-8a9e-3ce24cb48d86" + } + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 21, + "Id": "6151f5ab282d90e4", + "Name": "process-1", + "EventTimestamp": "2025-12-10T00:14:19.089Z", + "ParentId": "98c6f2c2287f4c73", + "StepStartedDetails": {} + }, + { + "EventType": "StepFailed", + "SubType": "Step", + "EventId": 22, + "Id": "6151f5ab282d90e4", + "Name": "process-1", + "EventTimestamp": "2025-12-10T00:14:19.089Z", + "ParentId": "98c6f2c2287f4c73", + "StepFailedDetails": { + "Error": { + "Payload": { + "ErrorMessage": "Item 2 failed", + "ErrorType": "Error" + } + }, + "RetryDetails": { + "CurrentAttempt": 1 + } + } + }, + { + "EventType": "ContextFailed", + "SubType": "MapIteration", + "EventId": 23, + "Id": "98c6f2c2287f4c73", + "Name": "map-item-1", + "EventTimestamp": "2025-12-10T00:14:19.091Z", + "ParentId": "c4ca4238a0b92382", + "ContextFailedDetails": { + "Error": { + "Payload": { + "ErrorType": "StepError", + "ErrorMessage": "Item 2 failed" + } + } + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 24, + "EventTimestamp": "2025-12-10T00:14:19.140Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:14:19.087Z", + "EndTimestamp": "2025-12-10T00:14:19.140Z", + "Error": {}, + "RequestId": "51db7b2b-74c1-4c06-9717-e23a40b8e997" + } + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 25, + "Id": "2f221a18eb863803", + "Name": "process-0", + "EventTimestamp": "2025-12-10T00:14:20.085Z", + "ParentId": "ea66c06c1e1c05fa", + "StepStartedDetails": {} + }, + { + "EventType": "StepFailed", + "SubType": "Step", + "EventId": 26, + "Id": "2f221a18eb863803", + "Name": "process-0", + "EventTimestamp": "2025-12-10T00:14:20.085Z", + "ParentId": "ea66c06c1e1c05fa", + "StepFailedDetails": { + "Error": { + "Payload": { + "ErrorMessage": "Item 1 failed", + "ErrorType": "Error" + } + }, + "RetryDetails": { + "CurrentAttempt": 1 + } + } + }, + { + "EventType": "ContextFailed", + "SubType": "MapIteration", + "EventId": 27, + "Id": "ea66c06c1e1c05fa", + "Name": "map-item-0", + "EventTimestamp": "2025-12-10T00:14:20.089Z", + "ParentId": "c4ca4238a0b92382", + "ContextFailedDetails": { + "Error": { + "Payload": { + "ErrorType": "StepError", + "ErrorMessage": "Item 1 failed" + } + } + } + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 28, + "Id": "b425e0c75591aa8f", + "Name": "process-2", + "EventTimestamp": "2025-12-10T00:14:20.092Z", + "ParentId": "13cee27a2bd93915", + "StepStartedDetails": {} + }, + { + "EventType": "StepFailed", + "SubType": "Step", + "EventId": 29, + "Id": "b425e0c75591aa8f", + "Name": "process-2", + "EventTimestamp": "2025-12-10T00:14:20.092Z", + "ParentId": "13cee27a2bd93915", + "StepFailedDetails": { + "Error": { + "Payload": { + "ErrorMessage": "Item 3 failed", + "ErrorType": "Error" + } + }, + "RetryDetails": { + "CurrentAttempt": 1 + } + } + }, + { + "EventType": "ContextFailed", + "SubType": "MapIteration", + "EventId": 30, + "Id": "13cee27a2bd93915", + "Name": "map-item-2", + "EventTimestamp": "2025-12-10T00:14:20.096Z", + "ParentId": "c4ca4238a0b92382", + "ContextFailedDetails": { + "Error": { + "Payload": { + "ErrorType": "StepError", + "ErrorMessage": "Item 3 failed" + } + } + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "Map", + "EventId": 31, + "Id": "c4ca4238a0b92382", + "Name": "failure-threshold-items", + "EventTimestamp": "2025-12-10T00:14:20.096Z", + "ContextSucceededDetails": { + "Result": { + "Payload": "{\"all\":[{\"error\":{\"cause\":{\"cause\":{\"name\":\"StepError\"},\"name\":\"StepError\",\"errorType\":\"StepError\"},\"name\":\"ChildContextError\",\"errorType\":\"ChildContextError\"},\"index\":0,\"status\":\"FAILED\"},{\"error\":{\"cause\":{\"cause\":{\"name\":\"StepError\"},\"name\":\"StepError\",\"errorType\":\"StepError\"},\"name\":\"ChildContextError\",\"errorType\":\"ChildContextError\"},\"index\":1,\"status\":\"FAILED\"},{\"error\":{\"cause\":{\"cause\":{\"name\":\"StepError\"},\"name\":\"StepError\",\"errorType\":\"StepError\"},\"name\":\"ChildContextError\",\"errorType\":\"ChildContextError\"},\"index\":2,\"status\":\"FAILED\"},{\"result\":8,\"index\":3,\"status\":\"SUCCEEDED\"},{\"result\":10,\"index\":4,\"status\":\"SUCCEEDED\"}],\"completionReason\":\"FAILURE_TOLERANCE_EXCEEDED\"}" + } + } + }, + { + "EventType": "WaitStarted", + "SubType": "Wait", + "EventId": 32, + "Id": "c81e728d9d4c2f63", + "EventTimestamp": "2025-12-10T00:14:20.096Z", + "WaitStartedDetails": { + "Duration": 1, + "ScheduledEndTimestamp": "2025-12-10T00:14:21.096Z" + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 33, + "EventTimestamp": "2025-12-10T00:14:20.148Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:14:20.082Z", + "EndTimestamp": "2025-12-10T00:14:20.148Z", + "Error": {}, + "RequestId": "c1852b3b-388c-4904-a611-ad6dc0c422f0" + } + }, + { + "EventType": "WaitSucceeded", + "SubType": "Wait", + "EventId": 34, + "Id": "c81e728d9d4c2f63", + "EventTimestamp": "2025-12-10T00:14:21.098Z", + "WaitSucceededDetails": { + "Duration": 1 + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 35, + "EventTimestamp": "2025-12-10T00:14:21.101Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:14:21.098Z", + "EndTimestamp": "2025-12-10T00:14:21.101Z", + "Error": {}, + "RequestId": "8960e15c-7773-408c-9e0e-5efdfb89c535" + } + }, + { + "EventType": "ExecutionSucceeded", + "EventId": 36, + "Id": "dfeefa8f-8522-49d4-b8a0-0adb383962d6", + "EventTimestamp": "2025-12-10T00:14:21.101Z", + "ExecutionSucceededDetails": { + "Result": { + "Payload": "{\"completionReason\":\"FAILURE_TOLERANCE_EXCEEDED\",\"successCount\":2,\"failureCount\":3,\"totalCount\":5}" + } + } + } +] diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/map/failure-threshold-exceeded-count/map-failure-threshold-exceeded-count.test.ts b/packages/aws-durable-execution-sdk-js-examples/src/examples/map/failure-threshold-exceeded-count/map-failure-threshold-exceeded-count.test.ts index e52be164..0697a4fe 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/map/failure-threshold-exceeded-count/map-failure-threshold-exceeded-count.test.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/map/failure-threshold-exceeded-count/map-failure-threshold-exceeded-count.test.ts @@ -4,7 +4,7 @@ import { OperationStatus } from "@aws/durable-execution-sdk-js-testing"; createTests({ handler, - tests: (runner) => { + tests: (runner, { assertEventSignatures }) => { it("should return FAILURE_TOLERANCE_EXCEEDED when failure count exceeds threshold", async () => { const execution = await runner.run(); const result = execution.getResult() as any; @@ -24,6 +24,8 @@ createTests({ ].forEach(({ name, status }) => { expect(runner.getOperation(name)?.getStatus()).toBe(status); }); + + assertEventSignatures(execution); }); }, }); diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/map/failure-threshold-exceeded-percentage/map-failure-threshold-exceeded-percentage.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/map/failure-threshold-exceeded-percentage/map-failure-threshold-exceeded-percentage.history.json new file mode 100644 index 00000000..9dc3f08a --- /dev/null +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/map/failure-threshold-exceeded-percentage/map-failure-threshold-exceeded-percentage.history.json @@ -0,0 +1,451 @@ +[ + { + "EventType": "ExecutionStarted", + "EventId": 1, + "Id": "33400a67-a585-469c-8ca6-0f951de8489b", + "EventTimestamp": "2025-12-10T00:15:10.355Z", + "ExecutionStartedDetails": { + "Input": { + "Payload": "{}" + } + } + }, + { + "EventType": "ContextStarted", + "SubType": "Map", + "EventId": 2, + "Id": "c4ca4238a0b92382", + "Name": "failure-threshold-items", + "EventTimestamp": "2025-12-10T00:15:10.396Z", + "ContextStartedDetails": {} + }, + { + "EventType": "ContextStarted", + "SubType": "MapIteration", + "EventId": 3, + "Id": "ea66c06c1e1c05fa", + "Name": "map-item-0", + "EventTimestamp": "2025-12-10T00:15:10.396Z", + "ParentId": "c4ca4238a0b92382", + "ContextStartedDetails": {} + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 4, + "Id": "2f221a18eb863803", + "Name": "process-0", + "EventTimestamp": "2025-12-10T00:15:10.396Z", + "ParentId": "ea66c06c1e1c05fa", + "StepStartedDetails": {} + }, + { + "EventType": "ContextStarted", + "SubType": "MapIteration", + "EventId": 5, + "Id": "98c6f2c2287f4c73", + "Name": "map-item-1", + "EventTimestamp": "2025-12-10T00:15:10.396Z", + "ParentId": "c4ca4238a0b92382", + "ContextStartedDetails": {} + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 6, + "Id": "6151f5ab282d90e4", + "Name": "process-1", + "EventTimestamp": "2025-12-10T00:15:10.396Z", + "ParentId": "98c6f2c2287f4c73", + "StepStartedDetails": {} + }, + { + "EventType": "ContextStarted", + "SubType": "MapIteration", + "EventId": 7, + "Id": "13cee27a2bd93915", + "Name": "map-item-2", + "EventTimestamp": "2025-12-10T00:15:10.396Z", + "ParentId": "c4ca4238a0b92382", + "ContextStartedDetails": {} + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 8, + "Id": "b425e0c75591aa8f", + "Name": "process-2", + "EventTimestamp": "2025-12-10T00:15:10.396Z", + "ParentId": "13cee27a2bd93915", + "StepStartedDetails": {} + }, + { + "EventType": "ContextStarted", + "SubType": "MapIteration", + "EventId": 9, + "Id": "3a170a9fe4f47efa", + "Name": "map-item-3", + "EventTimestamp": "2025-12-10T00:15:10.396Z", + "ParentId": "c4ca4238a0b92382", + "ContextStartedDetails": {} + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 10, + "Id": "a4e1cd317d54f087", + "Name": "process-3", + "EventTimestamp": "2025-12-10T00:15:10.396Z", + "ParentId": "3a170a9fe4f47efa", + "StepStartedDetails": {} + }, + { + "EventType": "ContextStarted", + "SubType": "MapIteration", + "EventId": 11, + "Id": "12426c956d1bc501", + "Name": "map-item-4", + "EventTimestamp": "2025-12-10T00:15:10.396Z", + "ParentId": "c4ca4238a0b92382", + "ContextStartedDetails": {} + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 12, + "Id": "0f42756e5788f9b0", + "Name": "process-4", + "EventTimestamp": "2025-12-10T00:15:10.396Z", + "ParentId": "12426c956d1bc501", + "StepStartedDetails": {} + }, + { + "EventType": "StepFailed", + "SubType": "Step", + "EventId": 13, + "Id": "2f221a18eb863803", + "Name": "process-0", + "EventTimestamp": "2025-12-10T00:15:10.396Z", + "ParentId": "ea66c06c1e1c05fa", + "StepFailedDetails": { + "Error": { + "Payload": { + "ErrorMessage": "Item 1 failed", + "ErrorType": "Error" + } + }, + "RetryDetails": { + "NextAttemptDelaySeconds": 3, + "CurrentAttempt": 1 + } + } + }, + { + "EventType": "StepFailed", + "SubType": "Step", + "EventId": 14, + "Id": "6151f5ab282d90e4", + "Name": "process-1", + "EventTimestamp": "2025-12-10T00:15:10.396Z", + "ParentId": "98c6f2c2287f4c73", + "StepFailedDetails": { + "Error": { + "Payload": { + "ErrorMessage": "Item 2 failed", + "ErrorType": "Error" + } + }, + "RetryDetails": { + "NextAttemptDelaySeconds": 2, + "CurrentAttempt": 1 + } + } + }, + { + "EventType": "StepFailed", + "SubType": "Step", + "EventId": 15, + "Id": "b425e0c75591aa8f", + "Name": "process-2", + "EventTimestamp": "2025-12-10T00:15:10.396Z", + "ParentId": "13cee27a2bd93915", + "StepFailedDetails": { + "Error": { + "Payload": { + "ErrorMessage": "Item 3 failed", + "ErrorType": "Error" + } + }, + "RetryDetails": { + "NextAttemptDelaySeconds": 3, + "CurrentAttempt": 1 + } + } + }, + { + "EventType": "StepSucceeded", + "SubType": "Step", + "EventId": 16, + "Id": "a4e1cd317d54f087", + "Name": "process-3", + "EventTimestamp": "2025-12-10T00:15:10.396Z", + "ParentId": "3a170a9fe4f47efa", + "StepSucceededDetails": { + "Result": { + "Payload": "8" + }, + "RetryDetails": {} + } + }, + { + "EventType": "StepSucceeded", + "SubType": "Step", + "EventId": 17, + "Id": "0f42756e5788f9b0", + "Name": "process-4", + "EventTimestamp": "2025-12-10T00:15:10.396Z", + "ParentId": "12426c956d1bc501", + "StepSucceededDetails": { + "Result": { + "Payload": "10" + }, + "RetryDetails": {} + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "MapIteration", + "EventId": 18, + "Id": "3a170a9fe4f47efa", + "Name": "map-item-3", + "EventTimestamp": "2025-12-10T00:15:10.400Z", + "ParentId": "c4ca4238a0b92382", + "ContextSucceededDetails": { + "Result": { + "Payload": "8" + } + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "MapIteration", + "EventId": 19, + "Id": "12426c956d1bc501", + "Name": "map-item-4", + "EventTimestamp": "2025-12-10T00:15:10.400Z", + "ParentId": "c4ca4238a0b92382", + "ContextSucceededDetails": { + "Result": { + "Payload": "10" + } + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 20, + "EventTimestamp": "2025-12-10T00:15:10.401Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:15:10.355Z", + "EndTimestamp": "2025-12-10T00:15:10.401Z", + "Error": {}, + "RequestId": "0352d14b-1bd4-43a2-95d1-6e9ecba69149" + } + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 21, + "Id": "2f221a18eb863803", + "Name": "process-0", + "EventTimestamp": "2025-12-10T00:15:10.437Z", + "ParentId": "ea66c06c1e1c05fa", + "StepStartedDetails": {} + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 22, + "Id": "6151f5ab282d90e4", + "Name": "process-1", + "EventTimestamp": "2025-12-10T00:15:10.437Z", + "ParentId": "98c6f2c2287f4c73", + "StepStartedDetails": {} + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 23, + "Id": "b425e0c75591aa8f", + "Name": "process-2", + "EventTimestamp": "2025-12-10T00:15:10.437Z", + "ParentId": "13cee27a2bd93915", + "StepStartedDetails": {} + }, + { + "EventType": "StepFailed", + "SubType": "Step", + "EventId": 24, + "Id": "2f221a18eb863803", + "Name": "process-0", + "EventTimestamp": "2025-12-10T00:15:10.437Z", + "ParentId": "ea66c06c1e1c05fa", + "StepFailedDetails": { + "Error": { + "Payload": { + "ErrorMessage": "Item 1 failed", + "ErrorType": "Error" + } + }, + "RetryDetails": { + "CurrentAttempt": 1 + } + } + }, + { + "EventType": "StepFailed", + "SubType": "Step", + "EventId": 25, + "Id": "6151f5ab282d90e4", + "Name": "process-1", + "EventTimestamp": "2025-12-10T00:15:10.437Z", + "ParentId": "98c6f2c2287f4c73", + "StepFailedDetails": { + "Error": { + "Payload": { + "ErrorMessage": "Item 2 failed", + "ErrorType": "Error" + } + }, + "RetryDetails": { + "CurrentAttempt": 1 + } + } + }, + { + "EventType": "StepFailed", + "SubType": "Step", + "EventId": 26, + "Id": "b425e0c75591aa8f", + "Name": "process-2", + "EventTimestamp": "2025-12-10T00:15:10.437Z", + "ParentId": "13cee27a2bd93915", + "StepFailedDetails": { + "Error": { + "Payload": { + "ErrorMessage": "Item 3 failed", + "ErrorType": "Error" + } + }, + "RetryDetails": { + "CurrentAttempt": 1 + } + } + }, + { + "EventType": "ContextFailed", + "SubType": "MapIteration", + "EventId": 27, + "Id": "ea66c06c1e1c05fa", + "Name": "map-item-0", + "EventTimestamp": "2025-12-10T00:15:10.458Z", + "ParentId": "c4ca4238a0b92382", + "ContextFailedDetails": { + "Error": { + "Payload": { + "ErrorType": "StepError", + "ErrorMessage": "Item 1 failed" + } + } + } + }, + { + "EventType": "ContextFailed", + "SubType": "MapIteration", + "EventId": 28, + "Id": "98c6f2c2287f4c73", + "Name": "map-item-1", + "EventTimestamp": "2025-12-10T00:15:10.458Z", + "ParentId": "c4ca4238a0b92382", + "ContextFailedDetails": { + "Error": { + "Payload": { + "ErrorType": "StepError", + "ErrorMessage": "Item 2 failed" + } + } + } + }, + { + "EventType": "ContextFailed", + "SubType": "MapIteration", + "EventId": 29, + "Id": "13cee27a2bd93915", + "Name": "map-item-2", + "EventTimestamp": "2025-12-10T00:15:10.458Z", + "ParentId": "c4ca4238a0b92382", + "ContextFailedDetails": { + "Error": { + "Payload": { + "ErrorType": "StepError", + "ErrorMessage": "Item 3 failed" + } + } + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "Map", + "EventId": 30, + "Id": "c4ca4238a0b92382", + "Name": "failure-threshold-items", + "EventTimestamp": "2025-12-10T00:15:10.458Z", + "ContextSucceededDetails": { + "Result": { + "Payload": "{\"all\":[{\"error\":{\"cause\":{\"cause\":{\"name\":\"StepError\"},\"name\":\"StepError\",\"errorType\":\"StepError\"},\"name\":\"ChildContextError\",\"errorType\":\"ChildContextError\"},\"index\":0,\"status\":\"FAILED\"},{\"error\":{\"cause\":{\"cause\":{\"name\":\"StepError\"},\"name\":\"StepError\",\"errorType\":\"StepError\"},\"name\":\"ChildContextError\",\"errorType\":\"ChildContextError\"},\"index\":1,\"status\":\"FAILED\"},{\"error\":{\"cause\":{\"cause\":{\"name\":\"StepError\"},\"name\":\"StepError\",\"errorType\":\"StepError\"},\"name\":\"ChildContextError\",\"errorType\":\"ChildContextError\"},\"index\":2,\"status\":\"FAILED\"},{\"result\":8,\"index\":3,\"status\":\"SUCCEEDED\"},{\"result\":10,\"index\":4,\"status\":\"SUCCEEDED\"}],\"completionReason\":\"FAILURE_TOLERANCE_EXCEEDED\"}" + } + } + }, + { + "EventType": "WaitStarted", + "SubType": "Wait", + "EventId": 31, + "Id": "c81e728d9d4c2f63", + "EventTimestamp": "2025-12-10T00:15:10.458Z", + "WaitStartedDetails": { + "Duration": 1, + "ScheduledEndTimestamp": "2025-12-10T00:15:11.458Z" + } + }, + { + "EventType": "WaitSucceeded", + "SubType": "Wait", + "EventId": 32, + "Id": "c81e728d9d4c2f63", + "EventTimestamp": "2025-12-10T00:15:10.459Z", + "WaitSucceededDetails": { + "Duration": 1 + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 33, + "EventTimestamp": "2025-12-10T00:15:10.480Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:15:10.414Z", + "EndTimestamp": "2025-12-10T00:15:10.480Z", + "Error": {}, + "RequestId": "0fb9a2be-98da-4aa4-9333-386754660b36" + } + }, + { + "EventType": "ExecutionSucceeded", + "EventId": 34, + "Id": "33400a67-a585-469c-8ca6-0f951de8489b", + "EventTimestamp": "2025-12-10T00:15:10.481Z", + "ExecutionSucceededDetails": { + "Result": { + "Payload": "{\"completionReason\":\"FAILURE_TOLERANCE_EXCEEDED\",\"successCount\":2,\"failureCount\":3,\"totalCount\":5}" + } + } + } +] diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/map/failure-threshold-exceeded-percentage/map-failure-threshold-exceeded-percentage.test.ts b/packages/aws-durable-execution-sdk-js-examples/src/examples/map/failure-threshold-exceeded-percentage/map-failure-threshold-exceeded-percentage.test.ts index dfa0b183..81d1bdb9 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/map/failure-threshold-exceeded-percentage/map-failure-threshold-exceeded-percentage.test.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/map/failure-threshold-exceeded-percentage/map-failure-threshold-exceeded-percentage.test.ts @@ -4,7 +4,7 @@ import { OperationStatus } from "@aws/durable-execution-sdk-js-testing"; createTests({ handler, - tests: (runner) => { + tests: (runner, { assertEventSignatures }) => { it("should return FAILURE_TOLERANCE_EXCEEDED when failure percentage exceeds threshold", async () => { const execution = await runner.run(); const result = execution.getResult() as any; @@ -24,6 +24,8 @@ createTests({ ].forEach(({ name, status }) => { expect(runner.getOperation(name)?.getStatus()).toBe(status); }); + + assertEventSignatures(execution); }); }, }); diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/map/min-successful/map-min-successful.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/map/min-successful/map-min-successful.history.json new file mode 100644 index 00000000..5f565136 --- /dev/null +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/map/min-successful/map-min-successful.history.json @@ -0,0 +1,236 @@ +[ + { + "EventType": "ExecutionStarted", + "EventId": 1, + "Id": "9d245077-e425-42f8-a8b5-521cac34e9d2", + "EventTimestamp": "2025-12-10T00:12:31.901Z", + "ExecutionStartedDetails": { + "Input": { + "Payload": "{}" + } + } + }, + { + "EventType": "ContextStarted", + "SubType": "Map", + "EventId": 2, + "Id": "c4ca4238a0b92382", + "Name": "min-successful-items", + "EventTimestamp": "2025-12-10T00:12:31.906Z", + "ContextStartedDetails": {} + }, + { + "EventType": "ContextStarted", + "SubType": "MapIteration", + "EventId": 3, + "Id": "ea66c06c1e1c05fa", + "Name": "map-item-0", + "EventTimestamp": "2025-12-10T00:12:31.906Z", + "ParentId": "c4ca4238a0b92382", + "ContextStartedDetails": {} + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 4, + "Id": "2f221a18eb863803", + "Name": "process-0", + "EventTimestamp": "2025-12-10T00:12:31.906Z", + "ParentId": "ea66c06c1e1c05fa", + "StepStartedDetails": {} + }, + { + "EventType": "ContextStarted", + "SubType": "MapIteration", + "EventId": 5, + "Id": "98c6f2c2287f4c73", + "Name": "map-item-1", + "EventTimestamp": "2025-12-10T00:12:31.906Z", + "ParentId": "c4ca4238a0b92382", + "ContextStartedDetails": {} + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 6, + "Id": "6151f5ab282d90e4", + "Name": "process-1", + "EventTimestamp": "2025-12-10T00:12:31.906Z", + "ParentId": "98c6f2c2287f4c73", + "StepStartedDetails": {} + }, + { + "EventType": "ContextStarted", + "SubType": "MapIteration", + "EventId": 7, + "Id": "13cee27a2bd93915", + "Name": "map-item-2", + "EventTimestamp": "2025-12-10T00:12:31.906Z", + "ParentId": "c4ca4238a0b92382", + "ContextStartedDetails": {} + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 8, + "Id": "b425e0c75591aa8f", + "Name": "process-2", + "EventTimestamp": "2025-12-10T00:12:31.906Z", + "ParentId": "13cee27a2bd93915", + "StepStartedDetails": {} + }, + { + "EventType": "ContextStarted", + "SubType": "MapIteration", + "EventId": 9, + "Id": "3a170a9fe4f47efa", + "Name": "map-item-3", + "EventTimestamp": "2025-12-10T00:12:31.906Z", + "ParentId": "c4ca4238a0b92382", + "ContextStartedDetails": {} + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 10, + "Id": "a4e1cd317d54f087", + "Name": "process-3", + "EventTimestamp": "2025-12-10T00:12:31.906Z", + "ParentId": "3a170a9fe4f47efa", + "StepStartedDetails": {} + }, + { + "EventType": "ContextStarted", + "SubType": "MapIteration", + "EventId": 11, + "Id": "12426c956d1bc501", + "Name": "map-item-4", + "EventTimestamp": "2025-12-10T00:12:31.906Z", + "ParentId": "c4ca4238a0b92382", + "ContextStartedDetails": {} + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 12, + "Id": "0f42756e5788f9b0", + "Name": "process-4", + "EventTimestamp": "2025-12-10T00:12:31.906Z", + "ParentId": "12426c956d1bc501", + "StepStartedDetails": {} + }, + { + "EventType": "StepSucceeded", + "SubType": "Step", + "EventId": 13, + "Id": "2f221a18eb863803", + "Name": "process-0", + "EventTimestamp": "2025-12-10T00:12:32.005Z", + "ParentId": "ea66c06c1e1c05fa", + "StepSucceededDetails": { + "Result": { + "Payload": "\"Item 1 processed\"" + }, + "RetryDetails": {} + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "MapIteration", + "EventId": 14, + "Id": "ea66c06c1e1c05fa", + "Name": "map-item-0", + "EventTimestamp": "2025-12-10T00:12:32.007Z", + "ParentId": "c4ca4238a0b92382", + "ContextSucceededDetails": { + "Result": { + "Payload": "\"Item 1 processed\"" + } + } + }, + { + "EventType": "StepSucceeded", + "SubType": "Step", + "EventId": 15, + "Id": "6151f5ab282d90e4", + "Name": "process-1", + "EventTimestamp": "2025-12-10T00:12:32.106Z", + "ParentId": "98c6f2c2287f4c73", + "StepSucceededDetails": { + "Result": { + "Payload": "\"Item 2 processed\"" + }, + "RetryDetails": {} + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "MapIteration", + "EventId": 16, + "Id": "98c6f2c2287f4c73", + "Name": "map-item-1", + "EventTimestamp": "2025-12-10T00:12:32.108Z", + "ParentId": "c4ca4238a0b92382", + "ContextSucceededDetails": { + "Result": { + "Payload": "\"Item 2 processed\"" + } + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "Map", + "EventId": 17, + "Id": "c4ca4238a0b92382", + "Name": "min-successful-items", + "EventTimestamp": "2025-12-10T00:12:32.108Z", + "ContextSucceededDetails": { + "Result": { + "Payload": "{\"all\":[{\"result\":\"Item 1 processed\",\"index\":0,\"status\":\"SUCCEEDED\"},{\"result\":\"Item 2 processed\",\"index\":1,\"status\":\"SUCCEEDED\"},{\"index\":2,\"status\":\"STARTED\"},{\"index\":3,\"status\":\"STARTED\"},{\"index\":4,\"status\":\"STARTED\"}],\"completionReason\":\"MIN_SUCCESSFUL_REACHED\"}" + } + } + }, + { + "EventType": "WaitStarted", + "SubType": "Wait", + "EventId": 18, + "Id": "c81e728d9d4c2f63", + "EventTimestamp": "2025-12-10T00:12:32.108Z", + "WaitStartedDetails": { + "Duration": 1, + "ScheduledEndTimestamp": "2025-12-10T00:12:33.108Z" + } + }, + { + "EventType": "WaitSucceeded", + "SubType": "Wait", + "EventId": 19, + "Id": "c81e728d9d4c2f63", + "EventTimestamp": "2025-12-10T00:12:33.109Z", + "WaitSucceededDetails": { + "Duration": 1 + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 20, + "EventTimestamp": "2025-12-10T00:12:33.111Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:12:31.901Z", + "EndTimestamp": "2025-12-10T00:12:33.111Z", + "Error": {}, + "RequestId": "d45c051d-4981-4258-8008-22d1bac542de" + } + }, + { + "EventType": "ExecutionSucceeded", + "EventId": 21, + "Id": "9d245077-e425-42f8-a8b5-521cac34e9d2", + "EventTimestamp": "2025-12-10T00:12:33.111Z", + "ExecutionSucceededDetails": { + "Result": { + "Payload": "{\"successCount\":2,\"totalCount\":5,\"completionReason\":\"MIN_SUCCESSFUL_REACHED\",\"results\":[\"Item 1 processed\",\"Item 2 processed\"]}" + } + } + } +] diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/map/min-successful/map-min-successful.test.ts b/packages/aws-durable-execution-sdk-js-examples/src/examples/map/min-successful/map-min-successful.test.ts index 5b6e1515..59ec40b1 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/map/min-successful/map-min-successful.test.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/map/min-successful/map-min-successful.test.ts @@ -40,6 +40,8 @@ createTests({ // Verify the results array matches expect(result.results).toEqual(["Item 1 processed", "Item 2 processed"]); + + assertEventSignatures(execution); }); }, }); diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/map/tolerated-failure-count/map-tolerated-failure-count.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/map/tolerated-failure-count/map-tolerated-failure-count.history.json new file mode 100644 index 00000000..f3fd9d1c --- /dev/null +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/map/tolerated-failure-count/map-tolerated-failure-count.history.json @@ -0,0 +1,350 @@ +[ + { + "EventType": "ExecutionStarted", + "EventId": 1, + "Id": "68762d3e-bf8a-4214-8592-6ecb25c032b9", + "EventTimestamp": "2025-12-10T00:12:09.149Z", + "ExecutionStartedDetails": { + "Input": { + "Payload": "{}" + } + } + }, + { + "EventType": "ContextStarted", + "SubType": "Map", + "EventId": 2, + "Id": "c4ca4238a0b92382", + "Name": "failure-count-items", + "EventTimestamp": "2025-12-10T00:12:09.154Z", + "ContextStartedDetails": {} + }, + { + "EventType": "ContextStarted", + "SubType": "MapIteration", + "EventId": 3, + "Id": "ea66c06c1e1c05fa", + "Name": "map-item-0", + "EventTimestamp": "2025-12-10T00:12:09.154Z", + "ParentId": "c4ca4238a0b92382", + "ContextStartedDetails": {} + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 4, + "Id": "2f221a18eb863803", + "Name": "process-0", + "EventTimestamp": "2025-12-10T00:12:09.154Z", + "ParentId": "ea66c06c1e1c05fa", + "StepStartedDetails": {} + }, + { + "EventType": "ContextStarted", + "SubType": "MapIteration", + "EventId": 5, + "Id": "98c6f2c2287f4c73", + "Name": "map-item-1", + "EventTimestamp": "2025-12-10T00:12:09.154Z", + "ParentId": "c4ca4238a0b92382", + "ContextStartedDetails": {} + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 6, + "Id": "6151f5ab282d90e4", + "Name": "process-1", + "EventTimestamp": "2025-12-10T00:12:09.154Z", + "ParentId": "98c6f2c2287f4c73", + "StepStartedDetails": {} + }, + { + "EventType": "ContextStarted", + "SubType": "MapIteration", + "EventId": 7, + "Id": "13cee27a2bd93915", + "Name": "map-item-2", + "EventTimestamp": "2025-12-10T00:12:09.154Z", + "ParentId": "c4ca4238a0b92382", + "ContextStartedDetails": {} + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 8, + "Id": "b425e0c75591aa8f", + "Name": "process-2", + "EventTimestamp": "2025-12-10T00:12:09.154Z", + "ParentId": "13cee27a2bd93915", + "StepStartedDetails": {} + }, + { + "EventType": "ContextStarted", + "SubType": "MapIteration", + "EventId": 9, + "Id": "3a170a9fe4f47efa", + "Name": "map-item-3", + "EventTimestamp": "2025-12-10T00:12:09.154Z", + "ParentId": "c4ca4238a0b92382", + "ContextStartedDetails": {} + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 10, + "Id": "a4e1cd317d54f087", + "Name": "process-3", + "EventTimestamp": "2025-12-10T00:12:09.154Z", + "ParentId": "3a170a9fe4f47efa", + "StepStartedDetails": {} + }, + { + "EventType": "ContextStarted", + "SubType": "MapIteration", + "EventId": 11, + "Id": "12426c956d1bc501", + "Name": "map-item-4", + "EventTimestamp": "2025-12-10T00:12:09.154Z", + "ParentId": "c4ca4238a0b92382", + "ContextStartedDetails": {} + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 12, + "Id": "0f42756e5788f9b0", + "Name": "process-4", + "EventTimestamp": "2025-12-10T00:12:09.154Z", + "ParentId": "12426c956d1bc501", + "StepStartedDetails": {} + }, + { + "EventType": "StepFailed", + "SubType": "Step", + "EventId": 13, + "Id": "6151f5ab282d90e4", + "Name": "process-1", + "EventTimestamp": "2025-12-10T00:12:09.154Z", + "ParentId": "98c6f2c2287f4c73", + "StepFailedDetails": { + "Error": { + "Payload": { + "ErrorMessage": "Processing failed for item 2", + "ErrorType": "Error" + } + }, + "RetryDetails": { + "CurrentAttempt": 1 + } + } + }, + { + "EventType": "StepFailed", + "SubType": "Step", + "EventId": 14, + "Id": "a4e1cd317d54f087", + "Name": "process-3", + "EventTimestamp": "2025-12-10T00:12:09.154Z", + "ParentId": "3a170a9fe4f47efa", + "StepFailedDetails": { + "Error": { + "Payload": { + "ErrorMessage": "Processing failed for item 4", + "ErrorType": "Error" + } + }, + "RetryDetails": { + "CurrentAttempt": 1 + } + } + }, + { + "EventType": "StepSucceeded", + "SubType": "Step", + "EventId": 15, + "Id": "2f221a18eb863803", + "Name": "process-0", + "EventTimestamp": "2025-12-10T00:12:09.154Z", + "ParentId": "ea66c06c1e1c05fa", + "StepSucceededDetails": { + "Result": { + "Payload": "\"Item 1 processed\"" + }, + "RetryDetails": {} + } + }, + { + "EventType": "StepSucceeded", + "SubType": "Step", + "EventId": 16, + "Id": "b425e0c75591aa8f", + "Name": "process-2", + "EventTimestamp": "2025-12-10T00:12:09.154Z", + "ParentId": "13cee27a2bd93915", + "StepSucceededDetails": { + "Result": { + "Payload": "\"Item 3 processed\"" + }, + "RetryDetails": {} + } + }, + { + "EventType": "StepSucceeded", + "SubType": "Step", + "EventId": 17, + "Id": "0f42756e5788f9b0", + "Name": "process-4", + "EventTimestamp": "2025-12-10T00:12:09.154Z", + "ParentId": "12426c956d1bc501", + "StepSucceededDetails": { + "Result": { + "Payload": "\"Item 5 processed\"" + }, + "RetryDetails": {} + } + }, + { + "EventType": "ContextFailed", + "SubType": "MapIteration", + "EventId": 18, + "Id": "98c6f2c2287f4c73", + "Name": "map-item-1", + "EventTimestamp": "2025-12-10T00:12:09.157Z", + "ParentId": "c4ca4238a0b92382", + "ContextFailedDetails": { + "Error": { + "Payload": { + "ErrorType": "StepError", + "ErrorMessage": "Processing failed for item 2" + } + } + } + }, + { + "EventType": "ContextFailed", + "SubType": "MapIteration", + "EventId": 19, + "Id": "3a170a9fe4f47efa", + "Name": "map-item-3", + "EventTimestamp": "2025-12-10T00:12:09.157Z", + "ParentId": "c4ca4238a0b92382", + "ContextFailedDetails": { + "Error": { + "Payload": { + "ErrorType": "StepError", + "ErrorMessage": "Processing failed for item 4" + } + } + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "MapIteration", + "EventId": 20, + "Id": "ea66c06c1e1c05fa", + "Name": "map-item-0", + "EventTimestamp": "2025-12-10T00:12:09.157Z", + "ParentId": "c4ca4238a0b92382", + "ContextSucceededDetails": { + "Result": { + "Payload": "\"Item 1 processed\"" + } + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "MapIteration", + "EventId": 21, + "Id": "13cee27a2bd93915", + "Name": "map-item-2", + "EventTimestamp": "2025-12-10T00:12:09.157Z", + "ParentId": "c4ca4238a0b92382", + "ContextSucceededDetails": { + "Result": { + "Payload": "\"Item 3 processed\"" + } + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "MapIteration", + "EventId": 22, + "Id": "12426c956d1bc501", + "Name": "map-item-4", + "EventTimestamp": "2025-12-10T00:12:09.157Z", + "ParentId": "c4ca4238a0b92382", + "ContextSucceededDetails": { + "Result": { + "Payload": "\"Item 5 processed\"" + } + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "Map", + "EventId": 23, + "Id": "c4ca4238a0b92382", + "Name": "failure-count-items", + "EventTimestamp": "2025-12-10T00:12:09.157Z", + "ContextSucceededDetails": { + "Result": { + "Payload": "{\"all\":[{\"result\":\"Item 1 processed\",\"index\":0,\"status\":\"SUCCEEDED\"},{\"error\":{\"cause\":{\"cause\":{\"name\":\"StepError\"},\"name\":\"StepError\",\"errorType\":\"StepError\"},\"name\":\"ChildContextError\",\"errorType\":\"ChildContextError\"},\"index\":1,\"status\":\"FAILED\"},{\"result\":\"Item 3 processed\",\"index\":2,\"status\":\"SUCCEEDED\"},{\"error\":{\"cause\":{\"cause\":{\"name\":\"StepError\"},\"name\":\"StepError\",\"errorType\":\"StepError\"},\"name\":\"ChildContextError\",\"errorType\":\"ChildContextError\"},\"index\":3,\"status\":\"FAILED\"},{\"result\":\"Item 5 processed\",\"index\":4,\"status\":\"SUCCEEDED\"}],\"completionReason\":\"ALL_COMPLETED\"}" + } + } + }, + { + "EventType": "WaitStarted", + "SubType": "Wait", + "EventId": 24, + "Id": "c81e728d9d4c2f63", + "EventTimestamp": "2025-12-10T00:12:09.157Z", + "WaitStartedDetails": { + "Duration": 1, + "ScheduledEndTimestamp": "2025-12-10T00:12:10.157Z" + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 25, + "EventTimestamp": "2025-12-10T00:12:09.210Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:12:09.148Z", + "EndTimestamp": "2025-12-10T00:12:09.210Z", + "Error": {}, + "RequestId": "426c5dd9-da62-43ce-bd84-0f16d855ee95" + } + }, + { + "EventType": "WaitSucceeded", + "SubType": "Wait", + "EventId": 26, + "Id": "c81e728d9d4c2f63", + "EventTimestamp": "2025-12-10T00:12:10.158Z", + "WaitSucceededDetails": { + "Duration": 1 + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 27, + "EventTimestamp": "2025-12-10T00:12:10.160Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:12:10.159Z", + "EndTimestamp": "2025-12-10T00:12:10.160Z", + "Error": {}, + "RequestId": "bdfb5652-5562-41bd-b9bc-690d2e175007" + } + }, + { + "EventType": "ExecutionSucceeded", + "EventId": 28, + "Id": "68762d3e-bf8a-4214-8592-6ecb25c032b9", + "EventTimestamp": "2025-12-10T00:12:10.160Z", + "ExecutionSucceededDetails": { + "Result": { + "Payload": "{\"successCount\":3,\"failureCount\":2,\"totalCount\":5,\"completionReason\":\"ALL_COMPLETED\",\"hasFailure\":true}" + } + } + } +] diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/map/tolerated-failure-count/map-tolerated-failure-count.test.ts b/packages/aws-durable-execution-sdk-js-examples/src/examples/map/tolerated-failure-count/map-tolerated-failure-count.test.ts index 0c664983..1e9dccbe 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/map/tolerated-failure-count/map-tolerated-failure-count.test.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/map/tolerated-failure-count/map-tolerated-failure-count.test.ts @@ -4,7 +4,7 @@ import { OperationStatus } from "@aws/durable-execution-sdk-js-testing"; createTests({ handler, - tests: (runner) => { + tests: (runner, { assertEventSignatures }) => { it("should complete when failure tolerance is reached", async () => { const execution = await runner.run(); const result = execution.getResult() as any; @@ -26,6 +26,8 @@ createTests({ ].forEach(({ name, status }) => { expect(runner.getOperation(name)?.getStatus()).toBe(status); }); + + assertEventSignatures(execution); }); }, }); diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/map/tolerated-failure-percentage/map-tolerated-failure-percentage.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/map/tolerated-failure-percentage/map-tolerated-failure-percentage.history.json new file mode 100644 index 00000000..5c7bce0a --- /dev/null +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/map/tolerated-failure-percentage/map-tolerated-failure-percentage.history.json @@ -0,0 +1,603 @@ +[ + { + "EventType": "ExecutionStarted", + "EventId": 1, + "Id": "86d63f39-976e-40da-9a9c-1f4927c7f7b3", + "EventTimestamp": "2025-12-10T00:12:07.585Z", + "ExecutionStartedDetails": { + "Input": { + "Payload": "{}" + } + } + }, + { + "EventType": "ContextStarted", + "SubType": "Map", + "EventId": 2, + "Id": "c4ca4238a0b92382", + "Name": "failure-percentage-items", + "EventTimestamp": "2025-12-10T00:12:07.594Z", + "ContextStartedDetails": {} + }, + { + "EventType": "ContextStarted", + "SubType": "MapIteration", + "EventId": 3, + "Id": "ea66c06c1e1c05fa", + "Name": "map-item-0", + "EventTimestamp": "2025-12-10T00:12:07.594Z", + "ParentId": "c4ca4238a0b92382", + "ContextStartedDetails": {} + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 4, + "Id": "2f221a18eb863803", + "Name": "process-0", + "EventTimestamp": "2025-12-10T00:12:07.594Z", + "ParentId": "ea66c06c1e1c05fa", + "StepStartedDetails": {} + }, + { + "EventType": "ContextStarted", + "SubType": "MapIteration", + "EventId": 5, + "Id": "98c6f2c2287f4c73", + "Name": "map-item-1", + "EventTimestamp": "2025-12-10T00:12:07.594Z", + "ParentId": "c4ca4238a0b92382", + "ContextStartedDetails": {} + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 6, + "Id": "6151f5ab282d90e4", + "Name": "process-1", + "EventTimestamp": "2025-12-10T00:12:07.594Z", + "ParentId": "98c6f2c2287f4c73", + "StepStartedDetails": {} + }, + { + "EventType": "ContextStarted", + "SubType": "MapIteration", + "EventId": 7, + "Id": "13cee27a2bd93915", + "Name": "map-item-2", + "EventTimestamp": "2025-12-10T00:12:07.594Z", + "ParentId": "c4ca4238a0b92382", + "ContextStartedDetails": {} + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 8, + "Id": "b425e0c75591aa8f", + "Name": "process-2", + "EventTimestamp": "2025-12-10T00:12:07.594Z", + "ParentId": "13cee27a2bd93915", + "StepStartedDetails": {} + }, + { + "EventType": "ContextStarted", + "SubType": "MapIteration", + "EventId": 9, + "Id": "3a170a9fe4f47efa", + "Name": "map-item-3", + "EventTimestamp": "2025-12-10T00:12:07.594Z", + "ParentId": "c4ca4238a0b92382", + "ContextStartedDetails": {} + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 10, + "Id": "a4e1cd317d54f087", + "Name": "process-3", + "EventTimestamp": "2025-12-10T00:12:07.594Z", + "ParentId": "3a170a9fe4f47efa", + "StepStartedDetails": {} + }, + { + "EventType": "ContextStarted", + "SubType": "MapIteration", + "EventId": 11, + "Id": "12426c956d1bc501", + "Name": "map-item-4", + "EventTimestamp": "2025-12-10T00:12:07.594Z", + "ParentId": "c4ca4238a0b92382", + "ContextStartedDetails": {} + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 12, + "Id": "0f42756e5788f9b0", + "Name": "process-4", + "EventTimestamp": "2025-12-10T00:12:07.594Z", + "ParentId": "12426c956d1bc501", + "StepStartedDetails": {} + }, + { + "EventType": "ContextStarted", + "SubType": "MapIteration", + "EventId": 13, + "Id": "449daf85c71a9f8e", + "Name": "map-item-5", + "EventTimestamp": "2025-12-10T00:12:07.594Z", + "ParentId": "c4ca4238a0b92382", + "ContextStartedDetails": {} + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 14, + "Id": "eb1e930ffcc9bd72", + "Name": "process-5", + "EventTimestamp": "2025-12-10T00:12:07.594Z", + "ParentId": "449daf85c71a9f8e", + "StepStartedDetails": {} + }, + { + "EventType": "ContextStarted", + "SubType": "MapIteration", + "EventId": 15, + "Id": "6813b5c7ce3f9204", + "Name": "map-item-6", + "EventTimestamp": "2025-12-10T00:12:07.594Z", + "ParentId": "c4ca4238a0b92382", + "ContextStartedDetails": {} + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 16, + "Id": "da76a88f237d9e53", + "Name": "process-6", + "EventTimestamp": "2025-12-10T00:12:07.594Z", + "ParentId": "6813b5c7ce3f9204", + "StepStartedDetails": {} + }, + { + "EventType": "ContextStarted", + "SubType": "MapIteration", + "EventId": 17, + "Id": "d04b95489bc4e2bc", + "Name": "map-item-7", + "EventTimestamp": "2025-12-10T00:12:07.594Z", + "ParentId": "c4ca4238a0b92382", + "ContextStartedDetails": {} + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 18, + "Id": "7bb95ef96d539344", + "Name": "process-7", + "EventTimestamp": "2025-12-10T00:12:07.594Z", + "ParentId": "d04b95489bc4e2bc", + "StepStartedDetails": {} + }, + { + "EventType": "ContextStarted", + "SubType": "MapIteration", + "EventId": 19, + "Id": "2f15587a6a4cc313", + "Name": "map-item-8", + "EventTimestamp": "2025-12-10T00:12:07.594Z", + "ParentId": "c4ca4238a0b92382", + "ContextStartedDetails": {} + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 20, + "Id": "e02ec69c09b4932d", + "Name": "process-8", + "EventTimestamp": "2025-12-10T00:12:07.594Z", + "ParentId": "2f15587a6a4cc313", + "StepStartedDetails": {} + }, + { + "EventType": "ContextStarted", + "SubType": "MapIteration", + "EventId": 21, + "Id": "dd56b78777e20754", + "Name": "map-item-9", + "EventTimestamp": "2025-12-10T00:12:07.594Z", + "ParentId": "c4ca4238a0b92382", + "ContextStartedDetails": {} + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 22, + "Id": "d3457e8fe9c52dd1", + "Name": "process-9", + "EventTimestamp": "2025-12-10T00:12:07.594Z", + "ParentId": "dd56b78777e20754", + "StepStartedDetails": {} + }, + { + "EventType": "StepFailed", + "SubType": "Step", + "EventId": 23, + "Id": "b425e0c75591aa8f", + "Name": "process-2", + "EventTimestamp": "2025-12-10T00:12:07.595Z", + "ParentId": "13cee27a2bd93915", + "StepFailedDetails": { + "Error": { + "Payload": { + "ErrorMessage": "Processing failed for item 3", + "ErrorType": "Error" + } + }, + "RetryDetails": { + "CurrentAttempt": 1 + } + } + }, + { + "EventType": "StepFailed", + "SubType": "Step", + "EventId": 24, + "Id": "eb1e930ffcc9bd72", + "Name": "process-5", + "EventTimestamp": "2025-12-10T00:12:07.595Z", + "ParentId": "449daf85c71a9f8e", + "StepFailedDetails": { + "Error": { + "Payload": { + "ErrorMessage": "Processing failed for item 6", + "ErrorType": "Error" + } + }, + "RetryDetails": { + "CurrentAttempt": 1 + } + } + }, + { + "EventType": "StepFailed", + "SubType": "Step", + "EventId": 25, + "Id": "e02ec69c09b4932d", + "Name": "process-8", + "EventTimestamp": "2025-12-10T00:12:07.595Z", + "ParentId": "2f15587a6a4cc313", + "StepFailedDetails": { + "Error": { + "Payload": { + "ErrorMessage": "Processing failed for item 9", + "ErrorType": "Error" + } + }, + "RetryDetails": { + "CurrentAttempt": 1 + } + } + }, + { + "EventType": "StepSucceeded", + "SubType": "Step", + "EventId": 26, + "Id": "2f221a18eb863803", + "Name": "process-0", + "EventTimestamp": "2025-12-10T00:12:07.595Z", + "ParentId": "ea66c06c1e1c05fa", + "StepSucceededDetails": { + "Result": { + "Payload": "\"Item 1 processed\"" + }, + "RetryDetails": {} + } + }, + { + "EventType": "StepSucceeded", + "SubType": "Step", + "EventId": 27, + "Id": "6151f5ab282d90e4", + "Name": "process-1", + "EventTimestamp": "2025-12-10T00:12:07.595Z", + "ParentId": "98c6f2c2287f4c73", + "StepSucceededDetails": { + "Result": { + "Payload": "\"Item 2 processed\"" + }, + "RetryDetails": {} + } + }, + { + "EventType": "StepSucceeded", + "SubType": "Step", + "EventId": 28, + "Id": "a4e1cd317d54f087", + "Name": "process-3", + "EventTimestamp": "2025-12-10T00:12:07.595Z", + "ParentId": "3a170a9fe4f47efa", + "StepSucceededDetails": { + "Result": { + "Payload": "\"Item 4 processed\"" + }, + "RetryDetails": {} + } + }, + { + "EventType": "StepSucceeded", + "SubType": "Step", + "EventId": 29, + "Id": "0f42756e5788f9b0", + "Name": "process-4", + "EventTimestamp": "2025-12-10T00:12:07.595Z", + "ParentId": "12426c956d1bc501", + "StepSucceededDetails": { + "Result": { + "Payload": "\"Item 5 processed\"" + }, + "RetryDetails": {} + } + }, + { + "EventType": "StepSucceeded", + "SubType": "Step", + "EventId": 30, + "Id": "da76a88f237d9e53", + "Name": "process-6", + "EventTimestamp": "2025-12-10T00:12:07.595Z", + "ParentId": "6813b5c7ce3f9204", + "StepSucceededDetails": { + "Result": { + "Payload": "\"Item 7 processed\"" + }, + "RetryDetails": {} + } + }, + { + "EventType": "StepSucceeded", + "SubType": "Step", + "EventId": 31, + "Id": "7bb95ef96d539344", + "Name": "process-7", + "EventTimestamp": "2025-12-10T00:12:07.595Z", + "ParentId": "d04b95489bc4e2bc", + "StepSucceededDetails": { + "Result": { + "Payload": "\"Item 8 processed\"" + }, + "RetryDetails": {} + } + }, + { + "EventType": "StepSucceeded", + "SubType": "Step", + "EventId": 32, + "Id": "d3457e8fe9c52dd1", + "Name": "process-9", + "EventTimestamp": "2025-12-10T00:12:07.595Z", + "ParentId": "dd56b78777e20754", + "StepSucceededDetails": { + "Result": { + "Payload": "\"Item 10 processed\"" + }, + "RetryDetails": {} + } + }, + { + "EventType": "ContextFailed", + "SubType": "MapIteration", + "EventId": 33, + "Id": "13cee27a2bd93915", + "Name": "map-item-2", + "EventTimestamp": "2025-12-10T00:12:07.600Z", + "ParentId": "c4ca4238a0b92382", + "ContextFailedDetails": { + "Error": { + "Payload": { + "ErrorType": "StepError", + "ErrorMessage": "Processing failed for item 3" + } + } + } + }, + { + "EventType": "ContextFailed", + "SubType": "MapIteration", + "EventId": 34, + "Id": "449daf85c71a9f8e", + "Name": "map-item-5", + "EventTimestamp": "2025-12-10T00:12:07.600Z", + "ParentId": "c4ca4238a0b92382", + "ContextFailedDetails": { + "Error": { + "Payload": { + "ErrorType": "StepError", + "ErrorMessage": "Processing failed for item 6" + } + } + } + }, + { + "EventType": "ContextFailed", + "SubType": "MapIteration", + "EventId": 35, + "Id": "2f15587a6a4cc313", + "Name": "map-item-8", + "EventTimestamp": "2025-12-10T00:12:07.600Z", + "ParentId": "c4ca4238a0b92382", + "ContextFailedDetails": { + "Error": { + "Payload": { + "ErrorType": "StepError", + "ErrorMessage": "Processing failed for item 9" + } + } + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "MapIteration", + "EventId": 36, + "Id": "ea66c06c1e1c05fa", + "Name": "map-item-0", + "EventTimestamp": "2025-12-10T00:12:07.600Z", + "ParentId": "c4ca4238a0b92382", + "ContextSucceededDetails": { + "Result": { + "Payload": "\"Item 1 processed\"" + } + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "MapIteration", + "EventId": 37, + "Id": "98c6f2c2287f4c73", + "Name": "map-item-1", + "EventTimestamp": "2025-12-10T00:12:07.600Z", + "ParentId": "c4ca4238a0b92382", + "ContextSucceededDetails": { + "Result": { + "Payload": "\"Item 2 processed\"" + } + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "MapIteration", + "EventId": 38, + "Id": "3a170a9fe4f47efa", + "Name": "map-item-3", + "EventTimestamp": "2025-12-10T00:12:07.600Z", + "ParentId": "c4ca4238a0b92382", + "ContextSucceededDetails": { + "Result": { + "Payload": "\"Item 4 processed\"" + } + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "MapIteration", + "EventId": 39, + "Id": "12426c956d1bc501", + "Name": "map-item-4", + "EventTimestamp": "2025-12-10T00:12:07.600Z", + "ParentId": "c4ca4238a0b92382", + "ContextSucceededDetails": { + "Result": { + "Payload": "\"Item 5 processed\"" + } + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "MapIteration", + "EventId": 40, + "Id": "6813b5c7ce3f9204", + "Name": "map-item-6", + "EventTimestamp": "2025-12-10T00:12:07.600Z", + "ParentId": "c4ca4238a0b92382", + "ContextSucceededDetails": { + "Result": { + "Payload": "\"Item 7 processed\"" + } + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "MapIteration", + "EventId": 41, + "Id": "d04b95489bc4e2bc", + "Name": "map-item-7", + "EventTimestamp": "2025-12-10T00:12:07.600Z", + "ParentId": "c4ca4238a0b92382", + "ContextSucceededDetails": { + "Result": { + "Payload": "\"Item 8 processed\"" + } + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "MapIteration", + "EventId": 42, + "Id": "dd56b78777e20754", + "Name": "map-item-9", + "EventTimestamp": "2025-12-10T00:12:07.600Z", + "ParentId": "c4ca4238a0b92382", + "ContextSucceededDetails": { + "Result": { + "Payload": "\"Item 10 processed\"" + } + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "Map", + "EventId": 43, + "Id": "c4ca4238a0b92382", + "Name": "failure-percentage-items", + "EventTimestamp": "2025-12-10T00:12:07.600Z", + "ContextSucceededDetails": { + "Result": { + "Payload": "{\"all\":[{\"result\":\"Item 1 processed\",\"index\":0,\"status\":\"SUCCEEDED\"},{\"result\":\"Item 2 processed\",\"index\":1,\"status\":\"SUCCEEDED\"},{\"error\":{\"cause\":{\"cause\":{\"name\":\"StepError\"},\"name\":\"StepError\",\"errorType\":\"StepError\"},\"name\":\"ChildContextError\",\"errorType\":\"ChildContextError\"},\"index\":2,\"status\":\"FAILED\"},{\"result\":\"Item 4 processed\",\"index\":3,\"status\":\"SUCCEEDED\"},{\"result\":\"Item 5 processed\",\"index\":4,\"status\":\"SUCCEEDED\"},{\"error\":{\"cause\":{\"cause\":{\"name\":\"StepError\"},\"name\":\"StepError\",\"errorType\":\"StepError\"},\"name\":\"ChildContextError\",\"errorType\":\"ChildContextError\"},\"index\":5,\"status\":\"FAILED\"},{\"result\":\"Item 7 processed\",\"index\":6,\"status\":\"SUCCEEDED\"},{\"result\":\"Item 8 processed\",\"index\":7,\"status\":\"SUCCEEDED\"},{\"error\":{\"cause\":{\"cause\":{\"name\":\"StepError\"},\"name\":\"StepError\",\"errorType\":\"StepError\"},\"name\":\"ChildContextError\",\"errorType\":\"ChildContextError\"},\"index\":8,\"status\":\"FAILED\"},{\"result\":\"Item 10 processed\",\"index\":9,\"status\":\"SUCCEEDED\"}],\"completionReason\":\"ALL_COMPLETED\"}" + } + } + }, + { + "EventType": "WaitStarted", + "SubType": "Wait", + "EventId": 44, + "Id": "c81e728d9d4c2f63", + "EventTimestamp": "2025-12-10T00:12:07.601Z", + "WaitStartedDetails": { + "Duration": 1, + "ScheduledEndTimestamp": "2025-12-10T00:12:08.601Z" + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 45, + "EventTimestamp": "2025-12-10T00:12:07.653Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:12:07.585Z", + "EndTimestamp": "2025-12-10T00:12:07.653Z", + "Error": {}, + "RequestId": "2b347dce-bb63-4c65-a1de-b4197fa02a96" + } + }, + { + "EventType": "WaitSucceeded", + "SubType": "Wait", + "EventId": 46, + "Id": "c81e728d9d4c2f63", + "EventTimestamp": "2025-12-10T00:12:08.601Z", + "WaitSucceededDetails": { + "Duration": 1 + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 47, + "EventTimestamp": "2025-12-10T00:12:08.604Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:12:08.602Z", + "EndTimestamp": "2025-12-10T00:12:08.604Z", + "Error": {}, + "RequestId": "321a6295-4ed9-4b0f-b587-c3f573e48f10" + } + }, + { + "EventType": "ExecutionSucceeded", + "EventId": 48, + "Id": "86d63f39-976e-40da-9a9c-1f4927c7f7b3", + "EventTimestamp": "2025-12-10T00:12:08.604Z", + "ExecutionSucceededDetails": { + "Result": { + "Payload": "{\"successCount\":7,\"failureCount\":3,\"totalCount\":10,\"failurePercentage\":30,\"completionReason\":\"ALL_COMPLETED\"}" + } + } + } +] diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/map/tolerated-failure-percentage/map-tolerated-failure-percentage.test.ts b/packages/aws-durable-execution-sdk-js-examples/src/examples/map/tolerated-failure-percentage/map-tolerated-failure-percentage.test.ts index 539778b8..53a0a0a9 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/map/tolerated-failure-percentage/map-tolerated-failure-percentage.test.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/map/tolerated-failure-percentage/map-tolerated-failure-percentage.test.ts @@ -4,7 +4,7 @@ import { OperationStatus } from "@aws/durable-execution-sdk-js-testing"; createTests({ handler, - tests: (runner) => { + tests: (runner, { assertEventSignatures }) => { it("should complete with acceptable failure percentage", async () => { const execution = await runner.run(); const result = execution.getResult() as any; @@ -27,6 +27,8 @@ createTests({ ].forEach(({ name, status }) => { expect(runner.getOperation(name)?.getStatus()).toBe(status); }); + + assertEventSignatures(execution); }); }, }); diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/basic/parallel-basic.test.ts b/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/basic/parallel-basic.test.ts index c4fc3e60..5c65cf0e 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/basic/parallel-basic.test.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/basic/parallel-basic.test.ts @@ -4,20 +4,15 @@ import { createTests } from "../../../utils/test-helper"; createTests({ handler, tests: (runner, { assertEventSignatures }) => { - it("should run correct number of durable steps", async () => { - const execution = await runner.run(); - - expect(runner.getOperation("parallel").getChildOperations()).toHaveLength( - 3, - ); - }); - it("should return correct result", async () => { const execution = await runner.run(); const result = execution.getResult(); expect(execution.getResult()).toBeDefined(); + expect(runner.getOperation("parallel").getChildOperations()).toHaveLength( + 3, + ); assertEventSignatures(execution); }); diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/failure-threshold-exceeded-count/parallel-failure-threshold-exceeded-count.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/failure-threshold-exceeded-count/parallel-failure-threshold-exceeded-count.history.json new file mode 100644 index 00000000..6acf4f10 --- /dev/null +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/failure-threshold-exceeded-count/parallel-failure-threshold-exceeded-count.history.json @@ -0,0 +1,473 @@ +[ + { + "EventType": "ExecutionStarted", + "EventId": 1, + "Id": "cda5a2ff-8872-4ee7-b6e5-51f26cc6bd45", + "EventTimestamp": "2025-12-10T00:12:07.523Z", + "ExecutionStartedDetails": { + "Input": { + "Payload": "{}" + } + } + }, + { + "EventType": "ContextStarted", + "SubType": "Parallel", + "EventId": 2, + "Id": "c4ca4238a0b92382", + "Name": "failure-threshold-tasks", + "EventTimestamp": "2025-12-10T00:12:07.532Z", + "ContextStartedDetails": {} + }, + { + "EventType": "ContextStarted", + "SubType": "ParallelBranch", + "EventId": 3, + "Id": "ea66c06c1e1c05fa", + "Name": "parallel-branch-0", + "EventTimestamp": "2025-12-10T00:12:07.533Z", + "ParentId": "c4ca4238a0b92382", + "ContextStartedDetails": {} + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 4, + "Id": "2f221a18eb863803", + "Name": "task-1", + "EventTimestamp": "2025-12-10T00:12:07.533Z", + "ParentId": "ea66c06c1e1c05fa", + "StepStartedDetails": {} + }, + { + "EventType": "ContextStarted", + "SubType": "ParallelBranch", + "EventId": 5, + "Id": "98c6f2c2287f4c73", + "Name": "parallel-branch-1", + "EventTimestamp": "2025-12-10T00:12:07.533Z", + "ParentId": "c4ca4238a0b92382", + "ContextStartedDetails": {} + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 6, + "Id": "6151f5ab282d90e4", + "Name": "task-2", + "EventTimestamp": "2025-12-10T00:12:07.533Z", + "ParentId": "98c6f2c2287f4c73", + "StepStartedDetails": {} + }, + { + "EventType": "ContextStarted", + "SubType": "ParallelBranch", + "EventId": 7, + "Id": "13cee27a2bd93915", + "Name": "parallel-branch-2", + "EventTimestamp": "2025-12-10T00:12:07.533Z", + "ParentId": "c4ca4238a0b92382", + "ContextStartedDetails": {} + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 8, + "Id": "b425e0c75591aa8f", + "Name": "task-3", + "EventTimestamp": "2025-12-10T00:12:07.533Z", + "ParentId": "13cee27a2bd93915", + "StepStartedDetails": {} + }, + { + "EventType": "ContextStarted", + "SubType": "ParallelBranch", + "EventId": 9, + "Id": "3a170a9fe4f47efa", + "Name": "parallel-branch-3", + "EventTimestamp": "2025-12-10T00:12:07.533Z", + "ParentId": "c4ca4238a0b92382", + "ContextStartedDetails": {} + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 10, + "Id": "a4e1cd317d54f087", + "Name": "task-4", + "EventTimestamp": "2025-12-10T00:12:07.533Z", + "ParentId": "3a170a9fe4f47efa", + "StepStartedDetails": {} + }, + { + "EventType": "ContextStarted", + "SubType": "ParallelBranch", + "EventId": 11, + "Id": "12426c956d1bc501", + "Name": "parallel-branch-4", + "EventTimestamp": "2025-12-10T00:12:07.533Z", + "ParentId": "c4ca4238a0b92382", + "ContextStartedDetails": {} + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 12, + "Id": "0f42756e5788f9b0", + "Name": "task-5", + "EventTimestamp": "2025-12-10T00:12:07.533Z", + "ParentId": "12426c956d1bc501", + "StepStartedDetails": {} + }, + { + "EventType": "StepFailed", + "SubType": "Step", + "EventId": 13, + "Id": "2f221a18eb863803", + "Name": "task-1", + "EventTimestamp": "2025-12-10T00:12:07.533Z", + "ParentId": "ea66c06c1e1c05fa", + "StepFailedDetails": { + "Error": { + "Payload": { + "ErrorMessage": "Task 1 failed", + "ErrorType": "Error" + } + }, + "RetryDetails": { + "NextAttemptDelaySeconds": 1, + "CurrentAttempt": 1 + } + } + }, + { + "EventType": "StepFailed", + "SubType": "Step", + "EventId": 14, + "Id": "6151f5ab282d90e4", + "Name": "task-2", + "EventTimestamp": "2025-12-10T00:12:07.537Z", + "ParentId": "98c6f2c2287f4c73", + "StepFailedDetails": { + "Error": { + "Payload": { + "ErrorMessage": "Task 2 failed", + "ErrorType": "Error" + } + }, + "RetryDetails": { + "NextAttemptDelaySeconds": 3, + "CurrentAttempt": 1 + } + } + }, + { + "EventType": "StepFailed", + "SubType": "Step", + "EventId": 15, + "Id": "b425e0c75591aa8f", + "Name": "task-3", + "EventTimestamp": "2025-12-10T00:12:07.537Z", + "ParentId": "13cee27a2bd93915", + "StepFailedDetails": { + "Error": { + "Payload": { + "ErrorMessage": "Task 3 failed", + "ErrorType": "Error" + } + }, + "RetryDetails": { + "NextAttemptDelaySeconds": 3, + "CurrentAttempt": 1 + } + } + }, + { + "EventType": "StepSucceeded", + "SubType": "Step", + "EventId": 16, + "Id": "a4e1cd317d54f087", + "Name": "task-4", + "EventTimestamp": "2025-12-10T00:12:07.537Z", + "ParentId": "3a170a9fe4f47efa", + "StepSucceededDetails": { + "Result": { + "Payload": "\"Task 4 success\"" + }, + "RetryDetails": {} + } + }, + { + "EventType": "StepSucceeded", + "SubType": "Step", + "EventId": 17, + "Id": "0f42756e5788f9b0", + "Name": "task-5", + "EventTimestamp": "2025-12-10T00:12:07.538Z", + "ParentId": "12426c956d1bc501", + "StepSucceededDetails": { + "Result": { + "Payload": "\"Task 5 success\"" + }, + "RetryDetails": {} + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "ParallelBranch", + "EventId": 18, + "Id": "3a170a9fe4f47efa", + "Name": "parallel-branch-3", + "EventTimestamp": "2025-12-10T00:12:07.541Z", + "ParentId": "c4ca4238a0b92382", + "ContextSucceededDetails": { + "Result": { + "Payload": "\"Task 4 success\"" + } + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "ParallelBranch", + "EventId": 19, + "Id": "12426c956d1bc501", + "Name": "parallel-branch-4", + "EventTimestamp": "2025-12-10T00:12:07.541Z", + "ParentId": "c4ca4238a0b92382", + "ContextSucceededDetails": { + "Result": { + "Payload": "\"Task 5 success\"" + } + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 20, + "EventTimestamp": "2025-12-10T00:12:07.591Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:12:07.523Z", + "EndTimestamp": "2025-12-10T00:12:07.590Z", + "Error": {}, + "RequestId": "29bc2a12-87be-49c8-aa8e-19473336f0e1" + } + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 21, + "Id": "2f221a18eb863803", + "Name": "task-1", + "EventTimestamp": "2025-12-10T00:12:08.549Z", + "ParentId": "ea66c06c1e1c05fa", + "StepStartedDetails": {} + }, + { + "EventType": "StepFailed", + "SubType": "Step", + "EventId": 22, + "Id": "2f221a18eb863803", + "Name": "task-1", + "EventTimestamp": "2025-12-10T00:12:08.549Z", + "ParentId": "ea66c06c1e1c05fa", + "StepFailedDetails": { + "Error": { + "Payload": { + "ErrorMessage": "Task 1 failed", + "ErrorType": "Error" + } + }, + "RetryDetails": { + "CurrentAttempt": 1 + } + } + }, + { + "EventType": "ContextFailed", + "SubType": "ParallelBranch", + "EventId": 23, + "Id": "ea66c06c1e1c05fa", + "Name": "parallel-branch-0", + "EventTimestamp": "2025-12-10T00:12:08.552Z", + "ParentId": "c4ca4238a0b92382", + "ContextFailedDetails": { + "Error": { + "Payload": { + "ErrorType": "StepError", + "ErrorMessage": "Task 1 failed" + } + } + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 24, + "EventTimestamp": "2025-12-10T00:12:08.602Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:12:08.545Z", + "EndTimestamp": "2025-12-10T00:12:08.602Z", + "Error": {}, + "RequestId": "031dc47a-c2ee-4918-8477-8ea308ef2668" + } + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 25, + "Id": "6151f5ab282d90e4", + "Name": "task-2", + "EventTimestamp": "2025-12-10T00:12:10.542Z", + "ParentId": "98c6f2c2287f4c73", + "StepStartedDetails": {} + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 26, + "Id": "b425e0c75591aa8f", + "Name": "task-3", + "EventTimestamp": "2025-12-10T00:12:10.542Z", + "ParentId": "13cee27a2bd93915", + "StepStartedDetails": {} + }, + { + "EventType": "StepFailed", + "SubType": "Step", + "EventId": 27, + "Id": "6151f5ab282d90e4", + "Name": "task-2", + "EventTimestamp": "2025-12-10T00:12:10.542Z", + "ParentId": "98c6f2c2287f4c73", + "StepFailedDetails": { + "Error": { + "Payload": { + "ErrorMessage": "Task 2 failed", + "ErrorType": "Error" + } + }, + "RetryDetails": { + "CurrentAttempt": 1 + } + } + }, + { + "EventType": "StepFailed", + "SubType": "Step", + "EventId": 28, + "Id": "b425e0c75591aa8f", + "Name": "task-3", + "EventTimestamp": "2025-12-10T00:12:10.542Z", + "ParentId": "13cee27a2bd93915", + "StepFailedDetails": { + "Error": { + "Payload": { + "ErrorMessage": "Task 3 failed", + "ErrorType": "Error" + } + }, + "RetryDetails": { + "CurrentAttempt": 1 + } + } + }, + { + "EventType": "ContextFailed", + "SubType": "ParallelBranch", + "EventId": 29, + "Id": "98c6f2c2287f4c73", + "Name": "parallel-branch-1", + "EventTimestamp": "2025-12-10T00:12:10.544Z", + "ParentId": "c4ca4238a0b92382", + "ContextFailedDetails": { + "Error": { + "Payload": { + "ErrorType": "StepError", + "ErrorMessage": "Task 2 failed" + } + } + } + }, + { + "EventType": "ContextFailed", + "SubType": "ParallelBranch", + "EventId": 30, + "Id": "13cee27a2bd93915", + "Name": "parallel-branch-2", + "EventTimestamp": "2025-12-10T00:12:10.544Z", + "ParentId": "c4ca4238a0b92382", + "ContextFailedDetails": { + "Error": { + "Payload": { + "ErrorType": "StepError", + "ErrorMessage": "Task 3 failed" + } + } + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "Parallel", + "EventId": 31, + "Id": "c4ca4238a0b92382", + "Name": "failure-threshold-tasks", + "EventTimestamp": "2025-12-10T00:12:10.544Z", + "ContextSucceededDetails": { + "Result": { + "Payload": "{\"all\":[{\"error\":{\"cause\":{\"cause\":{\"name\":\"StepError\"},\"name\":\"StepError\",\"errorType\":\"StepError\"},\"name\":\"ChildContextError\",\"errorType\":\"ChildContextError\"},\"index\":0,\"status\":\"FAILED\"},{\"error\":{\"cause\":{\"cause\":{\"name\":\"StepError\"},\"name\":\"StepError\",\"errorType\":\"StepError\"},\"name\":\"ChildContextError\",\"errorType\":\"ChildContextError\"},\"index\":1,\"status\":\"FAILED\"},{\"error\":{\"cause\":{\"cause\":{\"name\":\"StepError\"},\"name\":\"StepError\",\"errorType\":\"StepError\"},\"name\":\"ChildContextError\",\"errorType\":\"ChildContextError\"},\"index\":2,\"status\":\"FAILED\"},{\"result\":\"Task 4 success\",\"index\":3,\"status\":\"SUCCEEDED\"},{\"result\":\"Task 5 success\",\"index\":4,\"status\":\"SUCCEEDED\"}],\"completionReason\":\"FAILURE_TOLERANCE_EXCEEDED\"}" + } + } + }, + { + "EventType": "WaitStarted", + "SubType": "Wait", + "EventId": 32, + "Id": "c81e728d9d4c2f63", + "EventTimestamp": "2025-12-10T00:12:10.544Z", + "WaitStartedDetails": { + "Duration": 1, + "ScheduledEndTimestamp": "2025-12-10T00:12:11.544Z" + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 33, + "EventTimestamp": "2025-12-10T00:12:10.596Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:12:10.539Z", + "EndTimestamp": "2025-12-10T00:12:10.596Z", + "Error": {}, + "RequestId": "a735f242-e42d-42d5-b133-709e2eec8da9" + } + }, + { + "EventType": "WaitSucceeded", + "SubType": "Wait", + "EventId": 34, + "Id": "c81e728d9d4c2f63", + "EventTimestamp": "2025-12-10T00:12:11.546Z", + "WaitSucceededDetails": { + "Duration": 1 + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 35, + "EventTimestamp": "2025-12-10T00:12:11.547Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:12:11.546Z", + "EndTimestamp": "2025-12-10T00:12:11.547Z", + "Error": {}, + "RequestId": "1b0cf111-c862-4ded-ae63-aaa84639e8b4" + } + }, + { + "EventType": "ExecutionSucceeded", + "EventId": 36, + "Id": "cda5a2ff-8872-4ee7-b6e5-51f26cc6bd45", + "EventTimestamp": "2025-12-10T00:12:11.547Z", + "ExecutionSucceededDetails": { + "Result": { + "Payload": "{\"completionReason\":\"FAILURE_TOLERANCE_EXCEEDED\",\"successCount\":2,\"failureCount\":3,\"totalCount\":5}" + } + } + } +] diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/failure-threshold-exceeded-count/parallel-failure-threshold-exceeded-count.test.ts b/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/failure-threshold-exceeded-count/parallel-failure-threshold-exceeded-count.test.ts index e90a380f..be773169 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/failure-threshold-exceeded-count/parallel-failure-threshold-exceeded-count.test.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/failure-threshold-exceeded-count/parallel-failure-threshold-exceeded-count.test.ts @@ -3,7 +3,7 @@ import { createTests } from "../../../utils/test-helper"; createTests({ handler, - tests: (runner) => { + tests: (runner, { assertEventSignatures }) => { it("should return FAILURE_TOLERANCE_EXCEEDED when failure count exceeds threshold", async () => { const execution = await runner.run(); const result = execution.getResult() as any; @@ -12,6 +12,8 @@ createTests({ expect(result.successCount).toBe(2); // Tasks 4 and 5 succeed expect(result.failureCount).toBe(3); // Tasks 1, 2, 3 fail (exceeds threshold of 2) expect(result.totalCount).toBe(5); + + assertEventSignatures(execution); }); }, }); diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/failure-threshold-exceeded-percentage/parallel-failure-threshold-exceeded-percentage.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/failure-threshold-exceeded-percentage/parallel-failure-threshold-exceeded-percentage.history.json new file mode 100644 index 00000000..dfdc6738 --- /dev/null +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/failure-threshold-exceeded-percentage/parallel-failure-threshold-exceeded-percentage.history.json @@ -0,0 +1,451 @@ +[ + { + "EventType": "ExecutionStarted", + "EventId": 1, + "Id": "10987b52-759d-4d31-a87d-f3ccb156f41a", + "EventTimestamp": "2025-12-10T00:15:08.861Z", + "ExecutionStartedDetails": { + "Input": { + "Payload": "{}" + } + } + }, + { + "EventType": "ContextStarted", + "SubType": "Parallel", + "EventId": 2, + "Id": "c4ca4238a0b92382", + "Name": "failure-threshold-tasks", + "EventTimestamp": "2025-12-10T00:15:08.904Z", + "ContextStartedDetails": {} + }, + { + "EventType": "ContextStarted", + "SubType": "ParallelBranch", + "EventId": 3, + "Id": "ea66c06c1e1c05fa", + "Name": "parallel-branch-0", + "EventTimestamp": "2025-12-10T00:15:08.904Z", + "ParentId": "c4ca4238a0b92382", + "ContextStartedDetails": {} + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 4, + "Id": "2f221a18eb863803", + "Name": "task-1", + "EventTimestamp": "2025-12-10T00:15:08.904Z", + "ParentId": "ea66c06c1e1c05fa", + "StepStartedDetails": {} + }, + { + "EventType": "ContextStarted", + "SubType": "ParallelBranch", + "EventId": 5, + "Id": "98c6f2c2287f4c73", + "Name": "parallel-branch-1", + "EventTimestamp": "2025-12-10T00:15:08.904Z", + "ParentId": "c4ca4238a0b92382", + "ContextStartedDetails": {} + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 6, + "Id": "6151f5ab282d90e4", + "Name": "task-2", + "EventTimestamp": "2025-12-10T00:15:08.904Z", + "ParentId": "98c6f2c2287f4c73", + "StepStartedDetails": {} + }, + { + "EventType": "ContextStarted", + "SubType": "ParallelBranch", + "EventId": 7, + "Id": "13cee27a2bd93915", + "Name": "parallel-branch-2", + "EventTimestamp": "2025-12-10T00:15:08.904Z", + "ParentId": "c4ca4238a0b92382", + "ContextStartedDetails": {} + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 8, + "Id": "b425e0c75591aa8f", + "Name": "task-3", + "EventTimestamp": "2025-12-10T00:15:08.904Z", + "ParentId": "13cee27a2bd93915", + "StepStartedDetails": {} + }, + { + "EventType": "ContextStarted", + "SubType": "ParallelBranch", + "EventId": 9, + "Id": "3a170a9fe4f47efa", + "Name": "parallel-branch-3", + "EventTimestamp": "2025-12-10T00:15:08.904Z", + "ParentId": "c4ca4238a0b92382", + "ContextStartedDetails": {} + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 10, + "Id": "a4e1cd317d54f087", + "Name": "task-4", + "EventTimestamp": "2025-12-10T00:15:08.904Z", + "ParentId": "3a170a9fe4f47efa", + "StepStartedDetails": {} + }, + { + "EventType": "ContextStarted", + "SubType": "ParallelBranch", + "EventId": 11, + "Id": "12426c956d1bc501", + "Name": "parallel-branch-4", + "EventTimestamp": "2025-12-10T00:15:08.904Z", + "ParentId": "c4ca4238a0b92382", + "ContextStartedDetails": {} + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 12, + "Id": "0f42756e5788f9b0", + "Name": "task-5", + "EventTimestamp": "2025-12-10T00:15:08.904Z", + "ParentId": "12426c956d1bc501", + "StepStartedDetails": {} + }, + { + "EventType": "StepFailed", + "SubType": "Step", + "EventId": 13, + "Id": "2f221a18eb863803", + "Name": "task-1", + "EventTimestamp": "2025-12-10T00:15:08.904Z", + "ParentId": "ea66c06c1e1c05fa", + "StepFailedDetails": { + "Error": { + "Payload": { + "ErrorMessage": "Task 1 failed", + "ErrorType": "Error" + } + }, + "RetryDetails": { + "NextAttemptDelaySeconds": 1, + "CurrentAttempt": 1 + } + } + }, + { + "EventType": "StepFailed", + "SubType": "Step", + "EventId": 14, + "Id": "6151f5ab282d90e4", + "Name": "task-2", + "EventTimestamp": "2025-12-10T00:15:08.906Z", + "ParentId": "98c6f2c2287f4c73", + "StepFailedDetails": { + "Error": { + "Payload": { + "ErrorMessage": "Task 2 failed", + "ErrorType": "Error" + } + }, + "RetryDetails": { + "NextAttemptDelaySeconds": 3, + "CurrentAttempt": 1 + } + } + }, + { + "EventType": "StepFailed", + "SubType": "Step", + "EventId": 15, + "Id": "b425e0c75591aa8f", + "Name": "task-3", + "EventTimestamp": "2025-12-10T00:15:08.906Z", + "ParentId": "13cee27a2bd93915", + "StepFailedDetails": { + "Error": { + "Payload": { + "ErrorMessage": "Task 3 failed", + "ErrorType": "Error" + } + }, + "RetryDetails": { + "NextAttemptDelaySeconds": 3, + "CurrentAttempt": 1 + } + } + }, + { + "EventType": "StepSucceeded", + "SubType": "Step", + "EventId": 16, + "Id": "a4e1cd317d54f087", + "Name": "task-4", + "EventTimestamp": "2025-12-10T00:15:08.906Z", + "ParentId": "3a170a9fe4f47efa", + "StepSucceededDetails": { + "Result": { + "Payload": "\"Task 4 success\"" + }, + "RetryDetails": {} + } + }, + { + "EventType": "StepSucceeded", + "SubType": "Step", + "EventId": 17, + "Id": "0f42756e5788f9b0", + "Name": "task-5", + "EventTimestamp": "2025-12-10T00:15:08.906Z", + "ParentId": "12426c956d1bc501", + "StepSucceededDetails": { + "Result": { + "Payload": "\"Task 5 success\"" + }, + "RetryDetails": {} + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "ParallelBranch", + "EventId": 18, + "Id": "3a170a9fe4f47efa", + "Name": "parallel-branch-3", + "EventTimestamp": "2025-12-10T00:15:08.911Z", + "ParentId": "c4ca4238a0b92382", + "ContextSucceededDetails": { + "Result": { + "Payload": "\"Task 4 success\"" + } + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "ParallelBranch", + "EventId": 19, + "Id": "12426c956d1bc501", + "Name": "parallel-branch-4", + "EventTimestamp": "2025-12-10T00:15:08.911Z", + "ParentId": "c4ca4238a0b92382", + "ContextSucceededDetails": { + "Result": { + "Payload": "\"Task 5 success\"" + } + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 20, + "EventTimestamp": "2025-12-10T00:15:08.912Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:15:08.860Z", + "EndTimestamp": "2025-12-10T00:15:08.912Z", + "Error": {}, + "RequestId": "94b982cf-2168-48e8-98db-82e418609eec" + } + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 21, + "Id": "2f221a18eb863803", + "Name": "task-1", + "EventTimestamp": "2025-12-10T00:15:08.944Z", + "ParentId": "ea66c06c1e1c05fa", + "StepStartedDetails": {} + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 22, + "Id": "6151f5ab282d90e4", + "Name": "task-2", + "EventTimestamp": "2025-12-10T00:15:08.944Z", + "ParentId": "98c6f2c2287f4c73", + "StepStartedDetails": {} + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 23, + "Id": "b425e0c75591aa8f", + "Name": "task-3", + "EventTimestamp": "2025-12-10T00:15:08.944Z", + "ParentId": "13cee27a2bd93915", + "StepStartedDetails": {} + }, + { + "EventType": "StepFailed", + "SubType": "Step", + "EventId": 24, + "Id": "2f221a18eb863803", + "Name": "task-1", + "EventTimestamp": "2025-12-10T00:15:08.944Z", + "ParentId": "ea66c06c1e1c05fa", + "StepFailedDetails": { + "Error": { + "Payload": { + "ErrorMessage": "Task 1 failed", + "ErrorType": "Error" + } + }, + "RetryDetails": { + "CurrentAttempt": 1 + } + } + }, + { + "EventType": "StepFailed", + "SubType": "Step", + "EventId": 25, + "Id": "6151f5ab282d90e4", + "Name": "task-2", + "EventTimestamp": "2025-12-10T00:15:08.944Z", + "ParentId": "98c6f2c2287f4c73", + "StepFailedDetails": { + "Error": { + "Payload": { + "ErrorMessage": "Task 2 failed", + "ErrorType": "Error" + } + }, + "RetryDetails": { + "CurrentAttempt": 1 + } + } + }, + { + "EventType": "StepFailed", + "SubType": "Step", + "EventId": 26, + "Id": "b425e0c75591aa8f", + "Name": "task-3", + "EventTimestamp": "2025-12-10T00:15:08.944Z", + "ParentId": "13cee27a2bd93915", + "StepFailedDetails": { + "Error": { + "Payload": { + "ErrorMessage": "Task 3 failed", + "ErrorType": "Error" + } + }, + "RetryDetails": { + "CurrentAttempt": 1 + } + } + }, + { + "EventType": "ContextFailed", + "SubType": "ParallelBranch", + "EventId": 27, + "Id": "ea66c06c1e1c05fa", + "Name": "parallel-branch-0", + "EventTimestamp": "2025-12-10T00:15:08.966Z", + "ParentId": "c4ca4238a0b92382", + "ContextFailedDetails": { + "Error": { + "Payload": { + "ErrorType": "StepError", + "ErrorMessage": "Task 1 failed" + } + } + } + }, + { + "EventType": "ContextFailed", + "SubType": "ParallelBranch", + "EventId": 28, + "Id": "98c6f2c2287f4c73", + "Name": "parallel-branch-1", + "EventTimestamp": "2025-12-10T00:15:08.966Z", + "ParentId": "c4ca4238a0b92382", + "ContextFailedDetails": { + "Error": { + "Payload": { + "ErrorType": "StepError", + "ErrorMessage": "Task 2 failed" + } + } + } + }, + { + "EventType": "ContextFailed", + "SubType": "ParallelBranch", + "EventId": 29, + "Id": "13cee27a2bd93915", + "Name": "parallel-branch-2", + "EventTimestamp": "2025-12-10T00:15:08.966Z", + "ParentId": "c4ca4238a0b92382", + "ContextFailedDetails": { + "Error": { + "Payload": { + "ErrorType": "StepError", + "ErrorMessage": "Task 3 failed" + } + } + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "Parallel", + "EventId": 30, + "Id": "c4ca4238a0b92382", + "Name": "failure-threshold-tasks", + "EventTimestamp": "2025-12-10T00:15:08.966Z", + "ContextSucceededDetails": { + "Result": { + "Payload": "{\"all\":[{\"error\":{\"cause\":{\"cause\":{\"name\":\"StepError\"},\"name\":\"StepError\",\"errorType\":\"StepError\"},\"name\":\"ChildContextError\",\"errorType\":\"ChildContextError\"},\"index\":0,\"status\":\"FAILED\"},{\"error\":{\"cause\":{\"cause\":{\"name\":\"StepError\"},\"name\":\"StepError\",\"errorType\":\"StepError\"},\"name\":\"ChildContextError\",\"errorType\":\"ChildContextError\"},\"index\":1,\"status\":\"FAILED\"},{\"error\":{\"cause\":{\"cause\":{\"name\":\"StepError\"},\"name\":\"StepError\",\"errorType\":\"StepError\"},\"name\":\"ChildContextError\",\"errorType\":\"ChildContextError\"},\"index\":2,\"status\":\"FAILED\"},{\"result\":\"Task 4 success\",\"index\":3,\"status\":\"SUCCEEDED\"},{\"result\":\"Task 5 success\",\"index\":4,\"status\":\"SUCCEEDED\"}],\"completionReason\":\"FAILURE_TOLERANCE_EXCEEDED\"}" + } + } + }, + { + "EventType": "WaitStarted", + "SubType": "Wait", + "EventId": 31, + "Id": "c81e728d9d4c2f63", + "EventTimestamp": "2025-12-10T00:15:08.966Z", + "WaitStartedDetails": { + "Duration": 1, + "ScheduledEndTimestamp": "2025-12-10T00:15:09.966Z" + } + }, + { + "EventType": "WaitSucceeded", + "SubType": "Wait", + "EventId": 32, + "Id": "c81e728d9d4c2f63", + "EventTimestamp": "2025-12-10T00:15:08.968Z", + "WaitSucceededDetails": { + "Duration": 1 + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 33, + "EventTimestamp": "2025-12-10T00:15:08.988Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:15:08.923Z", + "EndTimestamp": "2025-12-10T00:15:08.988Z", + "Error": {}, + "RequestId": "05310f70-731e-46ac-b236-3aa3178cc695" + } + }, + { + "EventType": "ExecutionSucceeded", + "EventId": 34, + "Id": "10987b52-759d-4d31-a87d-f3ccb156f41a", + "EventTimestamp": "2025-12-10T00:15:08.989Z", + "ExecutionSucceededDetails": { + "Result": { + "Payload": "{\"completionReason\":\"FAILURE_TOLERANCE_EXCEEDED\",\"successCount\":2,\"failureCount\":3,\"totalCount\":5}" + } + } + } +] diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/failure-threshold-exceeded-percentage/parallel-failure-threshold-exceeded-percentage.test.ts b/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/failure-threshold-exceeded-percentage/parallel-failure-threshold-exceeded-percentage.test.ts index 4bf35aa1..d0bd9827 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/failure-threshold-exceeded-percentage/parallel-failure-threshold-exceeded-percentage.test.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/failure-threshold-exceeded-percentage/parallel-failure-threshold-exceeded-percentage.test.ts @@ -3,7 +3,7 @@ import { createTests } from "../../../utils/test-helper"; createTests({ handler, - tests: (runner) => { + tests: (runner, { assertEventSignatures }) => { it("should return FAILURE_TOLERANCE_EXCEEDED when failure percentage exceeds threshold", async () => { const execution = await runner.run(); const result = execution.getResult() as any; @@ -12,6 +12,8 @@ createTests({ expect(result.successCount).toBe(2); // Tasks 4 and 5 succeed expect(result.failureCount).toBe(3); // Tasks 1, 2, 3 fail (60% > 50% threshold) expect(result.totalCount).toBe(5); + + assertEventSignatures(execution); }); }, }); diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/min-successful-with-callback/parallel-min-successful-callback.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/min-successful-with-callback/parallel-min-successful-callback.history.json new file mode 100644 index 00000000..da0f7162 --- /dev/null +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/min-successful-with-callback/parallel-min-successful-callback.history.json @@ -0,0 +1,165 @@ +[ + { + "EventType": "ExecutionStarted", + "EventId": 1, + "Id": "51465649-ee49-44fe-bd23-8f493687450a", + "EventTimestamp": "2025-12-10T00:15:08.612Z", + "ExecutionStartedDetails": { + "Input": { + "Payload": "{}" + } + } + }, + { + "EventType": "ContextStarted", + "SubType": "Parallel", + "EventId": 2, + "Id": "c4ca4238a0b92382", + "Name": "parallel-callbacks", + "EventTimestamp": "2025-12-10T00:15:08.643Z", + "ContextStartedDetails": {} + }, + { + "EventType": "ContextStarted", + "SubType": "ParallelBranch", + "EventId": 3, + "Id": "ea66c06c1e1c05fa", + "Name": "parallel-branch-0", + "EventTimestamp": "2025-12-10T00:15:08.643Z", + "ParentId": "c4ca4238a0b92382", + "ContextStartedDetails": {} + }, + { + "EventType": "CallbackStarted", + "SubType": "Callback", + "EventId": 4, + "Id": "2f221a18eb863803", + "Name": "branch-1-callback", + "EventTimestamp": "2025-12-10T00:15:08.643Z", + "ParentId": "ea66c06c1e1c05fa", + "CallbackStartedDetails": { + "CallbackId": "eyJleGVjdXRpb25JZCI6ImY4OWExNTE3LWRmMTUtNGE3ZS1hY2U0LThjMjlhZDU0ODIzYiIsIm9wZXJhdGlvbklkIjoiMmYyMjFhMThlYjg2MzgwMyIsInRva2VuIjoiOTFlYjRiZWItN2UxOS00ZDZmLWJlMjEtNzcyMzE3N2Q4ZmMxIn0=", + "Input": {} + } + }, + { + "EventType": "ContextStarted", + "SubType": "ParallelBranch", + "EventId": 5, + "Id": "98c6f2c2287f4c73", + "Name": "parallel-branch-1", + "EventTimestamp": "2025-12-10T00:15:08.643Z", + "ParentId": "c4ca4238a0b92382", + "ContextStartedDetails": {} + }, + { + "EventType": "CallbackStarted", + "SubType": "Callback", + "EventId": 6, + "Id": "6151f5ab282d90e4", + "Name": "branch-2-callback", + "EventTimestamp": "2025-12-10T00:15:08.644Z", + "ParentId": "98c6f2c2287f4c73", + "CallbackStartedDetails": { + "CallbackId": "eyJleGVjdXRpb25JZCI6ImY4OWExNTE3LWRmMTUtNGE3ZS1hY2U0LThjMjlhZDU0ODIzYiIsIm9wZXJhdGlvbklkIjoiNjE1MWY1YWIyODJkOTBlNCIsInRva2VuIjoiYmUyYzRkNzItNWU4My00YzdjLWIwMzctZTcyNDdjNTM2ZTY1In0=", + "Input": {} + } + }, + { + "EventType": "ContextStarted", + "SubType": "ParallelBranch", + "EventId": 7, + "Id": "13cee27a2bd93915", + "Name": "parallel-branch-2", + "EventTimestamp": "2025-12-10T00:15:08.644Z", + "ParentId": "c4ca4238a0b92382", + "ContextStartedDetails": {} + }, + { + "EventType": "CallbackStarted", + "SubType": "Callback", + "EventId": 8, + "Id": "b425e0c75591aa8f", + "Name": "branch-3-callback", + "EventTimestamp": "2025-12-10T00:15:08.644Z", + "ParentId": "13cee27a2bd93915", + "CallbackStartedDetails": { + "CallbackId": "eyJleGVjdXRpb25JZCI6ImY4OWExNTE3LWRmMTUtNGE3ZS1hY2U0LThjMjlhZDU0ODIzYiIsIm9wZXJhdGlvbklkIjoiYjQyNWUwYzc1NTkxYWE4ZiIsInRva2VuIjoiNDJmYjA2YzMtYzQyZC00YTMyLWI3MzctOWZiMGE4YzlhNTZmIn0=", + "Input": {} + } + }, + { + "EventType": "CallbackSucceeded", + "SubType": "Callback", + "EventId": 9, + "Id": "2f221a18eb863803", + "Name": "branch-1-callback", + "EventTimestamp": "2025-12-10T00:15:08.646Z", + "ParentId": "ea66c06c1e1c05fa", + "CallbackSucceededDetails": { + "Result": { + "Payload": "result-1" + } + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 10, + "EventTimestamp": "2025-12-10T00:15:08.704Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:15:08.611Z", + "EndTimestamp": "2025-12-10T00:15:08.704Z", + "Error": {}, + "RequestId": "51316857-f314-4967-a0c0-4e044422a5ab" + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "ParallelBranch", + "EventId": 11, + "Id": "ea66c06c1e1c05fa", + "Name": "parallel-branch-0", + "EventTimestamp": "2025-12-10T00:15:08.747Z", + "ParentId": "c4ca4238a0b92382", + "ContextSucceededDetails": { + "Result": { + "Payload": "\"result-1\"" + } + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "Parallel", + "EventId": 12, + "Id": "c4ca4238a0b92382", + "Name": "parallel-callbacks", + "EventTimestamp": "2025-12-10T00:15:08.747Z", + "ContextSucceededDetails": { + "Result": { + "Payload": "{\"all\":[{\"result\":\"result-1\",\"index\":0,\"status\":\"SUCCEEDED\"},{\"index\":1,\"status\":\"STARTED\"},{\"index\":2,\"status\":\"STARTED\"}],\"completionReason\":\"MIN_SUCCESSFUL_REACHED\"}" + } + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 13, + "EventTimestamp": "2025-12-10T00:15:08.748Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:15:08.725Z", + "EndTimestamp": "2025-12-10T00:15:08.748Z", + "Error": {}, + "RequestId": "9b897d92-09b0-403b-bd67-1b6e5aae403e" + } + }, + { + "EventType": "ExecutionSucceeded", + "EventId": 14, + "Id": "51465649-ee49-44fe-bd23-8f493687450a", + "EventTimestamp": "2025-12-10T00:15:08.748Z", + "ExecutionSucceededDetails": { + "Result": { + "Payload": "[\"result-1\"]" + } + } + } +] diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/min-successful-with-callback/parallel-min-successful-callback.test.ts b/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/min-successful-with-callback/parallel-min-successful-callback.test.ts index 064329a8..e77bb95b 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/min-successful-with-callback/parallel-min-successful-callback.test.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/min-successful-with-callback/parallel-min-successful-callback.test.ts @@ -8,7 +8,7 @@ import { createTests } from "../../../utils/test-helper"; createTests({ handler, invocationType: InvocationType.Event, - tests: (runner) => { + tests: (runner, { assertEventSignatures }) => { it("should succeed when only one of three callbacks completes (minSuccessful:1)", async () => { const callback1Op = runner.getOperation("branch-1-callback"); const callback2Op = runner.getOperation("branch-2-callback"); @@ -34,6 +34,8 @@ createTests({ const results = execution.getResult() as string[]; expect(results.length).toBeGreaterThanOrEqual(1); expect(results[0]).toBe("result-1"); + + assertEventSignatures(execution); }, 10000); }, }); diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/min-successful/parallel-min-successful.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/min-successful/parallel-min-successful.history.json new file mode 100644 index 00000000..ec9db904 --- /dev/null +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/min-successful/parallel-min-successful.history.json @@ -0,0 +1,216 @@ +[ + { + "EventType": "ExecutionStarted", + "EventId": 1, + "Id": "03d6c29c-125f-4aec-8e82-cfdf27f2c4c8", + "EventTimestamp": "2025-12-10T00:12:26.332Z", + "ExecutionStartedDetails": { + "Input": { + "Payload": "{}" + } + } + }, + { + "EventType": "ContextStarted", + "SubType": "Parallel", + "EventId": 2, + "Id": "c4ca4238a0b92382", + "Name": "min-successful-branches", + "EventTimestamp": "2025-12-10T00:12:26.337Z", + "ContextStartedDetails": {} + }, + { + "EventType": "ContextStarted", + "SubType": "ParallelBranch", + "EventId": 3, + "Id": "ea66c06c1e1c05fa", + "Name": "parallel-branch-0", + "EventTimestamp": "2025-12-10T00:12:26.337Z", + "ParentId": "c4ca4238a0b92382", + "ContextStartedDetails": {} + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 4, + "Id": "2f221a18eb863803", + "Name": "branch-1", + "EventTimestamp": "2025-12-10T00:12:26.337Z", + "ParentId": "ea66c06c1e1c05fa", + "StepStartedDetails": {} + }, + { + "EventType": "ContextStarted", + "SubType": "ParallelBranch", + "EventId": 5, + "Id": "98c6f2c2287f4c73", + "Name": "parallel-branch-1", + "EventTimestamp": "2025-12-10T00:12:26.337Z", + "ParentId": "c4ca4238a0b92382", + "ContextStartedDetails": {} + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 6, + "Id": "6151f5ab282d90e4", + "Name": "branch-2", + "EventTimestamp": "2025-12-10T00:12:26.337Z", + "ParentId": "98c6f2c2287f4c73", + "StepStartedDetails": {} + }, + { + "EventType": "ContextStarted", + "SubType": "ParallelBranch", + "EventId": 7, + "Id": "13cee27a2bd93915", + "Name": "parallel-branch-2", + "EventTimestamp": "2025-12-10T00:12:26.337Z", + "ParentId": "c4ca4238a0b92382", + "ContextStartedDetails": {} + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 8, + "Id": "b425e0c75591aa8f", + "Name": "branch-3", + "EventTimestamp": "2025-12-10T00:12:26.337Z", + "ParentId": "13cee27a2bd93915", + "StepStartedDetails": {} + }, + { + "EventType": "ContextStarted", + "SubType": "ParallelBranch", + "EventId": 9, + "Id": "3a170a9fe4f47efa", + "Name": "parallel-branch-3", + "EventTimestamp": "2025-12-10T00:12:26.337Z", + "ParentId": "c4ca4238a0b92382", + "ContextStartedDetails": {} + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 10, + "Id": "a4e1cd317d54f087", + "Name": "branch-4", + "EventTimestamp": "2025-12-10T00:12:26.337Z", + "ParentId": "3a170a9fe4f47efa", + "StepStartedDetails": {} + }, + { + "EventType": "StepSucceeded", + "SubType": "Step", + "EventId": 11, + "Id": "2f221a18eb863803", + "Name": "branch-1", + "EventTimestamp": "2025-12-10T00:12:26.437Z", + "ParentId": "ea66c06c1e1c05fa", + "StepSucceededDetails": { + "Result": { + "Payload": "\"Branch 1 result\"" + }, + "RetryDetails": {} + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "ParallelBranch", + "EventId": 12, + "Id": "ea66c06c1e1c05fa", + "Name": "parallel-branch-0", + "EventTimestamp": "2025-12-10T00:12:26.439Z", + "ParentId": "c4ca4238a0b92382", + "ContextSucceededDetails": { + "Result": { + "Payload": "\"Branch 1 result\"" + } + } + }, + { + "EventType": "StepSucceeded", + "SubType": "Step", + "EventId": 13, + "Id": "6151f5ab282d90e4", + "Name": "branch-2", + "EventTimestamp": "2025-12-10T00:12:26.538Z", + "ParentId": "98c6f2c2287f4c73", + "StepSucceededDetails": { + "Result": { + "Payload": "\"Branch 2 result\"" + }, + "RetryDetails": {} + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "ParallelBranch", + "EventId": 14, + "Id": "98c6f2c2287f4c73", + "Name": "parallel-branch-1", + "EventTimestamp": "2025-12-10T00:12:26.540Z", + "ParentId": "c4ca4238a0b92382", + "ContextSucceededDetails": { + "Result": { + "Payload": "\"Branch 2 result\"" + } + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "Parallel", + "EventId": 15, + "Id": "c4ca4238a0b92382", + "Name": "min-successful-branches", + "EventTimestamp": "2025-12-10T00:12:26.540Z", + "ContextSucceededDetails": { + "Result": { + "Payload": "{\"all\":[{\"result\":\"Branch 1 result\",\"index\":0,\"status\":\"SUCCEEDED\"},{\"result\":\"Branch 2 result\",\"index\":1,\"status\":\"SUCCEEDED\"},{\"index\":2,\"status\":\"STARTED\"},{\"index\":3,\"status\":\"STARTED\"}],\"completionReason\":\"MIN_SUCCESSFUL_REACHED\"}" + } + } + }, + { + "EventType": "WaitStarted", + "SubType": "Wait", + "EventId": 16, + "Id": "c81e728d9d4c2f63", + "EventTimestamp": "2025-12-10T00:12:26.540Z", + "WaitStartedDetails": { + "Duration": 1, + "ScheduledEndTimestamp": "2025-12-10T00:12:27.541Z" + } + }, + { + "EventType": "WaitSucceeded", + "SubType": "Wait", + "EventId": 17, + "Id": "c81e728d9d4c2f63", + "EventTimestamp": "2025-12-10T00:12:27.542Z", + "WaitSucceededDetails": { + "Duration": 1 + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 18, + "EventTimestamp": "2025-12-10T00:12:27.542Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:12:26.332Z", + "EndTimestamp": "2025-12-10T00:12:27.542Z", + "Error": {}, + "RequestId": "f3fddb6a-3e25-4f65-b6de-eebe53a53c38" + } + }, + { + "EventType": "ExecutionSucceeded", + "EventId": 19, + "Id": "03d6c29c-125f-4aec-8e82-cfdf27f2c4c8", + "EventTimestamp": "2025-12-10T00:12:27.542Z", + "ExecutionSucceededDetails": { + "Result": { + "Payload": "{\"successCount\":2,\"totalCount\":4,\"completionReason\":\"MIN_SUCCESSFUL_REACHED\",\"results\":[\"Branch 1 result\",\"Branch 2 result\"]}" + } + } + } +] diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/min-successful/parallel-min-successful.test.ts b/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/min-successful/parallel-min-successful.test.ts index 58d3cde5..f6cf866a 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/min-successful/parallel-min-successful.test.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/min-successful/parallel-min-successful.test.ts @@ -8,7 +8,7 @@ createTests({ checkpointDelay: 100, }, handler, - tests: (runner) => { + tests: (runner, { assertEventSignatures }) => { it("should complete early when minSuccessful is reached", async () => { const execution = await runner.run(); const result = execution.getResult() as any; @@ -36,6 +36,8 @@ createTests({ // Verify the results array matches expect(result.results).toEqual(["Branch 1 result", "Branch 2 result"]); + + assertEventSignatures(execution); }); }, }); diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/tolerated-failure-count/parallel-tolerated-failure-count.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/tolerated-failure-count/parallel-tolerated-failure-count.history.json new file mode 100644 index 00000000..da7a97ed --- /dev/null +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/tolerated-failure-count/parallel-tolerated-failure-count.history.json @@ -0,0 +1,350 @@ +[ + { + "EventType": "ExecutionStarted", + "EventId": 1, + "Id": "2d9ce8ae-d485-4ca9-a1ef-0e11acb56f3d", + "EventTimestamp": "2025-12-10T00:12:07.576Z", + "ExecutionStartedDetails": { + "Input": { + "Payload": "{}" + } + } + }, + { + "EventType": "ContextStarted", + "SubType": "Parallel", + "EventId": 2, + "Id": "c4ca4238a0b92382", + "Name": "failure-count-branches", + "EventTimestamp": "2025-12-10T00:12:07.586Z", + "ContextStartedDetails": {} + }, + { + "EventType": "ContextStarted", + "SubType": "ParallelBranch", + "EventId": 3, + "Id": "ea66c06c1e1c05fa", + "Name": "parallel-branch-0", + "EventTimestamp": "2025-12-10T00:12:07.586Z", + "ParentId": "c4ca4238a0b92382", + "ContextStartedDetails": {} + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 4, + "Id": "2f221a18eb863803", + "Name": "branch-1", + "EventTimestamp": "2025-12-10T00:12:07.586Z", + "ParentId": "ea66c06c1e1c05fa", + "StepStartedDetails": {} + }, + { + "EventType": "ContextStarted", + "SubType": "ParallelBranch", + "EventId": 5, + "Id": "98c6f2c2287f4c73", + "Name": "parallel-branch-1", + "EventTimestamp": "2025-12-10T00:12:07.586Z", + "ParentId": "c4ca4238a0b92382", + "ContextStartedDetails": {} + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 6, + "Id": "6151f5ab282d90e4", + "Name": "branch-2", + "EventTimestamp": "2025-12-10T00:12:07.586Z", + "ParentId": "98c6f2c2287f4c73", + "StepStartedDetails": {} + }, + { + "EventType": "ContextStarted", + "SubType": "ParallelBranch", + "EventId": 7, + "Id": "13cee27a2bd93915", + "Name": "parallel-branch-2", + "EventTimestamp": "2025-12-10T00:12:07.586Z", + "ParentId": "c4ca4238a0b92382", + "ContextStartedDetails": {} + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 8, + "Id": "b425e0c75591aa8f", + "Name": "branch-3", + "EventTimestamp": "2025-12-10T00:12:07.586Z", + "ParentId": "13cee27a2bd93915", + "StepStartedDetails": {} + }, + { + "EventType": "ContextStarted", + "SubType": "ParallelBranch", + "EventId": 9, + "Id": "3a170a9fe4f47efa", + "Name": "parallel-branch-3", + "EventTimestamp": "2025-12-10T00:12:07.586Z", + "ParentId": "c4ca4238a0b92382", + "ContextStartedDetails": {} + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 10, + "Id": "a4e1cd317d54f087", + "Name": "branch-4", + "EventTimestamp": "2025-12-10T00:12:07.586Z", + "ParentId": "3a170a9fe4f47efa", + "StepStartedDetails": {} + }, + { + "EventType": "ContextStarted", + "SubType": "ParallelBranch", + "EventId": 11, + "Id": "12426c956d1bc501", + "Name": "parallel-branch-4", + "EventTimestamp": "2025-12-10T00:12:07.586Z", + "ParentId": "c4ca4238a0b92382", + "ContextStartedDetails": {} + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 12, + "Id": "0f42756e5788f9b0", + "Name": "branch-5", + "EventTimestamp": "2025-12-10T00:12:07.586Z", + "ParentId": "12426c956d1bc501", + "StepStartedDetails": {} + }, + { + "EventType": "StepFailed", + "SubType": "Step", + "EventId": 13, + "Id": "6151f5ab282d90e4", + "Name": "branch-2", + "EventTimestamp": "2025-12-10T00:12:07.586Z", + "ParentId": "98c6f2c2287f4c73", + "StepFailedDetails": { + "Error": { + "Payload": { + "ErrorMessage": "Branch 2 failed", + "ErrorType": "Error" + } + }, + "RetryDetails": { + "CurrentAttempt": 1 + } + } + }, + { + "EventType": "StepFailed", + "SubType": "Step", + "EventId": 14, + "Id": "a4e1cd317d54f087", + "Name": "branch-4", + "EventTimestamp": "2025-12-10T00:12:07.586Z", + "ParentId": "3a170a9fe4f47efa", + "StepFailedDetails": { + "Error": { + "Payload": { + "ErrorMessage": "Branch 4 failed", + "ErrorType": "Error" + } + }, + "RetryDetails": { + "CurrentAttempt": 1 + } + } + }, + { + "EventType": "StepSucceeded", + "SubType": "Step", + "EventId": 15, + "Id": "2f221a18eb863803", + "Name": "branch-1", + "EventTimestamp": "2025-12-10T00:12:07.586Z", + "ParentId": "ea66c06c1e1c05fa", + "StepSucceededDetails": { + "Result": { + "Payload": "\"Branch 1 success\"" + }, + "RetryDetails": {} + } + }, + { + "EventType": "StepSucceeded", + "SubType": "Step", + "EventId": 16, + "Id": "b425e0c75591aa8f", + "Name": "branch-3", + "EventTimestamp": "2025-12-10T00:12:07.586Z", + "ParentId": "13cee27a2bd93915", + "StepSucceededDetails": { + "Result": { + "Payload": "\"Branch 3 success\"" + }, + "RetryDetails": {} + } + }, + { + "EventType": "StepSucceeded", + "SubType": "Step", + "EventId": 17, + "Id": "0f42756e5788f9b0", + "Name": "branch-5", + "EventTimestamp": "2025-12-10T00:12:07.586Z", + "ParentId": "12426c956d1bc501", + "StepSucceededDetails": { + "Result": { + "Payload": "\"Branch 5 success\"" + }, + "RetryDetails": {} + } + }, + { + "EventType": "ContextFailed", + "SubType": "ParallelBranch", + "EventId": 18, + "Id": "98c6f2c2287f4c73", + "Name": "parallel-branch-1", + "EventTimestamp": "2025-12-10T00:12:07.590Z", + "ParentId": "c4ca4238a0b92382", + "ContextFailedDetails": { + "Error": { + "Payload": { + "ErrorType": "StepError", + "ErrorMessage": "Branch 2 failed" + } + } + } + }, + { + "EventType": "ContextFailed", + "SubType": "ParallelBranch", + "EventId": 19, + "Id": "3a170a9fe4f47efa", + "Name": "parallel-branch-3", + "EventTimestamp": "2025-12-10T00:12:07.590Z", + "ParentId": "c4ca4238a0b92382", + "ContextFailedDetails": { + "Error": { + "Payload": { + "ErrorType": "StepError", + "ErrorMessage": "Branch 4 failed" + } + } + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "ParallelBranch", + "EventId": 20, + "Id": "ea66c06c1e1c05fa", + "Name": "parallel-branch-0", + "EventTimestamp": "2025-12-10T00:12:07.590Z", + "ParentId": "c4ca4238a0b92382", + "ContextSucceededDetails": { + "Result": { + "Payload": "\"Branch 1 success\"" + } + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "ParallelBranch", + "EventId": 21, + "Id": "13cee27a2bd93915", + "Name": "parallel-branch-2", + "EventTimestamp": "2025-12-10T00:12:07.590Z", + "ParentId": "c4ca4238a0b92382", + "ContextSucceededDetails": { + "Result": { + "Payload": "\"Branch 3 success\"" + } + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "ParallelBranch", + "EventId": 22, + "Id": "12426c956d1bc501", + "Name": "parallel-branch-4", + "EventTimestamp": "2025-12-10T00:12:07.590Z", + "ParentId": "c4ca4238a0b92382", + "ContextSucceededDetails": { + "Result": { + "Payload": "\"Branch 5 success\"" + } + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "Parallel", + "EventId": 23, + "Id": "c4ca4238a0b92382", + "Name": "failure-count-branches", + "EventTimestamp": "2025-12-10T00:12:07.590Z", + "ContextSucceededDetails": { + "Result": { + "Payload": "{\"all\":[{\"result\":\"Branch 1 success\",\"index\":0,\"status\":\"SUCCEEDED\"},{\"error\":{\"cause\":{\"cause\":{\"name\":\"StepError\"},\"name\":\"StepError\",\"errorType\":\"StepError\"},\"name\":\"ChildContextError\",\"errorType\":\"ChildContextError\"},\"index\":1,\"status\":\"FAILED\"},{\"result\":\"Branch 3 success\",\"index\":2,\"status\":\"SUCCEEDED\"},{\"error\":{\"cause\":{\"cause\":{\"name\":\"StepError\"},\"name\":\"StepError\",\"errorType\":\"StepError\"},\"name\":\"ChildContextError\",\"errorType\":\"ChildContextError\"},\"index\":3,\"status\":\"FAILED\"},{\"result\":\"Branch 5 success\",\"index\":4,\"status\":\"SUCCEEDED\"}],\"completionReason\":\"ALL_COMPLETED\"}" + } + } + }, + { + "EventType": "WaitStarted", + "SubType": "Wait", + "EventId": 24, + "Id": "c81e728d9d4c2f63", + "EventTimestamp": "2025-12-10T00:12:07.592Z", + "WaitStartedDetails": { + "Duration": 1, + "ScheduledEndTimestamp": "2025-12-10T00:12:08.592Z" + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 25, + "EventTimestamp": "2025-12-10T00:12:07.645Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:12:07.576Z", + "EndTimestamp": "2025-12-10T00:12:07.644Z", + "Error": {}, + "RequestId": "61beea7b-4b3e-42e8-af17-5d9822fdf5e9" + } + }, + { + "EventType": "WaitSucceeded", + "SubType": "Wait", + "EventId": 26, + "Id": "c81e728d9d4c2f63", + "EventTimestamp": "2025-12-10T00:12:08.592Z", + "WaitSucceededDetails": { + "Duration": 1 + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 27, + "EventTimestamp": "2025-12-10T00:12:08.595Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:12:08.592Z", + "EndTimestamp": "2025-12-10T00:12:08.595Z", + "Error": {}, + "RequestId": "255263b5-25e5-4d2d-9eef-419b97adf1bf" + } + }, + { + "EventType": "ExecutionSucceeded", + "EventId": 28, + "Id": "2d9ce8ae-d485-4ca9-a1ef-0e11acb56f3d", + "EventTimestamp": "2025-12-10T00:12:08.595Z", + "ExecutionSucceededDetails": { + "Result": { + "Payload": "{\"successCount\":3,\"failureCount\":2,\"totalCount\":5,\"completionReason\":\"ALL_COMPLETED\",\"hasFailure\":true}" + } + } + } +] diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/tolerated-failure-count/parallel-tolerated-failure-count.test.ts b/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/tolerated-failure-count/parallel-tolerated-failure-count.test.ts index 5c5e27cc..25044b20 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/tolerated-failure-count/parallel-tolerated-failure-count.test.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/tolerated-failure-count/parallel-tolerated-failure-count.test.ts @@ -4,7 +4,7 @@ import { OperationStatus } from "@aws/durable-execution-sdk-js-testing"; createTests({ handler, - tests: (runner) => { + tests: (runner, { assertEventSignatures }) => { it("should complete when failure tolerance is reached", async () => { const execution = await runner.run(); const result = execution.getResult() as any; @@ -26,6 +26,8 @@ createTests({ ].forEach(({ name, status }) => { expect(runner.getOperation(name)?.getStatus()).toBe(status); }); + + assertEventSignatures(execution); }); }, }); diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/tolerated-failure-percentage/parallel-tolerated-failure-percentage.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/tolerated-failure-percentage/parallel-tolerated-failure-percentage.history.json new file mode 100644 index 00000000..de58e53c --- /dev/null +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/tolerated-failure-percentage/parallel-tolerated-failure-percentage.history.json @@ -0,0 +1,350 @@ +[ + { + "EventType": "ExecutionStarted", + "EventId": 1, + "Id": "b70c416c-7ad8-4763-9d2e-47cc0a808e9c", + "EventTimestamp": "2025-12-10T00:12:07.533Z", + "ExecutionStartedDetails": { + "Input": { + "Payload": "{}" + } + } + }, + { + "EventType": "ContextStarted", + "SubType": "Parallel", + "EventId": 2, + "Id": "c4ca4238a0b92382", + "Name": "failure-percentage-branches", + "EventTimestamp": "2025-12-10T00:12:07.542Z", + "ContextStartedDetails": {} + }, + { + "EventType": "ContextStarted", + "SubType": "ParallelBranch", + "EventId": 3, + "Id": "ea66c06c1e1c05fa", + "Name": "parallel-branch-0", + "EventTimestamp": "2025-12-10T00:12:07.542Z", + "ParentId": "c4ca4238a0b92382", + "ContextStartedDetails": {} + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 4, + "Id": "2f221a18eb863803", + "Name": "branch-1", + "EventTimestamp": "2025-12-10T00:12:07.542Z", + "ParentId": "ea66c06c1e1c05fa", + "StepStartedDetails": {} + }, + { + "EventType": "ContextStarted", + "SubType": "ParallelBranch", + "EventId": 5, + "Id": "98c6f2c2287f4c73", + "Name": "parallel-branch-1", + "EventTimestamp": "2025-12-10T00:12:07.542Z", + "ParentId": "c4ca4238a0b92382", + "ContextStartedDetails": {} + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 6, + "Id": "6151f5ab282d90e4", + "Name": "branch-2", + "EventTimestamp": "2025-12-10T00:12:07.542Z", + "ParentId": "98c6f2c2287f4c73", + "StepStartedDetails": {} + }, + { + "EventType": "ContextStarted", + "SubType": "ParallelBranch", + "EventId": 7, + "Id": "13cee27a2bd93915", + "Name": "parallel-branch-2", + "EventTimestamp": "2025-12-10T00:12:07.542Z", + "ParentId": "c4ca4238a0b92382", + "ContextStartedDetails": {} + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 8, + "Id": "b425e0c75591aa8f", + "Name": "branch-3", + "EventTimestamp": "2025-12-10T00:12:07.542Z", + "ParentId": "13cee27a2bd93915", + "StepStartedDetails": {} + }, + { + "EventType": "ContextStarted", + "SubType": "ParallelBranch", + "EventId": 9, + "Id": "3a170a9fe4f47efa", + "Name": "parallel-branch-3", + "EventTimestamp": "2025-12-10T00:12:07.542Z", + "ParentId": "c4ca4238a0b92382", + "ContextStartedDetails": {} + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 10, + "Id": "a4e1cd317d54f087", + "Name": "branch-4", + "EventTimestamp": "2025-12-10T00:12:07.542Z", + "ParentId": "3a170a9fe4f47efa", + "StepStartedDetails": {} + }, + { + "EventType": "ContextStarted", + "SubType": "ParallelBranch", + "EventId": 11, + "Id": "12426c956d1bc501", + "Name": "parallel-branch-4", + "EventTimestamp": "2025-12-10T00:12:07.542Z", + "ParentId": "c4ca4238a0b92382", + "ContextStartedDetails": {} + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 12, + "Id": "0f42756e5788f9b0", + "Name": "branch-5", + "EventTimestamp": "2025-12-10T00:12:07.542Z", + "ParentId": "12426c956d1bc501", + "StepStartedDetails": {} + }, + { + "EventType": "StepFailed", + "SubType": "Step", + "EventId": 13, + "Id": "6151f5ab282d90e4", + "Name": "branch-2", + "EventTimestamp": "2025-12-10T00:12:07.542Z", + "ParentId": "98c6f2c2287f4c73", + "StepFailedDetails": { + "Error": { + "Payload": { + "ErrorMessage": "Branch 2 failed", + "ErrorType": "Error" + } + }, + "RetryDetails": { + "CurrentAttempt": 1 + } + } + }, + { + "EventType": "StepFailed", + "SubType": "Step", + "EventId": 14, + "Id": "a4e1cd317d54f087", + "Name": "branch-4", + "EventTimestamp": "2025-12-10T00:12:07.542Z", + "ParentId": "3a170a9fe4f47efa", + "StepFailedDetails": { + "Error": { + "Payload": { + "ErrorMessage": "Branch 4 failed", + "ErrorType": "Error" + } + }, + "RetryDetails": { + "CurrentAttempt": 1 + } + } + }, + { + "EventType": "StepSucceeded", + "SubType": "Step", + "EventId": 15, + "Id": "2f221a18eb863803", + "Name": "branch-1", + "EventTimestamp": "2025-12-10T00:12:07.542Z", + "ParentId": "ea66c06c1e1c05fa", + "StepSucceededDetails": { + "Result": { + "Payload": "\"Branch 1 success\"" + }, + "RetryDetails": {} + } + }, + { + "EventType": "StepSucceeded", + "SubType": "Step", + "EventId": 16, + "Id": "b425e0c75591aa8f", + "Name": "branch-3", + "EventTimestamp": "2025-12-10T00:12:07.542Z", + "ParentId": "13cee27a2bd93915", + "StepSucceededDetails": { + "Result": { + "Payload": "\"Branch 3 success\"" + }, + "RetryDetails": {} + } + }, + { + "EventType": "StepSucceeded", + "SubType": "Step", + "EventId": 17, + "Id": "0f42756e5788f9b0", + "Name": "branch-5", + "EventTimestamp": "2025-12-10T00:12:07.542Z", + "ParentId": "12426c956d1bc501", + "StepSucceededDetails": { + "Result": { + "Payload": "\"Branch 5 success\"" + }, + "RetryDetails": {} + } + }, + { + "EventType": "ContextFailed", + "SubType": "ParallelBranch", + "EventId": 18, + "Id": "98c6f2c2287f4c73", + "Name": "parallel-branch-1", + "EventTimestamp": "2025-12-10T00:12:07.547Z", + "ParentId": "c4ca4238a0b92382", + "ContextFailedDetails": { + "Error": { + "Payload": { + "ErrorType": "StepError", + "ErrorMessage": "Branch 2 failed" + } + } + } + }, + { + "EventType": "ContextFailed", + "SubType": "ParallelBranch", + "EventId": 19, + "Id": "3a170a9fe4f47efa", + "Name": "parallel-branch-3", + "EventTimestamp": "2025-12-10T00:12:07.547Z", + "ParentId": "c4ca4238a0b92382", + "ContextFailedDetails": { + "Error": { + "Payload": { + "ErrorType": "StepError", + "ErrorMessage": "Branch 4 failed" + } + } + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "ParallelBranch", + "EventId": 20, + "Id": "ea66c06c1e1c05fa", + "Name": "parallel-branch-0", + "EventTimestamp": "2025-12-10T00:12:07.547Z", + "ParentId": "c4ca4238a0b92382", + "ContextSucceededDetails": { + "Result": { + "Payload": "\"Branch 1 success\"" + } + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "ParallelBranch", + "EventId": 21, + "Id": "13cee27a2bd93915", + "Name": "parallel-branch-2", + "EventTimestamp": "2025-12-10T00:12:07.547Z", + "ParentId": "c4ca4238a0b92382", + "ContextSucceededDetails": { + "Result": { + "Payload": "\"Branch 3 success\"" + } + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "ParallelBranch", + "EventId": 22, + "Id": "12426c956d1bc501", + "Name": "parallel-branch-4", + "EventTimestamp": "2025-12-10T00:12:07.547Z", + "ParentId": "c4ca4238a0b92382", + "ContextSucceededDetails": { + "Result": { + "Payload": "\"Branch 5 success\"" + } + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "Parallel", + "EventId": 23, + "Id": "c4ca4238a0b92382", + "Name": "failure-percentage-branches", + "EventTimestamp": "2025-12-10T00:12:07.547Z", + "ContextSucceededDetails": { + "Result": { + "Payload": "{\"all\":[{\"result\":\"Branch 1 success\",\"index\":0,\"status\":\"SUCCEEDED\"},{\"error\":{\"cause\":{\"cause\":{\"name\":\"StepError\"},\"name\":\"StepError\",\"errorType\":\"StepError\"},\"name\":\"ChildContextError\",\"errorType\":\"ChildContextError\"},\"index\":1,\"status\":\"FAILED\"},{\"result\":\"Branch 3 success\",\"index\":2,\"status\":\"SUCCEEDED\"},{\"error\":{\"cause\":{\"cause\":{\"name\":\"StepError\"},\"name\":\"StepError\",\"errorType\":\"StepError\"},\"name\":\"ChildContextError\",\"errorType\":\"ChildContextError\"},\"index\":3,\"status\":\"FAILED\"},{\"result\":\"Branch 5 success\",\"index\":4,\"status\":\"SUCCEEDED\"}],\"completionReason\":\"ALL_COMPLETED\"}" + } + } + }, + { + "EventType": "WaitStarted", + "SubType": "Wait", + "EventId": 24, + "Id": "c81e728d9d4c2f63", + "EventTimestamp": "2025-12-10T00:12:07.550Z", + "WaitStartedDetails": { + "Duration": 1, + "ScheduledEndTimestamp": "2025-12-10T00:12:08.550Z" + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 25, + "EventTimestamp": "2025-12-10T00:12:07.602Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:12:07.533Z", + "EndTimestamp": "2025-12-10T00:12:07.602Z", + "Error": {}, + "RequestId": "8db03422-62dc-4df0-9b32-bac605fd0a16" + } + }, + { + "EventType": "WaitSucceeded", + "SubType": "Wait", + "EventId": 26, + "Id": "c81e728d9d4c2f63", + "EventTimestamp": "2025-12-10T00:12:08.548Z", + "WaitSucceededDetails": { + "Duration": 1 + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 27, + "EventTimestamp": "2025-12-10T00:12:08.550Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:12:08.549Z", + "EndTimestamp": "2025-12-10T00:12:08.550Z", + "Error": {}, + "RequestId": "4fdd45f2-3c4a-4406-b058-afe09d83f950" + } + }, + { + "EventType": "ExecutionSucceeded", + "EventId": 28, + "Id": "b70c416c-7ad8-4763-9d2e-47cc0a808e9c", + "EventTimestamp": "2025-12-10T00:12:08.550Z", + "ExecutionSucceededDetails": { + "Result": { + "Payload": "{\"successCount\":3,\"failureCount\":2,\"totalCount\":5,\"failurePercentage\":40,\"completionReason\":\"ALL_COMPLETED\"}" + } + } + } +] diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/tolerated-failure-percentage/parallel-tolerated-failure-percentage.test.ts b/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/tolerated-failure-percentage/parallel-tolerated-failure-percentage.test.ts index faaa0d94..5c3e7926 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/tolerated-failure-percentage/parallel-tolerated-failure-percentage.test.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/tolerated-failure-percentage/parallel-tolerated-failure-percentage.test.ts @@ -4,7 +4,7 @@ import { OperationStatus } from "@aws/durable-execution-sdk-js-testing"; createTests({ handler, - tests: (runner) => { + tests: (runner, { assertEventSignatures }) => { it("should complete with acceptable failure percentage", async () => { const execution = await runner.run(); @@ -27,6 +27,8 @@ createTests({ ].forEach(({ name, status }) => { expect(runner.getOperation(name)?.getStatus()).toBe(status); }); + + assertEventSignatures(execution); }); }, }); diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/serde/basic/serde-basic.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/serde/basic/serde-basic.history.json new file mode 100644 index 00000000..2197517d --- /dev/null +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/serde/basic/serde-basic.history.json @@ -0,0 +1,113 @@ +[ + { + "EventType": "ExecutionStarted", + "EventId": 1, + "Id": "2e049fba-40e4-43c6-b8c3-91f610c45b7c", + "EventTimestamp": "2025-12-10T00:12:07.729Z", + "ExecutionStartedDetails": { + "Input": { + "Payload": "{\"firstName\":\"John\",\"lastName\":\"Doe\",\"email\":\"john.doe@example.com\"}" + } + } + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 2, + "Id": "c4ca4238a0b92382", + "Name": "create-user", + "EventTimestamp": "2025-12-10T00:12:07.738Z", + "StepStartedDetails": {} + }, + { + "EventType": "StepSucceeded", + "SubType": "Step", + "EventId": 3, + "Id": "c4ca4238a0b92382", + "Name": "create-user", + "EventTimestamp": "2025-12-10T00:12:07.738Z", + "StepSucceededDetails": { + "Result": { + "Payload": "{\"firstName\":\"John\",\"lastName\":\"Doe\",\"email\":\"john.doe@example.com\"}" + }, + "RetryDetails": {} + } + }, + { + "EventType": "WaitStarted", + "SubType": "Wait", + "EventId": 4, + "Id": "c81e728d9d4c2f63", + "EventTimestamp": "2025-12-10T00:12:07.740Z", + "WaitStartedDetails": { + "Duration": 1, + "ScheduledEndTimestamp": "2025-12-10T00:12:08.740Z" + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 5, + "EventTimestamp": "2025-12-10T00:12:07.792Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:12:07.729Z", + "EndTimestamp": "2025-12-10T00:12:07.791Z", + "Error": {}, + "RequestId": "5dd0479a-bc9a-463e-8096-a7d21d35374a" + } + }, + { + "EventType": "WaitSucceeded", + "SubType": "Wait", + "EventId": 6, + "Id": "c81e728d9d4c2f63", + "EventTimestamp": "2025-12-10T00:12:08.742Z", + "WaitSucceededDetails": { + "Duration": 1 + } + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 7, + "Id": "eccbc87e4b5ce2fe", + "Name": "greet-user", + "EventTimestamp": "2025-12-10T00:12:08.744Z", + "StepStartedDetails": {} + }, + { + "EventType": "StepSucceeded", + "SubType": "Step", + "EventId": 8, + "Id": "eccbc87e4b5ce2fe", + "Name": "greet-user", + "EventTimestamp": "2025-12-10T00:12:08.744Z", + "StepSucceededDetails": { + "Result": { + "Payload": "\"Hello, I'm John Doe. My email is john.doe@example.com\"" + }, + "RetryDetails": {} + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 9, + "EventTimestamp": "2025-12-10T00:12:08.745Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:12:08.742Z", + "EndTimestamp": "2025-12-10T00:12:08.745Z", + "Error": {}, + "RequestId": "23ab2d54-6123-4a67-b435-07237a2c6a1d" + } + }, + { + "EventType": "ExecutionSucceeded", + "EventId": 10, + "Id": "2e049fba-40e4-43c6-b8c3-91f610c45b7c", + "EventTimestamp": "2025-12-10T00:12:08.745Z", + "ExecutionSucceededDetails": { + "Result": { + "Payload": "{\"user\":{\"firstName\":\"John\",\"lastName\":\"Doe\",\"email\":\"john.doe@example.com\"},\"greeting\":\"Hello, I'm John Doe. My email is john.doe@example.com\"}" + } + } + } +] diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/serde/basic/serde-basic.test.ts b/packages/aws-durable-execution-sdk-js-examples/src/examples/serde/basic/serde-basic.test.ts index f4e15e0a..e75fa3fc 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/serde/basic/serde-basic.test.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/serde/basic/serde-basic.test.ts @@ -7,7 +7,7 @@ import { handler } from "./serde-basic"; createTests({ handler, - tests: (runner) => { + tests: (runner, { assertEventSignatures }) => { it("should preserve User class methods across replay with createClassSerdes", async () => { const execution = await runner.run({ payload: { @@ -57,6 +57,8 @@ createTests({ expect(result.greeting).toBe( "Hello, I'm John Doe. My email is john.doe@example.com", ); + + assertEventSignatures(execution); }); it("should work with different user data", async () => { @@ -82,6 +84,8 @@ createTests({ // This proves createClassSerdes successfully preserved the User class methods // during deserialization after the wait/replay + + assertEventSignatures(execution); }); }, }); diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/anonymous/wait-for-callback-anonymous.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/anonymous/wait-for-callback-anonymous.history.json new file mode 100644 index 00000000..8aaf5a96 --- /dev/null +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/anonymous/wait-for-callback-anonymous.history.json @@ -0,0 +1,112 @@ +[ + { + "EventType": "ExecutionStarted", + "EventId": 1, + "Id": "c954be46-0465-4285-86db-4cf750e9b3bb", + "EventTimestamp": "2025-12-10T00:15:09.611Z", + "ExecutionStartedDetails": { + "Input": { + "Payload": "{}" + } + } + }, + { + "EventType": "ContextStarted", + "SubType": "WaitForCallback", + "EventId": 2, + "Id": "c4ca4238a0b92382", + "EventTimestamp": "2025-12-10T00:15:09.648Z", + "ContextStartedDetails": {} + }, + { + "EventType": "CallbackStarted", + "SubType": "Callback", + "EventId": 3, + "Id": "ea66c06c1e1c05fa", + "EventTimestamp": "2025-12-10T00:15:09.648Z", + "ParentId": "c4ca4238a0b92382", + "CallbackStartedDetails": { + "CallbackId": "eyJleGVjdXRpb25JZCI6ImRiOGE5OTIwLTJjZWUtNDE0YS1hOWFjLWM0NzY0YWQzZWRkNiIsIm9wZXJhdGlvbklkIjoiZWE2NmMwNmMxZTFjMDVmYSIsInRva2VuIjoiZGJhYWZkZmEtYjEwOS00M2VkLTljNGEtMjkzMmRlOWVlOTI2In0=", + "Input": {} + } + }, + { + "EventType": "CallbackSucceeded", + "SubType": "Callback", + "EventId": 4, + "Id": "ea66c06c1e1c05fa", + "EventTimestamp": "2025-12-10T00:15:09.650Z", + "ParentId": "c4ca4238a0b92382", + "CallbackSucceededDetails": { + "Result": { + "Payload": "{\"data\":\"callback_completed\"}" + } + } + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 5, + "Id": "98c6f2c2287f4c73", + "EventTimestamp": "2025-12-10T00:15:09.668Z", + "ParentId": "c4ca4238a0b92382", + "StepStartedDetails": {} + }, + { + "EventType": "StepSucceeded", + "SubType": "Step", + "EventId": 6, + "Id": "98c6f2c2287f4c73", + "EventTimestamp": "2025-12-10T00:15:10.717Z", + "ParentId": "c4ca4238a0b92382", + "StepSucceededDetails": { + "Result": {}, + "RetryDetails": {} + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 7, + "EventTimestamp": "2025-12-10T00:15:10.779Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:15:09.611Z", + "EndTimestamp": "2025-12-10T00:15:10.779Z", + "Error": {}, + "RequestId": "6923bcad-b4d5-488f-b094-b2f4de03ae93" + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "WaitForCallback", + "EventId": 8, + "Id": "c4ca4238a0b92382", + "EventTimestamp": "2025-12-10T00:15:10.828Z", + "ContextSucceededDetails": { + "Result": { + "Payload": "\"{\\\"data\\\":\\\"callback_completed\\\"}\"" + } + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 9, + "EventTimestamp": "2025-12-10T00:15:10.831Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:15:10.803Z", + "EndTimestamp": "2025-12-10T00:15:10.831Z", + "Error": {}, + "RequestId": "e0bbc1ff-2bc5-4b36-a891-c2a5fb9f5aff" + } + }, + { + "EventType": "ExecutionSucceeded", + "EventId": 10, + "Id": "c954be46-0465-4285-86db-4cf750e9b3bb", + "EventTimestamp": "2025-12-10T00:15:10.832Z", + "ExecutionSucceededDetails": { + "Result": { + "Payload": "{\"callbackResult\":\"{\\\"data\\\":\\\"callback_completed\\\"}\",\"completed\":true}" + } + } + } +] diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/anonymous/wait-for-callback-anonymous.test.ts b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/anonymous/wait-for-callback-anonymous.test.ts index 7367155f..cbd83977 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/anonymous/wait-for-callback-anonymous.test.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/anonymous/wait-for-callback-anonymous.test.ts @@ -8,7 +8,7 @@ import { createTests } from "../../../utils/test-helper"; createTests({ handler, invocationType: InvocationType.Event, - tests: (runner) => { + tests: (runner, { assertEventSignatures }) => { it("should handle basic waitForCallback with anonymous submitter", async () => { // Start the execution (this will pause at the callback) const executionPromise = runner.run(); @@ -33,6 +33,8 @@ createTests({ // Verify operations were tracked expect(result.getOperations().length).toBeGreaterThan(0); + + assertEventSignatures(result); }); }, }); diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/basic/wait-for-callback-failure.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/basic/wait-for-callback-failure.history.json new file mode 100644 index 00000000..726e660e --- /dev/null +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/basic/wait-for-callback-failure.history.json @@ -0,0 +1,128 @@ +[ + { + "EventType": "ExecutionStarted", + "EventId": 1, + "Id": "9c5860c6-b007-4679-aa02-960bfb103fa3", + "EventTimestamp": "2025-12-10T00:15:08.871Z", + "ExecutionStartedDetails": { + "Input": { + "Payload": "{}" + } + } + }, + { + "EventType": "ContextStarted", + "SubType": "WaitForCallback", + "EventId": 2, + "Id": "c4ca4238a0b92382", + "Name": "my callback function", + "EventTimestamp": "2025-12-10T00:15:08.912Z", + "ContextStartedDetails": {} + }, + { + "EventType": "CallbackStarted", + "SubType": "Callback", + "EventId": 3, + "Id": "ea66c06c1e1c05fa", + "EventTimestamp": "2025-12-10T00:15:08.912Z", + "ParentId": "c4ca4238a0b92382", + "CallbackStartedDetails": { + "CallbackId": "eyJleGVjdXRpb25JZCI6ImJlZDZjM2FmLTdiM2QtNDY1NS1hZDhhLTQ4ZjQ5MjA0YzBhZiIsIm9wZXJhdGlvbklkIjoiZWE2NmMwNmMxZTFjMDVmYSIsInRva2VuIjoiYTI5YTlhNWUtYTVlYS00MjMxLWJhYzUtOTZhMDM5NjMyYTFkIn0=", + "Timeout": 5, + "Input": {} + } + }, + { + "EventType": "CallbackFailed", + "SubType": "Callback", + "EventId": 4, + "Id": "ea66c06c1e1c05fa", + "EventTimestamp": "2025-12-10T00:15:08.913Z", + "ParentId": "c4ca4238a0b92382", + "CallbackFailedDetails": { + "Error": { + "Payload": { + "ErrorMessage": "ERROR" + } + } + } + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 5, + "Id": "98c6f2c2287f4c73", + "EventTimestamp": "2025-12-10T00:15:08.933Z", + "ParentId": "c4ca4238a0b92382", + "StepStartedDetails": {} + }, + { + "EventType": "StepSucceeded", + "SubType": "Step", + "EventId": 6, + "Id": "98c6f2c2287f4c73", + "EventTimestamp": "2025-12-10T00:15:08.933Z", + "ParentId": "c4ca4238a0b92382", + "StepSucceededDetails": { + "Result": {}, + "RetryDetails": {} + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 7, + "EventTimestamp": "2025-12-10T00:15:08.994Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:15:08.871Z", + "EndTimestamp": "2025-12-10T00:15:08.994Z", + "Error": {}, + "RequestId": "361449f1-38f7-4f4f-a4f1-880d7a0d3afb" + } + }, + { + "EventType": "ContextFailed", + "SubType": "WaitForCallback", + "EventId": 8, + "Id": "c4ca4238a0b92382", + "Name": "my callback function", + "EventTimestamp": "2025-12-10T00:15:09.036Z", + "ContextFailedDetails": { + "Error": { + "Payload": { + "ErrorType": "CallbackError", + "ErrorMessage": "ERROR" + } + } + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 9, + "EventTimestamp": "2025-12-10T00:15:09.037Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:15:09.015Z", + "EndTimestamp": "2025-12-10T00:15:09.037Z", + "Error": { + "Payload": { + "ErrorType": "ChildContextError", + "ErrorMessage": "ERROR" + } + }, + "RequestId": "d8e44864-d425-4631-8cfa-ef8f3a70747f" + } + }, + { + "EventType": "ExecutionFailed", + "EventId": 10, + "Id": "9c5860c6-b007-4679-aa02-960bfb103fa3", + "EventTimestamp": "2025-12-10T00:15:09.037Z", + "ExecutionFailedDetails": { + "Error": { + "Payload": { + "ErrorType": "ChildContextError", + "ErrorMessage": "ERROR" + } + } + } + } +] diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/basic/wait-for-callback-success.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/basic/wait-for-callback-success.history.json new file mode 100644 index 00000000..e70c7ef7 --- /dev/null +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/basic/wait-for-callback-success.history.json @@ -0,0 +1,115 @@ +[ + { + "EventType": "ExecutionStarted", + "EventId": 1, + "Id": "e1dd2330-e452-4524-8f4f-2576431ff6a3", + "EventTimestamp": "2025-12-10T00:15:08.596Z", + "ExecutionStartedDetails": { + "Input": { + "Payload": "{}" + } + } + }, + { + "EventType": "ContextStarted", + "SubType": "WaitForCallback", + "EventId": 2, + "Id": "c4ca4238a0b92382", + "Name": "my callback function", + "EventTimestamp": "2025-12-10T00:15:08.637Z", + "ContextStartedDetails": {} + }, + { + "EventType": "CallbackStarted", + "SubType": "Callback", + "EventId": 3, + "Id": "ea66c06c1e1c05fa", + "EventTimestamp": "2025-12-10T00:15:08.638Z", + "ParentId": "c4ca4238a0b92382", + "CallbackStartedDetails": { + "CallbackId": "eyJleGVjdXRpb25JZCI6ImQwZmNjNTQ2LTg1YTItNGZjMS05OGEwLWM3YzdmYWRkZmZhOSIsIm9wZXJhdGlvbklkIjoiZWE2NmMwNmMxZTFjMDVmYSIsInRva2VuIjoiYjE3MjkwODktOTc0YS00NTVlLWIzYmYtODJiOWUwZGFmYWMzIn0=", + "Timeout": 5, + "Input": {} + } + }, + { + "EventType": "CallbackSucceeded", + "SubType": "Callback", + "EventId": 4, + "Id": "ea66c06c1e1c05fa", + "EventTimestamp": "2025-12-10T00:15:08.640Z", + "ParentId": "c4ca4238a0b92382", + "CallbackSucceededDetails": { + "Result": { + "Payload": "succeeded" + } + } + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 5, + "Id": "98c6f2c2287f4c73", + "EventTimestamp": "2025-12-10T00:15:08.658Z", + "ParentId": "c4ca4238a0b92382", + "StepStartedDetails": {} + }, + { + "EventType": "StepSucceeded", + "SubType": "Step", + "EventId": 6, + "Id": "98c6f2c2287f4c73", + "EventTimestamp": "2025-12-10T00:15:08.658Z", + "ParentId": "c4ca4238a0b92382", + "StepSucceededDetails": { + "Result": {}, + "RetryDetails": {} + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 7, + "EventTimestamp": "2025-12-10T00:15:08.720Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:15:08.596Z", + "EndTimestamp": "2025-12-10T00:15:08.720Z", + "Error": {}, + "RequestId": "6d705aa0-f050-4028-b679-22cbba2d8f23" + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "WaitForCallback", + "EventId": 8, + "Id": "c4ca4238a0b92382", + "Name": "my callback function", + "EventTimestamp": "2025-12-10T00:15:08.763Z", + "ContextSucceededDetails": { + "Result": { + "Payload": "\"succeeded\"" + } + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 9, + "EventTimestamp": "2025-12-10T00:15:08.764Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:15:08.741Z", + "EndTimestamp": "2025-12-10T00:15:08.764Z", + "Error": {}, + "RequestId": "bf3f4e39-e7a4-47d6-8414-1d0a1d94640b" + } + }, + { + "EventType": "ExecutionSucceeded", + "EventId": 10, + "Id": "e1dd2330-e452-4524-8f4f-2576431ff6a3", + "EventTimestamp": "2025-12-10T00:15:08.764Z", + "ExecutionSucceededDetails": { + "Result": { + "Payload": "\"succeeded\"" + } + } + } +] diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/basic/wait-for-callback.test.ts b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/basic/wait-for-callback.test.ts index 41709a84..f412e7e6 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/basic/wait-for-callback.test.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/basic/wait-for-callback.test.ts @@ -8,7 +8,7 @@ import { createTests } from "../../../utils/test-helper"; createTests({ handler, invocationType: InvocationType.Event, - tests: (runner, { isCloud }) => { + tests: (runner, { isCloud, assertEventSignatures }) => { it("function completes when callback succeeds - happy case", async () => { const executionPromise = runner.run(); @@ -19,6 +19,8 @@ createTests({ const execution = await executionPromise; expect(execution.getResult()).toEqual("succeeded"); + + assertEventSignatures(execution, "success"); }); it("function completes when callback fails - happy case", async () => { @@ -31,6 +33,8 @@ createTests({ const execution = await executionPromise; expect(execution.getError()).toBeDefined(); + + assertEventSignatures(execution, "failure"); }); // TODO: fix testing lib local runner time scaling to handle timeouts better @@ -39,6 +43,8 @@ createTests({ const execution = await runner.run(); expect(execution.getError()).toBeDefined(); + + assertEventSignatures(execution, "timed-out"); }); } }, diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/child-context/wait-for-callback-child-context.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/child-context/wait-for-callback-child-context.history.json new file mode 100644 index 00000000..9367686e --- /dev/null +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/child-context/wait-for-callback-child-context.history.json @@ -0,0 +1,253 @@ +[ + { + "EventType": "ExecutionStarted", + "EventId": 1, + "Id": "e39cc4cc-0f5b-4a91-8775-38b3a26c2f00", + "EventTimestamp": "2025-12-10T00:15:09.667Z", + "ExecutionStartedDetails": { + "Input": { + "Payload": "{\"test\":\"child-context-callbacks\"}" + } + } + }, + { + "EventType": "ContextStarted", + "SubType": "WaitForCallback", + "EventId": 2, + "Id": "c4ca4238a0b92382", + "Name": "parent-callback-op", + "EventTimestamp": "2025-12-10T00:15:09.704Z", + "ContextStartedDetails": {} + }, + { + "EventType": "CallbackStarted", + "SubType": "Callback", + "EventId": 3, + "Id": "ea66c06c1e1c05fa", + "EventTimestamp": "2025-12-10T00:15:09.704Z", + "ParentId": "c4ca4238a0b92382", + "CallbackStartedDetails": { + "CallbackId": "eyJleGVjdXRpb25JZCI6IjZkMzJlYmJmLTliM2EtNDc2Ni05YTM2LTZlZDBlMzk5OTM4YSIsIm9wZXJhdGlvbklkIjoiZWE2NmMwNmMxZTFjMDVmYSIsInRva2VuIjoiZDJhMTUzMmEtYWVhMy00Y2M4LTk3MjQtNmU4N2QxZTRkNDNhIn0=", + "Input": {} + } + }, + { + "EventType": "CallbackSucceeded", + "SubType": "Callback", + "EventId": 4, + "Id": "ea66c06c1e1c05fa", + "EventTimestamp": "2025-12-10T00:15:09.705Z", + "ParentId": "c4ca4238a0b92382", + "CallbackSucceededDetails": { + "Result": { + "Payload": "{\"parentData\":\"parent-completed\"}" + } + } + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 5, + "Id": "98c6f2c2287f4c73", + "EventTimestamp": "2025-12-10T00:15:09.723Z", + "ParentId": "c4ca4238a0b92382", + "StepStartedDetails": {} + }, + { + "EventType": "StepSucceeded", + "SubType": "Step", + "EventId": 6, + "Id": "98c6f2c2287f4c73", + "EventTimestamp": "2025-12-10T00:15:09.723Z", + "ParentId": "c4ca4238a0b92382", + "StepSucceededDetails": { + "Result": {}, + "RetryDetails": {} + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 7, + "EventTimestamp": "2025-12-10T00:15:09.785Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:15:09.667Z", + "EndTimestamp": "2025-12-10T00:15:09.785Z", + "Error": {}, + "RequestId": "b66163d6-6deb-4777-a62d-82f20e7de3f0" + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "WaitForCallback", + "EventId": 8, + "Id": "c4ca4238a0b92382", + "Name": "parent-callback-op", + "EventTimestamp": "2025-12-10T00:15:09.828Z", + "ContextSucceededDetails": { + "Result": { + "Payload": "\"{\\\"parentData\\\":\\\"parent-completed\\\"}\"" + } + } + }, + { + "EventType": "ContextStarted", + "SubType": "RunInChildContext", + "EventId": 9, + "Id": "c81e728d9d4c2f63", + "Name": "child-context-with-callback", + "EventTimestamp": "2025-12-10T00:15:09.828Z", + "ContextStartedDetails": {} + }, + { + "EventType": "WaitStarted", + "SubType": "Wait", + "EventId": 10, + "Id": "8fbdbf5573b18fae", + "Name": "child-wait", + "EventTimestamp": "2025-12-10T00:15:09.828Z", + "ParentId": "c81e728d9d4c2f63", + "WaitStartedDetails": { + "Duration": 1, + "ScheduledEndTimestamp": "2025-12-10T00:15:10.828Z" + } + }, + { + "EventType": "WaitSucceeded", + "SubType": "Wait", + "EventId": 11, + "Id": "8fbdbf5573b18fae", + "Name": "child-wait", + "EventTimestamp": "2025-12-10T00:15:09.829Z", + "ParentId": "c81e728d9d4c2f63", + "WaitSucceededDetails": { + "Duration": 1 + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 12, + "EventTimestamp": "2025-12-10T00:15:09.829Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:15:09.805Z", + "EndTimestamp": "2025-12-10T00:15:09.829Z", + "Error": {}, + "RequestId": "71857a1f-96f5-4f24-9e94-ec88d3828a35" + } + }, + { + "EventType": "ContextStarted", + "SubType": "WaitForCallback", + "EventId": 13, + "Id": "3c46a0407be60a1f", + "Name": "child-callback-op", + "EventTimestamp": "2025-12-10T00:15:09.869Z", + "ParentId": "c81e728d9d4c2f63", + "ContextStartedDetails": {} + }, + { + "EventType": "CallbackStarted", + "SubType": "Callback", + "EventId": 14, + "Id": "61e70e07c25ca2dd", + "EventTimestamp": "2025-12-10T00:15:09.869Z", + "ParentId": "3c46a0407be60a1f", + "CallbackStartedDetails": { + "CallbackId": "eyJleGVjdXRpb25JZCI6IjZkMzJlYmJmLTliM2EtNDc2Ni05YTM2LTZlZDBlMzk5OTM4YSIsIm9wZXJhdGlvbklkIjoiNjFlNzBlMDdjMjVjYTJkZCIsInRva2VuIjoiMTZkZTVjZmItOTZjZC00YmEyLTllYjAtNjhiZGNkY2VjOGI0In0=", + "Input": {} + } + }, + { + "EventType": "CallbackSucceeded", + "SubType": "Callback", + "EventId": 15, + "Id": "61e70e07c25ca2dd", + "EventTimestamp": "2025-12-10T00:15:09.870Z", + "ParentId": "3c46a0407be60a1f", + "CallbackSucceededDetails": { + "Result": { + "Payload": "{\"childData\":42}" + } + } + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 16, + "Id": "c2f098f784fd6490", + "EventTimestamp": "2025-12-10T00:15:09.888Z", + "ParentId": "3c46a0407be60a1f", + "StepStartedDetails": {} + }, + { + "EventType": "StepSucceeded", + "SubType": "Step", + "EventId": 17, + "Id": "c2f098f784fd6490", + "EventTimestamp": "2025-12-10T00:15:09.888Z", + "ParentId": "3c46a0407be60a1f", + "StepSucceededDetails": { + "Result": {}, + "RetryDetails": {} + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 18, + "EventTimestamp": "2025-12-10T00:15:09.950Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:15:09.848Z", + "EndTimestamp": "2025-12-10T00:15:09.950Z", + "Error": {}, + "RequestId": "3e11c40b-b4cf-49bb-90f0-ac2e3958e5bb" + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "WaitForCallback", + "EventId": 19, + "Id": "3c46a0407be60a1f", + "Name": "child-callback-op", + "EventTimestamp": "2025-12-10T00:15:09.994Z", + "ParentId": "c81e728d9d4c2f63", + "ContextSucceededDetails": { + "Result": { + "Payload": "\"{\\\"childData\\\":42}\"" + } + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "RunInChildContext", + "EventId": 20, + "Id": "c81e728d9d4c2f63", + "Name": "child-context-with-callback", + "EventTimestamp": "2025-12-10T00:15:09.994Z", + "ContextSucceededDetails": { + "Result": { + "Payload": "{\"childResult\":\"{\\\"childData\\\":42}\",\"childProcessed\":true}" + } + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 21, + "EventTimestamp": "2025-12-10T00:15:09.994Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:15:09.971Z", + "EndTimestamp": "2025-12-10T00:15:09.994Z", + "Error": {}, + "RequestId": "7c0f94cc-e457-496c-86c8-d11c44c5a152" + } + }, + { + "EventType": "ExecutionSucceeded", + "EventId": 22, + "Id": "e39cc4cc-0f5b-4a91-8775-38b3a26c2f00", + "EventTimestamp": "2025-12-10T00:15:09.994Z", + "ExecutionSucceededDetails": { + "Result": { + "Payload": "{\"parentResult\":\"{\\\"parentData\\\":\\\"parent-completed\\\"}\",\"childContextResult\":{\"childResult\":\"{\\\"childData\\\":42}\",\"childProcessed\":true}}" + } + } + } +] diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/child-context/wait-for-callback-child-context.test.ts b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/child-context/wait-for-callback-child-context.test.ts index 1ad3adaa..048af041 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/child-context/wait-for-callback-child-context.test.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/child-context/wait-for-callback-child-context.test.ts @@ -9,7 +9,7 @@ import { createTests } from "../../../utils/test-helper"; createTests({ handler, invocationType: InvocationType.Event, - tests: (runner) => { + tests: (runner, { assertEventSignatures }) => { it("should handle waitForCallback within child contexts", async () => { // Get operations - parent callback, child context, child wait, child callback const parentCallbackOp = runner.getOperation("parent-callback-op"); @@ -52,6 +52,8 @@ createTests({ status: OperationStatus.SUCCEEDED, }); expect(completedOperations.length).toBe(8); + + assertEventSignatures(result); }); }, }); diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/failures/wait-for-callback-failures.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/failures/wait-for-callback-failures.history.json new file mode 100644 index 00000000..3a7d7cd4 --- /dev/null +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/failures/wait-for-callback-failures.history.json @@ -0,0 +1,118 @@ +[ + { + "EventType": "ExecutionStarted", + "EventId": 1, + "Id": "b9117e67-76c4-453f-b9b4-136f52e60076", + "EventTimestamp": "2025-12-10T00:15:10.030Z", + "ExecutionStartedDetails": { + "Input": { + "Payload": "{}" + } + } + }, + { + "EventType": "ContextStarted", + "SubType": "WaitForCallback", + "EventId": 2, + "Id": "c4ca4238a0b92382", + "EventTimestamp": "2025-12-10T00:15:10.062Z", + "ContextStartedDetails": {} + }, + { + "EventType": "CallbackStarted", + "SubType": "Callback", + "EventId": 3, + "Id": "ea66c06c1e1c05fa", + "EventTimestamp": "2025-12-10T00:15:10.062Z", + "ParentId": "c4ca4238a0b92382", + "CallbackStartedDetails": { + "CallbackId": "eyJleGVjdXRpb25JZCI6IjNiMDU4Njk2LTI3MjctNGM1Zi05MDZiLTUxZjEwMDRkNTY1ZSIsIm9wZXJhdGlvbklkIjoiZWE2NmMwNmMxZTFjMDVmYSIsInRva2VuIjoiOWEyYTdhMjYtNTc1YS00YTljLWI1ZjctNjJkNWNkMzBhMDgzIn0=", + "Input": {} + } + }, + { + "EventType": "CallbackFailed", + "SubType": "Callback", + "EventId": 4, + "Id": "ea66c06c1e1c05fa", + "EventTimestamp": "2025-12-10T00:15:10.071Z", + "ParentId": "c4ca4238a0b92382", + "CallbackFailedDetails": { + "Error": { + "Payload": { + "ErrorMessage": "External API failure", + "ErrorType": "APIException" + } + } + } + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 5, + "Id": "98c6f2c2287f4c73", + "EventTimestamp": "2025-12-10T00:15:10.076Z", + "ParentId": "c4ca4238a0b92382", + "StepStartedDetails": {} + }, + { + "EventType": "StepSucceeded", + "SubType": "Step", + "EventId": 6, + "Id": "98c6f2c2287f4c73", + "EventTimestamp": "2025-12-10T00:15:11.120Z", + "ParentId": "c4ca4238a0b92382", + "StepSucceededDetails": { + "Result": {}, + "RetryDetails": {} + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 7, + "EventTimestamp": "2025-12-10T00:15:11.180Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:15:10.030Z", + "EndTimestamp": "2025-12-10T00:15:11.180Z", + "Error": {}, + "RequestId": "92fa7e21-950a-42c3-8356-d863115841a0" + } + }, + { + "EventType": "ContextFailed", + "SubType": "WaitForCallback", + "EventId": 8, + "Id": "c4ca4238a0b92382", + "EventTimestamp": "2025-12-10T00:15:11.220Z", + "ContextFailedDetails": { + "Error": { + "Payload": { + "ErrorType": "CallbackError", + "ErrorMessage": "External API failure" + } + } + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 9, + "EventTimestamp": "2025-12-10T00:15:11.220Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:15:11.200Z", + "EndTimestamp": "2025-12-10T00:15:11.220Z", + "Error": {}, + "RequestId": "ac2c194a-1c2c-43c0-931f-100e2731cd30" + } + }, + { + "EventType": "ExecutionSucceeded", + "EventId": 10, + "Id": "b9117e67-76c4-453f-b9b4-136f52e60076", + "EventTimestamp": "2025-12-10T00:15:11.221Z", + "ExecutionSucceededDetails": { + "Result": { + "Payload": "{\"success\":false,\"error\":\"External API failure\"}" + } + } + } +] diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/failures/wait-for-callback-failures.test.ts b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/failures/wait-for-callback-failures.test.ts index 7c1d87bd..b507e324 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/failures/wait-for-callback-failures.test.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/failures/wait-for-callback-failures.test.ts @@ -8,7 +8,7 @@ import { createTests } from "../../../utils/test-helper"; createTests({ handler, invocationType: InvocationType.Event, - tests: (runner) => { + tests: (runner, { assertEventSignatures }) => { it("should handle waitForCallback with callback failure scenarios", async () => { // Start the execution (this will pause at the callback) const executionPromise = runner.run(); @@ -33,6 +33,8 @@ createTests({ const completedOperations = result.getOperations(); expect(completedOperations.length).toEqual(3); + + assertEventSignatures(result); }); }, }); diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/heartbeat-sends/wait-for-callback-heartbeat-sends.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/heartbeat-sends/wait-for-callback-heartbeat-sends.history.json new file mode 100644 index 00000000..b742282f --- /dev/null +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/heartbeat-sends/wait-for-callback-heartbeat-sends.history.json @@ -0,0 +1,113 @@ +[ + { + "EventType": "ExecutionStarted", + "EventId": 1, + "Id": "398c39ed-5087-4e5f-84de-ea20fc7bae53", + "EventTimestamp": "2025-12-10T00:12:29.567Z", + "ExecutionStartedDetails": { + "Input": { + "Payload": "{\"isCloud\":false}" + } + } + }, + { + "EventType": "ContextStarted", + "SubType": "WaitForCallback", + "EventId": 2, + "Id": "c4ca4238a0b92382", + "EventTimestamp": "2025-12-10T00:12:29.572Z", + "ContextStartedDetails": {} + }, + { + "EventType": "CallbackStarted", + "SubType": "Callback", + "EventId": 3, + "Id": "ea66c06c1e1c05fa", + "EventTimestamp": "2025-12-10T00:12:29.572Z", + "ParentId": "c4ca4238a0b92382", + "CallbackStartedDetails": { + "CallbackId": "eyJleGVjdXRpb25JZCI6Ijk2NjIxNTY2LTIxODktNDJkNC1hMWI3LTQ1OTBhOWFmY2E1NSIsIm9wZXJhdGlvbklkIjoiZWE2NmMwNmMxZTFjMDVmYSIsInRva2VuIjoiMjE5MmIzYTItZmVjZC00ODI1LWIyNTUtMGJiOWZhZmE3YjMyIn0=", + "HeartbeatTimeout": 1, + "Input": {} + } + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 4, + "Id": "98c6f2c2287f4c73", + "EventTimestamp": "2025-12-10T00:12:29.575Z", + "ParentId": "c4ca4238a0b92382", + "StepStartedDetails": {} + }, + { + "EventType": "StepSucceeded", + "SubType": "Step", + "EventId": 5, + "Id": "98c6f2c2287f4c73", + "EventTimestamp": "2025-12-10T00:12:29.675Z", + "ParentId": "c4ca4238a0b92382", + "StepSucceededDetails": { + "Result": {}, + "RetryDetails": {} + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 6, + "EventTimestamp": "2025-12-10T00:12:29.726Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:12:29.567Z", + "EndTimestamp": "2025-12-10T00:12:29.726Z", + "Error": {}, + "RequestId": "b4363077-0440-431c-8cae-47b1047abc66" + } + }, + { + "EventType": "CallbackSucceeded", + "SubType": "Callback", + "EventId": 7, + "Id": "ea66c06c1e1c05fa", + "EventTimestamp": "2025-12-10T00:12:30.175Z", + "ParentId": "c4ca4238a0b92382", + "CallbackSucceededDetails": { + "Result": { + "Payload": "{\"processed\":1000}" + } + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "WaitForCallback", + "EventId": 8, + "Id": "c4ca4238a0b92382", + "EventTimestamp": "2025-12-10T00:12:30.179Z", + "ContextSucceededDetails": { + "Result": { + "Payload": "\"{\\\"processed\\\":1000}\"" + } + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 9, + "EventTimestamp": "2025-12-10T00:12:30.179Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:12:30.177Z", + "EndTimestamp": "2025-12-10T00:12:30.179Z", + "Error": {}, + "RequestId": "36949279-c127-43a4-8554-8b43073402ed" + } + }, + { + "EventType": "ExecutionSucceeded", + "EventId": 10, + "Id": "398c39ed-5087-4e5f-84de-ea20fc7bae53", + "EventTimestamp": "2025-12-10T00:12:30.179Z", + "ExecutionSucceededDetails": { + "Result": { + "Payload": "{\"callbackResult\":\"{\\\"processed\\\":1000}\",\"completed\":true}" + } + } + } +] diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/heartbeat-sends/wait-for-callback-heartbeat-sends.test.ts b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/heartbeat-sends/wait-for-callback-heartbeat-sends.test.ts index a6fbceff..e3d3ab5d 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/heartbeat-sends/wait-for-callback-heartbeat-sends.test.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/heartbeat-sends/wait-for-callback-heartbeat-sends.test.ts @@ -12,7 +12,7 @@ createTests({ localRunnerConfig: { skipTime: false, }, - tests: (runner, { isCloud }) => { + tests: (runner, { isCloud, assertEventSignatures }) => { it("should handle waitForCallback heartbeat scenarios during long-running submitter execution", async () => { const executionPromise = runner.run({ payload: { isCloud }, @@ -53,6 +53,8 @@ createTests({ status: OperationStatus.SUCCEEDED, }); expect(completedOperations.length).toBeGreaterThan(0); + + assertEventSignatures(result); }); }, }); diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/mixed-ops/wait-for-callback-mixed-ops.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/mixed-ops/wait-for-callback-mixed-ops.history.json new file mode 100644 index 00000000..e06c22e1 --- /dev/null +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/mixed-ops/wait-for-callback-mixed-ops.history.json @@ -0,0 +1,228 @@ +[ + { + "EventType": "ExecutionStarted", + "EventId": 1, + "Id": "306a63fb-bb71-4c48-a20c-f42d50f446b7", + "EventTimestamp": "2025-12-10T00:15:09.246Z", + "ExecutionStartedDetails": { + "Input": { + "Payload": "{}" + } + } + }, + { + "EventType": "WaitStarted", + "SubType": "Wait", + "EventId": 2, + "Id": "c4ca4238a0b92382", + "Name": "initial-wait", + "EventTimestamp": "2025-12-10T00:15:09.277Z", + "WaitStartedDetails": { + "Duration": 1, + "ScheduledEndTimestamp": "2025-12-10T00:15:10.277Z" + } + }, + { + "EventType": "WaitSucceeded", + "SubType": "Wait", + "EventId": 3, + "Id": "c4ca4238a0b92382", + "Name": "initial-wait", + "EventTimestamp": "2025-12-10T00:15:09.278Z", + "WaitSucceededDetails": { + "Duration": 1 + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 4, + "EventTimestamp": "2025-12-10T00:15:09.278Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:15:09.246Z", + "EndTimestamp": "2025-12-10T00:15:09.278Z", + "Error": {}, + "RequestId": "f6e1ab7f-5851-4c2b-97b2-b9476adf5535" + } + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 5, + "Id": "c81e728d9d4c2f63", + "Name": "fetch-user-data", + "EventTimestamp": "2025-12-10T00:15:09.322Z", + "StepStartedDetails": {} + }, + { + "EventType": "StepSucceeded", + "SubType": "Step", + "EventId": 6, + "Id": "c81e728d9d4c2f63", + "Name": "fetch-user-data", + "EventTimestamp": "2025-12-10T00:15:09.322Z", + "StepSucceededDetails": { + "Result": { + "Payload": "{\"userId\":123,\"name\":\"John Doe\"}" + }, + "RetryDetails": {} + } + }, + { + "EventType": "ContextStarted", + "SubType": "WaitForCallback", + "EventId": 7, + "Id": "eccbc87e4b5ce2fe", + "Name": "wait-for-callback", + "EventTimestamp": "2025-12-10T00:15:09.342Z", + "ContextStartedDetails": {} + }, + { + "EventType": "CallbackStarted", + "SubType": "Callback", + "EventId": 8, + "Id": "c9e6e7b69f98f516", + "EventTimestamp": "2025-12-10T00:15:09.343Z", + "ParentId": "eccbc87e4b5ce2fe", + "CallbackStartedDetails": { + "CallbackId": "eyJleGVjdXRpb25JZCI6ImUyMzRhYjkyLThjNTItNDkxNC1hMjkwLWY3ZjY2ODY2YjAyMSIsIm9wZXJhdGlvbklkIjoiYzllNmU3YjY5Zjk4ZjUxNiIsInRva2VuIjoiMjEyODMwNjAtMDc2ZC00NmY5LTkzYWEtOTE2ZjUxYzhkZjQ2In0=", + "Input": {} + } + }, + { + "EventType": "CallbackSucceeded", + "SubType": "Callback", + "EventId": 9, + "Id": "c9e6e7b69f98f516", + "EventTimestamp": "2025-12-10T00:15:09.345Z", + "ParentId": "eccbc87e4b5ce2fe", + "CallbackSucceededDetails": { + "Result": { + "Payload": "{\"processed\":true}" + } + } + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 10, + "Id": "b772d43b49bb57b5", + "EventTimestamp": "2025-12-10T00:15:09.362Z", + "ParentId": "eccbc87e4b5ce2fe", + "StepStartedDetails": {} + }, + { + "EventType": "StepSucceeded", + "SubType": "Step", + "EventId": 11, + "Id": "b772d43b49bb57b5", + "EventTimestamp": "2025-12-10T00:15:09.467Z", + "ParentId": "eccbc87e4b5ce2fe", + "StepSucceededDetails": { + "Result": {}, + "RetryDetails": {} + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 12, + "EventTimestamp": "2025-12-10T00:15:09.527Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:15:09.298Z", + "EndTimestamp": "2025-12-10T00:15:09.527Z", + "Error": {}, + "RequestId": "a32fd7f6-2436-4ee8-a2ea-09dfd118a5ee" + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "WaitForCallback", + "EventId": 13, + "Id": "eccbc87e4b5ce2fe", + "Name": "wait-for-callback", + "EventTimestamp": "2025-12-10T00:15:09.569Z", + "ContextSucceededDetails": { + "Result": { + "Payload": "\"{\\\"processed\\\":true}\"" + } + } + }, + { + "EventType": "WaitStarted", + "SubType": "Wait", + "EventId": 14, + "Id": "a87ff679a2f3e71d", + "Name": "final-wait", + "EventTimestamp": "2025-12-10T00:15:09.569Z", + "WaitStartedDetails": { + "Duration": 2, + "ScheduledEndTimestamp": "2025-12-10T00:15:11.569Z" + } + }, + { + "EventType": "WaitSucceeded", + "SubType": "Wait", + "EventId": 15, + "Id": "a87ff679a2f3e71d", + "Name": "final-wait", + "EventTimestamp": "2025-12-10T00:15:09.570Z", + "WaitSucceededDetails": { + "Duration": 2 + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 16, + "EventTimestamp": "2025-12-10T00:15:09.570Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:15:09.547Z", + "EndTimestamp": "2025-12-10T00:15:09.570Z", + "Error": {}, + "RequestId": "42c5f388-4f12-42a3-a9d3-05e6171d613c" + } + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 17, + "Id": "e4da3b7fbbce2345", + "Name": "finalize-processing", + "EventTimestamp": "2025-12-10T00:15:09.610Z", + "StepStartedDetails": {} + }, + { + "EventType": "StepSucceeded", + "SubType": "Step", + "EventId": 18, + "Id": "e4da3b7fbbce2345", + "Name": "finalize-processing", + "EventTimestamp": "2025-12-10T00:15:09.610Z", + "StepSucceededDetails": { + "Result": { + "Payload": "{\"status\":\"completed\",\"timestamp\":1765325711589}" + }, + "RetryDetails": {} + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 19, + "EventTimestamp": "2025-12-10T00:15:09.611Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:15:09.588Z", + "EndTimestamp": "2025-12-10T00:15:09.611Z", + "Error": {}, + "RequestId": "398dc4a0-cf48-4e10-8c4d-819bc50fa404" + } + }, + { + "EventType": "ExecutionSucceeded", + "EventId": 20, + "Id": "306a63fb-bb71-4c48-a20c-f42d50f446b7", + "EventTimestamp": "2025-12-10T00:15:09.611Z", + "ExecutionSucceededDetails": { + "Result": { + "Payload": "{\"stepResult\":{\"userId\":123,\"name\":\"John Doe\"},\"callbackResult\":\"{\\\"processed\\\":true}\",\"finalStep\":{\"status\":\"completed\",\"timestamp\":1765325711589},\"workflowCompleted\":true}" + } + } + } +] diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/mixed-ops/wait-for-callback-mixed-ops.test.ts b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/mixed-ops/wait-for-callback-mixed-ops.test.ts index aa070fab..2dad0f39 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/mixed-ops/wait-for-callback-mixed-ops.test.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/mixed-ops/wait-for-callback-mixed-ops.test.ts @@ -9,7 +9,7 @@ import { createTests } from "../../../utils/test-helper"; createTests({ handler, invocationType: InvocationType.Event, - tests: (runner) => { + tests: (runner, { assertEventSignatures }) => { it("should handle waitForCallback mixed with steps, waits, and other operations", async () => { const callbackOperation = runner.getOperation("wait-for-callback"); @@ -44,6 +44,8 @@ createTests({ status: OperationStatus.SUCCEEDED, }); expect(completedOperations.length).toBe(7); + + assertEventSignatures(result); }); }, }); diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/multiple-invocations/wait-for-callback-multiple-invocations.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/multiple-invocations/wait-for-callback-multiple-invocations.history.json new file mode 100644 index 00000000..b6e0929f --- /dev/null +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/multiple-invocations/wait-for-callback-multiple-invocations.history.json @@ -0,0 +1,273 @@ +[ + { + "EventType": "ExecutionStarted", + "EventId": 1, + "Id": "cb4f4efd-59c3-472c-a44b-ee902b460647", + "EventTimestamp": "2025-12-10T00:15:09.992Z", + "ExecutionStartedDetails": { + "Input": { + "Payload": "{\"test\":\"multiple-invocations\"}" + } + } + }, + { + "EventType": "WaitStarted", + "SubType": "Wait", + "EventId": 2, + "Id": "c4ca4238a0b92382", + "Name": "wait-invocation-1", + "EventTimestamp": "2025-12-10T00:15:10.015Z", + "WaitStartedDetails": { + "Duration": 1, + "ScheduledEndTimestamp": "2025-12-10T00:15:11.015Z" + } + }, + { + "EventType": "WaitSucceeded", + "SubType": "Wait", + "EventId": 3, + "Id": "c4ca4238a0b92382", + "Name": "wait-invocation-1", + "EventTimestamp": "2025-12-10T00:15:10.016Z", + "WaitSucceededDetails": { + "Duration": 1 + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 4, + "EventTimestamp": "2025-12-10T00:15:10.016Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:15:09.992Z", + "EndTimestamp": "2025-12-10T00:15:10.016Z", + "Error": {}, + "RequestId": "94c49b99-ea48-4e7c-bf5d-59947766a1db" + } + }, + { + "EventType": "ContextStarted", + "SubType": "WaitForCallback", + "EventId": 5, + "Id": "c81e728d9d4c2f63", + "Name": "first-callback", + "EventTimestamp": "2025-12-10T00:15:10.067Z", + "ContextStartedDetails": {} + }, + { + "EventType": "CallbackStarted", + "SubType": "Callback", + "EventId": 6, + "Id": "8fbdbf5573b18fae", + "EventTimestamp": "2025-12-10T00:15:10.067Z", + "ParentId": "c81e728d9d4c2f63", + "CallbackStartedDetails": { + "CallbackId": "eyJleGVjdXRpb25JZCI6Ijg3YTc5NjZlLTFlODItNGYwOC1hZmFlLTg4YmNjYTU3ODU2NSIsIm9wZXJhdGlvbklkIjoiOGZiZGJmNTU3M2IxOGZhZSIsInRva2VuIjoiYTE3YzI1MzQtMGJiZS00ZmQzLWI5OGQtNDJjOTEyOWU4Zjc3In0=", + "Input": {} + } + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 7, + "Id": "3c46a0407be60a1f", + "EventTimestamp": "2025-12-10T00:15:10.088Z", + "ParentId": "c81e728d9d4c2f63", + "StepStartedDetails": {} + }, + { + "EventType": "StepSucceeded", + "SubType": "Step", + "EventId": 8, + "Id": "3c46a0407be60a1f", + "EventTimestamp": "2025-12-10T00:15:10.088Z", + "ParentId": "c81e728d9d4c2f63", + "StepSucceededDetails": { + "Result": {}, + "RetryDetails": {} + } + }, + { + "EventType": "CallbackSucceeded", + "SubType": "Callback", + "EventId": 9, + "Id": "8fbdbf5573b18fae", + "EventTimestamp": "2025-12-10T00:15:10.096Z", + "ParentId": "c81e728d9d4c2f63", + "CallbackSucceededDetails": { + "Result": { + "Payload": "{\"step\":1}" + } + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 10, + "EventTimestamp": "2025-12-10T00:15:10.146Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:15:10.041Z", + "EndTimestamp": "2025-12-10T00:15:10.146Z", + "Error": {}, + "RequestId": "2a57e98b-dfe2-4365-8d0d-a3dc1d0cb26b" + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "WaitForCallback", + "EventId": 11, + "Id": "c81e728d9d4c2f63", + "Name": "first-callback", + "EventTimestamp": "2025-12-10T00:15:10.188Z", + "ContextSucceededDetails": { + "Result": { + "Payload": "\"{\\\"step\\\":1}\"" + } + } + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 12, + "Id": "eccbc87e4b5ce2fe", + "Name": "process-callback-data", + "EventTimestamp": "2025-12-10T00:15:10.188Z", + "StepStartedDetails": {} + }, + { + "EventType": "StepSucceeded", + "SubType": "Step", + "EventId": 13, + "Id": "eccbc87e4b5ce2fe", + "Name": "process-callback-data", + "EventTimestamp": "2025-12-10T00:15:10.188Z", + "StepSucceededDetails": { + "Result": { + "Payload": "{\"processed\":true,\"step\":1}" + }, + "RetryDetails": {} + } + }, + { + "EventType": "WaitStarted", + "SubType": "Wait", + "EventId": 14, + "Id": "a87ff679a2f3e71d", + "Name": "wait-invocation-2", + "EventTimestamp": "2025-12-10T00:15:10.208Z", + "WaitStartedDetails": { + "Duration": 1, + "ScheduledEndTimestamp": "2025-12-10T00:15:11.208Z" + } + }, + { + "EventType": "WaitSucceeded", + "SubType": "Wait", + "EventId": 15, + "Id": "a87ff679a2f3e71d", + "Name": "wait-invocation-2", + "EventTimestamp": "2025-12-10T00:15:10.209Z", + "WaitSucceededDetails": { + "Duration": 1 + } + }, + { + "EventType": "ContextStarted", + "SubType": "WaitForCallback", + "EventId": 16, + "Id": "e4da3b7fbbce2345", + "Name": "second-callback", + "EventTimestamp": "2025-12-10T00:15:10.251Z", + "ContextStartedDetails": {} + }, + { + "EventType": "CallbackStarted", + "SubType": "Callback", + "EventId": 17, + "Id": "19a1de167122a18a", + "EventTimestamp": "2025-12-10T00:15:10.251Z", + "ParentId": "e4da3b7fbbce2345", + "CallbackStartedDetails": { + "CallbackId": "eyJleGVjdXRpb25JZCI6Ijg3YTc5NjZlLTFlODItNGYwOC1hZmFlLTg4YmNjYTU3ODU2NSIsIm9wZXJhdGlvbklkIjoiMTlhMWRlMTY3MTIyYTE4YSIsInRva2VuIjoiMTkyNzFlZDktNTVhMC00MzczLTk3YTEtYTBlNmM3YmY3YTI4In0=", + "Input": {} + } + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 18, + "Id": "dca19ffa163054fe", + "EventTimestamp": "2025-12-10T00:15:10.271Z", + "ParentId": "e4da3b7fbbce2345", + "StepStartedDetails": {} + }, + { + "EventType": "StepSucceeded", + "SubType": "Step", + "EventId": 19, + "Id": "dca19ffa163054fe", + "EventTimestamp": "2025-12-10T00:15:10.271Z", + "ParentId": "e4da3b7fbbce2345", + "StepSucceededDetails": { + "Result": {}, + "RetryDetails": {} + } + }, + { + "EventType": "CallbackSucceeded", + "SubType": "Callback", + "EventId": 20, + "Id": "19a1de167122a18a", + "EventTimestamp": "2025-12-10T00:15:10.272Z", + "ParentId": "e4da3b7fbbce2345", + "CallbackSucceededDetails": { + "Result": { + "Payload": "{\"step\":2}" + } + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 21, + "EventTimestamp": "2025-12-10T00:15:10.333Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:15:10.166Z", + "EndTimestamp": "2025-12-10T00:15:10.333Z", + "Error": {}, + "RequestId": "de8fdd22-af11-43e6-92eb-5ceea86cafc2" + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "WaitForCallback", + "EventId": 22, + "Id": "e4da3b7fbbce2345", + "Name": "second-callback", + "EventTimestamp": "2025-12-10T00:15:10.376Z", + "ContextSucceededDetails": { + "Result": { + "Payload": "\"{\\\"step\\\":2}\"" + } + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 23, + "EventTimestamp": "2025-12-10T00:15:10.376Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:15:10.353Z", + "EndTimestamp": "2025-12-10T00:15:10.376Z", + "Error": {}, + "RequestId": "c6334fb0-631d-4cca-b3bc-88857a044145" + } + }, + { + "EventType": "ExecutionSucceeded", + "EventId": 24, + "Id": "cb4f4efd-59c3-472c-a44b-ee902b460647", + "EventTimestamp": "2025-12-10T00:15:10.376Z", + "ExecutionSucceededDetails": { + "Result": { + "Payload": "{\"firstCallback\":\"{\\\"step\\\":1}\",\"secondCallback\":\"{\\\"step\\\":2}\",\"stepResult\":{\"processed\":true,\"step\":1},\"invocationCount\":\"multiple\"}" + } + } + } +] diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/multiple-invocations/wait-for-callback-multiple-invocations.test.ts b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/multiple-invocations/wait-for-callback-multiple-invocations.test.ts index 92e6bc4b..6b574b09 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/multiple-invocations/wait-for-callback-multiple-invocations.test.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/multiple-invocations/wait-for-callback-multiple-invocations.test.ts @@ -11,7 +11,7 @@ createTests({ localRunnerConfig: { skipTime: false, }, - tests: (runner) => { + tests: (runner, { assertEventSignatures }) => { it("should handle multiple invocations tracking with waitForCallback operations", async () => { // Get operations for verification const firstCallbackOp = runner.getOperation("first-callback"); @@ -51,6 +51,8 @@ createTests({ // Verify operations were executed const operations = result.getOperations(); expect(operations.length).toBeGreaterThan(4); // wait + callback + step + wait + callback operations + + assertEventSignatures(result); }); }, }); diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/nested/wait-for-callback-nested.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/nested/wait-for-callback-nested.history.json new file mode 100644 index 00000000..30aead16 --- /dev/null +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/nested/wait-for-callback-nested.history.json @@ -0,0 +1,358 @@ +[ + { + "EventType": "ExecutionStarted", + "EventId": 1, + "Id": "f66e69d4-c309-4df7-be6b-9164dacd1e6c", + "EventTimestamp": "2025-12-10T00:15:09.629Z", + "ExecutionStartedDetails": { + "Input": { + "Payload": "{}" + } + } + }, + { + "EventType": "ContextStarted", + "SubType": "WaitForCallback", + "EventId": 2, + "Id": "c4ca4238a0b92382", + "Name": "outer-callback-op", + "EventTimestamp": "2025-12-10T00:15:09.656Z", + "ContextStartedDetails": {} + }, + { + "EventType": "CallbackStarted", + "SubType": "Callback", + "EventId": 3, + "Id": "ea66c06c1e1c05fa", + "EventTimestamp": "2025-12-10T00:15:09.656Z", + "ParentId": "c4ca4238a0b92382", + "CallbackStartedDetails": { + "CallbackId": "eyJleGVjdXRpb25JZCI6IjJiNjM3MjA4LWUzNmEtNGFlNS04NGU3LWIxNzQ1MDc5NTg2NyIsIm9wZXJhdGlvbklkIjoiZWE2NmMwNmMxZTFjMDVmYSIsInRva2VuIjoiYzY4Njk4NjYtNjk4ZS00NzU4LTlmNTYtM2IzNmQzYjk3ODEyIn0=", + "Input": {} + } + }, + { + "EventType": "CallbackSucceeded", + "SubType": "Callback", + "EventId": 4, + "Id": "ea66c06c1e1c05fa", + "EventTimestamp": "2025-12-10T00:15:09.657Z", + "ParentId": "c4ca4238a0b92382", + "CallbackSucceededDetails": { + "Result": { + "Payload": "{\"level\":\"outer-completed\"}" + } + } + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 5, + "Id": "98c6f2c2287f4c73", + "EventTimestamp": "2025-12-10T00:15:09.676Z", + "ParentId": "c4ca4238a0b92382", + "StepStartedDetails": {} + }, + { + "EventType": "StepSucceeded", + "SubType": "Step", + "EventId": 6, + "Id": "98c6f2c2287f4c73", + "EventTimestamp": "2025-12-10T00:15:09.676Z", + "ParentId": "c4ca4238a0b92382", + "StepSucceededDetails": { + "Result": {}, + "RetryDetails": {} + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 7, + "EventTimestamp": "2025-12-10T00:15:09.737Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:15:09.629Z", + "EndTimestamp": "2025-12-10T00:15:09.737Z", + "Error": {}, + "RequestId": "7d351710-35b3-4557-92b9-d04a3bae3960" + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "WaitForCallback", + "EventId": 8, + "Id": "c4ca4238a0b92382", + "Name": "outer-callback-op", + "EventTimestamp": "2025-12-10T00:15:09.780Z", + "ContextSucceededDetails": { + "Result": { + "Payload": "\"{\\\"level\\\":\\\"outer-completed\\\"}\"" + } + } + }, + { + "EventType": "ContextStarted", + "SubType": "RunInChildContext", + "EventId": 9, + "Id": "c81e728d9d4c2f63", + "Name": "outer-child-context", + "EventTimestamp": "2025-12-10T00:15:09.780Z", + "ContextStartedDetails": {} + }, + { + "EventType": "ContextStarted", + "SubType": "WaitForCallback", + "EventId": 10, + "Id": "8fbdbf5573b18fae", + "Name": "inner-callback-op", + "EventTimestamp": "2025-12-10T00:15:09.780Z", + "ParentId": "c81e728d9d4c2f63", + "ContextStartedDetails": {} + }, + { + "EventType": "CallbackStarted", + "SubType": "Callback", + "EventId": 11, + "Id": "de9160b4a2cf6c27", + "EventTimestamp": "2025-12-10T00:15:09.780Z", + "ParentId": "8fbdbf5573b18fae", + "CallbackStartedDetails": { + "CallbackId": "eyJleGVjdXRpb25JZCI6IjJiNjM3MjA4LWUzNmEtNGFlNS04NGU3LWIxNzQ1MDc5NTg2NyIsIm9wZXJhdGlvbklkIjoiZGU5MTYwYjRhMmNmNmMyNyIsInRva2VuIjoiZjI0Y2VmZDQtNWRiMC00NDJhLWE2OTUtYzFmYzhlYjRiMTZkIn0=", + "Input": {} + } + }, + { + "EventType": "CallbackSucceeded", + "SubType": "Callback", + "EventId": 12, + "Id": "de9160b4a2cf6c27", + "EventTimestamp": "2025-12-10T00:15:09.781Z", + "ParentId": "8fbdbf5573b18fae", + "CallbackSucceededDetails": { + "Result": { + "Payload": "{\"level\":\"inner-completed\"}" + } + } + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 13, + "Id": "0d9f92bdd748d70d", + "EventTimestamp": "2025-12-10T00:15:09.801Z", + "ParentId": "8fbdbf5573b18fae", + "StepStartedDetails": {} + }, + { + "EventType": "StepSucceeded", + "SubType": "Step", + "EventId": 14, + "Id": "0d9f92bdd748d70d", + "EventTimestamp": "2025-12-10T00:15:09.801Z", + "ParentId": "8fbdbf5573b18fae", + "StepSucceededDetails": { + "Result": {}, + "RetryDetails": {} + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 15, + "EventTimestamp": "2025-12-10T00:15:09.861Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:15:09.757Z", + "EndTimestamp": "2025-12-10T00:15:09.861Z", + "Error": {}, + "RequestId": "9f5ddc83-7ed8-491a-a760-65267b039fae" + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "WaitForCallback", + "EventId": 16, + "Id": "8fbdbf5573b18fae", + "Name": "inner-callback-op", + "EventTimestamp": "2025-12-10T00:15:09.904Z", + "ParentId": "c81e728d9d4c2f63", + "ContextSucceededDetails": { + "Result": { + "Payload": "\"{\\\"level\\\":\\\"inner-completed\\\"}\"" + } + } + }, + { + "EventType": "ContextStarted", + "SubType": "RunInChildContext", + "EventId": 17, + "Id": "3c46a0407be60a1f", + "Name": "inner-child-context", + "EventTimestamp": "2025-12-10T00:15:09.905Z", + "ParentId": "c81e728d9d4c2f63", + "ContextStartedDetails": {} + }, + { + "EventType": "WaitStarted", + "SubType": "Wait", + "EventId": 18, + "Id": "61e70e07c25ca2dd", + "Name": "deep-wait", + "EventTimestamp": "2025-12-10T00:15:09.905Z", + "ParentId": "3c46a0407be60a1f", + "WaitStartedDetails": { + "Duration": 5, + "ScheduledEndTimestamp": "2025-12-10T00:15:14.905Z" + } + }, + { + "EventType": "WaitSucceeded", + "SubType": "Wait", + "EventId": 19, + "Id": "61e70e07c25ca2dd", + "Name": "deep-wait", + "EventTimestamp": "2025-12-10T00:15:09.905Z", + "ParentId": "3c46a0407be60a1f", + "WaitSucceededDetails": { + "Duration": 5 + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 20, + "EventTimestamp": "2025-12-10T00:15:09.906Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:15:09.882Z", + "EndTimestamp": "2025-12-10T00:15:09.906Z", + "Error": {}, + "RequestId": "362090dc-fb23-4727-99de-966c358a3d9e" + } + }, + { + "EventType": "ContextStarted", + "SubType": "WaitForCallback", + "EventId": 21, + "Id": "c2f098f784fd6490", + "Name": "nested-callback-op", + "EventTimestamp": "2025-12-10T00:15:09.945Z", + "ParentId": "3c46a0407be60a1f", + "ContextStartedDetails": {} + }, + { + "EventType": "CallbackStarted", + "SubType": "Callback", + "EventId": 22, + "Id": "1d03fc80da7b6145", + "EventTimestamp": "2025-12-10T00:15:09.945Z", + "ParentId": "c2f098f784fd6490", + "CallbackStartedDetails": { + "CallbackId": "eyJleGVjdXRpb25JZCI6IjJiNjM3MjA4LWUzNmEtNGFlNS04NGU3LWIxNzQ1MDc5NTg2NyIsIm9wZXJhdGlvbklkIjoiMWQwM2ZjODBkYTdiNjE0NSIsInRva2VuIjoiZmFkNTZjNmYtZTRmNS00NzYwLTkzMDgtYzQxZGI5NzMyOTUxIn0=", + "Input": {} + } + }, + { + "EventType": "CallbackSucceeded", + "SubType": "Callback", + "EventId": 23, + "Id": "1d03fc80da7b6145", + "EventTimestamp": "2025-12-10T00:15:09.946Z", + "ParentId": "c2f098f784fd6490", + "CallbackSucceededDetails": { + "Result": { + "Payload": "{\"level\":\"nested-completed\"}" + } + } + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 24, + "Id": "8976069e5d6bb1a6", + "EventTimestamp": "2025-12-10T00:15:09.966Z", + "ParentId": "c2f098f784fd6490", + "StepStartedDetails": {} + }, + { + "EventType": "StepSucceeded", + "SubType": "Step", + "EventId": 25, + "Id": "8976069e5d6bb1a6", + "EventTimestamp": "2025-12-10T00:15:09.966Z", + "ParentId": "c2f098f784fd6490", + "StepSucceededDetails": { + "Result": {}, + "RetryDetails": {} + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 26, + "EventTimestamp": "2025-12-10T00:15:10.026Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:15:09.922Z", + "EndTimestamp": "2025-12-10T00:15:10.026Z", + "Error": {}, + "RequestId": "f2d7cae6-9602-495a-874e-810097662393" + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "WaitForCallback", + "EventId": 27, + "Id": "c2f098f784fd6490", + "Name": "nested-callback-op", + "EventTimestamp": "2025-12-10T00:15:10.072Z", + "ParentId": "3c46a0407be60a1f", + "ContextSucceededDetails": { + "Result": { + "Payload": "\"{\\\"level\\\":\\\"nested-completed\\\"}\"" + } + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "RunInChildContext", + "EventId": 28, + "Id": "3c46a0407be60a1f", + "Name": "inner-child-context", + "EventTimestamp": "2025-12-10T00:15:10.072Z", + "ParentId": "c81e728d9d4c2f63", + "ContextSucceededDetails": { + "Result": { + "Payload": "{\"nestedCallback\":\"{\\\"level\\\":\\\"nested-completed\\\"}\",\"deepLevel\":\"inner-child\"}" + } + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "RunInChildContext", + "EventId": 29, + "Id": "c81e728d9d4c2f63", + "Name": "outer-child-context", + "EventTimestamp": "2025-12-10T00:15:10.072Z", + "ContextSucceededDetails": { + "Result": { + "Payload": "{\"innerCallback\":\"{\\\"level\\\":\\\"inner-completed\\\"}\",\"deepNested\":{\"nestedCallback\":\"{\\\"level\\\":\\\"nested-completed\\\"}\",\"deepLevel\":\"inner-child\"},\"level\":\"outer-child\"}" + } + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 30, + "EventTimestamp": "2025-12-10T00:15:10.074Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:15:10.052Z", + "EndTimestamp": "2025-12-10T00:15:10.074Z", + "Error": {}, + "RequestId": "77d1ae8c-8613-4c67-8955-dab858f60b5f" + } + }, + { + "EventType": "ExecutionSucceeded", + "EventId": 31, + "Id": "f66e69d4-c309-4df7-be6b-9164dacd1e6c", + "EventTimestamp": "2025-12-10T00:15:10.074Z", + "ExecutionSucceededDetails": { + "Result": { + "Payload": "{\"outerCallback\":\"{\\\"level\\\":\\\"outer-completed\\\"}\",\"nestedResults\":{\"innerCallback\":\"{\\\"level\\\":\\\"inner-completed\\\"}\",\"deepNested\":{\"nestedCallback\":\"{\\\"level\\\":\\\"nested-completed\\\"}\",\"deepLevel\":\"inner-child\"},\"level\":\"outer-child\"}}" + } + } + } +] diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/nested/wait-for-callback-nested.test.ts b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/nested/wait-for-callback-nested.test.ts index 32ce3fc2..b2b615a1 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/nested/wait-for-callback-nested.test.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/nested/wait-for-callback-nested.test.ts @@ -8,7 +8,7 @@ import { createTests } from "../../../utils/test-helper"; createTests({ handler, invocationType: InvocationType.Event, - tests: (runner) => { + tests: (runner, { assertEventSignatures }) => { it("should handle nested waitForCallback operations in child contexts", async () => { // Get operations - outer callback, outer context, inner callback, inner context, deep wait, nested callback const outerCallbackOp = runner.getOperation("outer-callback-op"); @@ -58,6 +58,8 @@ createTests({ // Should have tracked all operations const completedOperations = result.getOperations(); expect(completedOperations.length).toBe(12); + + assertEventSignatures(result); }); }, }); diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/serdes/wait-for-callback-serdes.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/serdes/wait-for-callback-serdes.history.json new file mode 100644 index 00000000..fa3a6b15 --- /dev/null +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/serdes/wait-for-callback-serdes.history.json @@ -0,0 +1,189 @@ +[ + { + "EventType": "ExecutionStarted", + "EventId": 1, + "Id": "75f3d6bf-ca37-415d-af6f-d010babfc6ea", + "EventTimestamp": "2025-12-10T00:15:10.516Z", + "ExecutionStartedDetails": { + "Input": { + "Payload": "{}" + } + } + }, + { + "EventType": "ContextStarted", + "SubType": "WaitForCallback", + "EventId": 2, + "Id": "c4ca4238a0b92382", + "Name": "custom-serdes-callback", + "EventTimestamp": "2025-12-10T00:15:10.554Z", + "ContextStartedDetails": {} + }, + { + "EventType": "CallbackStarted", + "SubType": "Callback", + "EventId": 3, + "Id": "ea66c06c1e1c05fa", + "EventTimestamp": "2025-12-10T00:15:10.554Z", + "ParentId": "c4ca4238a0b92382", + "CallbackStartedDetails": { + "CallbackId": "eyJleGVjdXRpb25JZCI6IjEwOWM2MzM3LTc5ZGQtNDFmNi05MGYxLWE4MWU5NDdiYTZmYSIsIm9wZXJhdGlvbklkIjoiZWE2NmMwNmMxZTFjMDVmYSIsInRva2VuIjoiNmNjMjM4MDMtY2QwNy00N2YxLTlkNjYtOTA3OTZlNDVlYTNjIn0=", + "Timeout": 300, + "Input": {} + } + }, + { + "EventType": "CallbackSucceeded", + "SubType": "Callback", + "EventId": 4, + "Id": "ea66c06c1e1c05fa", + "EventTimestamp": "2025-12-10T00:15:10.555Z", + "ParentId": "c4ca4238a0b92382", + "CallbackSucceededDetails": { + "Result": { + "Payload": "{\"id\":42,\"message\":\"Hello Custom Serdes\",\"timestamp\":\"2025-06-15T12:30:45Z\",\"metadata\":{\"version\":\"2.0.0\",\"processed\":false}}" + } + } + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 5, + "Id": "98c6f2c2287f4c73", + "EventTimestamp": "2025-12-10T00:15:10.575Z", + "ParentId": "c4ca4238a0b92382", + "StepStartedDetails": {} + }, + { + "EventType": "StepSucceeded", + "SubType": "Step", + "EventId": 6, + "Id": "98c6f2c2287f4c73", + "EventTimestamp": "2025-12-10T00:15:10.575Z", + "ParentId": "c4ca4238a0b92382", + "StepSucceededDetails": { + "Result": {}, + "RetryDetails": {} + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 7, + "EventTimestamp": "2025-12-10T00:15:10.637Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:15:10.516Z", + "EndTimestamp": "2025-12-10T00:15:10.637Z", + "Error": {}, + "RequestId": "0634e555-0d4e-47d6-b3c3-611339ca2ae3" + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "WaitForCallback", + "EventId": 8, + "Id": "c4ca4238a0b92382", + "Name": "custom-serdes-callback", + "EventTimestamp": "2025-12-10T00:15:10.680Z", + "ContextSucceededDetails": { + "Result": { + "Payload": "\"{\\\"id\\\":42,\\\"message\\\":\\\"Hello Custom Serdes\\\",\\\"timestamp\\\":\\\"2025-06-15T12:30:45Z\\\",\\\"metadata\\\":{\\\"version\\\":\\\"2.0.0\\\",\\\"processed\\\":false}}\"" + } + } + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 9, + "Id": "c81e728d9d4c2f63", + "EventTimestamp": "2025-12-10T00:15:10.680Z", + "StepStartedDetails": {} + }, + { + "EventType": "StepSucceeded", + "SubType": "Step", + "EventId": 10, + "Id": "c81e728d9d4c2f63", + "EventTimestamp": "2025-12-10T00:15:10.680Z", + "StepSucceededDetails": { + "Result": { + "Payload": "true" + }, + "RetryDetails": {} + } + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 11, + "Id": "eccbc87e4b5ce2fe", + "EventTimestamp": "2025-12-10T00:15:10.701Z", + "StepStartedDetails": {} + }, + { + "EventType": "StepSucceeded", + "SubType": "Step", + "EventId": 12, + "Id": "eccbc87e4b5ce2fe", + "EventTimestamp": "2025-12-10T00:15:10.701Z", + "StepSucceededDetails": { + "Result": { + "Payload": "true" + }, + "RetryDetails": {} + } + }, + { + "EventType": "WaitStarted", + "SubType": "Wait", + "EventId": 13, + "Id": "a87ff679a2f3e71d", + "EventTimestamp": "2025-12-10T00:15:10.722Z", + "WaitStartedDetails": { + "Duration": 1, + "ScheduledEndTimestamp": "2025-12-10T00:15:11.722Z" + } + }, + { + "EventType": "WaitSucceeded", + "SubType": "Wait", + "EventId": 14, + "Id": "a87ff679a2f3e71d", + "EventTimestamp": "2025-12-10T00:15:10.723Z", + "WaitSucceededDetails": { + "Duration": 1 + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 15, + "EventTimestamp": "2025-12-10T00:15:10.723Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:15:10.658Z", + "EndTimestamp": "2025-12-10T00:15:10.723Z", + "Error": {}, + "RequestId": "5493eaa1-a356-41c8-9f76-987552b1feba" + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 16, + "EventTimestamp": "2025-12-10T00:15:10.743Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:15:10.742Z", + "EndTimestamp": "2025-12-10T00:15:10.743Z", + "Error": {}, + "RequestId": "037d7bc0-b9e3-4b3b-b87e-d74f06ee5911" + } + }, + { + "EventType": "ExecutionSucceeded", + "EventId": 17, + "Id": "75f3d6bf-ca37-415d-af6f-d010babfc6ea", + "EventTimestamp": "2025-12-10T00:15:10.743Z", + "ExecutionSucceededDetails": { + "Result": { + "Payload": "{\"receivedData\":{\"id\":42,\"message\":\"Hello Custom Serdes\",\"timestamp\":\"2025-06-15T12:30:45.000Z\",\"metadata\":{\"version\":\"2.0.0\",\"processed\":true}},\"hasCircularReference\":true,\"isDateAfterReplay\":true,\"isDateBeforeReplay\":true,\"isSerdesProcessedBefore\":true,\"isSerdesProcessedAfter\":true}" + } + } + } +] diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/serdes/wait-for-callback-serdes.test.ts b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/serdes/wait-for-callback-serdes.test.ts index 7102488b..a38adb00 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/serdes/wait-for-callback-serdes.test.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/serdes/wait-for-callback-serdes.test.ts @@ -9,7 +9,7 @@ import { createTests } from "../../../utils/test-helper"; createTests({ handler, invocationType: InvocationType.Event, - tests: (runner) => { + tests: (runner, { assertEventSignatures }) => { it("should handle waitForCallback with custom serdes configuration", async () => { const executionPromise = runner.run(); @@ -60,6 +60,8 @@ createTests({ status: OperationStatus.SUCCEEDED, }); expect(completedOperations.length).toBeGreaterThan(0); + + assertEventSignatures(result); }); }, }); diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/submitter-failure-catchable/wait-for-callback-submitter-failure-catchable.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/submitter-failure-catchable/wait-for-callback-submitter-failure-catchable.history.json new file mode 100644 index 00000000..37470321 --- /dev/null +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/submitter-failure-catchable/wait-for-callback-submitter-failure-catchable.history.json @@ -0,0 +1,180 @@ +[ + { + "EventType": "ExecutionStarted", + "EventId": 1, + "Id": "a0408aae-cfa0-4909-821a-2cb9af2a770a", + "EventTimestamp": "2025-12-10T00:12:24.018Z", + "ExecutionStartedDetails": { + "Input": { + "Payload": "{}" + } + } + }, + { + "EventType": "ContextStarted", + "SubType": "WaitForCallback", + "EventId": 2, + "Id": "c4ca4238a0b92382", + "Name": "failing-submitter-callback", + "EventTimestamp": "2025-12-10T00:12:24.023Z", + "ContextStartedDetails": {} + }, + { + "EventType": "CallbackStarted", + "SubType": "Callback", + "EventId": 3, + "Id": "ea66c06c1e1c05fa", + "EventTimestamp": "2025-12-10T00:12:24.023Z", + "ParentId": "c4ca4238a0b92382", + "CallbackStartedDetails": { + "CallbackId": "eyJleGVjdXRpb25JZCI6IjRkZTBmYzA2LTlkYjMtNGMxNi1iNGVjLWJmYTFkYjUzM2QyOSIsIm9wZXJhdGlvbklkIjoiZWE2NmMwNmMxZTFjMDVmYSIsInRva2VuIjoiM2I3ZWJjZDItMmNkYy00NjlhLWI4OWYtMzM4ZGU5NWEwMGEyIn0=", + "Input": {} + } + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 4, + "Id": "98c6f2c2287f4c73", + "EventTimestamp": "2025-12-10T00:12:24.025Z", + "ParentId": "c4ca4238a0b92382", + "StepStartedDetails": {} + }, + { + "EventType": "StepFailed", + "SubType": "Step", + "EventId": 5, + "Id": "98c6f2c2287f4c73", + "EventTimestamp": "2025-12-10T00:12:24.525Z", + "ParentId": "c4ca4238a0b92382", + "StepFailedDetails": { + "Error": { + "Payload": { + "ErrorMessage": "Submitter failed", + "ErrorType": "Error" + } + }, + "RetryDetails": { + "NextAttemptDelaySeconds": 1, + "CurrentAttempt": 1 + } + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 6, + "EventTimestamp": "2025-12-10T00:12:24.577Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:12:24.018Z", + "EndTimestamp": "2025-12-10T00:12:24.577Z", + "Error": {}, + "RequestId": "6cf15bbe-b7a4-419e-b917-4520102ba5d7" + } + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 7, + "Id": "98c6f2c2287f4c73", + "EventTimestamp": "2025-12-10T00:12:25.527Z", + "ParentId": "c4ca4238a0b92382", + "StepStartedDetails": {} + }, + { + "EventType": "StepFailed", + "SubType": "Step", + "EventId": 8, + "Id": "98c6f2c2287f4c73", + "EventTimestamp": "2025-12-10T00:12:26.028Z", + "ParentId": "c4ca4238a0b92382", + "StepFailedDetails": { + "Error": { + "Payload": { + "ErrorMessage": "Submitter failed", + "ErrorType": "Error" + } + }, + "RetryDetails": { + "NextAttemptDelaySeconds": 1, + "CurrentAttempt": 1 + } + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 9, + "EventTimestamp": "2025-12-10T00:12:26.080Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:12:25.525Z", + "EndTimestamp": "2025-12-10T00:12:26.080Z", + "Error": {}, + "RequestId": "1f652da1-15c2-4ce2-a395-c78800314198" + } + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 10, + "Id": "98c6f2c2287f4c73", + "EventTimestamp": "2025-12-10T00:12:27.032Z", + "ParentId": "c4ca4238a0b92382", + "StepStartedDetails": {} + }, + { + "EventType": "StepFailed", + "SubType": "Step", + "EventId": 11, + "Id": "98c6f2c2287f4c73", + "EventTimestamp": "2025-12-10T00:12:27.533Z", + "ParentId": "c4ca4238a0b92382", + "StepFailedDetails": { + "Error": { + "Payload": { + "ErrorMessage": "Submitter failed", + "ErrorType": "Error" + } + }, + "RetryDetails": { + "CurrentAttempt": 2 + } + } + }, + { + "EventType": "ContextFailed", + "SubType": "WaitForCallback", + "EventId": 12, + "Id": "c4ca4238a0b92382", + "Name": "failing-submitter-callback", + "EventTimestamp": "2025-12-10T00:12:27.534Z", + "ContextFailedDetails": { + "Error": { + "Payload": { + "ErrorType": "StepError", + "ErrorMessage": "Submitter failed" + } + } + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 13, + "EventTimestamp": "2025-12-10T00:12:27.534Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:12:27.030Z", + "EndTimestamp": "2025-12-10T00:12:27.534Z", + "Error": {}, + "RequestId": "8da70025-3134-42db-878f-a72e3c4c8d0a" + } + }, + { + "EventType": "ExecutionSucceeded", + "EventId": 14, + "Id": "a0408aae-cfa0-4909-821a-2cb9af2a770a", + "EventTimestamp": "2025-12-10T00:12:27.534Z", + "ExecutionSucceededDetails": { + "Result": { + "Payload": "{\"success\":false,\"error\":\"Submitter failed\"}" + } + } + } +] diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/submitter-failure-catchable/wait-for-callback-submitter-failure-catchable.test.ts b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/submitter-failure-catchable/wait-for-callback-submitter-failure-catchable.test.ts index f464d455..338a39b8 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/submitter-failure-catchable/wait-for-callback-submitter-failure-catchable.test.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/submitter-failure-catchable/wait-for-callback-submitter-failure-catchable.test.ts @@ -5,7 +5,7 @@ import { createTests } from "../../../utils/test-helper"; createTests({ handler, invocationType: InvocationType.Event, - tests: (runner) => { + tests: (runner, { assertEventSignatures }) => { it("should catch submitter failure in try-catch block", async () => { const execution = await runner.run(); @@ -15,18 +15,8 @@ createTests({ success: false, error: expect.stringContaining("Submitter failed"), }); - }); - - it("should handle submitter failure gracefully after retries", async () => { - const execution = await runner.run(); - - // Verify error is caught and returned in response - const result = execution.getResult() as any; - expect(result.success).toBe(false); - expect(result.error).toContain("Submitter failed"); - // Execution completes successfully (doesn't hang or throw unhandled error) - expect(execution.getResult()).toBeDefined(); + assertEventSignatures(execution); }); }, }); diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/submitter-retry-success/wait-for-callback-submitter-retry-success.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/submitter-retry-success/wait-for-callback-submitter-retry-success.history.json new file mode 100644 index 00000000..14cce7e6 --- /dev/null +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/submitter-retry-success/wait-for-callback-submitter-retry-success.history.json @@ -0,0 +1,114 @@ +[ + { + "EventType": "ExecutionStarted", + "EventId": 1, + "Id": "e2067af3-c418-4d3b-96df-a5ca4e117a49", + "EventTimestamp": "2025-12-10T00:15:08.608Z", + "ExecutionStartedDetails": { + "Input": { + "Payload": "{\"shouldFail\":false}" + } + } + }, + { + "EventType": "ContextStarted", + "SubType": "WaitForCallback", + "EventId": 2, + "Id": "c4ca4238a0b92382", + "Name": "retry-submitter-callback", + "EventTimestamp": "2025-12-10T00:15:08.636Z", + "ContextStartedDetails": {} + }, + { + "EventType": "CallbackStarted", + "SubType": "Callback", + "EventId": 3, + "Id": "ea66c06c1e1c05fa", + "EventTimestamp": "2025-12-10T00:15:08.636Z", + "ParentId": "c4ca4238a0b92382", + "CallbackStartedDetails": { + "CallbackId": "eyJleGVjdXRpb25JZCI6ImU2NjQwYzRiLTllMmYtNDI1Ny1hOTAxLWUxMTZhMjUxMTg4OCIsIm9wZXJhdGlvbklkIjoiZWE2NmMwNmMxZTFjMDVmYSIsInRva2VuIjoiMjNkZWE0NTEtM2NmNC00YTkwLTg5NjctYmVlNjdhMjQ0ZjY2In0=", + "Input": {} + } + }, + { + "EventType": "CallbackSucceeded", + "SubType": "Callback", + "EventId": 4, + "Id": "ea66c06c1e1c05fa", + "EventTimestamp": "2025-12-10T00:15:08.641Z", + "ParentId": "c4ca4238a0b92382", + "CallbackSucceededDetails": { + "Result": { + "Payload": "{\"data\":\"completed\"}" + } + } + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 5, + "Id": "98c6f2c2287f4c73", + "EventTimestamp": "2025-12-10T00:15:08.656Z", + "ParentId": "c4ca4238a0b92382", + "StepStartedDetails": {} + }, + { + "EventType": "StepSucceeded", + "SubType": "Step", + "EventId": 6, + "Id": "98c6f2c2287f4c73", + "EventTimestamp": "2025-12-10T00:15:08.656Z", + "ParentId": "c4ca4238a0b92382", + "StepSucceededDetails": { + "Result": {}, + "RetryDetails": {} + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 7, + "EventTimestamp": "2025-12-10T00:15:08.718Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:15:08.608Z", + "EndTimestamp": "2025-12-10T00:15:08.718Z", + "Error": {}, + "RequestId": "2b3250a6-0803-44d8-bab2-ce40cdb66d85" + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "WaitForCallback", + "EventId": 8, + "Id": "c4ca4238a0b92382", + "Name": "retry-submitter-callback", + "EventTimestamp": "2025-12-10T00:15:08.760Z", + "ContextSucceededDetails": { + "Result": { + "Payload": "\"{\\\"data\\\":\\\"completed\\\"}\"" + } + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 9, + "EventTimestamp": "2025-12-10T00:15:08.760Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:15:08.737Z", + "EndTimestamp": "2025-12-10T00:15:08.760Z", + "Error": {}, + "RequestId": "80e9ce8f-15e1-4ac6-b75f-f2efe9b7bec9" + } + }, + { + "EventType": "ExecutionSucceeded", + "EventId": 10, + "Id": "e2067af3-c418-4d3b-96df-a5ca4e117a49", + "EventTimestamp": "2025-12-10T00:15:08.761Z", + "ExecutionSucceededDetails": { + "Result": { + "Payload": "{\"result\":\"{\\\"data\\\":\\\"completed\\\"}\",\"success\":true}" + } + } + } +] diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/submitter-retry-success/wait-for-callback-submitter-retry-success.test.ts b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/submitter-retry-success/wait-for-callback-submitter-retry-success.test.ts index c1592c80..4d964ada 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/submitter-retry-success/wait-for-callback-submitter-retry-success.test.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/submitter-retry-success/wait-for-callback-submitter-retry-success.test.ts @@ -8,7 +8,7 @@ import { createTests } from "../../../utils/test-helper"; createTests({ handler, invocationType: InvocationType.Event, - tests: (runner) => { + tests: (runner, { assertEventSignatures }) => { it("should complete successfully when submitter succeeds", async () => { const executionPromise = runner.run({ payload: { shouldFail: false } }); @@ -24,6 +24,8 @@ createTests({ result: JSON.stringify({ data: "completed" }), success: true, }); + + assertEventSignatures(execution); }); it("should fail after exhausting retries when submitter always fails", async () => { diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/timeout/wait-for-callback-timeout.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/timeout/wait-for-callback-timeout.history.json new file mode 100644 index 00000000..56e01aac --- /dev/null +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/timeout/wait-for-callback-timeout.history.json @@ -0,0 +1,118 @@ +[ + { + "EventType": "ExecutionStarted", + "EventId": 1, + "Id": "e1121610-07ff-4850-8c04-b98532a3bee4", + "EventTimestamp": "2025-12-10T00:12:28.109Z", + "ExecutionStartedDetails": { + "Input": { + "Payload": "{\"test\":\"timeout-scenario\"}" + } + } + }, + { + "EventType": "ContextStarted", + "SubType": "WaitForCallback", + "EventId": 2, + "Id": "c4ca4238a0b92382", + "EventTimestamp": "2025-12-10T00:12:28.114Z", + "ContextStartedDetails": {} + }, + { + "EventType": "CallbackStarted", + "SubType": "Callback", + "EventId": 3, + "Id": "ea66c06c1e1c05fa", + "EventTimestamp": "2025-12-10T00:12:28.114Z", + "ParentId": "c4ca4238a0b92382", + "CallbackStartedDetails": { + "CallbackId": "eyJleGVjdXRpb25JZCI6ImYwNmZjMDU5LWI5NTEtNDllNS05YTUwLWM5OWRmZTNhYjJjNCIsIm9wZXJhdGlvbklkIjoiZWE2NmMwNmMxZTFjMDVmYSIsInRva2VuIjoiYjE4MGEzN2EtMDdjMC00MDQ4LTlmZjktMzNiODlkNTJhNDU1In0=", + "Timeout": 1, + "Input": {} + } + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 4, + "Id": "98c6f2c2287f4c73", + "EventTimestamp": "2025-12-10T00:12:28.116Z", + "ParentId": "c4ca4238a0b92382", + "StepStartedDetails": {} + }, + { + "EventType": "StepSucceeded", + "SubType": "Step", + "EventId": 5, + "Id": "98c6f2c2287f4c73", + "EventTimestamp": "2025-12-10T00:12:28.116Z", + "ParentId": "c4ca4238a0b92382", + "StepSucceededDetails": { + "Result": {}, + "RetryDetails": {} + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 6, + "EventTimestamp": "2025-12-10T00:12:28.168Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:12:28.109Z", + "EndTimestamp": "2025-12-10T00:12:28.168Z", + "Error": {}, + "RequestId": "e6aceb7f-54ec-457b-bf82-38c62b68c8ab" + } + }, + { + "EventType": "CallbackTimedOut", + "SubType": "Callback", + "EventId": 7, + "Id": "ea66c06c1e1c05fa", + "EventTimestamp": "2025-12-10T00:12:29.115Z", + "ParentId": "c4ca4238a0b92382", + "CallbackTimedOutDetails": { + "Error": { + "Payload": { + "ErrorMessage": "Callback timed out" + } + } + } + }, + { + "EventType": "ContextFailed", + "SubType": "WaitForCallback", + "EventId": 8, + "Id": "c4ca4238a0b92382", + "EventTimestamp": "2025-12-10T00:12:29.119Z", + "ContextFailedDetails": { + "Error": { + "Payload": { + "ErrorType": "CallbackError", + "ErrorMessage": "Callback timed out" + } + } + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 9, + "EventTimestamp": "2025-12-10T00:12:29.119Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-10T00:12:29.117Z", + "EndTimestamp": "2025-12-10T00:12:29.119Z", + "Error": {}, + "RequestId": "b40a9b97-60fe-4a61-97cf-6cf8c8b9d72a" + } + }, + { + "EventType": "ExecutionSucceeded", + "EventId": 10, + "Id": "e1121610-07ff-4850-8c04-b98532a3bee4", + "EventTimestamp": "2025-12-10T00:12:29.119Z", + "ExecutionSucceededDetails": { + "Result": { + "Payload": "{\"success\":false,\"error\":\"Callback timed out\"}" + } + } + } +] diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/timeout/wait-for-callback-timeout.test.ts b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/timeout/wait-for-callback-timeout.test.ts index be0feb45..7b6bc757 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/timeout/wait-for-callback-timeout.test.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/timeout/wait-for-callback-timeout.test.ts @@ -5,7 +5,7 @@ import { createTests } from "../../../utils/test-helper"; createTests({ handler, invocationType: InvocationType.Event, - tests: (runner) => { + tests: (runner, { assertEventSignatures }) => { it("should handle waitForCallback timeout scenarios", async () => { const result = await runner.run({ payload: { test: "timeout-scenario" }, @@ -17,6 +17,8 @@ createTests({ success: false, error: expect.any(String), }); + + assertEventSignatures(result); }); }, }); diff --git a/packages/aws-durable-execution-sdk-js-examples/src/utils/test-helper.ts b/packages/aws-durable-execution-sdk-js-examples/src/utils/test-helper.ts index 07e608b7..a6ebc660 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/utils/test-helper.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/utils/test-helper.ts @@ -9,7 +9,7 @@ import { LocalDurableTestRunnerSetupParameters, TestResult, } from "@aws/durable-execution-sdk-js-testing"; -import { readFileSync } from "fs"; +import { existsSync, readFileSync, writeFileSync } from "fs"; import path from "path"; export interface FunctionNameMap { @@ -139,14 +139,21 @@ function getCallerFile(): string { */ export function createTests(testDef: TestDefinition) { const isIntegrationTest = process.env.NODE_ENV === "integration"; + const generateHistories = process.env.GENERATE_HISTORY === "true"; const isTimeSkipping = (testDef.localRunnerConfig?.skipTime ?? true) && !isIntegrationTest; + if (generateHistories && isTimeSkipping && !isIntegrationTest) { + console.warn("Disabling skipTime since GENERATE_HISTORY is true"); + jest.setTimeout(120000); + } + const testFileName = getCallerFile(); const parsedFunctionName = path.basename(testFileName, ".test.ts"); + let calledAssertEventSignature = false; const testHelper: TestHelper = { - isTimeSkipping, + isTimeSkipping: isTimeSkipping && !generateHistories, isCloud: isIntegrationTest, assertEventSignatures: (testResult: TestResult, suffix) => { calledAssertEventSignature = true; @@ -159,10 +166,28 @@ export function createTests(testDef: TestDefinition) { path.dirname(testFileName), `${historyFileBasename}.history.json`, ); + + if (generateHistories) { + if (!existsSync(historyFilePath)) { + console.log(`Generated missing history for ${historyFileBasename}`); + writeFileSync( + historyFilePath, + JSON.stringify(testResult.getHistoryEvents(), null, 2), + ); + return; + } + } + + if (!existsSync(historyFilePath)) { + throw new Error( + `History file ${historyFilePath} does not exist. Please run the test with GENERATE_HISTORY=true to generate it.`, + ); + } + return assertEventSignatures( testResult.getHistoryEvents(), JSON.parse(readFileSync(historyFilePath).toString("utf-8")), - testHelper.isTimeSkipping, + isTimeSkipping, ); }, functionNameMap: isIntegrationTest @@ -172,7 +197,7 @@ export function createTests(testDef: TestDefinition) { afterAll(() => { if (!calledAssertEventSignature) { - console.warn( + throw new Error( `assertEventSignature was not called for test ${parsedFunctionName}`, ); } From 28b6ad612efa8df001391ba43fd287efaf5089f6 Mon Sep 17 00:00:00 2001 From: Anthony Ting Date: Wed, 10 Dec 2025 16:58:08 -0800 Subject: [PATCH 05/14] fix wait for callback multiple invocations history --- ...callback-multiple-invocations.history.json | 131 ++++++++++-------- 1 file changed, 71 insertions(+), 60 deletions(-) diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/multiple-invocations/wait-for-callback-multiple-invocations.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/multiple-invocations/wait-for-callback-multiple-invocations.history.json index b6e0929f..7f0ab556 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/multiple-invocations/wait-for-callback-multiple-invocations.history.json +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/multiple-invocations/wait-for-callback-multiple-invocations.history.json @@ -2,8 +2,8 @@ { "EventType": "ExecutionStarted", "EventId": 1, - "Id": "cb4f4efd-59c3-472c-a44b-ee902b460647", - "EventTimestamp": "2025-12-10T00:15:09.992Z", + "Id": "7e96946b-8064-40a3-9775-52df4461a1a0", + "EventTimestamp": "2025-12-11T00:57:48.416Z", "ExecutionStartedDetails": { "Input": { "Payload": "{\"test\":\"multiple-invocations\"}" @@ -16,41 +16,41 @@ "EventId": 2, "Id": "c4ca4238a0b92382", "Name": "wait-invocation-1", - "EventTimestamp": "2025-12-10T00:15:10.015Z", + "EventTimestamp": "2025-12-11T00:57:48.422Z", "WaitStartedDetails": { "Duration": 1, - "ScheduledEndTimestamp": "2025-12-10T00:15:11.015Z" + "ScheduledEndTimestamp": "2025-12-11T00:57:49.422Z" + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 3, + "EventTimestamp": "2025-12-11T00:57:48.425Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-11T00:57:48.416Z", + "EndTimestamp": "2025-12-11T00:57:48.425Z", + "Error": {}, + "RequestId": "1f306733-3ca0-44fa-81e2-70c2d4d9a80d" } }, { "EventType": "WaitSucceeded", "SubType": "Wait", - "EventId": 3, + "EventId": 4, "Id": "c4ca4238a0b92382", "Name": "wait-invocation-1", - "EventTimestamp": "2025-12-10T00:15:10.016Z", + "EventTimestamp": "2025-12-11T00:57:49.422Z", "WaitSucceededDetails": { "Duration": 1 } }, - { - "EventType": "InvocationCompleted", - "EventId": 4, - "EventTimestamp": "2025-12-10T00:15:10.016Z", - "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-10T00:15:09.992Z", - "EndTimestamp": "2025-12-10T00:15:10.016Z", - "Error": {}, - "RequestId": "94c49b99-ea48-4e7c-bf5d-59947766a1db" - } - }, { "EventType": "ContextStarted", "SubType": "WaitForCallback", "EventId": 5, "Id": "c81e728d9d4c2f63", "Name": "first-callback", - "EventTimestamp": "2025-12-10T00:15:10.067Z", + "EventTimestamp": "2025-12-11T00:57:49.424Z", "ContextStartedDetails": {} }, { @@ -58,10 +58,10 @@ "SubType": "Callback", "EventId": 6, "Id": "8fbdbf5573b18fae", - "EventTimestamp": "2025-12-10T00:15:10.067Z", + "EventTimestamp": "2025-12-11T00:57:49.424Z", "ParentId": "c81e728d9d4c2f63", "CallbackStartedDetails": { - "CallbackId": "eyJleGVjdXRpb25JZCI6Ijg3YTc5NjZlLTFlODItNGYwOC1hZmFlLTg4YmNjYTU3ODU2NSIsIm9wZXJhdGlvbklkIjoiOGZiZGJmNTU3M2IxOGZhZSIsInRva2VuIjoiYTE3YzI1MzQtMGJiZS00ZmQzLWI5OGQtNDJjOTEyOWU4Zjc3In0=", + "CallbackId": "eyJleGVjdXRpb25JZCI6ImU0ZGVhNzBmLTk3ZmEtNDg0Yy04ZTM3LTMzOGZkM2FjZTQxYiIsIm9wZXJhdGlvbklkIjoiOGZiZGJmNTU3M2IxOGZhZSIsInRva2VuIjoiOTAwZTkyZjQtY2UzZC00ZDg5LWJiOWUtZmQxMGY2NDFhMjg5In0=", "Input": {} } }, @@ -70,7 +70,7 @@ "SubType": "Step", "EventId": 7, "Id": "3c46a0407be60a1f", - "EventTimestamp": "2025-12-10T00:15:10.088Z", + "EventTimestamp": "2025-12-11T00:57:49.426Z", "ParentId": "c81e728d9d4c2f63", "StepStartedDetails": {} }, @@ -79,7 +79,7 @@ "SubType": "Step", "EventId": 8, "Id": "3c46a0407be60a1f", - "EventTimestamp": "2025-12-10T00:15:10.088Z", + "EventTimestamp": "2025-12-11T00:57:49.427Z", "ParentId": "c81e728d9d4c2f63", "StepSucceededDetails": { "Result": {}, @@ -91,7 +91,7 @@ "SubType": "Callback", "EventId": 9, "Id": "8fbdbf5573b18fae", - "EventTimestamp": "2025-12-10T00:15:10.096Z", + "EventTimestamp": "2025-12-11T00:57:49.428Z", "ParentId": "c81e728d9d4c2f63", "CallbackSucceededDetails": { "Result": { @@ -102,12 +102,12 @@ { "EventType": "InvocationCompleted", "EventId": 10, - "EventTimestamp": "2025-12-10T00:15:10.146Z", + "EventTimestamp": "2025-12-11T00:57:49.428Z", "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-10T00:15:10.041Z", - "EndTimestamp": "2025-12-10T00:15:10.146Z", + "StartTimestamp": "2025-12-11T00:57:49.422Z", + "EndTimestamp": "2025-12-11T00:57:49.428Z", "Error": {}, - "RequestId": "2a57e98b-dfe2-4365-8d0d-a3dc1d0cb26b" + "RequestId": "4c10a9dd-5aec-411e-b797-6ecb46aa9fa6" } }, { @@ -116,7 +116,7 @@ "EventId": 11, "Id": "c81e728d9d4c2f63", "Name": "first-callback", - "EventTimestamp": "2025-12-10T00:15:10.188Z", + "EventTimestamp": "2025-12-11T00:57:49.431Z", "ContextSucceededDetails": { "Result": { "Payload": "\"{\\\"step\\\":1}\"" @@ -129,7 +129,7 @@ "EventId": 12, "Id": "eccbc87e4b5ce2fe", "Name": "process-callback-data", - "EventTimestamp": "2025-12-10T00:15:10.188Z", + "EventTimestamp": "2025-12-11T00:57:49.432Z", "StepStartedDetails": {} }, { @@ -138,7 +138,7 @@ "EventId": 13, "Id": "eccbc87e4b5ce2fe", "Name": "process-callback-data", - "EventTimestamp": "2025-12-10T00:15:10.188Z", + "EventTimestamp": "2025-12-11T00:57:49.432Z", "StepSucceededDetails": { "Result": { "Payload": "{\"processed\":true,\"step\":1}" @@ -152,19 +152,30 @@ "EventId": 14, "Id": "a87ff679a2f3e71d", "Name": "wait-invocation-2", - "EventTimestamp": "2025-12-10T00:15:10.208Z", + "EventTimestamp": "2025-12-11T00:57:49.433Z", "WaitStartedDetails": { "Duration": 1, - "ScheduledEndTimestamp": "2025-12-10T00:15:11.208Z" + "ScheduledEndTimestamp": "2025-12-11T00:57:50.433Z" + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 15, + "EventTimestamp": "2025-12-11T00:57:49.435Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-11T00:57:49.429Z", + "EndTimestamp": "2025-12-11T00:57:49.435Z", + "Error": {}, + "RequestId": "ccc0514b-782f-4768-af1d-69c0d5d8670c" } }, { "EventType": "WaitSucceeded", "SubType": "Wait", - "EventId": 15, + "EventId": 16, "Id": "a87ff679a2f3e71d", "Name": "wait-invocation-2", - "EventTimestamp": "2025-12-10T00:15:10.209Z", + "EventTimestamp": "2025-12-11T00:57:50.433Z", "WaitSucceededDetails": { "Duration": 1 } @@ -172,39 +183,39 @@ { "EventType": "ContextStarted", "SubType": "WaitForCallback", - "EventId": 16, + "EventId": 17, "Id": "e4da3b7fbbce2345", "Name": "second-callback", - "EventTimestamp": "2025-12-10T00:15:10.251Z", + "EventTimestamp": "2025-12-11T00:57:50.436Z", "ContextStartedDetails": {} }, { "EventType": "CallbackStarted", "SubType": "Callback", - "EventId": 17, + "EventId": 18, "Id": "19a1de167122a18a", - "EventTimestamp": "2025-12-10T00:15:10.251Z", + "EventTimestamp": "2025-12-11T00:57:50.436Z", "ParentId": "e4da3b7fbbce2345", "CallbackStartedDetails": { - "CallbackId": "eyJleGVjdXRpb25JZCI6Ijg3YTc5NjZlLTFlODItNGYwOC1hZmFlLTg4YmNjYTU3ODU2NSIsIm9wZXJhdGlvbklkIjoiMTlhMWRlMTY3MTIyYTE4YSIsInRva2VuIjoiMTkyNzFlZDktNTVhMC00MzczLTk3YTEtYTBlNmM3YmY3YTI4In0=", + "CallbackId": "eyJleGVjdXRpb25JZCI6ImU0ZGVhNzBmLTk3ZmEtNDg0Yy04ZTM3LTMzOGZkM2FjZTQxYiIsIm9wZXJhdGlvbklkIjoiMTlhMWRlMTY3MTIyYTE4YSIsInRva2VuIjoiNThhYTIzMzUtYWZkYi00N2M0LTk4NzQtY2E5NjE1ZDU5MzNmIn0=", "Input": {} } }, { "EventType": "StepStarted", "SubType": "Step", - "EventId": 18, + "EventId": 19, "Id": "dca19ffa163054fe", - "EventTimestamp": "2025-12-10T00:15:10.271Z", + "EventTimestamp": "2025-12-11T00:57:50.437Z", "ParentId": "e4da3b7fbbce2345", "StepStartedDetails": {} }, { "EventType": "StepSucceeded", "SubType": "Step", - "EventId": 19, + "EventId": 20, "Id": "dca19ffa163054fe", - "EventTimestamp": "2025-12-10T00:15:10.271Z", + "EventTimestamp": "2025-12-11T00:57:50.437Z", "ParentId": "e4da3b7fbbce2345", "StepSucceededDetails": { "Result": {}, @@ -214,9 +225,9 @@ { "EventType": "CallbackSucceeded", "SubType": "Callback", - "EventId": 20, + "EventId": 21, "Id": "19a1de167122a18a", - "EventTimestamp": "2025-12-10T00:15:10.272Z", + "EventTimestamp": "2025-12-11T00:57:50.438Z", "ParentId": "e4da3b7fbbce2345", "CallbackSucceededDetails": { "Result": { @@ -226,22 +237,22 @@ }, { "EventType": "InvocationCompleted", - "EventId": 21, - "EventTimestamp": "2025-12-10T00:15:10.333Z", + "EventId": 22, + "EventTimestamp": "2025-12-11T00:57:50.439Z", "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-10T00:15:10.166Z", - "EndTimestamp": "2025-12-10T00:15:10.333Z", + "StartTimestamp": "2025-12-11T00:57:50.433Z", + "EndTimestamp": "2025-12-11T00:57:50.439Z", "Error": {}, - "RequestId": "de8fdd22-af11-43e6-92eb-5ceea86cafc2" + "RequestId": "bfded0ba-76dc-4900-bbcd-7abb62cff2bc" } }, { "EventType": "ContextSucceeded", "SubType": "WaitForCallback", - "EventId": 22, + "EventId": 23, "Id": "e4da3b7fbbce2345", "Name": "second-callback", - "EventTimestamp": "2025-12-10T00:15:10.376Z", + "EventTimestamp": "2025-12-11T00:57:50.441Z", "ContextSucceededDetails": { "Result": { "Payload": "\"{\\\"step\\\":2}\"" @@ -250,20 +261,20 @@ }, { "EventType": "InvocationCompleted", - "EventId": 23, - "EventTimestamp": "2025-12-10T00:15:10.376Z", + "EventId": 24, + "EventTimestamp": "2025-12-11T00:57:50.441Z", "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-10T00:15:10.353Z", - "EndTimestamp": "2025-12-10T00:15:10.376Z", + "StartTimestamp": "2025-12-11T00:57:50.439Z", + "EndTimestamp": "2025-12-11T00:57:50.441Z", "Error": {}, - "RequestId": "c6334fb0-631d-4cca-b3bc-88857a044145" + "RequestId": "51b1bff4-216b-4f2f-8045-486656ba5667" } }, { "EventType": "ExecutionSucceeded", - "EventId": 24, - "Id": "cb4f4efd-59c3-472c-a44b-ee902b460647", - "EventTimestamp": "2025-12-10T00:15:10.376Z", + "EventId": 25, + "Id": "7e96946b-8064-40a3-9775-52df4461a1a0", + "EventTimestamp": "2025-12-11T00:57:50.441Z", "ExecutionSucceededDetails": { "Result": { "Payload": "{\"firstCallback\":\"{\\\"step\\\":1}\",\"secondCallback\":\"{\\\"step\\\":2}\",\"stepResult\":{\"processed\":true,\"step\":1},\"invocationCount\":\"multiple\"}" From 4e6296c7d5c4e8709160f6e601f473037c7123af Mon Sep 17 00:00:00 2001 From: Anthony Ting Date: Thu, 11 Dec 2025 14:10:59 -0800 Subject: [PATCH 06/14] send callback success updates in parallel, and delay success to ensure invocation completes --- .../create-callback-concurrent.history.json | 62 +++++++++---------- .../create-callback-concurrent.test.ts | 11 +++- 2 files changed, 39 insertions(+), 34 deletions(-) diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/concurrent/create-callback-concurrent.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/concurrent/create-callback-concurrent.history.json index 59efc1fe..96d5bf22 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/concurrent/create-callback-concurrent.history.json +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/concurrent/create-callback-concurrent.history.json @@ -2,8 +2,8 @@ { "EventType": "ExecutionStarted", "EventId": 1, - "Id": "baad178f-c918-474e-932a-7d0f8868e4be", - "EventTimestamp": "2025-12-10T00:15:09.988Z", + "Id": "ef61112a-8abb-4cb1-b4eb-e84df17b3eff", + "EventTimestamp": "2025-12-11T22:10:27.253Z", "ExecutionStartedDetails": { "Input": { "Payload": "{}" @@ -16,9 +16,9 @@ "EventId": 2, "Id": "c4ca4238a0b92382", "Name": "api-call-1", - "EventTimestamp": "2025-12-10T00:15:10.018Z", + "EventTimestamp": "2025-12-11T22:10:27.286Z", "CallbackStartedDetails": { - "CallbackId": "eyJleGVjdXRpb25JZCI6IjNlZWIyMjRlLWM2ZGMtNDMzZC04NjFhLWI2YzlhZTIzMjg3NSIsIm9wZXJhdGlvbklkIjoiYzRjYTQyMzhhMGI5MjM4MiIsInRva2VuIjoiM2RjNGQ0ZjAtZGM4OS00YThiLTgxZDgtMmExZDE2MTVhMGRkIn0=", + "CallbackId": "eyJleGVjdXRpb25JZCI6ImY5MmRjZDMzLTE1NTEtNDg2OS04ZDhmLTVkY2E1ZmMzNjM0YyIsIm9wZXJhdGlvbklkIjoiYzRjYTQyMzhhMGI5MjM4MiIsInRva2VuIjoiYmMxM2U4MjYtNmIyZC00MzQyLThjOTYtNDg1MmM1NDhjNTk2In0=", "Timeout": 300, "Input": {} } @@ -29,9 +29,9 @@ "EventId": 3, "Id": "c81e728d9d4c2f63", "Name": "api-call-2", - "EventTimestamp": "2025-12-10T00:15:10.039Z", + "EventTimestamp": "2025-12-11T22:10:27.307Z", "CallbackStartedDetails": { - "CallbackId": "eyJleGVjdXRpb25JZCI6IjNlZWIyMjRlLWM2ZGMtNDMzZC04NjFhLWI2YzlhZTIzMjg3NSIsIm9wZXJhdGlvbklkIjoiYzgxZTcyOGQ5ZDRjMmY2MyIsInRva2VuIjoiMjAwMjczNzMtNWM0Zi00OGY2LTg0NTEtODc4MmM5Njg4ZTNiIn0=", + "CallbackId": "eyJleGVjdXRpb25JZCI6ImY5MmRjZDMzLTE1NTEtNDg2OS04ZDhmLTVkY2E1ZmMzNjM0YyIsIm9wZXJhdGlvbklkIjoiYzgxZTcyOGQ5ZDRjMmY2MyIsInRva2VuIjoiY2EyOWZmYWQtZDMyMi00YmQ1LTlkNGMtNGY4ZjAxYTk2MjI1In0=", "Timeout": 300, "Input": {} } @@ -42,20 +42,31 @@ "EventId": 4, "Id": "eccbc87e4b5ce2fe", "Name": "api-call-3", - "EventTimestamp": "2025-12-10T00:15:10.067Z", + "EventTimestamp": "2025-12-11T22:10:27.327Z", "CallbackStartedDetails": { - "CallbackId": "eyJleGVjdXRpb25JZCI6IjNlZWIyMjRlLWM2ZGMtNDMzZC04NjFhLWI2YzlhZTIzMjg3NSIsIm9wZXJhdGlvbklkIjoiZWNjYmM4N2U0YjVjZTJmZSIsInRva2VuIjoiZTAyMTdlNWItMDQyZS00MmRjLWEwNmEtZGFkMzQ4ZjgzNzQwIn0=", + "CallbackId": "eyJleGVjdXRpb25JZCI6ImY5MmRjZDMzLTE1NTEtNDg2OS04ZDhmLTVkY2E1ZmMzNjM0YyIsIm9wZXJhdGlvbklkIjoiZWNjYmM4N2U0YjVjZTJmZSIsInRva2VuIjoiYjAzNTJkYTItMjlhNy00NjViLWI1ZDItNzdjMDgxOTI1MzBlIn0=", "Timeout": 300, "Input": {} } }, + { + "EventType": "InvocationCompleted", + "EventId": 5, + "EventTimestamp": "2025-12-11T22:10:27.347Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-11T22:10:27.253Z", + "EndTimestamp": "2025-12-11T22:10:27.347Z", + "Error": {}, + "RequestId": "87f8f141-1f5f-456f-b2ce-332246be3e33" + } + }, { "EventType": "CallbackSucceeded", "SubType": "Callback", - "EventId": 5, + "EventId": 6, "Id": "c81e728d9d4c2f63", "Name": "api-call-2", - "EventTimestamp": "2025-12-10T00:15:10.070Z", + "EventTimestamp": "2025-12-11T22:10:27.431Z", "CallbackSucceededDetails": { "Result": { "Payload": "{\"id\":2,\"data\":\"second\"}" @@ -65,10 +76,10 @@ { "EventType": "CallbackSucceeded", "SubType": "Callback", - "EventId": 6, + "EventId": 7, "Id": "c4ca4238a0b92382", "Name": "api-call-1", - "EventTimestamp": "2025-12-10T00:15:10.071Z", + "EventTimestamp": "2025-12-11T22:10:27.432Z", "CallbackSucceededDetails": { "Result": { "Payload": "{\"id\":1,\"data\":\"first\"}" @@ -78,43 +89,32 @@ { "EventType": "CallbackSucceeded", "SubType": "Callback", - "EventId": 7, + "EventId": 8, "Id": "eccbc87e4b5ce2fe", "Name": "api-call-3", - "EventTimestamp": "2025-12-10T00:15:10.075Z", + "EventTimestamp": "2025-12-11T22:10:27.432Z", "CallbackSucceededDetails": { "Result": { "Payload": "{\"id\":3,\"data\":\"third\"}" } } }, - { - "EventType": "InvocationCompleted", - "EventId": 8, - "EventTimestamp": "2025-12-10T00:15:10.126Z", - "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-10T00:15:09.987Z", - "EndTimestamp": "2025-12-10T00:15:10.126Z", - "Error": {}, - "RequestId": "6f2132e4-4618-4e08-88c0-9819e79685ca" - } - }, { "EventType": "InvocationCompleted", "EventId": 9, - "EventTimestamp": "2025-12-10T00:15:10.146Z", + "EventTimestamp": "2025-12-11T22:10:27.453Z", "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-10T00:15:10.146Z", - "EndTimestamp": "2025-12-10T00:15:10.146Z", + "StartTimestamp": "2025-12-11T22:10:27.452Z", + "EndTimestamp": "2025-12-11T22:10:27.453Z", "Error": {}, - "RequestId": "7b23a50d-1b08-47d5-96ed-473f84c01ffd" + "RequestId": "9f51c6e9-d21b-4ba7-be12-2ced22ae2f29" } }, { "EventType": "ExecutionSucceeded", "EventId": 10, - "Id": "baad178f-c918-474e-932a-7d0f8868e4be", - "EventTimestamp": "2025-12-10T00:15:10.147Z", + "Id": "ef61112a-8abb-4cb1-b4eb-e84df17b3eff", + "EventTimestamp": "2025-12-11T22:10:27.453Z", "ExecutionSucceededDetails": { "Result": { "Payload": "{\"results\":[\"{\\\"id\\\":1,\\\"data\\\":\\\"first\\\"}\",\"{\\\"id\\\":2,\\\"data\\\":\\\"second\\\"}\",\"{\\\"id\\\":3,\\\"data\\\":\\\"third\\\"}\"],\"allCompleted\":true}" diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/concurrent/create-callback-concurrent.test.ts b/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/concurrent/create-callback-concurrent.test.ts index 1c3400ac..002f5f82 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/concurrent/create-callback-concurrent.test.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/concurrent/create-callback-concurrent.test.ts @@ -25,22 +25,27 @@ createTests({ callback3.waitForData(WaitingOperationStatus.STARTED), ]); + // Wait a bit to ensure invocations complete (TODO: add a waitForInvocation to testing lib) + await new Promise((resolve) => setTimeout(resolve, 100)); + // Complete callbacks in different order const callbackResult2 = JSON.stringify({ id: 2, data: "second", }); - await callback2.sendCallbackSuccess(callbackResult2); const callbackResult1 = JSON.stringify({ id: 1, data: "first", }); - await callback1.sendCallbackSuccess(callbackResult1); const callbackResult3 = JSON.stringify({ id: 3, data: "third", }); - await callback3.sendCallbackSuccess(callbackResult3); + await Promise.all([ + callback2.sendCallbackSuccess(callbackResult2), + callback1.sendCallbackSuccess(callbackResult1), + callback3.sendCallbackSuccess(callbackResult3), + ]); const result = await executionPromise; From 7fbf36cd2178a3916ef8b12e34ea36f54a2395b4 Mon Sep 17 00:00:00 2001 From: Anthony Ting Date: Thu, 11 Dec 2025 14:37:14 -0800 Subject: [PATCH 07/14] add invocation difference config --- .../create-callback-concurrent.test.ts | 4 +- .../src/utils/test-helper.ts | 46 ++++++++++++++++++- 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/concurrent/create-callback-concurrent.test.ts b/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/concurrent/create-callback-concurrent.test.ts index 002f5f82..6dfd13d4 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/concurrent/create-callback-concurrent.test.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/concurrent/create-callback-concurrent.test.ts @@ -63,7 +63,9 @@ createTests({ ), ).toBe(true); - assertEventSignatures(result); + assertEventSignatures(result, undefined, { + invocationCompletedDifference: 1, + }); }); }, }); diff --git a/packages/aws-durable-execution-sdk-js-examples/src/utils/test-helper.ts b/packages/aws-durable-execution-sdk-js-examples/src/utils/test-helper.ts index a6ebc660..29dc4f58 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/utils/test-helper.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/utils/test-helper.ts @@ -42,10 +42,23 @@ export interface TestDefinition { localRunnerConfig?: LocalDurableTestRunnerSetupParameters; } +export interface EventSignatureConfig { + /** + * Due to API delays or other conditions, the number of invocations can change. + * This property sets a threshold where the number of invocations in the actual history + * must be in a specified range based on the expected history. + */ + invocationCompletedDifference?: number; +} + export interface TestHelper { isTimeSkipping: boolean; isCloud: boolean; - assertEventSignatures(testResult: TestResult, suffix?: string): void; + assertEventSignatures( + testResult: TestResult, + suffix?: string, + eventSignatureConfig?: EventSignatureConfig, + ): void; functionNameMap: FunctionNameMap; } @@ -104,10 +117,34 @@ function assertEventSignatures( actualEvents: Event[], expectedEvents: EventSignature[], isTimeSkipping: boolean = false, + eventSignatureConfig?: EventSignatureConfig, ) { const actualCounts = countEventSignatures(actualEvents, isTimeSkipping); const expectedCounts = countEventSignatures(expectedEvents, isTimeSkipping); + if (eventSignatureConfig?.invocationCompletedDifference) { + const invocationCompletedSignature = JSON.stringify( + createEventSignature({ EventType: EventType.InvocationCompleted }), + ); + + const actualInvocationCompleted = actualCounts.get( + invocationCompletedSignature, + ); + actualCounts.delete(invocationCompletedSignature); + + const expectedInvocationsCompleted = expectedCounts.get( + invocationCompletedSignature, + ); + expectedCounts.delete(invocationCompletedSignature); + + const invocationCompletedDifference = Math.abs( + actualInvocationCompleted - expectedInvocationsCompleted, + ); + expect(invocationCompletedDifference).toBeLessThanOrEqual( + eventSignatureConfig.invocationCompletedDifference, + ); + } + expect(actualCounts).toEqual(expectedCounts); } @@ -155,7 +192,11 @@ export function createTests(testDef: TestDefinition) { const testHelper: TestHelper = { isTimeSkipping: isTimeSkipping && !generateHistories, isCloud: isIntegrationTest, - assertEventSignatures: (testResult: TestResult, suffix) => { + assertEventSignatures: ( + testResult: TestResult, + suffix, + eventSignatureConfig, + ) => { calledAssertEventSignature = true; const historyFileBasename = suffix @@ -188,6 +229,7 @@ export function createTests(testDef: TestDefinition) { testResult.getHistoryEvents(), JSON.parse(readFileSync(historyFilePath).toString("utf-8")), isTimeSkipping, + eventSignatureConfig, ); }, functionNameMap: isIntegrationTest From 529b9f6430177fbe34ee58f8f057b20cb47800d2 Mon Sep 17 00:00:00 2001 From: Anthony Ting Date: Thu, 11 Dec 2025 15:52:23 -0800 Subject: [PATCH 08/14] wait for invocation completion in create callback mixed ops --- .../create-callback-mixed-ops.history.json | 82 +++++++++---------- .../create-callback-mixed-ops.test.ts | 4 + 2 files changed, 45 insertions(+), 41 deletions(-) diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/mixed-ops/create-callback-mixed-ops.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/mixed-ops/create-callback-mixed-ops.history.json index 9dfe103f..47ea6f5b 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/mixed-ops/create-callback-mixed-ops.history.json +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/mixed-ops/create-callback-mixed-ops.history.json @@ -2,8 +2,8 @@ { "EventType": "ExecutionStarted", "EventId": 1, - "Id": "6e7afd87-c2cd-4b0a-9d07-e40c3bf50842", - "EventTimestamp": "2025-12-10T00:12:39.173Z", + "Id": "3143bfd1-a390-4143-bf5c-f015c3c69dc3", + "EventTimestamp": "2025-12-11T23:51:39.590Z", "ExecutionStartedDetails": { "Input": { "Payload": "{}" @@ -16,7 +16,7 @@ "EventId": 2, "Id": "c4ca4238a0b92382", "Name": "fetch-data", - "EventTimestamp": "2025-12-10T00:12:39.177Z", + "EventTimestamp": "2025-12-11T23:51:39.624Z", "StepStartedDetails": {} }, { @@ -25,7 +25,7 @@ "EventId": 3, "Id": "c4ca4238a0b92382", "Name": "fetch-data", - "EventTimestamp": "2025-12-10T00:12:39.177Z", + "EventTimestamp": "2025-12-11T23:51:39.624Z", "StepSucceededDetails": { "Result": { "Payload": "{\"userId\":123,\"name\":\"John Doe\"}" @@ -39,79 +39,79 @@ "EventId": 4, "Id": "c81e728d9d4c2f63", "Name": "process-user", - "EventTimestamp": "2025-12-10T00:12:39.179Z", + "EventTimestamp": "2025-12-11T23:51:39.644Z", "CallbackStartedDetails": { - "CallbackId": "eyJleGVjdXRpb25JZCI6ImM0M2MzNWYzLWRhMzMtNDkwZS05MDljLWMwNTU3ZjJkODQ3NCIsIm9wZXJhdGlvbklkIjoiYzgxZTcyOGQ5ZDRjMmY2MyIsInRva2VuIjoiYTMwNTU3NTMtNWJiMy00MzAyLWJkYjQtZGQ4NTQ0M2ZkMWIxIn0=", + "CallbackId": "eyJleGVjdXRpb25JZCI6ImUzZjZkZjhmLTk2NmQtNGRiMi1iYzkzLTQ4NWY5OWE1NWZlNSIsIm9wZXJhdGlvbklkIjoiYzgxZTcyOGQ5ZDRjMmY2MyIsInRva2VuIjoiZTBjMGE1OTgtOTBkYS00ODY1LWIzOWYtNDYxMzY2OWNiZTExIn0=", "Timeout": 300, "Input": {} } }, { - "EventType": "CallbackSucceeded", - "SubType": "Callback", + "EventType": "WaitStarted", + "SubType": "Wait", "EventId": 5, - "Id": "c81e728d9d4c2f63", - "Name": "process-user", - "EventTimestamp": "2025-12-10T00:12:39.180Z", - "CallbackSucceededDetails": { - "Result": { - "Payload": "{\"processed\":true,\"timestamp\":1765325559179}" - } + "Id": "eccbc87e4b5ce2fe", + "Name": "initial-wait", + "EventTimestamp": "2025-12-11T23:51:39.669Z", + "WaitStartedDetails": { + "Duration": 1, + "ScheduledEndTimestamp": "2025-12-11T23:51:40.669Z" } }, { - "EventType": "WaitStarted", + "EventType": "WaitSucceeded", "SubType": "Wait", "EventId": 6, "Id": "eccbc87e4b5ce2fe", "Name": "initial-wait", - "EventTimestamp": "2025-12-10T00:12:39.181Z", - "WaitStartedDetails": { - "Duration": 1, - "ScheduledEndTimestamp": "2025-12-10T00:12:40.181Z" + "EventTimestamp": "2025-12-11T23:51:39.670Z", + "WaitSucceededDetails": { + "Duration": 1 } }, { - "EventType": "InvocationCompleted", + "EventType": "CallbackSucceeded", + "SubType": "Callback", "EventId": 7, - "EventTimestamp": "2025-12-10T00:12:39.233Z", - "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-10T00:12:39.173Z", - "EndTimestamp": "2025-12-10T00:12:39.233Z", - "Error": {}, - "RequestId": "e7549444-7453-4869-b047-ee7feb42d122" + "Id": "c81e728d9d4c2f63", + "Name": "process-user", + "EventTimestamp": "2025-12-11T23:51:39.671Z", + "CallbackSucceededDetails": { + "Result": { + "Payload": "{\"processed\":true,\"timestamp\":1765497099653}" + } } }, { - "EventType": "WaitSucceeded", - "SubType": "Wait", + "EventType": "InvocationCompleted", "EventId": 8, - "Id": "eccbc87e4b5ce2fe", - "Name": "initial-wait", - "EventTimestamp": "2025-12-10T00:12:40.183Z", - "WaitSucceededDetails": { - "Duration": 1 + "EventTimestamp": "2025-12-11T23:51:39.671Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-11T23:51:39.590Z", + "EndTimestamp": "2025-12-11T23:51:39.671Z", + "Error": {}, + "RequestId": "525d4dec-9396-4fd3-a630-55f21c6e7878" } }, { "EventType": "InvocationCompleted", "EventId": 9, - "EventTimestamp": "2025-12-10T00:12:40.184Z", + "EventTimestamp": "2025-12-11T23:51:39.686Z", "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-10T00:12:40.183Z", - "EndTimestamp": "2025-12-10T00:12:40.184Z", + "StartTimestamp": "2025-12-11T23:51:39.685Z", + "EndTimestamp": "2025-12-11T23:51:39.686Z", "Error": {}, - "RequestId": "20d6750d-4768-426c-ab8f-082b128d44de" + "RequestId": "fe0baf45-05a8-4b36-9c83-179e5ecce4f7" } }, { "EventType": "ExecutionSucceeded", "EventId": 10, - "Id": "6e7afd87-c2cd-4b0a-9d07-e40c3bf50842", - "EventTimestamp": "2025-12-10T00:12:40.184Z", + "Id": "3143bfd1-a390-4143-bf5c-f015c3c69dc3", + "EventTimestamp": "2025-12-11T23:51:39.686Z", "ExecutionSucceededDetails": { "Result": { - "Payload": "{\"stepResult\":{\"userId\":123,\"name\":\"John Doe\"},\"callbackResult\":\"{\\\"processed\\\":true,\\\"timestamp\\\":1765325559179}\",\"completed\":true}" + "Payload": "{\"stepResult\":{\"userId\":123,\"name\":\"John Doe\"},\"callbackResult\":\"{\\\"processed\\\":true,\\\"timestamp\\\":1765497099653}\",\"completed\":true}" } } } diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/mixed-ops/create-callback-mixed-ops.test.ts b/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/mixed-ops/create-callback-mixed-ops.test.ts index 6f6d2a34..572dca91 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/mixed-ops/create-callback-mixed-ops.test.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/mixed-ops/create-callback-mixed-ops.test.ts @@ -12,12 +12,16 @@ createTests({ tests: (runner, { assertEventSignatures }) => { it("should handle callback operations mixed with other operation types", async () => { const callbackOperation = runner.getOperation("process-user"); + const waitOperation = runner.getOperation("initial-wait"); const executionPromise = runner.run(); // Wait for callback to start (other operations complete synchronously) await callbackOperation.waitForData(WaitingOperationStatus.STARTED); + // Wait for invocation to complete (when the wait state starts) + await waitOperation.waitForData(); + // Complete the callback const callbackResult = JSON.stringify({ processed: true, From 54f4372ba23454a77bd7f8b67c94d9d8c1b2eb0c Mon Sep 17 00:00:00 2001 From: Anthony Ting Date: Thu, 11 Dec 2025 16:07:04 -0800 Subject: [PATCH 09/14] fix history for create-callback-mixed-ops --- .../create-callback-mixed-ops.history.json | 71 +++++++++++-------- .../create-callback-mixed-ops.test.ts | 5 +- .../src/utils/test-helper.ts | 4 +- 3 files changed, 45 insertions(+), 35 deletions(-) diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/mixed-ops/create-callback-mixed-ops.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/mixed-ops/create-callback-mixed-ops.history.json index 47ea6f5b..f0d83f84 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/mixed-ops/create-callback-mixed-ops.history.json +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/mixed-ops/create-callback-mixed-ops.history.json @@ -2,8 +2,8 @@ { "EventType": "ExecutionStarted", "EventId": 1, - "Id": "3143bfd1-a390-4143-bf5c-f015c3c69dc3", - "EventTimestamp": "2025-12-11T23:51:39.590Z", + "Id": "420929c0-50c3-484b-9430-85d4f7b5d5a4", + "EventTimestamp": "2025-12-12T00:05:31.127Z", "ExecutionStartedDetails": { "Input": { "Payload": "{}" @@ -16,7 +16,7 @@ "EventId": 2, "Id": "c4ca4238a0b92382", "Name": "fetch-data", - "EventTimestamp": "2025-12-11T23:51:39.624Z", + "EventTimestamp": "2025-12-12T00:05:31.133Z", "StepStartedDetails": {} }, { @@ -25,7 +25,7 @@ "EventId": 3, "Id": "c4ca4238a0b92382", "Name": "fetch-data", - "EventTimestamp": "2025-12-11T23:51:39.624Z", + "EventTimestamp": "2025-12-12T00:05:31.133Z", "StepSucceededDetails": { "Result": { "Payload": "{\"userId\":123,\"name\":\"John Doe\"}" @@ -39,9 +39,9 @@ "EventId": 4, "Id": "c81e728d9d4c2f63", "Name": "process-user", - "EventTimestamp": "2025-12-11T23:51:39.644Z", + "EventTimestamp": "2025-12-12T00:05:31.136Z", "CallbackStartedDetails": { - "CallbackId": "eyJleGVjdXRpb25JZCI6ImUzZjZkZjhmLTk2NmQtNGRiMi1iYzkzLTQ4NWY5OWE1NWZlNSIsIm9wZXJhdGlvbklkIjoiYzgxZTcyOGQ5ZDRjMmY2MyIsInRva2VuIjoiZTBjMGE1OTgtOTBkYS00ODY1LWIzOWYtNDYxMzY2OWNiZTExIn0=", + "CallbackId": "eyJleGVjdXRpb25JZCI6IjYyMWJiNmVkLTgxYTItNGJjZC1iM2IzLTcxYjljYmIxNDY0MSIsIm9wZXJhdGlvbklkIjoiYzgxZTcyOGQ5ZDRjMmY2MyIsInRva2VuIjoiY2U1NDg5ZTYtZjhjNi00YzYzLWFkYjMtOWY1NGZjNWQ1YjdmIn0=", "Timeout": 300, "Input": {} } @@ -52,21 +52,21 @@ "EventId": 5, "Id": "eccbc87e4b5ce2fe", "Name": "initial-wait", - "EventTimestamp": "2025-12-11T23:51:39.669Z", + "EventTimestamp": "2025-12-12T00:05:31.139Z", "WaitStartedDetails": { "Duration": 1, - "ScheduledEndTimestamp": "2025-12-11T23:51:40.669Z" + "ScheduledEndTimestamp": "2025-12-12T00:05:32.139Z" } }, { - "EventType": "WaitSucceeded", - "SubType": "Wait", + "EventType": "InvocationCompleted", "EventId": 6, - "Id": "eccbc87e4b5ce2fe", - "Name": "initial-wait", - "EventTimestamp": "2025-12-11T23:51:39.670Z", - "WaitSucceededDetails": { - "Duration": 1 + "EventTimestamp": "2025-12-12T00:05:31.141Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-12T00:05:31.127Z", + "EndTimestamp": "2025-12-12T00:05:31.141Z", + "Error": {}, + "RequestId": "1a48e171-2080-4f28-849a-9b13a6b268f3" } }, { @@ -75,43 +75,54 @@ "EventId": 7, "Id": "c81e728d9d4c2f63", "Name": "process-user", - "EventTimestamp": "2025-12-11T23:51:39.671Z", + "EventTimestamp": "2025-12-12T00:05:31.238Z", "CallbackSucceededDetails": { "Result": { - "Payload": "{\"processed\":true,\"timestamp\":1765497099653}" + "Payload": "{\"processed\":true,\"timestamp\":1765497931237}" } } }, { "EventType": "InvocationCompleted", "EventId": 8, - "EventTimestamp": "2025-12-11T23:51:39.671Z", + "EventTimestamp": "2025-12-12T00:05:31.241Z", "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-11T23:51:39.590Z", - "EndTimestamp": "2025-12-11T23:51:39.671Z", + "StartTimestamp": "2025-12-12T00:05:31.239Z", + "EndTimestamp": "2025-12-12T00:05:31.241Z", "Error": {}, - "RequestId": "525d4dec-9396-4fd3-a630-55f21c6e7878" + "RequestId": "a39e57be-733f-4623-bd5c-7e9705fb8505" } }, { - "EventType": "InvocationCompleted", + "EventType": "WaitSucceeded", + "SubType": "Wait", "EventId": 9, - "EventTimestamp": "2025-12-11T23:51:39.686Z", + "Id": "eccbc87e4b5ce2fe", + "Name": "initial-wait", + "EventTimestamp": "2025-12-12T00:05:32.139Z", + "WaitSucceededDetails": { + "Duration": 1 + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 10, + "EventTimestamp": "2025-12-12T00:05:32.142Z", "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-11T23:51:39.685Z", - "EndTimestamp": "2025-12-11T23:51:39.686Z", + "StartTimestamp": "2025-12-12T00:05:32.139Z", + "EndTimestamp": "2025-12-12T00:05:32.142Z", "Error": {}, - "RequestId": "fe0baf45-05a8-4b36-9c83-179e5ecce4f7" + "RequestId": "bbbdd7de-3c2a-4f9b-acf2-1bc245928289" } }, { "EventType": "ExecutionSucceeded", - "EventId": 10, - "Id": "3143bfd1-a390-4143-bf5c-f015c3c69dc3", - "EventTimestamp": "2025-12-11T23:51:39.686Z", + "EventId": 11, + "Id": "420929c0-50c3-484b-9430-85d4f7b5d5a4", + "EventTimestamp": "2025-12-12T00:05:32.142Z", "ExecutionSucceededDetails": { "Result": { - "Payload": "{\"stepResult\":{\"userId\":123,\"name\":\"John Doe\"},\"callbackResult\":\"{\\\"processed\\\":true,\\\"timestamp\\\":1765497099653}\",\"completed\":true}" + "Payload": "{\"stepResult\":{\"userId\":123,\"name\":\"John Doe\"},\"callbackResult\":\"{\\\"processed\\\":true,\\\"timestamp\\\":1765497931237}\",\"completed\":true}" } } } diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/mixed-ops/create-callback-mixed-ops.test.ts b/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/mixed-ops/create-callback-mixed-ops.test.ts index 572dca91..45f1a5a4 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/mixed-ops/create-callback-mixed-ops.test.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/mixed-ops/create-callback-mixed-ops.test.ts @@ -12,15 +12,14 @@ createTests({ tests: (runner, { assertEventSignatures }) => { it("should handle callback operations mixed with other operation types", async () => { const callbackOperation = runner.getOperation("process-user"); - const waitOperation = runner.getOperation("initial-wait"); const executionPromise = runner.run(); // Wait for callback to start (other operations complete synchronously) await callbackOperation.waitForData(WaitingOperationStatus.STARTED); - // Wait for invocation to complete (when the wait state starts) - await waitOperation.waitForData(); + // Wait for invocation to complete + await new Promise((resolve) => setTimeout(resolve, 100)); // Complete the callback const callbackResult = JSON.stringify({ diff --git a/packages/aws-durable-execution-sdk-js-examples/src/utils/test-helper.ts b/packages/aws-durable-execution-sdk-js-examples/src/utils/test-helper.ts index 29dc4f58..4357412b 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/utils/test-helper.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/utils/test-helper.ts @@ -228,7 +228,7 @@ export function createTests(testDef: TestDefinition) { return assertEventSignatures( testResult.getHistoryEvents(), JSON.parse(readFileSync(historyFilePath).toString("utf-8")), - isTimeSkipping, + testHelper.isTimeSkipping, eventSignatureConfig, ); }, @@ -287,7 +287,7 @@ export function createTests(testDef: TestDefinition) { beforeAll(() => LocalDurableTestRunner.setupTestEnvironment({ ...testDef.localRunnerConfig, - skipTime: isTimeSkipping, + skipTime: testHelper.isTimeSkipping, }), ); afterAll(() => LocalDurableTestRunner.teardownTestEnvironment()); From 8e38f1f991039642a8b57d123cb7407e19586a38 Mon Sep 17 00:00:00 2001 From: Anthony Ting Date: Thu, 11 Dec 2025 16:08:12 -0800 Subject: [PATCH 10/14] disable bail temporarily --- .../jest.config.integration.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/aws-durable-execution-sdk-js-examples/jest.config.integration.js b/packages/aws-durable-execution-sdk-js-examples/jest.config.integration.js index f151e506..bdf3ea1b 100644 --- a/packages/aws-durable-execution-sdk-js-examples/jest.config.integration.js +++ b/packages/aws-durable-execution-sdk-js-examples/jest.config.integration.js @@ -8,5 +8,5 @@ module.exports = { testMatch: ["**/src/examples/**/*.test.ts"], testTimeout: 120000, testNamePattern: "cloud", - bail: true, + // bail: true, }; From 0ab3d7058467e2dd2fe80c07d47347831ee079fb Mon Sep 17 00:00:00 2001 From: Anthony Ting Date: Thu, 11 Dec 2025 16:29:45 -0800 Subject: [PATCH 11/14] enable wait-for-callback timeout test --- .../wait-for-callback-timed-out.history.json | 128 ++++++++++++++++++ .../basic/wait-for-callback.test.ts | 19 +-- .../basic/wait-for-callback.ts | 2 +- 3 files changed, 139 insertions(+), 10 deletions(-) create mode 100644 packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/basic/wait-for-callback-timed-out.history.json diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/basic/wait-for-callback-timed-out.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/basic/wait-for-callback-timed-out.history.json new file mode 100644 index 00000000..441c5476 --- /dev/null +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/basic/wait-for-callback-timed-out.history.json @@ -0,0 +1,128 @@ +[ + { + "EventType": "ExecutionStarted", + "EventId": 1, + "Id": "a97f0be2-220c-4b7c-99c5-8fb9d3349d93", + "EventTimestamp": "2025-12-12T00:23:39.528Z", + "ExecutionStartedDetails": { + "Input": { + "Payload": "{\"timeoutSeconds\":1}" + } + } + }, + { + "EventType": "ContextStarted", + "SubType": "WaitForCallback", + "EventId": 2, + "Id": "c4ca4238a0b92382", + "Name": "my callback function", + "EventTimestamp": "2025-12-12T00:23:39.533Z", + "ContextStartedDetails": {} + }, + { + "EventType": "CallbackStarted", + "SubType": "Callback", + "EventId": 3, + "Id": "ea66c06c1e1c05fa", + "EventTimestamp": "2025-12-12T00:23:39.533Z", + "ParentId": "c4ca4238a0b92382", + "CallbackStartedDetails": { + "CallbackId": "eyJleGVjdXRpb25JZCI6IjQ5Y2QzYjI5LTRhODYtNDQxZi1hNDRmLWNiZjBlZmJiNWEzNiIsIm9wZXJhdGlvbklkIjoiZWE2NmMwNmMxZTFjMDVmYSIsInRva2VuIjoiMmU5YTUwMWMtYmU1NS00ZjJlLTkzMjYtMjc4M2ZiYzhiYzcxIn0=", + "Timeout": 1, + "Input": {} + } + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 4, + "Id": "98c6f2c2287f4c73", + "EventTimestamp": "2025-12-12T00:23:39.535Z", + "ParentId": "c4ca4238a0b92382", + "StepStartedDetails": {} + }, + { + "EventType": "StepSucceeded", + "SubType": "Step", + "EventId": 5, + "Id": "98c6f2c2287f4c73", + "EventTimestamp": "2025-12-12T00:23:39.535Z", + "ParentId": "c4ca4238a0b92382", + "StepSucceededDetails": { + "Result": {}, + "RetryDetails": {} + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 6, + "EventTimestamp": "2025-12-12T00:23:39.537Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-12T00:23:39.528Z", + "EndTimestamp": "2025-12-12T00:23:39.537Z", + "Error": {}, + "RequestId": "d83611bc-3327-49f0-9d78-08246956e0cb" + } + }, + { + "EventType": "CallbackTimedOut", + "SubType": "Callback", + "EventId": 7, + "Id": "ea66c06c1e1c05fa", + "EventTimestamp": "2025-12-12T00:23:40.536Z", + "ParentId": "c4ca4238a0b92382", + "CallbackTimedOutDetails": { + "Error": { + "Payload": { + "ErrorMessage": "Callback timed out" + } + } + } + }, + { + "EventType": "ContextFailed", + "SubType": "WaitForCallback", + "EventId": 8, + "Id": "c4ca4238a0b92382", + "Name": "my callback function", + "EventTimestamp": "2025-12-12T00:23:40.546Z", + "ContextFailedDetails": { + "Error": { + "Payload": { + "ErrorType": "CallbackError", + "ErrorMessage": "Callback timed out" + } + } + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 9, + "EventTimestamp": "2025-12-12T00:23:40.547Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-12T00:23:40.542Z", + "EndTimestamp": "2025-12-12T00:23:40.547Z", + "Error": { + "Payload": { + "ErrorType": "ChildContextError", + "ErrorMessage": "Callback timed out" + } + }, + "RequestId": "0172677d-1faf-4949-a894-c5e96ee500eb" + } + }, + { + "EventType": "ExecutionFailed", + "EventId": 10, + "Id": "a97f0be2-220c-4b7c-99c5-8fb9d3349d93", + "EventTimestamp": "2025-12-12T00:23:40.547Z", + "ExecutionFailedDetails": { + "Error": { + "Payload": { + "ErrorType": "ChildContextError", + "ErrorMessage": "Callback timed out" + } + } + } + } +] diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/basic/wait-for-callback.test.ts b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/basic/wait-for-callback.test.ts index f412e7e6..e188d34d 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/basic/wait-for-callback.test.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/basic/wait-for-callback.test.ts @@ -8,7 +8,7 @@ import { createTests } from "../../../utils/test-helper"; createTests({ handler, invocationType: InvocationType.Event, - tests: (runner, { isCloud, assertEventSignatures }) => { + tests: (runner, { assertEventSignatures }) => { it("function completes when callback succeeds - happy case", async () => { const executionPromise = runner.run(); @@ -37,15 +37,16 @@ createTests({ assertEventSignatures(execution, "failure"); }); - // TODO: fix testing lib local runner time scaling to handle timeouts better - if (isCloud) { - it("function times out when callback is not called - failure case", async () => { - const execution = await runner.run(); + it("function times out when callback is not called - failure case", async () => { + const execution = await runner.run({ + payload: { + timeoutSeconds: 1, + }, + }); - expect(execution.getError()).toBeDefined(); + expect(execution.getError()).toBeDefined(); - assertEventSignatures(execution, "timed-out"); - }); - } + assertEventSignatures(execution, "timed-out"); + }); }, }); diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/basic/wait-for-callback.ts b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/basic/wait-for-callback.ts index be305bd5..1a37cc28 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/basic/wait-for-callback.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/basic/wait-for-callback.ts @@ -21,7 +21,7 @@ export const handler = withDurableExecution( "my callback function", mySubmitterFunction, { - timeout: { seconds: 5 }, + timeout: { seconds: event.timeoutSeconds ?? 5 }, }, ); log("Hello world after callback!"); From e76662c65cd9533c012a3b87cb8a782ade55e763 Mon Sep 17 00:00:00 2001 From: Anthony Ting Date: Thu, 11 Dec 2025 16:35:18 -0800 Subject: [PATCH 12/14] add invocation difference configs for threshold-exceeded tests --- ...threshold-exceeded-percentage.history.json | 227 ++++++++++-------- ...lure-threshold-exceeded-percentage.test.ts | 4 +- ...lure-threshold-exceeded-count.history.json | 199 +++++++-------- ...l-failure-threshold-exceeded-count.test.ts | 4 +- ...threshold-exceeded-percentage.history.json | 202 +++++++++------- ...lure-threshold-exceeded-percentage.test.ts | 4 +- 6 files changed, 356 insertions(+), 284 deletions(-) diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/map/failure-threshold-exceeded-percentage/map-failure-threshold-exceeded-percentage.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/map/failure-threshold-exceeded-percentage/map-failure-threshold-exceeded-percentage.history.json index 9dc3f08a..21d433af 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/map/failure-threshold-exceeded-percentage/map-failure-threshold-exceeded-percentage.history.json +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/map/failure-threshold-exceeded-percentage/map-failure-threshold-exceeded-percentage.history.json @@ -2,8 +2,8 @@ { "EventType": "ExecutionStarted", "EventId": 1, - "Id": "33400a67-a585-469c-8ca6-0f951de8489b", - "EventTimestamp": "2025-12-10T00:15:10.355Z", + "Id": "466e5072-8e3f-4b60-9c5d-0e345fa38e2f", + "EventTimestamp": "2025-12-12T00:34:22.994Z", "ExecutionStartedDetails": { "Input": { "Payload": "{}" @@ -16,7 +16,7 @@ "EventId": 2, "Id": "c4ca4238a0b92382", "Name": "failure-threshold-items", - "EventTimestamp": "2025-12-10T00:15:10.396Z", + "EventTimestamp": "2025-12-12T00:34:23.001Z", "ContextStartedDetails": {} }, { @@ -25,7 +25,7 @@ "EventId": 3, "Id": "ea66c06c1e1c05fa", "Name": "map-item-0", - "EventTimestamp": "2025-12-10T00:15:10.396Z", + "EventTimestamp": "2025-12-12T00:34:23.001Z", "ParentId": "c4ca4238a0b92382", "ContextStartedDetails": {} }, @@ -35,7 +35,7 @@ "EventId": 4, "Id": "2f221a18eb863803", "Name": "process-0", - "EventTimestamp": "2025-12-10T00:15:10.396Z", + "EventTimestamp": "2025-12-12T00:34:23.001Z", "ParentId": "ea66c06c1e1c05fa", "StepStartedDetails": {} }, @@ -45,7 +45,7 @@ "EventId": 5, "Id": "98c6f2c2287f4c73", "Name": "map-item-1", - "EventTimestamp": "2025-12-10T00:15:10.396Z", + "EventTimestamp": "2025-12-12T00:34:23.001Z", "ParentId": "c4ca4238a0b92382", "ContextStartedDetails": {} }, @@ -55,7 +55,7 @@ "EventId": 6, "Id": "6151f5ab282d90e4", "Name": "process-1", - "EventTimestamp": "2025-12-10T00:15:10.396Z", + "EventTimestamp": "2025-12-12T00:34:23.001Z", "ParentId": "98c6f2c2287f4c73", "StepStartedDetails": {} }, @@ -65,7 +65,7 @@ "EventId": 7, "Id": "13cee27a2bd93915", "Name": "map-item-2", - "EventTimestamp": "2025-12-10T00:15:10.396Z", + "EventTimestamp": "2025-12-12T00:34:23.001Z", "ParentId": "c4ca4238a0b92382", "ContextStartedDetails": {} }, @@ -75,7 +75,7 @@ "EventId": 8, "Id": "b425e0c75591aa8f", "Name": "process-2", - "EventTimestamp": "2025-12-10T00:15:10.396Z", + "EventTimestamp": "2025-12-12T00:34:23.001Z", "ParentId": "13cee27a2bd93915", "StepStartedDetails": {} }, @@ -85,7 +85,7 @@ "EventId": 9, "Id": "3a170a9fe4f47efa", "Name": "map-item-3", - "EventTimestamp": "2025-12-10T00:15:10.396Z", + "EventTimestamp": "2025-12-12T00:34:23.001Z", "ParentId": "c4ca4238a0b92382", "ContextStartedDetails": {} }, @@ -95,7 +95,7 @@ "EventId": 10, "Id": "a4e1cd317d54f087", "Name": "process-3", - "EventTimestamp": "2025-12-10T00:15:10.396Z", + "EventTimestamp": "2025-12-12T00:34:23.001Z", "ParentId": "3a170a9fe4f47efa", "StepStartedDetails": {} }, @@ -105,7 +105,7 @@ "EventId": 11, "Id": "12426c956d1bc501", "Name": "map-item-4", - "EventTimestamp": "2025-12-10T00:15:10.396Z", + "EventTimestamp": "2025-12-12T00:34:23.001Z", "ParentId": "c4ca4238a0b92382", "ContextStartedDetails": {} }, @@ -115,7 +115,7 @@ "EventId": 12, "Id": "0f42756e5788f9b0", "Name": "process-4", - "EventTimestamp": "2025-12-10T00:15:10.396Z", + "EventTimestamp": "2025-12-12T00:34:23.001Z", "ParentId": "12426c956d1bc501", "StepStartedDetails": {} }, @@ -125,7 +125,7 @@ "EventId": 13, "Id": "2f221a18eb863803", "Name": "process-0", - "EventTimestamp": "2025-12-10T00:15:10.396Z", + "EventTimestamp": "2025-12-12T00:34:23.001Z", "ParentId": "ea66c06c1e1c05fa", "StepFailedDetails": { "Error": { @@ -135,7 +135,7 @@ } }, "RetryDetails": { - "NextAttemptDelaySeconds": 3, + "NextAttemptDelaySeconds": 1, "CurrentAttempt": 1 } } @@ -146,7 +146,7 @@ "EventId": 14, "Id": "6151f5ab282d90e4", "Name": "process-1", - "EventTimestamp": "2025-12-10T00:15:10.396Z", + "EventTimestamp": "2025-12-12T00:34:23.003Z", "ParentId": "98c6f2c2287f4c73", "StepFailedDetails": { "Error": { @@ -156,7 +156,7 @@ } }, "RetryDetails": { - "NextAttemptDelaySeconds": 2, + "NextAttemptDelaySeconds": 5, "CurrentAttempt": 1 } } @@ -167,7 +167,7 @@ "EventId": 15, "Id": "b425e0c75591aa8f", "Name": "process-2", - "EventTimestamp": "2025-12-10T00:15:10.396Z", + "EventTimestamp": "2025-12-12T00:34:23.003Z", "ParentId": "13cee27a2bd93915", "StepFailedDetails": { "Error": { @@ -177,7 +177,7 @@ } }, "RetryDetails": { - "NextAttemptDelaySeconds": 3, + "NextAttemptDelaySeconds": 2, "CurrentAttempt": 1 } } @@ -188,7 +188,7 @@ "EventId": 16, "Id": "a4e1cd317d54f087", "Name": "process-3", - "EventTimestamp": "2025-12-10T00:15:10.396Z", + "EventTimestamp": "2025-12-12T00:34:23.003Z", "ParentId": "3a170a9fe4f47efa", "StepSucceededDetails": { "Result": { @@ -203,7 +203,7 @@ "EventId": 17, "Id": "0f42756e5788f9b0", "Name": "process-4", - "EventTimestamp": "2025-12-10T00:15:10.396Z", + "EventTimestamp": "2025-12-12T00:34:23.003Z", "ParentId": "12426c956d1bc501", "StepSucceededDetails": { "Result": { @@ -218,7 +218,7 @@ "EventId": 18, "Id": "3a170a9fe4f47efa", "Name": "map-item-3", - "EventTimestamp": "2025-12-10T00:15:10.400Z", + "EventTimestamp": "2025-12-12T00:34:23.006Z", "ParentId": "c4ca4238a0b92382", "ContextSucceededDetails": { "Result": { @@ -232,7 +232,7 @@ "EventId": 19, "Id": "12426c956d1bc501", "Name": "map-item-4", - "EventTimestamp": "2025-12-10T00:15:10.400Z", + "EventTimestamp": "2025-12-12T00:34:23.006Z", "ParentId": "c4ca4238a0b92382", "ContextSucceededDetails": { "Result": { @@ -243,12 +243,12 @@ { "EventType": "InvocationCompleted", "EventId": 20, - "EventTimestamp": "2025-12-10T00:15:10.401Z", + "EventTimestamp": "2025-12-12T00:34:23.007Z", "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-10T00:15:10.355Z", - "EndTimestamp": "2025-12-10T00:15:10.401Z", + "StartTimestamp": "2025-12-12T00:34:22.994Z", + "EndTimestamp": "2025-12-12T00:34:23.007Z", "Error": {}, - "RequestId": "0352d14b-1bd4-43a2-95d1-6e9ecba69149" + "RequestId": "13a80d9b-8923-464c-9463-d7d7328681c3" } }, { @@ -257,37 +257,17 @@ "EventId": 21, "Id": "2f221a18eb863803", "Name": "process-0", - "EventTimestamp": "2025-12-10T00:15:10.437Z", + "EventTimestamp": "2025-12-12T00:34:24.007Z", "ParentId": "ea66c06c1e1c05fa", "StepStartedDetails": {} }, - { - "EventType": "StepStarted", - "SubType": "Step", - "EventId": 22, - "Id": "6151f5ab282d90e4", - "Name": "process-1", - "EventTimestamp": "2025-12-10T00:15:10.437Z", - "ParentId": "98c6f2c2287f4c73", - "StepStartedDetails": {} - }, - { - "EventType": "StepStarted", - "SubType": "Step", - "EventId": 23, - "Id": "b425e0c75591aa8f", - "Name": "process-2", - "EventTimestamp": "2025-12-10T00:15:10.437Z", - "ParentId": "13cee27a2bd93915", - "StepStartedDetails": {} - }, { "EventType": "StepFailed", "SubType": "Step", - "EventId": 24, + "EventId": 22, "Id": "2f221a18eb863803", "Name": "process-0", - "EventTimestamp": "2025-12-10T00:15:10.437Z", + "EventTimestamp": "2025-12-12T00:34:24.007Z", "ParentId": "ea66c06c1e1c05fa", "StepFailedDetails": { "Error": { @@ -302,32 +282,50 @@ } }, { - "EventType": "StepFailed", - "SubType": "Step", - "EventId": 25, - "Id": "6151f5ab282d90e4", - "Name": "process-1", - "EventTimestamp": "2025-12-10T00:15:10.437Z", - "ParentId": "98c6f2c2287f4c73", - "StepFailedDetails": { + "EventType": "ContextFailed", + "SubType": "MapIteration", + "EventId": 23, + "Id": "ea66c06c1e1c05fa", + "Name": "map-item-0", + "EventTimestamp": "2025-12-12T00:34:24.011Z", + "ParentId": "c4ca4238a0b92382", + "ContextFailedDetails": { "Error": { "Payload": { - "ErrorMessage": "Item 2 failed", - "ErrorType": "Error" + "ErrorType": "StepError", + "ErrorMessage": "Item 1 failed" } - }, - "RetryDetails": { - "CurrentAttempt": 1 } } }, + { + "EventType": "InvocationCompleted", + "EventId": 24, + "EventTimestamp": "2025-12-12T00:34:24.012Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-12T00:34:24.004Z", + "EndTimestamp": "2025-12-12T00:34:24.012Z", + "Error": {}, + "RequestId": "5a9d24c8-2790-4961-b172-24ccf9f90587" + } + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 25, + "Id": "b425e0c75591aa8f", + "Name": "process-2", + "EventTimestamp": "2025-12-12T00:34:25.012Z", + "ParentId": "13cee27a2bd93915", + "StepStartedDetails": {} + }, { "EventType": "StepFailed", "SubType": "Step", "EventId": 26, "Id": "b425e0c75591aa8f", "Name": "process-2", - "EventTimestamp": "2025-12-10T00:15:10.437Z", + "EventTimestamp": "2025-12-12T00:34:25.012Z", "ParentId": "13cee27a2bd93915", "StepFailedDetails": { "Error": { @@ -345,49 +343,73 @@ "EventType": "ContextFailed", "SubType": "MapIteration", "EventId": 27, - "Id": "ea66c06c1e1c05fa", - "Name": "map-item-0", - "EventTimestamp": "2025-12-10T00:15:10.458Z", + "Id": "13cee27a2bd93915", + "Name": "map-item-2", + "EventTimestamp": "2025-12-12T00:34:25.015Z", "ParentId": "c4ca4238a0b92382", "ContextFailedDetails": { "Error": { "Payload": { "ErrorType": "StepError", - "ErrorMessage": "Item 1 failed" + "ErrorMessage": "Item 3 failed" } } } }, { - "EventType": "ContextFailed", - "SubType": "MapIteration", + "EventType": "InvocationCompleted", "EventId": 28, - "Id": "98c6f2c2287f4c73", - "Name": "map-item-1", - "EventTimestamp": "2025-12-10T00:15:10.458Z", - "ParentId": "c4ca4238a0b92382", - "ContextFailedDetails": { + "EventTimestamp": "2025-12-12T00:34:25.016Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-12T00:34:25.006Z", + "EndTimestamp": "2025-12-12T00:34:25.016Z", + "Error": {}, + "RequestId": "52caa01c-416f-4f4e-89c4-029a9ecffd70" + } + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 29, + "Id": "6151f5ab282d90e4", + "Name": "process-1", + "EventTimestamp": "2025-12-12T00:34:28.006Z", + "ParentId": "98c6f2c2287f4c73", + "StepStartedDetails": {} + }, + { + "EventType": "StepFailed", + "SubType": "Step", + "EventId": 30, + "Id": "6151f5ab282d90e4", + "Name": "process-1", + "EventTimestamp": "2025-12-12T00:34:28.006Z", + "ParentId": "98c6f2c2287f4c73", + "StepFailedDetails": { "Error": { "Payload": { - "ErrorType": "StepError", - "ErrorMessage": "Item 2 failed" + "ErrorMessage": "Item 2 failed", + "ErrorType": "Error" } + }, + "RetryDetails": { + "CurrentAttempt": 1 } } }, { "EventType": "ContextFailed", "SubType": "MapIteration", - "EventId": 29, - "Id": "13cee27a2bd93915", - "Name": "map-item-2", - "EventTimestamp": "2025-12-10T00:15:10.458Z", + "EventId": 31, + "Id": "98c6f2c2287f4c73", + "Name": "map-item-1", + "EventTimestamp": "2025-12-12T00:34:28.008Z", "ParentId": "c4ca4238a0b92382", "ContextFailedDetails": { "Error": { "Payload": { "ErrorType": "StepError", - "ErrorMessage": "Item 3 failed" + "ErrorMessage": "Item 2 failed" } } } @@ -395,10 +417,10 @@ { "EventType": "ContextSucceeded", "SubType": "Map", - "EventId": 30, + "EventId": 32, "Id": "c4ca4238a0b92382", "Name": "failure-threshold-items", - "EventTimestamp": "2025-12-10T00:15:10.458Z", + "EventTimestamp": "2025-12-12T00:34:28.008Z", "ContextSucceededDetails": { "Result": { "Payload": "{\"all\":[{\"error\":{\"cause\":{\"cause\":{\"name\":\"StepError\"},\"name\":\"StepError\",\"errorType\":\"StepError\"},\"name\":\"ChildContextError\",\"errorType\":\"ChildContextError\"},\"index\":0,\"status\":\"FAILED\"},{\"error\":{\"cause\":{\"cause\":{\"name\":\"StepError\"},\"name\":\"StepError\",\"errorType\":\"StepError\"},\"name\":\"ChildContextError\",\"errorType\":\"ChildContextError\"},\"index\":1,\"status\":\"FAILED\"},{\"error\":{\"cause\":{\"cause\":{\"name\":\"StepError\"},\"name\":\"StepError\",\"errorType\":\"StepError\"},\"name\":\"ChildContextError\",\"errorType\":\"ChildContextError\"},\"index\":2,\"status\":\"FAILED\"},{\"result\":8,\"index\":3,\"status\":\"SUCCEEDED\"},{\"result\":10,\"index\":4,\"status\":\"SUCCEEDED\"}],\"completionReason\":\"FAILURE_TOLERANCE_EXCEEDED\"}" @@ -408,40 +430,51 @@ { "EventType": "WaitStarted", "SubType": "Wait", - "EventId": 31, + "EventId": 33, "Id": "c81e728d9d4c2f63", - "EventTimestamp": "2025-12-10T00:15:10.458Z", + "EventTimestamp": "2025-12-12T00:34:28.008Z", "WaitStartedDetails": { "Duration": 1, - "ScheduledEndTimestamp": "2025-12-10T00:15:11.458Z" + "ScheduledEndTimestamp": "2025-12-12T00:34:29.008Z" + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 34, + "EventTimestamp": "2025-12-12T00:34:28.010Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-12T00:34:28.004Z", + "EndTimestamp": "2025-12-12T00:34:28.010Z", + "Error": {}, + "RequestId": "e3fbfbad-bc86-4c3b-951d-2ba6fe7b62ba" } }, { "EventType": "WaitSucceeded", "SubType": "Wait", - "EventId": 32, + "EventId": 35, "Id": "c81e728d9d4c2f63", - "EventTimestamp": "2025-12-10T00:15:10.459Z", + "EventTimestamp": "2025-12-12T00:34:29.009Z", "WaitSucceededDetails": { "Duration": 1 } }, { "EventType": "InvocationCompleted", - "EventId": 33, - "EventTimestamp": "2025-12-10T00:15:10.480Z", + "EventId": 36, + "EventTimestamp": "2025-12-12T00:34:29.012Z", "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-10T00:15:10.414Z", - "EndTimestamp": "2025-12-10T00:15:10.480Z", + "StartTimestamp": "2025-12-12T00:34:29.009Z", + "EndTimestamp": "2025-12-12T00:34:29.012Z", "Error": {}, - "RequestId": "0fb9a2be-98da-4aa4-9333-386754660b36" + "RequestId": "840af57f-8222-4df3-8db7-5c7ffd5858e1" } }, { "EventType": "ExecutionSucceeded", - "EventId": 34, - "Id": "33400a67-a585-469c-8ca6-0f951de8489b", - "EventTimestamp": "2025-12-10T00:15:10.481Z", + "EventId": 37, + "Id": "466e5072-8e3f-4b60-9c5d-0e345fa38e2f", + "EventTimestamp": "2025-12-12T00:34:29.012Z", "ExecutionSucceededDetails": { "Result": { "Payload": "{\"completionReason\":\"FAILURE_TOLERANCE_EXCEEDED\",\"successCount\":2,\"failureCount\":3,\"totalCount\":5}" diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/map/failure-threshold-exceeded-percentage/map-failure-threshold-exceeded-percentage.test.ts b/packages/aws-durable-execution-sdk-js-examples/src/examples/map/failure-threshold-exceeded-percentage/map-failure-threshold-exceeded-percentage.test.ts index 81d1bdb9..069f10c4 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/map/failure-threshold-exceeded-percentage/map-failure-threshold-exceeded-percentage.test.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/map/failure-threshold-exceeded-percentage/map-failure-threshold-exceeded-percentage.test.ts @@ -25,7 +25,9 @@ createTests({ expect(runner.getOperation(name)?.getStatus()).toBe(status); }); - assertEventSignatures(execution); + assertEventSignatures(execution, undefined, { + invocationCompletedDifference: 1, + }); }); }, }); diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/failure-threshold-exceeded-count/parallel-failure-threshold-exceeded-count.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/failure-threshold-exceeded-count/parallel-failure-threshold-exceeded-count.history.json index 6acf4f10..d14d70d9 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/failure-threshold-exceeded-count/parallel-failure-threshold-exceeded-count.history.json +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/failure-threshold-exceeded-count/parallel-failure-threshold-exceeded-count.history.json @@ -2,8 +2,8 @@ { "EventType": "ExecutionStarted", "EventId": 1, - "Id": "cda5a2ff-8872-4ee7-b6e5-51f26cc6bd45", - "EventTimestamp": "2025-12-10T00:12:07.523Z", + "Id": "4fd876c5-8911-4cd6-9c63-0dfb81d69a06", + "EventTimestamp": "2025-12-12T00:34:22.982Z", "ExecutionStartedDetails": { "Input": { "Payload": "{}" @@ -16,7 +16,7 @@ "EventId": 2, "Id": "c4ca4238a0b92382", "Name": "failure-threshold-tasks", - "EventTimestamp": "2025-12-10T00:12:07.532Z", + "EventTimestamp": "2025-12-12T00:34:22.988Z", "ContextStartedDetails": {} }, { @@ -25,7 +25,7 @@ "EventId": 3, "Id": "ea66c06c1e1c05fa", "Name": "parallel-branch-0", - "EventTimestamp": "2025-12-10T00:12:07.533Z", + "EventTimestamp": "2025-12-12T00:34:22.988Z", "ParentId": "c4ca4238a0b92382", "ContextStartedDetails": {} }, @@ -35,7 +35,7 @@ "EventId": 4, "Id": "2f221a18eb863803", "Name": "task-1", - "EventTimestamp": "2025-12-10T00:12:07.533Z", + "EventTimestamp": "2025-12-12T00:34:22.988Z", "ParentId": "ea66c06c1e1c05fa", "StepStartedDetails": {} }, @@ -45,7 +45,7 @@ "EventId": 5, "Id": "98c6f2c2287f4c73", "Name": "parallel-branch-1", - "EventTimestamp": "2025-12-10T00:12:07.533Z", + "EventTimestamp": "2025-12-12T00:34:22.988Z", "ParentId": "c4ca4238a0b92382", "ContextStartedDetails": {} }, @@ -55,7 +55,7 @@ "EventId": 6, "Id": "6151f5ab282d90e4", "Name": "task-2", - "EventTimestamp": "2025-12-10T00:12:07.533Z", + "EventTimestamp": "2025-12-12T00:34:22.988Z", "ParentId": "98c6f2c2287f4c73", "StepStartedDetails": {} }, @@ -65,7 +65,7 @@ "EventId": 7, "Id": "13cee27a2bd93915", "Name": "parallel-branch-2", - "EventTimestamp": "2025-12-10T00:12:07.533Z", + "EventTimestamp": "2025-12-12T00:34:22.988Z", "ParentId": "c4ca4238a0b92382", "ContextStartedDetails": {} }, @@ -75,7 +75,7 @@ "EventId": 8, "Id": "b425e0c75591aa8f", "Name": "task-3", - "EventTimestamp": "2025-12-10T00:12:07.533Z", + "EventTimestamp": "2025-12-12T00:34:22.988Z", "ParentId": "13cee27a2bd93915", "StepStartedDetails": {} }, @@ -85,7 +85,7 @@ "EventId": 9, "Id": "3a170a9fe4f47efa", "Name": "parallel-branch-3", - "EventTimestamp": "2025-12-10T00:12:07.533Z", + "EventTimestamp": "2025-12-12T00:34:22.988Z", "ParentId": "c4ca4238a0b92382", "ContextStartedDetails": {} }, @@ -95,7 +95,7 @@ "EventId": 10, "Id": "a4e1cd317d54f087", "Name": "task-4", - "EventTimestamp": "2025-12-10T00:12:07.533Z", + "EventTimestamp": "2025-12-12T00:34:22.988Z", "ParentId": "3a170a9fe4f47efa", "StepStartedDetails": {} }, @@ -105,7 +105,7 @@ "EventId": 11, "Id": "12426c956d1bc501", "Name": "parallel-branch-4", - "EventTimestamp": "2025-12-10T00:12:07.533Z", + "EventTimestamp": "2025-12-12T00:34:22.988Z", "ParentId": "c4ca4238a0b92382", "ContextStartedDetails": {} }, @@ -115,7 +115,7 @@ "EventId": 12, "Id": "0f42756e5788f9b0", "Name": "task-5", - "EventTimestamp": "2025-12-10T00:12:07.533Z", + "EventTimestamp": "2025-12-12T00:34:22.988Z", "ParentId": "12426c956d1bc501", "StepStartedDetails": {} }, @@ -125,7 +125,7 @@ "EventId": 13, "Id": "2f221a18eb863803", "Name": "task-1", - "EventTimestamp": "2025-12-10T00:12:07.533Z", + "EventTimestamp": "2025-12-12T00:34:22.988Z", "ParentId": "ea66c06c1e1c05fa", "StepFailedDetails": { "Error": { @@ -146,7 +146,7 @@ "EventId": 14, "Id": "6151f5ab282d90e4", "Name": "task-2", - "EventTimestamp": "2025-12-10T00:12:07.537Z", + "EventTimestamp": "2025-12-12T00:34:22.990Z", "ParentId": "98c6f2c2287f4c73", "StepFailedDetails": { "Error": { @@ -156,7 +156,7 @@ } }, "RetryDetails": { - "NextAttemptDelaySeconds": 3, + "NextAttemptDelaySeconds": 4, "CurrentAttempt": 1 } } @@ -167,7 +167,7 @@ "EventId": 15, "Id": "b425e0c75591aa8f", "Name": "task-3", - "EventTimestamp": "2025-12-10T00:12:07.537Z", + "EventTimestamp": "2025-12-12T00:34:22.990Z", "ParentId": "13cee27a2bd93915", "StepFailedDetails": { "Error": { @@ -188,7 +188,7 @@ "EventId": 16, "Id": "a4e1cd317d54f087", "Name": "task-4", - "EventTimestamp": "2025-12-10T00:12:07.537Z", + "EventTimestamp": "2025-12-12T00:34:22.990Z", "ParentId": "3a170a9fe4f47efa", "StepSucceededDetails": { "Result": { @@ -203,7 +203,7 @@ "EventId": 17, "Id": "0f42756e5788f9b0", "Name": "task-5", - "EventTimestamp": "2025-12-10T00:12:07.538Z", + "EventTimestamp": "2025-12-12T00:34:22.990Z", "ParentId": "12426c956d1bc501", "StepSucceededDetails": { "Result": { @@ -218,7 +218,7 @@ "EventId": 18, "Id": "3a170a9fe4f47efa", "Name": "parallel-branch-3", - "EventTimestamp": "2025-12-10T00:12:07.541Z", + "EventTimestamp": "2025-12-12T00:34:22.994Z", "ParentId": "c4ca4238a0b92382", "ContextSucceededDetails": { "Result": { @@ -232,7 +232,7 @@ "EventId": 19, "Id": "12426c956d1bc501", "Name": "parallel-branch-4", - "EventTimestamp": "2025-12-10T00:12:07.541Z", + "EventTimestamp": "2025-12-12T00:34:22.994Z", "ParentId": "c4ca4238a0b92382", "ContextSucceededDetails": { "Result": { @@ -243,12 +243,12 @@ { "EventType": "InvocationCompleted", "EventId": 20, - "EventTimestamp": "2025-12-10T00:12:07.591Z", + "EventTimestamp": "2025-12-12T00:34:22.994Z", "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-10T00:12:07.523Z", - "EndTimestamp": "2025-12-10T00:12:07.590Z", + "StartTimestamp": "2025-12-12T00:34:22.981Z", + "EndTimestamp": "2025-12-12T00:34:22.994Z", "Error": {}, - "RequestId": "29bc2a12-87be-49c8-aa8e-19473336f0e1" + "RequestId": "f59efb03-4778-4516-a85f-341ed3f9302c" } }, { @@ -257,7 +257,7 @@ "EventId": 21, "Id": "2f221a18eb863803", "Name": "task-1", - "EventTimestamp": "2025-12-10T00:12:08.549Z", + "EventTimestamp": "2025-12-12T00:34:23.995Z", "ParentId": "ea66c06c1e1c05fa", "StepStartedDetails": {} }, @@ -267,7 +267,7 @@ "EventId": 22, "Id": "2f221a18eb863803", "Name": "task-1", - "EventTimestamp": "2025-12-10T00:12:08.549Z", + "EventTimestamp": "2025-12-12T00:34:23.995Z", "ParentId": "ea66c06c1e1c05fa", "StepFailedDetails": { "Error": { @@ -287,7 +287,7 @@ "EventId": 23, "Id": "ea66c06c1e1c05fa", "Name": "parallel-branch-0", - "EventTimestamp": "2025-12-10T00:12:08.552Z", + "EventTimestamp": "2025-12-12T00:34:23.997Z", "ParentId": "c4ca4238a0b92382", "ContextFailedDetails": { "Error": { @@ -301,46 +301,36 @@ { "EventType": "InvocationCompleted", "EventId": 24, - "EventTimestamp": "2025-12-10T00:12:08.602Z", + "EventTimestamp": "2025-12-12T00:34:23.998Z", "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-10T00:12:08.545Z", - "EndTimestamp": "2025-12-10T00:12:08.602Z", + "StartTimestamp": "2025-12-12T00:34:23.991Z", + "EndTimestamp": "2025-12-12T00:34:23.998Z", "Error": {}, - "RequestId": "031dc47a-c2ee-4918-8477-8ea308ef2668" + "RequestId": "aa0ae911-0c67-473b-9329-8fb173e7d0e7" } }, { "EventType": "StepStarted", "SubType": "Step", "EventId": 25, - "Id": "6151f5ab282d90e4", - "Name": "task-2", - "EventTimestamp": "2025-12-10T00:12:10.542Z", - "ParentId": "98c6f2c2287f4c73", - "StepStartedDetails": {} - }, - { - "EventType": "StepStarted", - "SubType": "Step", - "EventId": 26, "Id": "b425e0c75591aa8f", "Name": "task-3", - "EventTimestamp": "2025-12-10T00:12:10.542Z", + "EventTimestamp": "2025-12-12T00:34:25.998Z", "ParentId": "13cee27a2bd93915", "StepStartedDetails": {} }, { "EventType": "StepFailed", "SubType": "Step", - "EventId": 27, - "Id": "6151f5ab282d90e4", - "Name": "task-2", - "EventTimestamp": "2025-12-10T00:12:10.542Z", - "ParentId": "98c6f2c2287f4c73", + "EventId": 26, + "Id": "b425e0c75591aa8f", + "Name": "task-3", + "EventTimestamp": "2025-12-12T00:34:25.998Z", + "ParentId": "13cee27a2bd93915", "StepFailedDetails": { "Error": { "Payload": { - "ErrorMessage": "Task 2 failed", + "ErrorMessage": "Task 3 failed", "ErrorType": "Error" } }, @@ -349,18 +339,56 @@ } } }, + { + "EventType": "ContextFailed", + "SubType": "ParallelBranch", + "EventId": 27, + "Id": "13cee27a2bd93915", + "Name": "parallel-branch-2", + "EventTimestamp": "2025-12-12T00:34:26.000Z", + "ParentId": "c4ca4238a0b92382", + "ContextFailedDetails": { + "Error": { + "Payload": { + "ErrorType": "StepError", + "ErrorMessage": "Task 3 failed" + } + } + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 28, + "EventTimestamp": "2025-12-12T00:34:26.000Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-12T00:34:25.994Z", + "EndTimestamp": "2025-12-12T00:34:26.000Z", + "Error": {}, + "RequestId": "5ce446a1-7dec-45eb-8618-615ad761c006" + } + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 29, + "Id": "6151f5ab282d90e4", + "Name": "task-2", + "EventTimestamp": "2025-12-12T00:34:26.996Z", + "ParentId": "98c6f2c2287f4c73", + "StepStartedDetails": {} + }, { "EventType": "StepFailed", "SubType": "Step", - "EventId": 28, - "Id": "b425e0c75591aa8f", - "Name": "task-3", - "EventTimestamp": "2025-12-10T00:12:10.542Z", - "ParentId": "13cee27a2bd93915", + "EventId": 30, + "Id": "6151f5ab282d90e4", + "Name": "task-2", + "EventTimestamp": "2025-12-12T00:34:26.996Z", + "ParentId": "98c6f2c2287f4c73", "StepFailedDetails": { "Error": { "Payload": { - "ErrorMessage": "Task 3 failed", + "ErrorMessage": "Task 2 failed", "ErrorType": "Error" } }, @@ -372,10 +400,10 @@ { "EventType": "ContextFailed", "SubType": "ParallelBranch", - "EventId": 29, + "EventId": 31, "Id": "98c6f2c2287f4c73", "Name": "parallel-branch-1", - "EventTimestamp": "2025-12-10T00:12:10.544Z", + "EventTimestamp": "2025-12-12T00:34:26.998Z", "ParentId": "c4ca4238a0b92382", "ContextFailedDetails": { "Error": { @@ -386,30 +414,13 @@ } } }, - { - "EventType": "ContextFailed", - "SubType": "ParallelBranch", - "EventId": 30, - "Id": "13cee27a2bd93915", - "Name": "parallel-branch-2", - "EventTimestamp": "2025-12-10T00:12:10.544Z", - "ParentId": "c4ca4238a0b92382", - "ContextFailedDetails": { - "Error": { - "Payload": { - "ErrorType": "StepError", - "ErrorMessage": "Task 3 failed" - } - } - } - }, { "EventType": "ContextSucceeded", "SubType": "Parallel", - "EventId": 31, + "EventId": 32, "Id": "c4ca4238a0b92382", "Name": "failure-threshold-tasks", - "EventTimestamp": "2025-12-10T00:12:10.544Z", + "EventTimestamp": "2025-12-12T00:34:26.998Z", "ContextSucceededDetails": { "Result": { "Payload": "{\"all\":[{\"error\":{\"cause\":{\"cause\":{\"name\":\"StepError\"},\"name\":\"StepError\",\"errorType\":\"StepError\"},\"name\":\"ChildContextError\",\"errorType\":\"ChildContextError\"},\"index\":0,\"status\":\"FAILED\"},{\"error\":{\"cause\":{\"cause\":{\"name\":\"StepError\"},\"name\":\"StepError\",\"errorType\":\"StepError\"},\"name\":\"ChildContextError\",\"errorType\":\"ChildContextError\"},\"index\":1,\"status\":\"FAILED\"},{\"error\":{\"cause\":{\"cause\":{\"name\":\"StepError\"},\"name\":\"StepError\",\"errorType\":\"StepError\"},\"name\":\"ChildContextError\",\"errorType\":\"ChildContextError\"},\"index\":2,\"status\":\"FAILED\"},{\"result\":\"Task 4 success\",\"index\":3,\"status\":\"SUCCEEDED\"},{\"result\":\"Task 5 success\",\"index\":4,\"status\":\"SUCCEEDED\"}],\"completionReason\":\"FAILURE_TOLERANCE_EXCEEDED\"}" @@ -419,51 +430,51 @@ { "EventType": "WaitStarted", "SubType": "Wait", - "EventId": 32, + "EventId": 33, "Id": "c81e728d9d4c2f63", - "EventTimestamp": "2025-12-10T00:12:10.544Z", + "EventTimestamp": "2025-12-12T00:34:26.998Z", "WaitStartedDetails": { "Duration": 1, - "ScheduledEndTimestamp": "2025-12-10T00:12:11.544Z" + "ScheduledEndTimestamp": "2025-12-12T00:34:27.998Z" } }, { "EventType": "InvocationCompleted", - "EventId": 33, - "EventTimestamp": "2025-12-10T00:12:10.596Z", + "EventId": 34, + "EventTimestamp": "2025-12-12T00:34:27.000Z", "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-10T00:12:10.539Z", - "EndTimestamp": "2025-12-10T00:12:10.596Z", + "StartTimestamp": "2025-12-12T00:34:26.993Z", + "EndTimestamp": "2025-12-12T00:34:27.000Z", "Error": {}, - "RequestId": "a735f242-e42d-42d5-b133-709e2eec8da9" + "RequestId": "9929a2af-9673-4a45-a136-0f2791d12ab9" } }, { "EventType": "WaitSucceeded", "SubType": "Wait", - "EventId": 34, + "EventId": 35, "Id": "c81e728d9d4c2f63", - "EventTimestamp": "2025-12-10T00:12:11.546Z", + "EventTimestamp": "2025-12-12T00:34:27.999Z", "WaitSucceededDetails": { "Duration": 1 } }, { "EventType": "InvocationCompleted", - "EventId": 35, - "EventTimestamp": "2025-12-10T00:12:11.547Z", + "EventId": 36, + "EventTimestamp": "2025-12-12T00:34:28.001Z", "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-10T00:12:11.546Z", - "EndTimestamp": "2025-12-10T00:12:11.547Z", + "StartTimestamp": "2025-12-12T00:34:28.000Z", + "EndTimestamp": "2025-12-12T00:34:28.001Z", "Error": {}, - "RequestId": "1b0cf111-c862-4ded-ae63-aaa84639e8b4" + "RequestId": "e645175c-28ef-45bc-b56f-6210cbe7b511" } }, { "EventType": "ExecutionSucceeded", - "EventId": 36, - "Id": "cda5a2ff-8872-4ee7-b6e5-51f26cc6bd45", - "EventTimestamp": "2025-12-10T00:12:11.547Z", + "EventId": 37, + "Id": "4fd876c5-8911-4cd6-9c63-0dfb81d69a06", + "EventTimestamp": "2025-12-12T00:34:28.001Z", "ExecutionSucceededDetails": { "Result": { "Payload": "{\"completionReason\":\"FAILURE_TOLERANCE_EXCEEDED\",\"successCount\":2,\"failureCount\":3,\"totalCount\":5}" diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/failure-threshold-exceeded-count/parallel-failure-threshold-exceeded-count.test.ts b/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/failure-threshold-exceeded-count/parallel-failure-threshold-exceeded-count.test.ts index be773169..07ffd5c1 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/failure-threshold-exceeded-count/parallel-failure-threshold-exceeded-count.test.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/failure-threshold-exceeded-count/parallel-failure-threshold-exceeded-count.test.ts @@ -13,7 +13,9 @@ createTests({ expect(result.failureCount).toBe(3); // Tasks 1, 2, 3 fail (exceeds threshold of 2) expect(result.totalCount).toBe(5); - assertEventSignatures(execution); + assertEventSignatures(execution, undefined, { + invocationCompletedDifference: 1, + }); }); }, }); diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/failure-threshold-exceeded-percentage/parallel-failure-threshold-exceeded-percentage.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/failure-threshold-exceeded-percentage/parallel-failure-threshold-exceeded-percentage.history.json index dfdc6738..9f3c18dd 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/failure-threshold-exceeded-percentage/parallel-failure-threshold-exceeded-percentage.history.json +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/failure-threshold-exceeded-percentage/parallel-failure-threshold-exceeded-percentage.history.json @@ -2,8 +2,8 @@ { "EventType": "ExecutionStarted", "EventId": 1, - "Id": "10987b52-759d-4d31-a87d-f3ccb156f41a", - "EventTimestamp": "2025-12-10T00:15:08.861Z", + "Id": "6195d06b-1435-46f4-b5a0-fea943f76af9", + "EventTimestamp": "2025-12-12T00:34:22.961Z", "ExecutionStartedDetails": { "Input": { "Payload": "{}" @@ -16,7 +16,7 @@ "EventId": 2, "Id": "c4ca4238a0b92382", "Name": "failure-threshold-tasks", - "EventTimestamp": "2025-12-10T00:15:08.904Z", + "EventTimestamp": "2025-12-12T00:34:22.969Z", "ContextStartedDetails": {} }, { @@ -25,7 +25,7 @@ "EventId": 3, "Id": "ea66c06c1e1c05fa", "Name": "parallel-branch-0", - "EventTimestamp": "2025-12-10T00:15:08.904Z", + "EventTimestamp": "2025-12-12T00:34:22.969Z", "ParentId": "c4ca4238a0b92382", "ContextStartedDetails": {} }, @@ -35,7 +35,7 @@ "EventId": 4, "Id": "2f221a18eb863803", "Name": "task-1", - "EventTimestamp": "2025-12-10T00:15:08.904Z", + "EventTimestamp": "2025-12-12T00:34:22.969Z", "ParentId": "ea66c06c1e1c05fa", "StepStartedDetails": {} }, @@ -45,7 +45,7 @@ "EventId": 5, "Id": "98c6f2c2287f4c73", "Name": "parallel-branch-1", - "EventTimestamp": "2025-12-10T00:15:08.904Z", + "EventTimestamp": "2025-12-12T00:34:22.969Z", "ParentId": "c4ca4238a0b92382", "ContextStartedDetails": {} }, @@ -55,7 +55,7 @@ "EventId": 6, "Id": "6151f5ab282d90e4", "Name": "task-2", - "EventTimestamp": "2025-12-10T00:15:08.904Z", + "EventTimestamp": "2025-12-12T00:34:22.969Z", "ParentId": "98c6f2c2287f4c73", "StepStartedDetails": {} }, @@ -65,7 +65,7 @@ "EventId": 7, "Id": "13cee27a2bd93915", "Name": "parallel-branch-2", - "EventTimestamp": "2025-12-10T00:15:08.904Z", + "EventTimestamp": "2025-12-12T00:34:22.969Z", "ParentId": "c4ca4238a0b92382", "ContextStartedDetails": {} }, @@ -75,7 +75,7 @@ "EventId": 8, "Id": "b425e0c75591aa8f", "Name": "task-3", - "EventTimestamp": "2025-12-10T00:15:08.904Z", + "EventTimestamp": "2025-12-12T00:34:22.969Z", "ParentId": "13cee27a2bd93915", "StepStartedDetails": {} }, @@ -85,7 +85,7 @@ "EventId": 9, "Id": "3a170a9fe4f47efa", "Name": "parallel-branch-3", - "EventTimestamp": "2025-12-10T00:15:08.904Z", + "EventTimestamp": "2025-12-12T00:34:22.969Z", "ParentId": "c4ca4238a0b92382", "ContextStartedDetails": {} }, @@ -95,7 +95,7 @@ "EventId": 10, "Id": "a4e1cd317d54f087", "Name": "task-4", - "EventTimestamp": "2025-12-10T00:15:08.904Z", + "EventTimestamp": "2025-12-12T00:34:22.969Z", "ParentId": "3a170a9fe4f47efa", "StepStartedDetails": {} }, @@ -105,7 +105,7 @@ "EventId": 11, "Id": "12426c956d1bc501", "Name": "parallel-branch-4", - "EventTimestamp": "2025-12-10T00:15:08.904Z", + "EventTimestamp": "2025-12-12T00:34:22.969Z", "ParentId": "c4ca4238a0b92382", "ContextStartedDetails": {} }, @@ -115,7 +115,7 @@ "EventId": 12, "Id": "0f42756e5788f9b0", "Name": "task-5", - "EventTimestamp": "2025-12-10T00:15:08.904Z", + "EventTimestamp": "2025-12-12T00:34:22.969Z", "ParentId": "12426c956d1bc501", "StepStartedDetails": {} }, @@ -125,7 +125,7 @@ "EventId": 13, "Id": "2f221a18eb863803", "Name": "task-1", - "EventTimestamp": "2025-12-10T00:15:08.904Z", + "EventTimestamp": "2025-12-12T00:34:22.969Z", "ParentId": "ea66c06c1e1c05fa", "StepFailedDetails": { "Error": { @@ -146,7 +146,7 @@ "EventId": 14, "Id": "6151f5ab282d90e4", "Name": "task-2", - "EventTimestamp": "2025-12-10T00:15:08.906Z", + "EventTimestamp": "2025-12-12T00:34:22.971Z", "ParentId": "98c6f2c2287f4c73", "StepFailedDetails": { "Error": { @@ -156,7 +156,7 @@ } }, "RetryDetails": { - "NextAttemptDelaySeconds": 3, + "NextAttemptDelaySeconds": 1, "CurrentAttempt": 1 } } @@ -167,7 +167,7 @@ "EventId": 15, "Id": "b425e0c75591aa8f", "Name": "task-3", - "EventTimestamp": "2025-12-10T00:15:08.906Z", + "EventTimestamp": "2025-12-12T00:34:22.971Z", "ParentId": "13cee27a2bd93915", "StepFailedDetails": { "Error": { @@ -177,7 +177,7 @@ } }, "RetryDetails": { - "NextAttemptDelaySeconds": 3, + "NextAttemptDelaySeconds": 2, "CurrentAttempt": 1 } } @@ -188,7 +188,7 @@ "EventId": 16, "Id": "a4e1cd317d54f087", "Name": "task-4", - "EventTimestamp": "2025-12-10T00:15:08.906Z", + "EventTimestamp": "2025-12-12T00:34:22.971Z", "ParentId": "3a170a9fe4f47efa", "StepSucceededDetails": { "Result": { @@ -203,7 +203,7 @@ "EventId": 17, "Id": "0f42756e5788f9b0", "Name": "task-5", - "EventTimestamp": "2025-12-10T00:15:08.906Z", + "EventTimestamp": "2025-12-12T00:34:22.971Z", "ParentId": "12426c956d1bc501", "StepSucceededDetails": { "Result": { @@ -218,7 +218,7 @@ "EventId": 18, "Id": "3a170a9fe4f47efa", "Name": "parallel-branch-3", - "EventTimestamp": "2025-12-10T00:15:08.911Z", + "EventTimestamp": "2025-12-12T00:34:22.974Z", "ParentId": "c4ca4238a0b92382", "ContextSucceededDetails": { "Result": { @@ -232,7 +232,7 @@ "EventId": 19, "Id": "12426c956d1bc501", "Name": "parallel-branch-4", - "EventTimestamp": "2025-12-10T00:15:08.911Z", + "EventTimestamp": "2025-12-12T00:34:22.974Z", "ParentId": "c4ca4238a0b92382", "ContextSucceededDetails": { "Result": { @@ -243,12 +243,12 @@ { "EventType": "InvocationCompleted", "EventId": 20, - "EventTimestamp": "2025-12-10T00:15:08.912Z", + "EventTimestamp": "2025-12-12T00:34:22.975Z", "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-10T00:15:08.860Z", - "EndTimestamp": "2025-12-10T00:15:08.912Z", + "StartTimestamp": "2025-12-12T00:34:22.960Z", + "EndTimestamp": "2025-12-12T00:34:22.975Z", "Error": {}, - "RequestId": "94b982cf-2168-48e8-98db-82e418609eec" + "RequestId": "356c3e0e-fdc9-4e0d-a720-129b013de4ff" } }, { @@ -257,37 +257,17 @@ "EventId": 21, "Id": "2f221a18eb863803", "Name": "task-1", - "EventTimestamp": "2025-12-10T00:15:08.944Z", + "EventTimestamp": "2025-12-12T00:34:23.977Z", "ParentId": "ea66c06c1e1c05fa", "StepStartedDetails": {} }, - { - "EventType": "StepStarted", - "SubType": "Step", - "EventId": 22, - "Id": "6151f5ab282d90e4", - "Name": "task-2", - "EventTimestamp": "2025-12-10T00:15:08.944Z", - "ParentId": "98c6f2c2287f4c73", - "StepStartedDetails": {} - }, - { - "EventType": "StepStarted", - "SubType": "Step", - "EventId": 23, - "Id": "b425e0c75591aa8f", - "Name": "task-3", - "EventTimestamp": "2025-12-10T00:15:08.944Z", - "ParentId": "13cee27a2bd93915", - "StepStartedDetails": {} - }, { "EventType": "StepFailed", "SubType": "Step", - "EventId": 24, + "EventId": 22, "Id": "2f221a18eb863803", "Name": "task-1", - "EventTimestamp": "2025-12-10T00:15:08.944Z", + "EventTimestamp": "2025-12-12T00:34:23.977Z", "ParentId": "ea66c06c1e1c05fa", "StepFailedDetails": { "Error": { @@ -302,37 +282,27 @@ } }, { - "EventType": "StepFailed", + "EventType": "StepStarted", "SubType": "Step", - "EventId": 25, + "EventId": 23, "Id": "6151f5ab282d90e4", "Name": "task-2", - "EventTimestamp": "2025-12-10T00:15:08.944Z", + "EventTimestamp": "2025-12-12T00:34:23.979Z", "ParentId": "98c6f2c2287f4c73", - "StepFailedDetails": { - "Error": { - "Payload": { - "ErrorMessage": "Task 2 failed", - "ErrorType": "Error" - } - }, - "RetryDetails": { - "CurrentAttempt": 1 - } - } + "StepStartedDetails": {} }, { "EventType": "StepFailed", "SubType": "Step", - "EventId": 26, - "Id": "b425e0c75591aa8f", - "Name": "task-3", - "EventTimestamp": "2025-12-10T00:15:08.944Z", - "ParentId": "13cee27a2bd93915", + "EventId": 24, + "Id": "6151f5ab282d90e4", + "Name": "task-2", + "EventTimestamp": "2025-12-12T00:34:23.979Z", + "ParentId": "98c6f2c2287f4c73", "StepFailedDetails": { "Error": { "Payload": { - "ErrorMessage": "Task 3 failed", + "ErrorMessage": "Task 2 failed", "ErrorType": "Error" } }, @@ -344,10 +314,10 @@ { "EventType": "ContextFailed", "SubType": "ParallelBranch", - "EventId": 27, + "EventId": 25, "Id": "ea66c06c1e1c05fa", "Name": "parallel-branch-0", - "EventTimestamp": "2025-12-10T00:15:08.966Z", + "EventTimestamp": "2025-12-12T00:34:23.979Z", "ParentId": "c4ca4238a0b92382", "ContextFailedDetails": { "Error": { @@ -361,10 +331,10 @@ { "EventType": "ContextFailed", "SubType": "ParallelBranch", - "EventId": 28, + "EventId": 26, "Id": "98c6f2c2287f4c73", "Name": "parallel-branch-1", - "EventTimestamp": "2025-12-10T00:15:08.966Z", + "EventTimestamp": "2025-12-12T00:34:23.982Z", "ParentId": "c4ca4238a0b92382", "ContextFailedDetails": { "Error": { @@ -375,13 +345,54 @@ } } }, + { + "EventType": "InvocationCompleted", + "EventId": 27, + "EventTimestamp": "2025-12-12T00:34:23.982Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-12T00:34:23.971Z", + "EndTimestamp": "2025-12-12T00:34:23.982Z", + "Error": {}, + "RequestId": "0645d44e-7feb-452e-9f09-8b3f18546e06" + } + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 28, + "Id": "b425e0c75591aa8f", + "Name": "task-3", + "EventTimestamp": "2025-12-12T00:34:24.979Z", + "ParentId": "13cee27a2bd93915", + "StepStartedDetails": {} + }, + { + "EventType": "StepFailed", + "SubType": "Step", + "EventId": 29, + "Id": "b425e0c75591aa8f", + "Name": "task-3", + "EventTimestamp": "2025-12-12T00:34:24.979Z", + "ParentId": "13cee27a2bd93915", + "StepFailedDetails": { + "Error": { + "Payload": { + "ErrorMessage": "Task 3 failed", + "ErrorType": "Error" + } + }, + "RetryDetails": { + "CurrentAttempt": 1 + } + } + }, { "EventType": "ContextFailed", "SubType": "ParallelBranch", - "EventId": 29, + "EventId": 30, "Id": "13cee27a2bd93915", "Name": "parallel-branch-2", - "EventTimestamp": "2025-12-10T00:15:08.966Z", + "EventTimestamp": "2025-12-12T00:34:24.983Z", "ParentId": "c4ca4238a0b92382", "ContextFailedDetails": { "Error": { @@ -395,10 +406,10 @@ { "EventType": "ContextSucceeded", "SubType": "Parallel", - "EventId": 30, + "EventId": 31, "Id": "c4ca4238a0b92382", "Name": "failure-threshold-tasks", - "EventTimestamp": "2025-12-10T00:15:08.966Z", + "EventTimestamp": "2025-12-12T00:34:24.983Z", "ContextSucceededDetails": { "Result": { "Payload": "{\"all\":[{\"error\":{\"cause\":{\"cause\":{\"name\":\"StepError\"},\"name\":\"StepError\",\"errorType\":\"StepError\"},\"name\":\"ChildContextError\",\"errorType\":\"ChildContextError\"},\"index\":0,\"status\":\"FAILED\"},{\"error\":{\"cause\":{\"cause\":{\"name\":\"StepError\"},\"name\":\"StepError\",\"errorType\":\"StepError\"},\"name\":\"ChildContextError\",\"errorType\":\"ChildContextError\"},\"index\":1,\"status\":\"FAILED\"},{\"error\":{\"cause\":{\"cause\":{\"name\":\"StepError\"},\"name\":\"StepError\",\"errorType\":\"StepError\"},\"name\":\"ChildContextError\",\"errorType\":\"ChildContextError\"},\"index\":2,\"status\":\"FAILED\"},{\"result\":\"Task 4 success\",\"index\":3,\"status\":\"SUCCEEDED\"},{\"result\":\"Task 5 success\",\"index\":4,\"status\":\"SUCCEEDED\"}],\"completionReason\":\"FAILURE_TOLERANCE_EXCEEDED\"}" @@ -408,40 +419,51 @@ { "EventType": "WaitStarted", "SubType": "Wait", - "EventId": 31, + "EventId": 32, "Id": "c81e728d9d4c2f63", - "EventTimestamp": "2025-12-10T00:15:08.966Z", + "EventTimestamp": "2025-12-12T00:34:24.983Z", "WaitStartedDetails": { "Duration": 1, - "ScheduledEndTimestamp": "2025-12-10T00:15:09.966Z" + "ScheduledEndTimestamp": "2025-12-12T00:34:25.983Z" + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 33, + "EventTimestamp": "2025-12-12T00:34:24.985Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-12T00:34:24.973Z", + "EndTimestamp": "2025-12-12T00:34:24.985Z", + "Error": {}, + "RequestId": "f4cf5407-ad20-4d1b-bc12-abeecbd4d5d3" } }, { "EventType": "WaitSucceeded", "SubType": "Wait", - "EventId": 32, + "EventId": 34, "Id": "c81e728d9d4c2f63", - "EventTimestamp": "2025-12-10T00:15:08.968Z", + "EventTimestamp": "2025-12-12T00:34:25.985Z", "WaitSucceededDetails": { "Duration": 1 } }, { "EventType": "InvocationCompleted", - "EventId": 33, - "EventTimestamp": "2025-12-10T00:15:08.988Z", + "EventId": 35, + "EventTimestamp": "2025-12-12T00:34:25.989Z", "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-10T00:15:08.923Z", - "EndTimestamp": "2025-12-10T00:15:08.988Z", + "StartTimestamp": "2025-12-12T00:34:25.986Z", + "EndTimestamp": "2025-12-12T00:34:25.989Z", "Error": {}, - "RequestId": "05310f70-731e-46ac-b236-3aa3178cc695" + "RequestId": "c785cb90-b5a3-4a39-8c5c-d32e3d05621e" } }, { "EventType": "ExecutionSucceeded", - "EventId": 34, - "Id": "10987b52-759d-4d31-a87d-f3ccb156f41a", - "EventTimestamp": "2025-12-10T00:15:08.989Z", + "EventId": 36, + "Id": "6195d06b-1435-46f4-b5a0-fea943f76af9", + "EventTimestamp": "2025-12-12T00:34:25.989Z", "ExecutionSucceededDetails": { "Result": { "Payload": "{\"completionReason\":\"FAILURE_TOLERANCE_EXCEEDED\",\"successCount\":2,\"failureCount\":3,\"totalCount\":5}" diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/failure-threshold-exceeded-percentage/parallel-failure-threshold-exceeded-percentage.test.ts b/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/failure-threshold-exceeded-percentage/parallel-failure-threshold-exceeded-percentage.test.ts index d0bd9827..ec45c8b3 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/failure-threshold-exceeded-percentage/parallel-failure-threshold-exceeded-percentage.test.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/failure-threshold-exceeded-percentage/parallel-failure-threshold-exceeded-percentage.test.ts @@ -13,7 +13,9 @@ createTests({ expect(result.failureCount).toBe(3); // Tasks 1, 2, 3 fail (60% > 50% threshold) expect(result.totalCount).toBe(5); - assertEventSignatures(execution); + assertEventSignatures(execution, undefined, { + invocationCompletedDifference: 1, + }); }); }, }); From 83135b62bee3e84fd69c3900bcd93f8b000e0990 Mon Sep 17 00:00:00 2001 From: Anthony Ting Date: Tue, 16 Dec 2025 14:11:22 -0800 Subject: [PATCH 13/14] fix missing import --- .../src/examples/map/min-successful/map-min-successful.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/map/min-successful/map-min-successful.test.ts b/packages/aws-durable-execution-sdk-js-examples/src/examples/map/min-successful/map-min-successful.test.ts index 59ec40b1..706f0a66 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/map/min-successful/map-min-successful.test.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/map/min-successful/map-min-successful.test.ts @@ -8,7 +8,7 @@ createTests({ skipTime: false, checkpointDelay: 100, }, - tests: (runner) => { + tests: (runner, { assertEventSignatures }) => { it("should complete early when minSuccessful is reached", async () => { const execution = await runner.run(); const result = execution.getResult() as any; From 2c3846e8329ede3b993104debc5f66fb6d30c98c Mon Sep 17 00:00:00 2001 From: Anthony Ting Date: Tue, 16 Dec 2025 17:00:11 -0800 Subject: [PATCH 14/14] update history files based on latest fixes --- .../create-callback-concurrent.test.ts | 2 +- ...lure-threshold-exceeded-count.history.json | 184 +++++------ .../map-min-successful.history.json | 167 +++------- ...essful-with-passing-threshold.history.json | 294 ++++++++++++++++++ ...-successful-with-passing-threshold.test.ts | 4 +- .../parallel-min-successful.history.json | 151 +++------ .../parallel/wait/parallel-wait.history.json | 84 ++--- .../parallel/wait/parallel-wait.test.ts | 7 +- .../wait-for-callback-anonymous.history.json | 66 ++-- .../wait-for-callback-anonymous.test.ts | 4 +- .../wait-for-callback-failure.history.json | 70 ++--- .../wait-for-callback-success.history.json | 66 ++-- .../wait-for-callback-timed-out.history.json | 38 +-- .../basic/wait-for-callback.test.ts | 4 +- ...it-for-callback-child-context.history.json | 150 ++++----- .../wait-for-callback-child-context.test.ts | 5 +- ...or-callback-failing-submitter.history.json | 180 +++++++++++ ...ait-for-callback-failing-submitter.test.ts | 7 +- .../wait-for-callback-failures.history.json | 72 ++--- .../wait-for-callback-failures.test.ts | 4 +- ...-for-callback-heartbeat-sends.history.json | 38 +-- .../wait-for-callback-heartbeat-sends.test.ts | 4 +- .../wait-for-callback-mixed-ops.history.json | 138 ++++---- .../wait-for-callback-mixed-ops.test.ts | 2 +- ...callback-multiple-invocations.history.json | 92 +++--- .../wait-for-callback-nested.history.json | 204 ++++++------ .../nested/wait-for-callback-nested.test.ts | 6 +- ...for-callback-quick-completion.history.json | 101 ++++++ ...wait-for-callback-quick-completion.test.ts | 4 +- .../wait-for-callback-serdes.history.json | 104 +++---- .../serdes/wait-for-callback-serdes.test.ts | 2 +- ...k-submitter-failure-catchable.history.json | 52 ++-- ...bmitter-retry-success-failure.history.json | 228 ++++++++++++++ ...mitter-retry-success-success.history.json} | 66 ++-- ...r-callback-submitter-retry-success.test.ts | 6 +- .../wait-for-callback-timeout.history.json | 38 +-- 36 files changed, 1660 insertions(+), 984 deletions(-) create mode 100644 packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/min-successful-with-passing-threshold/min-successful-with-passing-threshold.history.json create mode 100644 packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/failing-submitter/wait-for-callback-failing-submitter.history.json create mode 100644 packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/quick-completion/wait-for-callback-quick-completion.history.json create mode 100644 packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/submitter-retry-success/wait-for-callback-submitter-retry-success-failure.history.json rename packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/submitter-retry-success/{wait-for-callback-submitter-retry-success.history.json => wait-for-callback-submitter-retry-success-success.history.json} (64%) diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/concurrent/create-callback-concurrent.test.ts b/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/concurrent/create-callback-concurrent.test.ts index 6dfd13d4..1a6b5bda 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/concurrent/create-callback-concurrent.test.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/create-callback/concurrent/create-callback-concurrent.test.ts @@ -64,7 +64,7 @@ createTests({ ).toBe(true); assertEventSignatures(result, undefined, { - invocationCompletedDifference: 1, + invocationCompletedDifference: 2, }); }); }, diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/map/failure-threshold-exceeded-count/map-failure-threshold-exceeded-count.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/map/failure-threshold-exceeded-count/map-failure-threshold-exceeded-count.history.json index 7dcddb95..05054b6f 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/map/failure-threshold-exceeded-count/map-failure-threshold-exceeded-count.history.json +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/map/failure-threshold-exceeded-count/map-failure-threshold-exceeded-count.history.json @@ -2,8 +2,8 @@ { "EventType": "ExecutionStarted", "EventId": 1, - "Id": "dfeefa8f-8522-49d4-b8a0-0adb383962d6", - "EventTimestamp": "2025-12-10T00:14:18.046Z", + "Id": "76792fd2-f83c-4e19-8f2a-8a9b6491d9e1", + "EventTimestamp": "2025-12-17T00:59:15.121Z", "ExecutionStartedDetails": { "Input": { "Payload": "{}" @@ -16,7 +16,7 @@ "EventId": 2, "Id": "c4ca4238a0b92382", "Name": "failure-threshold-items", - "EventTimestamp": "2025-12-10T00:14:18.080Z", + "EventTimestamp": "2025-12-17T00:59:15.130Z", "ContextStartedDetails": {} }, { @@ -25,7 +25,7 @@ "EventId": 3, "Id": "ea66c06c1e1c05fa", "Name": "map-item-0", - "EventTimestamp": "2025-12-10T00:14:18.080Z", + "EventTimestamp": "2025-12-17T00:59:15.130Z", "ParentId": "c4ca4238a0b92382", "ContextStartedDetails": {} }, @@ -35,7 +35,7 @@ "EventId": 4, "Id": "2f221a18eb863803", "Name": "process-0", - "EventTimestamp": "2025-12-10T00:14:18.080Z", + "EventTimestamp": "2025-12-17T00:59:15.130Z", "ParentId": "ea66c06c1e1c05fa", "StepStartedDetails": {} }, @@ -45,7 +45,7 @@ "EventId": 5, "Id": "98c6f2c2287f4c73", "Name": "map-item-1", - "EventTimestamp": "2025-12-10T00:14:18.080Z", + "EventTimestamp": "2025-12-17T00:59:15.130Z", "ParentId": "c4ca4238a0b92382", "ContextStartedDetails": {} }, @@ -55,7 +55,7 @@ "EventId": 6, "Id": "6151f5ab282d90e4", "Name": "process-1", - "EventTimestamp": "2025-12-10T00:14:18.080Z", + "EventTimestamp": "2025-12-17T00:59:15.130Z", "ParentId": "98c6f2c2287f4c73", "StepStartedDetails": {} }, @@ -65,7 +65,7 @@ "EventId": 7, "Id": "13cee27a2bd93915", "Name": "map-item-2", - "EventTimestamp": "2025-12-10T00:14:18.080Z", + "EventTimestamp": "2025-12-17T00:59:15.130Z", "ParentId": "c4ca4238a0b92382", "ContextStartedDetails": {} }, @@ -75,7 +75,7 @@ "EventId": 8, "Id": "b425e0c75591aa8f", "Name": "process-2", - "EventTimestamp": "2025-12-10T00:14:18.080Z", + "EventTimestamp": "2025-12-17T00:59:15.130Z", "ParentId": "13cee27a2bd93915", "StepStartedDetails": {} }, @@ -85,7 +85,7 @@ "EventId": 9, "Id": "3a170a9fe4f47efa", "Name": "map-item-3", - "EventTimestamp": "2025-12-10T00:14:18.080Z", + "EventTimestamp": "2025-12-17T00:59:15.130Z", "ParentId": "c4ca4238a0b92382", "ContextStartedDetails": {} }, @@ -95,7 +95,7 @@ "EventId": 10, "Id": "a4e1cd317d54f087", "Name": "process-3", - "EventTimestamp": "2025-12-10T00:14:18.080Z", + "EventTimestamp": "2025-12-17T00:59:15.130Z", "ParentId": "3a170a9fe4f47efa", "StepStartedDetails": {} }, @@ -105,7 +105,7 @@ "EventId": 11, "Id": "12426c956d1bc501", "Name": "map-item-4", - "EventTimestamp": "2025-12-10T00:14:18.080Z", + "EventTimestamp": "2025-12-17T00:59:15.130Z", "ParentId": "c4ca4238a0b92382", "ContextStartedDetails": {} }, @@ -115,7 +115,7 @@ "EventId": 12, "Id": "0f42756e5788f9b0", "Name": "process-4", - "EventTimestamp": "2025-12-10T00:14:18.080Z", + "EventTimestamp": "2025-12-17T00:59:15.130Z", "ParentId": "12426c956d1bc501", "StepStartedDetails": {} }, @@ -125,7 +125,7 @@ "EventId": 13, "Id": "2f221a18eb863803", "Name": "process-0", - "EventTimestamp": "2025-12-10T00:14:18.080Z", + "EventTimestamp": "2025-12-17T00:59:15.130Z", "ParentId": "ea66c06c1e1c05fa", "StepFailedDetails": { "Error": { @@ -135,7 +135,7 @@ } }, "RetryDetails": { - "NextAttemptDelaySeconds": 2, + "NextAttemptDelaySeconds": 4, "CurrentAttempt": 1 } } @@ -146,7 +146,7 @@ "EventId": 14, "Id": "6151f5ab282d90e4", "Name": "process-1", - "EventTimestamp": "2025-12-10T00:14:18.086Z", + "EventTimestamp": "2025-12-17T00:59:15.132Z", "ParentId": "98c6f2c2287f4c73", "StepFailedDetails": { "Error": { @@ -156,7 +156,7 @@ } }, "RetryDetails": { - "NextAttemptDelaySeconds": 1, + "NextAttemptDelaySeconds": 4, "CurrentAttempt": 1 } } @@ -167,7 +167,7 @@ "EventId": 15, "Id": "b425e0c75591aa8f", "Name": "process-2", - "EventTimestamp": "2025-12-10T00:14:18.086Z", + "EventTimestamp": "2025-12-17T00:59:15.132Z", "ParentId": "13cee27a2bd93915", "StepFailedDetails": { "Error": { @@ -177,7 +177,7 @@ } }, "RetryDetails": { - "NextAttemptDelaySeconds": 2, + "NextAttemptDelaySeconds": 1, "CurrentAttempt": 1 } } @@ -188,7 +188,7 @@ "EventId": 16, "Id": "a4e1cd317d54f087", "Name": "process-3", - "EventTimestamp": "2025-12-10T00:14:18.086Z", + "EventTimestamp": "2025-12-17T00:59:15.132Z", "ParentId": "3a170a9fe4f47efa", "StepSucceededDetails": { "Result": { @@ -203,7 +203,7 @@ "EventId": 17, "Id": "0f42756e5788f9b0", "Name": "process-4", - "EventTimestamp": "2025-12-10T00:14:18.086Z", + "EventTimestamp": "2025-12-17T00:59:15.132Z", "ParentId": "12426c956d1bc501", "StepSucceededDetails": { "Result": { @@ -218,7 +218,7 @@ "EventId": 18, "Id": "3a170a9fe4f47efa", "Name": "map-item-3", - "EventTimestamp": "2025-12-10T00:14:18.090Z", + "EventTimestamp": "2025-12-17T00:59:15.136Z", "ParentId": "c4ca4238a0b92382", "ContextSucceededDetails": { "Result": { @@ -232,7 +232,7 @@ "EventId": 19, "Id": "12426c956d1bc501", "Name": "map-item-4", - "EventTimestamp": "2025-12-10T00:14:18.090Z", + "EventTimestamp": "2025-12-17T00:59:15.136Z", "ParentId": "c4ca4238a0b92382", "ContextSucceededDetails": { "Result": { @@ -243,36 +243,36 @@ { "EventType": "InvocationCompleted", "EventId": 20, - "EventTimestamp": "2025-12-10T00:14:18.139Z", + "EventTimestamp": "2025-12-17T00:59:15.184Z", "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-10T00:14:18.046Z", - "EndTimestamp": "2025-12-10T00:14:18.139Z", + "StartTimestamp": "2025-12-17T00:59:15.121Z", + "EndTimestamp": "2025-12-17T00:59:15.184Z", "Error": {}, - "RequestId": "d63bf0b3-dc58-4aa8-8a9e-3ce24cb48d86" + "RequestId": "a467f0c4-5599-47c0-911c-16969a899b3f" } }, { "EventType": "StepStarted", "SubType": "Step", "EventId": 21, - "Id": "6151f5ab282d90e4", - "Name": "process-1", - "EventTimestamp": "2025-12-10T00:14:19.089Z", - "ParentId": "98c6f2c2287f4c73", + "Id": "b425e0c75591aa8f", + "Name": "process-2", + "EventTimestamp": "2025-12-17T00:59:16.138Z", + "ParentId": "13cee27a2bd93915", "StepStartedDetails": {} }, { "EventType": "StepFailed", "SubType": "Step", "EventId": 22, - "Id": "6151f5ab282d90e4", - "Name": "process-1", - "EventTimestamp": "2025-12-10T00:14:19.089Z", - "ParentId": "98c6f2c2287f4c73", + "Id": "b425e0c75591aa8f", + "Name": "process-2", + "EventTimestamp": "2025-12-17T00:59:16.138Z", + "ParentId": "13cee27a2bd93915", "StepFailedDetails": { "Error": { "Payload": { - "ErrorMessage": "Item 2 failed", + "ErrorMessage": "Item 3 failed", "ErrorType": "Error" } }, @@ -285,15 +285,15 @@ "EventType": "ContextFailed", "SubType": "MapIteration", "EventId": 23, - "Id": "98c6f2c2287f4c73", - "Name": "map-item-1", - "EventTimestamp": "2025-12-10T00:14:19.091Z", + "Id": "13cee27a2bd93915", + "Name": "map-item-2", + "EventTimestamp": "2025-12-17T00:59:16.140Z", "ParentId": "c4ca4238a0b92382", "ContextFailedDetails": { "Error": { "Payload": { "ErrorType": "StepError", - "ErrorMessage": "Item 2 failed" + "ErrorMessage": "Item 3 failed" } } } @@ -301,12 +301,12 @@ { "EventType": "InvocationCompleted", "EventId": 24, - "EventTimestamp": "2025-12-10T00:14:19.140Z", + "EventTimestamp": "2025-12-17T00:59:16.188Z", "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-10T00:14:19.087Z", - "EndTimestamp": "2025-12-10T00:14:19.140Z", + "StartTimestamp": "2025-12-17T00:59:16.135Z", + "EndTimestamp": "2025-12-17T00:59:16.188Z", "Error": {}, - "RequestId": "51db7b2b-74c1-4c06-9717-e23a40b8e997" + "RequestId": "43eeed98-9706-4988-84e4-db6dcbd2417b" } }, { @@ -315,7 +315,7 @@ "EventId": 25, "Id": "2f221a18eb863803", "Name": "process-0", - "EventTimestamp": "2025-12-10T00:14:20.085Z", + "EventTimestamp": "2025-12-17T00:59:19.135Z", "ParentId": "ea66c06c1e1c05fa", "StepStartedDetails": {} }, @@ -325,7 +325,7 @@ "EventId": 26, "Id": "2f221a18eb863803", "Name": "process-0", - "EventTimestamp": "2025-12-10T00:14:20.085Z", + "EventTimestamp": "2025-12-17T00:59:19.135Z", "ParentId": "ea66c06c1e1c05fa", "StepFailedDetails": { "Error": { @@ -339,45 +339,28 @@ } } }, - { - "EventType": "ContextFailed", - "SubType": "MapIteration", - "EventId": 27, - "Id": "ea66c06c1e1c05fa", - "Name": "map-item-0", - "EventTimestamp": "2025-12-10T00:14:20.089Z", - "ParentId": "c4ca4238a0b92382", - "ContextFailedDetails": { - "Error": { - "Payload": { - "ErrorType": "StepError", - "ErrorMessage": "Item 1 failed" - } - } - } - }, { "EventType": "StepStarted", "SubType": "Step", - "EventId": 28, - "Id": "b425e0c75591aa8f", - "Name": "process-2", - "EventTimestamp": "2025-12-10T00:14:20.092Z", - "ParentId": "13cee27a2bd93915", + "EventId": 27, + "Id": "6151f5ab282d90e4", + "Name": "process-1", + "EventTimestamp": "2025-12-17T00:59:19.137Z", + "ParentId": "98c6f2c2287f4c73", "StepStartedDetails": {} }, { "EventType": "StepFailed", "SubType": "Step", - "EventId": 29, - "Id": "b425e0c75591aa8f", - "Name": "process-2", - "EventTimestamp": "2025-12-10T00:14:20.092Z", - "ParentId": "13cee27a2bd93915", + "EventId": 28, + "Id": "6151f5ab282d90e4", + "Name": "process-1", + "EventTimestamp": "2025-12-17T00:59:19.137Z", + "ParentId": "98c6f2c2287f4c73", "StepFailedDetails": { "Error": { "Payload": { - "ErrorMessage": "Item 3 failed", + "ErrorMessage": "Item 2 failed", "ErrorType": "Error" } }, @@ -386,19 +369,36 @@ } } }, + { + "EventType": "ContextFailed", + "SubType": "MapIteration", + "EventId": 29, + "Id": "ea66c06c1e1c05fa", + "Name": "map-item-0", + "EventTimestamp": "2025-12-17T00:59:19.137Z", + "ParentId": "c4ca4238a0b92382", + "ContextFailedDetails": { + "Error": { + "Payload": { + "ErrorType": "StepError", + "ErrorMessage": "Item 1 failed" + } + } + } + }, { "EventType": "ContextFailed", "SubType": "MapIteration", "EventId": 30, - "Id": "13cee27a2bd93915", - "Name": "map-item-2", - "EventTimestamp": "2025-12-10T00:14:20.096Z", + "Id": "98c6f2c2287f4c73", + "Name": "map-item-1", + "EventTimestamp": "2025-12-17T00:59:19.139Z", "ParentId": "c4ca4238a0b92382", "ContextFailedDetails": { "Error": { "Payload": { "ErrorType": "StepError", - "ErrorMessage": "Item 3 failed" + "ErrorMessage": "Item 2 failed" } } } @@ -409,7 +409,7 @@ "EventId": 31, "Id": "c4ca4238a0b92382", "Name": "failure-threshold-items", - "EventTimestamp": "2025-12-10T00:14:20.096Z", + "EventTimestamp": "2025-12-17T00:59:19.139Z", "ContextSucceededDetails": { "Result": { "Payload": "{\"all\":[{\"error\":{\"cause\":{\"cause\":{\"name\":\"StepError\"},\"name\":\"StepError\",\"errorType\":\"StepError\"},\"name\":\"ChildContextError\",\"errorType\":\"ChildContextError\"},\"index\":0,\"status\":\"FAILED\"},{\"error\":{\"cause\":{\"cause\":{\"name\":\"StepError\"},\"name\":\"StepError\",\"errorType\":\"StepError\"},\"name\":\"ChildContextError\",\"errorType\":\"ChildContextError\"},\"index\":1,\"status\":\"FAILED\"},{\"error\":{\"cause\":{\"cause\":{\"name\":\"StepError\"},\"name\":\"StepError\",\"errorType\":\"StepError\"},\"name\":\"ChildContextError\",\"errorType\":\"ChildContextError\"},\"index\":2,\"status\":\"FAILED\"},{\"result\":8,\"index\":3,\"status\":\"SUCCEEDED\"},{\"result\":10,\"index\":4,\"status\":\"SUCCEEDED\"}],\"completionReason\":\"FAILURE_TOLERANCE_EXCEEDED\"}" @@ -421,21 +421,21 @@ "SubType": "Wait", "EventId": 32, "Id": "c81e728d9d4c2f63", - "EventTimestamp": "2025-12-10T00:14:20.096Z", + "EventTimestamp": "2025-12-17T00:59:19.139Z", "WaitStartedDetails": { "Duration": 1, - "ScheduledEndTimestamp": "2025-12-10T00:14:21.096Z" + "ScheduledEndTimestamp": "2025-12-17T00:59:20.139Z" } }, { "EventType": "InvocationCompleted", "EventId": 33, - "EventTimestamp": "2025-12-10T00:14:20.148Z", + "EventTimestamp": "2025-12-17T00:59:19.191Z", "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-10T00:14:20.082Z", - "EndTimestamp": "2025-12-10T00:14:20.148Z", + "StartTimestamp": "2025-12-17T00:59:19.132Z", + "EndTimestamp": "2025-12-17T00:59:19.191Z", "Error": {}, - "RequestId": "c1852b3b-388c-4904-a611-ad6dc0c422f0" + "RequestId": "3b9349b4-f9e8-4b9a-b3ac-3418e2170923" } }, { @@ -443,7 +443,7 @@ "SubType": "Wait", "EventId": 34, "Id": "c81e728d9d4c2f63", - "EventTimestamp": "2025-12-10T00:14:21.098Z", + "EventTimestamp": "2025-12-17T00:59:20.141Z", "WaitSucceededDetails": { "Duration": 1 } @@ -451,19 +451,19 @@ { "EventType": "InvocationCompleted", "EventId": 35, - "EventTimestamp": "2025-12-10T00:14:21.101Z", + "EventTimestamp": "2025-12-17T00:59:20.142Z", "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-10T00:14:21.098Z", - "EndTimestamp": "2025-12-10T00:14:21.101Z", + "StartTimestamp": "2025-12-17T00:59:20.141Z", + "EndTimestamp": "2025-12-17T00:59:20.142Z", "Error": {}, - "RequestId": "8960e15c-7773-408c-9e0e-5efdfb89c535" + "RequestId": "10f9b51d-604e-4cc8-8baf-ee3138ae8833" } }, { "EventType": "ExecutionSucceeded", "EventId": 36, - "Id": "dfeefa8f-8522-49d4-b8a0-0adb383962d6", - "EventTimestamp": "2025-12-10T00:14:21.101Z", + "Id": "76792fd2-f83c-4e19-8f2a-8a9b6491d9e1", + "EventTimestamp": "2025-12-17T00:59:20.142Z", "ExecutionSucceededDetails": { "Result": { "Payload": "{\"completionReason\":\"FAILURE_TOLERANCE_EXCEEDED\",\"successCount\":2,\"failureCount\":3,\"totalCount\":5}" diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/map/min-successful/map-min-successful.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/map/min-successful/map-min-successful.history.json index 5f565136..8545af7e 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/map/min-successful/map-min-successful.history.json +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/map/min-successful/map-min-successful.history.json @@ -2,8 +2,8 @@ { "EventType": "ExecutionStarted", "EventId": 1, - "Id": "9d245077-e425-42f8-a8b5-521cac34e9d2", - "EventTimestamp": "2025-12-10T00:12:31.901Z", + "Id": "fdacfede-e7a7-44e9-9ae4-32235ccb56d7", + "EventTimestamp": "2025-12-17T00:58:29.541Z", "ExecutionStartedDetails": { "Input": { "Payload": "{}" @@ -16,7 +16,7 @@ "EventId": 2, "Id": "c4ca4238a0b92382", "Name": "min-successful-items", - "EventTimestamp": "2025-12-10T00:12:31.906Z", + "EventTimestamp": "2025-12-17T00:58:29.650Z", "ContextStartedDetails": {} }, { @@ -24,123 +24,58 @@ "SubType": "MapIteration", "EventId": 3, "Id": "ea66c06c1e1c05fa", - "Name": "map-item-0", - "EventTimestamp": "2025-12-10T00:12:31.906Z", + "Name": "process-0", + "EventTimestamp": "2025-12-17T00:58:29.650Z", "ParentId": "c4ca4238a0b92382", "ContextStartedDetails": {} }, - { - "EventType": "StepStarted", - "SubType": "Step", - "EventId": 4, - "Id": "2f221a18eb863803", - "Name": "process-0", - "EventTimestamp": "2025-12-10T00:12:31.906Z", - "ParentId": "ea66c06c1e1c05fa", - "StepStartedDetails": {} - }, { "EventType": "ContextStarted", "SubType": "MapIteration", - "EventId": 5, + "EventId": 4, "Id": "98c6f2c2287f4c73", - "Name": "map-item-1", - "EventTimestamp": "2025-12-10T00:12:31.906Z", + "Name": "process-1", + "EventTimestamp": "2025-12-17T00:58:29.650Z", "ParentId": "c4ca4238a0b92382", "ContextStartedDetails": {} }, - { - "EventType": "StepStarted", - "SubType": "Step", - "EventId": 6, - "Id": "6151f5ab282d90e4", - "Name": "process-1", - "EventTimestamp": "2025-12-10T00:12:31.906Z", - "ParentId": "98c6f2c2287f4c73", - "StepStartedDetails": {} - }, { "EventType": "ContextStarted", "SubType": "MapIteration", - "EventId": 7, + "EventId": 5, "Id": "13cee27a2bd93915", - "Name": "map-item-2", - "EventTimestamp": "2025-12-10T00:12:31.906Z", + "Name": "process-2", + "EventTimestamp": "2025-12-17T00:58:29.650Z", "ParentId": "c4ca4238a0b92382", "ContextStartedDetails": {} }, - { - "EventType": "StepStarted", - "SubType": "Step", - "EventId": 8, - "Id": "b425e0c75591aa8f", - "Name": "process-2", - "EventTimestamp": "2025-12-10T00:12:31.906Z", - "ParentId": "13cee27a2bd93915", - "StepStartedDetails": {} - }, { "EventType": "ContextStarted", "SubType": "MapIteration", - "EventId": 9, + "EventId": 6, "Id": "3a170a9fe4f47efa", - "Name": "map-item-3", - "EventTimestamp": "2025-12-10T00:12:31.906Z", + "Name": "process-3", + "EventTimestamp": "2025-12-17T00:58:29.650Z", "ParentId": "c4ca4238a0b92382", "ContextStartedDetails": {} }, - { - "EventType": "StepStarted", - "SubType": "Step", - "EventId": 10, - "Id": "a4e1cd317d54f087", - "Name": "process-3", - "EventTimestamp": "2025-12-10T00:12:31.906Z", - "ParentId": "3a170a9fe4f47efa", - "StepStartedDetails": {} - }, { "EventType": "ContextStarted", "SubType": "MapIteration", - "EventId": 11, + "EventId": 7, "Id": "12426c956d1bc501", - "Name": "map-item-4", - "EventTimestamp": "2025-12-10T00:12:31.906Z", + "Name": "process-4", + "EventTimestamp": "2025-12-17T00:58:29.650Z", "ParentId": "c4ca4238a0b92382", "ContextStartedDetails": {} }, - { - "EventType": "StepStarted", - "SubType": "Step", - "EventId": 12, - "Id": "0f42756e5788f9b0", - "Name": "process-4", - "EventTimestamp": "2025-12-10T00:12:31.906Z", - "ParentId": "12426c956d1bc501", - "StepStartedDetails": {} - }, - { - "EventType": "StepSucceeded", - "SubType": "Step", - "EventId": 13, - "Id": "2f221a18eb863803", - "Name": "process-0", - "EventTimestamp": "2025-12-10T00:12:32.005Z", - "ParentId": "ea66c06c1e1c05fa", - "StepSucceededDetails": { - "Result": { - "Payload": "\"Item 1 processed\"" - }, - "RetryDetails": {} - } - }, { "EventType": "ContextSucceeded", "SubType": "MapIteration", - "EventId": 14, + "EventId": 8, "Id": "ea66c06c1e1c05fa", - "Name": "map-item-0", - "EventTimestamp": "2025-12-10T00:12:32.007Z", + "Name": "process-0", + "EventTimestamp": "2025-12-17T00:58:29.752Z", "ParentId": "c4ca4238a0b92382", "ContextSucceededDetails": { "Result": { @@ -148,28 +83,13 @@ } } }, - { - "EventType": "StepSucceeded", - "SubType": "Step", - "EventId": 15, - "Id": "6151f5ab282d90e4", - "Name": "process-1", - "EventTimestamp": "2025-12-10T00:12:32.106Z", - "ParentId": "98c6f2c2287f4c73", - "StepSucceededDetails": { - "Result": { - "Payload": "\"Item 2 processed\"" - }, - "RetryDetails": {} - } - }, { "EventType": "ContextSucceeded", "SubType": "MapIteration", - "EventId": 16, + "EventId": 9, "Id": "98c6f2c2287f4c73", - "Name": "map-item-1", - "EventTimestamp": "2025-12-10T00:12:32.108Z", + "Name": "process-1", + "EventTimestamp": "2025-12-17T00:58:29.854Z", "ParentId": "c4ca4238a0b92382", "ContextSucceededDetails": { "Result": { @@ -180,10 +100,10 @@ { "EventType": "ContextSucceeded", "SubType": "Map", - "EventId": 17, + "EventId": 10, "Id": "c4ca4238a0b92382", "Name": "min-successful-items", - "EventTimestamp": "2025-12-10T00:12:32.108Z", + "EventTimestamp": "2025-12-17T00:58:29.854Z", "ContextSucceededDetails": { "Result": { "Payload": "{\"all\":[{\"result\":\"Item 1 processed\",\"index\":0,\"status\":\"SUCCEEDED\"},{\"result\":\"Item 2 processed\",\"index\":1,\"status\":\"SUCCEEDED\"},{\"index\":2,\"status\":\"STARTED\"},{\"index\":3,\"status\":\"STARTED\"},{\"index\":4,\"status\":\"STARTED\"}],\"completionReason\":\"MIN_SUCCESSFUL_REACHED\"}" @@ -193,40 +113,51 @@ { "EventType": "WaitStarted", "SubType": "Wait", - "EventId": 18, + "EventId": 11, "Id": "c81e728d9d4c2f63", - "EventTimestamp": "2025-12-10T00:12:32.108Z", + "EventTimestamp": "2025-12-17T00:58:29.856Z", "WaitStartedDetails": { "Duration": 1, - "ScheduledEndTimestamp": "2025-12-10T00:12:33.108Z" + "ScheduledEndTimestamp": "2025-12-17T00:58:30.856Z" + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 12, + "EventTimestamp": "2025-12-17T00:58:29.908Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-17T00:58:29.540Z", + "EndTimestamp": "2025-12-17T00:58:29.908Z", + "Error": {}, + "RequestId": "410ef6f3-8444-44cc-a415-ec08cdba0be3" } }, { "EventType": "WaitSucceeded", "SubType": "Wait", - "EventId": 19, + "EventId": 13, "Id": "c81e728d9d4c2f63", - "EventTimestamp": "2025-12-10T00:12:33.109Z", + "EventTimestamp": "2025-12-17T00:58:30.855Z", "WaitSucceededDetails": { "Duration": 1 } }, { "EventType": "InvocationCompleted", - "EventId": 20, - "EventTimestamp": "2025-12-10T00:12:33.111Z", + "EventId": 14, + "EventTimestamp": "2025-12-17T00:58:30.857Z", "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-10T00:12:31.901Z", - "EndTimestamp": "2025-12-10T00:12:33.111Z", + "StartTimestamp": "2025-12-17T00:58:30.855Z", + "EndTimestamp": "2025-12-17T00:58:30.857Z", "Error": {}, - "RequestId": "d45c051d-4981-4258-8008-22d1bac542de" + "RequestId": "5fd3bda2-7392-4a93-b47c-d145172d1f08" } }, { "EventType": "ExecutionSucceeded", - "EventId": 21, - "Id": "9d245077-e425-42f8-a8b5-521cac34e9d2", - "EventTimestamp": "2025-12-10T00:12:33.111Z", + "EventId": 15, + "Id": "fdacfede-e7a7-44e9-9ae4-32235ccb56d7", + "EventTimestamp": "2025-12-17T00:58:30.857Z", "ExecutionSucceededDetails": { "Result": { "Payload": "{\"successCount\":2,\"totalCount\":5,\"completionReason\":\"MIN_SUCCESSFUL_REACHED\",\"results\":[\"Item 1 processed\",\"Item 2 processed\"]}" diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/min-successful-with-passing-threshold/min-successful-with-passing-threshold.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/min-successful-with-passing-threshold/min-successful-with-passing-threshold.history.json new file mode 100644 index 00000000..c78db71c --- /dev/null +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/min-successful-with-passing-threshold/min-successful-with-passing-threshold.history.json @@ -0,0 +1,294 @@ +[ + { + "EventType": "ExecutionStarted", + "EventId": 1, + "Id": "8616e9a6-eb4c-451b-a5ce-726c1be5f31c", + "EventTimestamp": "2025-12-17T00:58:30.225Z", + "ExecutionStartedDetails": { + "Input": { + "Payload": "{}" + } + } + }, + { + "EventType": "ContextStarted", + "SubType": "Parallel", + "EventId": 2, + "Id": "c4ca4238a0b92382", + "Name": "min-successful-branches", + "EventTimestamp": "2025-12-17T00:58:30.334Z", + "ContextStartedDetails": {} + }, + { + "EventType": "ContextStarted", + "SubType": "ParallelBranch", + "EventId": 3, + "Id": "ea66c06c1e1c05fa", + "Name": "branch-1", + "EventTimestamp": "2025-12-17T00:58:30.334Z", + "ParentId": "c4ca4238a0b92382", + "ContextStartedDetails": {} + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 4, + "Id": "2f221a18eb863803", + "Name": "branch-1", + "EventTimestamp": "2025-12-17T00:58:30.334Z", + "ParentId": "ea66c06c1e1c05fa", + "StepStartedDetails": {} + }, + { + "EventType": "ContextStarted", + "SubType": "ParallelBranch", + "EventId": 5, + "Id": "98c6f2c2287f4c73", + "Name": "branch-2", + "EventTimestamp": "2025-12-17T00:58:30.335Z", + "ParentId": "c4ca4238a0b92382", + "ContextStartedDetails": {} + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 6, + "Id": "6151f5ab282d90e4", + "Name": "branch-2", + "EventTimestamp": "2025-12-17T00:58:30.335Z", + "ParentId": "98c6f2c2287f4c73", + "StepStartedDetails": {} + }, + { + "EventType": "ContextStarted", + "SubType": "ParallelBranch", + "EventId": 7, + "Id": "13cee27a2bd93915", + "Name": "branch-3", + "EventTimestamp": "2025-12-17T00:58:30.335Z", + "ParentId": "c4ca4238a0b92382", + "ContextStartedDetails": {} + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 8, + "Id": "b425e0c75591aa8f", + "Name": "branch-3", + "EventTimestamp": "2025-12-17T00:58:30.335Z", + "ParentId": "13cee27a2bd93915", + "StepStartedDetails": {} + }, + { + "EventType": "ContextStarted", + "SubType": "ParallelBranch", + "EventId": 9, + "Id": "3a170a9fe4f47efa", + "Name": "branch-4", + "EventTimestamp": "2025-12-17T00:58:30.335Z", + "ParentId": "c4ca4238a0b92382", + "ContextStartedDetails": {} + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 10, + "Id": "a4e1cd317d54f087", + "Name": "branch-4", + "EventTimestamp": "2025-12-17T00:58:30.335Z", + "ParentId": "3a170a9fe4f47efa", + "StepStartedDetails": {} + }, + { + "EventType": "ContextStarted", + "SubType": "ParallelBranch", + "EventId": 11, + "Id": "12426c956d1bc501", + "Name": "branch-5", + "EventTimestamp": "2025-12-17T00:58:30.335Z", + "ParentId": "c4ca4238a0b92382", + "ContextStartedDetails": {} + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 12, + "Id": "0f42756e5788f9b0", + "Name": "branch-4", + "EventTimestamp": "2025-12-17T00:58:30.335Z", + "ParentId": "12426c956d1bc501", + "StepStartedDetails": {} + }, + { + "EventType": "StepSucceeded", + "SubType": "Step", + "EventId": 13, + "Id": "2f221a18eb863803", + "Name": "branch-1", + "EventTimestamp": "2025-12-17T00:58:30.438Z", + "ParentId": "ea66c06c1e1c05fa", + "StepSucceededDetails": { + "Result": { + "Payload": "\"Branch 1 result\"" + }, + "RetryDetails": {} + } + }, + { + "EventType": "StepSucceeded", + "SubType": "Step", + "EventId": 14, + "Id": "6151f5ab282d90e4", + "Name": "branch-2", + "EventTimestamp": "2025-12-17T00:58:30.438Z", + "ParentId": "98c6f2c2287f4c73", + "StepSucceededDetails": { + "Result": { + "Payload": "\"Branch 2 result\"" + }, + "RetryDetails": {} + } + }, + { + "EventType": "StepSucceeded", + "SubType": "Step", + "EventId": 15, + "Id": "b425e0c75591aa8f", + "Name": "branch-3", + "EventTimestamp": "2025-12-17T00:58:30.438Z", + "ParentId": "13cee27a2bd93915", + "StepSucceededDetails": { + "Result": { + "Payload": "\"Branch 3 result\"" + }, + "RetryDetails": {} + } + }, + { + "EventType": "StepSucceeded", + "SubType": "Step", + "EventId": 16, + "Id": "a4e1cd317d54f087", + "Name": "branch-4", + "EventTimestamp": "2025-12-17T00:58:30.438Z", + "ParentId": "3a170a9fe4f47efa", + "StepSucceededDetails": { + "Result": { + "Payload": "\"Branch 4 result\"" + }, + "RetryDetails": {} + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "ParallelBranch", + "EventId": 17, + "Id": "ea66c06c1e1c05fa", + "Name": "branch-1", + "EventTimestamp": "2025-12-17T00:58:30.540Z", + "ParentId": "c4ca4238a0b92382", + "ContextSucceededDetails": { + "Result": { + "Payload": "\"Branch 1 result\"" + } + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "ParallelBranch", + "EventId": 18, + "Id": "98c6f2c2287f4c73", + "Name": "branch-2", + "EventTimestamp": "2025-12-17T00:58:30.540Z", + "ParentId": "c4ca4238a0b92382", + "ContextSucceededDetails": { + "Result": { + "Payload": "\"Branch 2 result\"" + } + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "ParallelBranch", + "EventId": 19, + "Id": "13cee27a2bd93915", + "Name": "branch-3", + "EventTimestamp": "2025-12-17T00:58:30.540Z", + "ParentId": "c4ca4238a0b92382", + "ContextSucceededDetails": { + "Result": { + "Payload": "\"Branch 3 result\"" + } + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "ParallelBranch", + "EventId": 20, + "Id": "3a170a9fe4f47efa", + "Name": "branch-4", + "EventTimestamp": "2025-12-17T00:58:30.540Z", + "ParentId": "c4ca4238a0b92382", + "ContextSucceededDetails": { + "Result": { + "Payload": "\"Branch 4 result\"" + } + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "Parallel", + "EventId": 21, + "Id": "c4ca4238a0b92382", + "Name": "min-successful-branches", + "EventTimestamp": "2025-12-17T00:58:30.540Z", + "ContextSucceededDetails": { + "Result": { + "Payload": "{\"all\":[{\"result\":\"Branch 1 result\",\"index\":0,\"status\":\"SUCCEEDED\"},{\"result\":\"Branch 2 result\",\"index\":1,\"status\":\"SUCCEEDED\"},{\"index\":2,\"status\":\"STARTED\"},{\"index\":3,\"status\":\"STARTED\"},{\"index\":4,\"status\":\"STARTED\"}],\"completionReason\":\"MIN_SUCCESSFUL_REACHED\"}" + } + } + }, + { + "EventType": "WaitStarted", + "SubType": "Wait", + "EventId": 22, + "Id": "c81e728d9d4c2f63", + "EventTimestamp": "2025-12-17T00:58:30.542Z", + "WaitStartedDetails": { + "Duration": 1, + "ScheduledEndTimestamp": "2025-12-17T00:58:31.542Z" + } + }, + { + "EventType": "WaitSucceeded", + "SubType": "Wait", + "EventId": 23, + "Id": "c81e728d9d4c2f63", + "EventTimestamp": "2025-12-17T00:58:31.542Z", + "WaitSucceededDetails": { + "Duration": 1 + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 24, + "EventTimestamp": "2025-12-17T00:58:31.643Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-17T00:58:30.225Z", + "EndTimestamp": "2025-12-17T00:58:31.643Z", + "Error": {}, + "RequestId": "41123f9f-f3d7-4369-8b5a-d01496a8d3c5" + } + }, + { + "EventType": "ExecutionSucceeded", + "EventId": 25, + "Id": "8616e9a6-eb4c-451b-a5ce-726c1be5f31c", + "EventTimestamp": "2025-12-17T00:58:31.643Z", + "ExecutionSucceededDetails": { + "Result": { + "Payload": "{\"successCount\":2,\"totalCount\":5,\"completionReason\":\"MIN_SUCCESSFUL_REACHED\",\"results\":[\"Branch 1 result\",\"Branch 2 result\"]}" + } + } + } +] diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/min-successful-with-passing-threshold/min-successful-with-passing-threshold.test.ts b/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/min-successful-with-passing-threshold/min-successful-with-passing-threshold.test.ts index d675f837..c90ee9b4 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/min-successful-with-passing-threshold/min-successful-with-passing-threshold.test.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/min-successful-with-passing-threshold/min-successful-with-passing-threshold.test.ts @@ -8,7 +8,7 @@ createTests({ checkpointDelay: 100, }, handler, - tests: (runner) => { + tests: (runner, { assertEventSignatures }) => { it("should complete early when minSuccessful is reached", async () => { const execution = await runner.run(); const result = execution.getResult() as any; @@ -37,6 +37,8 @@ createTests({ // Verify the results array matches expect(result.results).toEqual(["Branch 1 result", "Branch 2 result"]); + + assertEventSignatures(execution); }); }, }); diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/min-successful/parallel-min-successful.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/min-successful/parallel-min-successful.history.json index ec9db904..12fd8804 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/min-successful/parallel-min-successful.history.json +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/min-successful/parallel-min-successful.history.json @@ -2,8 +2,8 @@ { "EventType": "ExecutionStarted", "EventId": 1, - "Id": "03d6c29c-125f-4aec-8e82-cfdf27f2c4c8", - "EventTimestamp": "2025-12-10T00:12:26.332Z", + "Id": "810e0517-20b5-4ace-80c9-efafb76e0042", + "EventTimestamp": "2025-12-17T00:58:29.766Z", "ExecutionStartedDetails": { "Input": { "Payload": "{}" @@ -16,7 +16,7 @@ "EventId": 2, "Id": "c4ca4238a0b92382", "Name": "min-successful-branches", - "EventTimestamp": "2025-12-10T00:12:26.337Z", + "EventTimestamp": "2025-12-17T00:58:29.873Z", "ContextStartedDetails": {} }, { @@ -24,103 +24,48 @@ "SubType": "ParallelBranch", "EventId": 3, "Id": "ea66c06c1e1c05fa", - "Name": "parallel-branch-0", - "EventTimestamp": "2025-12-10T00:12:26.337Z", + "Name": "branch-1", + "EventTimestamp": "2025-12-17T00:58:29.873Z", "ParentId": "c4ca4238a0b92382", "ContextStartedDetails": {} }, - { - "EventType": "StepStarted", - "SubType": "Step", - "EventId": 4, - "Id": "2f221a18eb863803", - "Name": "branch-1", - "EventTimestamp": "2025-12-10T00:12:26.337Z", - "ParentId": "ea66c06c1e1c05fa", - "StepStartedDetails": {} - }, { "EventType": "ContextStarted", "SubType": "ParallelBranch", - "EventId": 5, + "EventId": 4, "Id": "98c6f2c2287f4c73", - "Name": "parallel-branch-1", - "EventTimestamp": "2025-12-10T00:12:26.337Z", + "Name": "branch-2", + "EventTimestamp": "2025-12-17T00:58:29.873Z", "ParentId": "c4ca4238a0b92382", "ContextStartedDetails": {} }, - { - "EventType": "StepStarted", - "SubType": "Step", - "EventId": 6, - "Id": "6151f5ab282d90e4", - "Name": "branch-2", - "EventTimestamp": "2025-12-10T00:12:26.337Z", - "ParentId": "98c6f2c2287f4c73", - "StepStartedDetails": {} - }, { "EventType": "ContextStarted", "SubType": "ParallelBranch", - "EventId": 7, + "EventId": 5, "Id": "13cee27a2bd93915", - "Name": "parallel-branch-2", - "EventTimestamp": "2025-12-10T00:12:26.337Z", + "Name": "branch-3", + "EventTimestamp": "2025-12-17T00:58:29.873Z", "ParentId": "c4ca4238a0b92382", "ContextStartedDetails": {} }, - { - "EventType": "StepStarted", - "SubType": "Step", - "EventId": 8, - "Id": "b425e0c75591aa8f", - "Name": "branch-3", - "EventTimestamp": "2025-12-10T00:12:26.337Z", - "ParentId": "13cee27a2bd93915", - "StepStartedDetails": {} - }, { "EventType": "ContextStarted", "SubType": "ParallelBranch", - "EventId": 9, + "EventId": 6, "Id": "3a170a9fe4f47efa", - "Name": "parallel-branch-3", - "EventTimestamp": "2025-12-10T00:12:26.337Z", + "Name": "branch-4", + "EventTimestamp": "2025-12-17T00:58:29.873Z", "ParentId": "c4ca4238a0b92382", "ContextStartedDetails": {} }, - { - "EventType": "StepStarted", - "SubType": "Step", - "EventId": 10, - "Id": "a4e1cd317d54f087", - "Name": "branch-4", - "EventTimestamp": "2025-12-10T00:12:26.337Z", - "ParentId": "3a170a9fe4f47efa", - "StepStartedDetails": {} - }, - { - "EventType": "StepSucceeded", - "SubType": "Step", - "EventId": 11, - "Id": "2f221a18eb863803", - "Name": "branch-1", - "EventTimestamp": "2025-12-10T00:12:26.437Z", - "ParentId": "ea66c06c1e1c05fa", - "StepSucceededDetails": { - "Result": { - "Payload": "\"Branch 1 result\"" - }, - "RetryDetails": {} - } - }, { "EventType": "ContextSucceeded", "SubType": "ParallelBranch", - "EventId": 12, + "EventId": 7, "Id": "ea66c06c1e1c05fa", - "Name": "parallel-branch-0", - "EventTimestamp": "2025-12-10T00:12:26.439Z", + "Name": "branch-1", + "EventTimestamp": "2025-12-17T00:58:29.976Z", "ParentId": "c4ca4238a0b92382", "ContextSucceededDetails": { "Result": { @@ -128,28 +73,13 @@ } } }, - { - "EventType": "StepSucceeded", - "SubType": "Step", - "EventId": 13, - "Id": "6151f5ab282d90e4", - "Name": "branch-2", - "EventTimestamp": "2025-12-10T00:12:26.538Z", - "ParentId": "98c6f2c2287f4c73", - "StepSucceededDetails": { - "Result": { - "Payload": "\"Branch 2 result\"" - }, - "RetryDetails": {} - } - }, { "EventType": "ContextSucceeded", "SubType": "ParallelBranch", - "EventId": 14, + "EventId": 8, "Id": "98c6f2c2287f4c73", - "Name": "parallel-branch-1", - "EventTimestamp": "2025-12-10T00:12:26.540Z", + "Name": "branch-2", + "EventTimestamp": "2025-12-17T00:58:30.078Z", "ParentId": "c4ca4238a0b92382", "ContextSucceededDetails": { "Result": { @@ -160,10 +90,10 @@ { "EventType": "ContextSucceeded", "SubType": "Parallel", - "EventId": 15, + "EventId": 9, "Id": "c4ca4238a0b92382", "Name": "min-successful-branches", - "EventTimestamp": "2025-12-10T00:12:26.540Z", + "EventTimestamp": "2025-12-17T00:58:30.078Z", "ContextSucceededDetails": { "Result": { "Payload": "{\"all\":[{\"result\":\"Branch 1 result\",\"index\":0,\"status\":\"SUCCEEDED\"},{\"result\":\"Branch 2 result\",\"index\":1,\"status\":\"SUCCEEDED\"},{\"index\":2,\"status\":\"STARTED\"},{\"index\":3,\"status\":\"STARTED\"}],\"completionReason\":\"MIN_SUCCESSFUL_REACHED\"}" @@ -173,40 +103,51 @@ { "EventType": "WaitStarted", "SubType": "Wait", - "EventId": 16, + "EventId": 10, "Id": "c81e728d9d4c2f63", - "EventTimestamp": "2025-12-10T00:12:26.540Z", + "EventTimestamp": "2025-12-17T00:58:30.083Z", "WaitStartedDetails": { "Duration": 1, - "ScheduledEndTimestamp": "2025-12-10T00:12:27.541Z" + "ScheduledEndTimestamp": "2025-12-17T00:58:31.083Z" + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 11, + "EventTimestamp": "2025-12-17T00:58:30.135Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-17T00:58:29.765Z", + "EndTimestamp": "2025-12-17T00:58:30.135Z", + "Error": {}, + "RequestId": "63101a38-1f97-4337-8052-c554ffc278ff" } }, { "EventType": "WaitSucceeded", "SubType": "Wait", - "EventId": 17, + "EventId": 12, "Id": "c81e728d9d4c2f63", - "EventTimestamp": "2025-12-10T00:12:27.542Z", + "EventTimestamp": "2025-12-17T00:58:31.079Z", "WaitSucceededDetails": { "Duration": 1 } }, { "EventType": "InvocationCompleted", - "EventId": 18, - "EventTimestamp": "2025-12-10T00:12:27.542Z", + "EventId": 13, + "EventTimestamp": "2025-12-17T00:58:31.081Z", "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-10T00:12:26.332Z", - "EndTimestamp": "2025-12-10T00:12:27.542Z", + "StartTimestamp": "2025-12-17T00:58:31.080Z", + "EndTimestamp": "2025-12-17T00:58:31.081Z", "Error": {}, - "RequestId": "f3fddb6a-3e25-4f65-b6de-eebe53a53c38" + "RequestId": "908f0992-b4ca-4cdd-a939-45e568c6a3ed" } }, { "EventType": "ExecutionSucceeded", - "EventId": 19, - "Id": "03d6c29c-125f-4aec-8e82-cfdf27f2c4c8", - "EventTimestamp": "2025-12-10T00:12:27.542Z", + "EventId": 14, + "Id": "810e0517-20b5-4ace-80c9-efafb76e0042", + "EventTimestamp": "2025-12-17T00:58:31.081Z", "ExecutionSucceededDetails": { "Result": { "Payload": "{\"successCount\":2,\"totalCount\":4,\"completionReason\":\"MIN_SUCCESSFUL_REACHED\",\"results\":[\"Branch 1 result\",\"Branch 2 result\"]}" diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/wait/parallel-wait.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/wait/parallel-wait.history.json index d36ace62..e9040b2c 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/wait/parallel-wait.history.json +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/wait/parallel-wait.history.json @@ -2,8 +2,8 @@ { "EventType": "ExecutionStarted", "EventId": 1, - "Id": "5bf93d96-3d76-4b4a-ab50-6030f2e8519a", - "EventTimestamp": "2025-12-05T00:16:50.853Z", + "Id": "e2353cfa-3083-477c-b1b5-5826461ae9d7", + "EventTimestamp": "2025-12-17T00:58:48.057Z", "ExecutionStartedDetails": { "Input": { "Payload": "{}" @@ -16,7 +16,7 @@ "EventId": 2, "Id": "c4ca4238a0b92382", "Name": "parent-block", - "EventTimestamp": "2025-12-05T00:16:50.869Z", + "EventTimestamp": "2025-12-17T00:58:48.062Z", "ContextStartedDetails": {} }, { @@ -25,7 +25,7 @@ "EventId": 3, "Id": "ea66c06c1e1c05fa", "Name": "parallel-branch-0", - "EventTimestamp": "2025-12-05T00:16:50.869Z", + "EventTimestamp": "2025-12-17T00:58:48.062Z", "ParentId": "c4ca4238a0b92382", "ContextStartedDetails": {} }, @@ -35,11 +35,11 @@ "EventId": 4, "Id": "2f221a18eb863803", "Name": "wait-1-second", - "EventTimestamp": "2025-12-05T00:16:50.872Z", + "EventTimestamp": "2025-12-17T00:58:48.062Z", "ParentId": "ea66c06c1e1c05fa", "WaitStartedDetails": { "Duration": 1, - "ScheduledEndTimestamp": "2025-12-05T00:16:51.872Z" + "ScheduledEndTimestamp": "2025-12-17T00:58:49.062Z" } }, { @@ -48,7 +48,7 @@ "EventId": 5, "Id": "98c6f2c2287f4c73", "Name": "parallel-branch-1", - "EventTimestamp": "2025-12-05T00:16:50.872Z", + "EventTimestamp": "2025-12-17T00:58:48.062Z", "ParentId": "c4ca4238a0b92382", "ContextStartedDetails": {} }, @@ -58,11 +58,11 @@ "EventId": 6, "Id": "6151f5ab282d90e4", "Name": "wait-1-second-again", - "EventTimestamp": "2025-12-05T00:16:50.872Z", + "EventTimestamp": "2025-12-17T00:58:48.062Z", "ParentId": "98c6f2c2287f4c73", "WaitStartedDetails": { "Duration": 1, - "ScheduledEndTimestamp": "2025-12-05T00:16:51.872Z" + "ScheduledEndTimestamp": "2025-12-17T00:58:49.062Z" } }, { @@ -71,7 +71,7 @@ "EventId": 7, "Id": "13cee27a2bd93915", "Name": "parallel-branch-2", - "EventTimestamp": "2025-12-05T00:16:50.872Z", + "EventTimestamp": "2025-12-17T00:58:48.062Z", "ParentId": "c4ca4238a0b92382", "ContextStartedDetails": {} }, @@ -81,11 +81,11 @@ "EventId": 8, "Id": "b425e0c75591aa8f", "Name": "wait-2-seconds", - "EventTimestamp": "2025-12-05T00:16:50.872Z", + "EventTimestamp": "2025-12-17T00:58:48.062Z", "ParentId": "13cee27a2bd93915", "WaitStartedDetails": { "Duration": 2, - "ScheduledEndTimestamp": "2025-12-05T00:16:52.872Z" + "ScheduledEndTimestamp": "2025-12-17T00:58:50.062Z" } }, { @@ -94,7 +94,7 @@ "EventId": 9, "Id": "3a170a9fe4f47efa", "Name": "parallel-branch-3", - "EventTimestamp": "2025-12-05T00:16:50.872Z", + "EventTimestamp": "2025-12-17T00:58:48.062Z", "ParentId": "c4ca4238a0b92382", "ContextStartedDetails": {} }, @@ -104,22 +104,22 @@ "EventId": 10, "Id": "a4e1cd317d54f087", "Name": "wait-5-seconds", - "EventTimestamp": "2025-12-05T00:16:50.872Z", + "EventTimestamp": "2025-12-17T00:58:48.062Z", "ParentId": "3a170a9fe4f47efa", "WaitStartedDetails": { "Duration": 5, - "ScheduledEndTimestamp": "2025-12-05T00:16:55.872Z" + "ScheduledEndTimestamp": "2025-12-17T00:58:53.062Z" } }, { "EventType": "InvocationCompleted", "EventId": 11, - "EventTimestamp": "2025-12-05T00:16:50.924Z", + "EventTimestamp": "2025-12-17T00:58:48.113Z", "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-05T00:16:50.853Z", - "EndTimestamp": "2025-12-05T00:16:50.924Z", + "StartTimestamp": "2025-12-17T00:58:48.057Z", + "EndTimestamp": "2025-12-17T00:58:48.113Z", "Error": {}, - "RequestId": "24b3c358-2e22-4f84-9423-577754ffe3c7" + "RequestId": "2a4f6fbe-9f0e-4b45-96d8-de1d8f698354" } }, { @@ -128,7 +128,7 @@ "EventId": 12, "Id": "2f221a18eb863803", "Name": "wait-1-second", - "EventTimestamp": "2025-12-05T00:16:51.872Z", + "EventTimestamp": "2025-12-17T00:58:49.064Z", "ParentId": "ea66c06c1e1c05fa", "WaitSucceededDetails": { "Duration": 1 @@ -140,7 +140,7 @@ "EventId": 13, "Id": "6151f5ab282d90e4", "Name": "wait-1-second-again", - "EventTimestamp": "2025-12-05T00:16:51.872Z", + "EventTimestamp": "2025-12-17T00:58:49.064Z", "ParentId": "98c6f2c2287f4c73", "WaitSucceededDetails": { "Duration": 1 @@ -152,7 +152,7 @@ "EventId": 14, "Id": "ea66c06c1e1c05fa", "Name": "parallel-branch-0", - "EventTimestamp": "2025-12-05T00:16:51.875Z", + "EventTimestamp": "2025-12-17T00:58:49.066Z", "ParentId": "c4ca4238a0b92382", "ContextSucceededDetails": { "Result": {} @@ -164,7 +164,7 @@ "EventId": 15, "Id": "98c6f2c2287f4c73", "Name": "parallel-branch-1", - "EventTimestamp": "2025-12-05T00:16:51.875Z", + "EventTimestamp": "2025-12-17T00:58:49.066Z", "ParentId": "c4ca4238a0b92382", "ContextSucceededDetails": { "Result": {} @@ -173,12 +173,12 @@ { "EventType": "InvocationCompleted", "EventId": 16, - "EventTimestamp": "2025-12-05T00:16:51.925Z", + "EventTimestamp": "2025-12-17T00:58:49.115Z", "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-05T00:16:51.872Z", - "EndTimestamp": "2025-12-05T00:16:51.925Z", + "StartTimestamp": "2025-12-17T00:58:49.064Z", + "EndTimestamp": "2025-12-17T00:58:49.115Z", "Error": {}, - "RequestId": "2119315f-aff7-4503-9556-8288b7cfaa5a" + "RequestId": "ce22cab3-2f49-4894-a523-199c69943054" } }, { @@ -187,7 +187,7 @@ "EventId": 17, "Id": "b425e0c75591aa8f", "Name": "wait-2-seconds", - "EventTimestamp": "2025-12-05T00:16:52.873Z", + "EventTimestamp": "2025-12-17T00:58:50.063Z", "ParentId": "13cee27a2bd93915", "WaitSucceededDetails": { "Duration": 2 @@ -199,7 +199,7 @@ "EventId": 18, "Id": "13cee27a2bd93915", "Name": "parallel-branch-2", - "EventTimestamp": "2025-12-05T00:16:52.877Z", + "EventTimestamp": "2025-12-17T00:58:50.065Z", "ParentId": "c4ca4238a0b92382", "ContextSucceededDetails": { "Result": {} @@ -208,12 +208,12 @@ { "EventType": "InvocationCompleted", "EventId": 19, - "EventTimestamp": "2025-12-05T00:16:52.929Z", + "EventTimestamp": "2025-12-17T00:58:50.115Z", "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-05T00:16:52.873Z", - "EndTimestamp": "2025-12-05T00:16:52.929Z", + "StartTimestamp": "2025-12-17T00:58:50.063Z", + "EndTimestamp": "2025-12-17T00:58:50.115Z", "Error": {}, - "RequestId": "5907d455-ef8a-4021-b822-bcffa5dd2d07" + "RequestId": "2112ab08-e782-4330-9a6e-a02fbd76f785" } }, { @@ -222,7 +222,7 @@ "EventId": 20, "Id": "a4e1cd317d54f087", "Name": "wait-5-seconds", - "EventTimestamp": "2025-12-05T00:16:55.873Z", + "EventTimestamp": "2025-12-17T00:58:53.063Z", "ParentId": "3a170a9fe4f47efa", "WaitSucceededDetails": { "Duration": 5 @@ -234,7 +234,7 @@ "EventId": 21, "Id": "3a170a9fe4f47efa", "Name": "parallel-branch-3", - "EventTimestamp": "2025-12-05T00:16:55.878Z", + "EventTimestamp": "2025-12-17T00:58:53.066Z", "ParentId": "c4ca4238a0b92382", "ContextSucceededDetails": { "Result": {} @@ -246,7 +246,7 @@ "EventId": 22, "Id": "c4ca4238a0b92382", "Name": "parent-block", - "EventTimestamp": "2025-12-05T00:16:55.880Z", + "EventTimestamp": "2025-12-17T00:58:53.066Z", "ContextSucceededDetails": { "Result": { "Payload": "{\"all\":[{\"index\":0,\"status\":\"SUCCEEDED\"},{\"index\":1,\"status\":\"SUCCEEDED\"},{\"index\":2,\"status\":\"SUCCEEDED\"},{\"index\":3,\"status\":\"SUCCEEDED\"}],\"completionReason\":\"ALL_COMPLETED\"}" @@ -256,19 +256,19 @@ { "EventType": "InvocationCompleted", "EventId": 23, - "EventTimestamp": "2025-12-05T00:16:55.881Z", + "EventTimestamp": "2025-12-17T00:58:53.066Z", "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-05T00:16:55.874Z", - "EndTimestamp": "2025-12-05T00:16:55.881Z", + "StartTimestamp": "2025-12-17T00:58:53.063Z", + "EndTimestamp": "2025-12-17T00:58:53.066Z", "Error": {}, - "RequestId": "6fa7d6b2-831c-4e48-a0c6-9cb81bdfe3c6" + "RequestId": "53627901-d108-44ec-b048-31cfd4186f91" } }, { "EventType": "ExecutionSucceeded", "EventId": 24, - "Id": "5bf93d96-3d76-4b4a-ab50-6030f2e8519a", - "EventTimestamp": "2025-12-05T00:16:55.881Z", + "Id": "e2353cfa-3083-477c-b1b5-5826461ae9d7", + "EventTimestamp": "2025-12-17T00:58:53.066Z", "ExecutionSucceededDetails": { "Result": { "Payload": "\"Completed waits\"" diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/wait/parallel-wait.test.ts b/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/wait/parallel-wait.test.ts index b8bc1585..ad6fec0f 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/wait/parallel-wait.test.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/parallel/wait/parallel-wait.test.ts @@ -26,12 +26,7 @@ createTests({ expect(wait2SecondsOp.getWaitDetails()!.waitSeconds!).toBe(2); expect(wait5SecondsOp.getWaitDetails()!.waitSeconds!).toBe(5); - // Not compatible with latest changes applied. - // There is a good change that this issue is related to - // testing library handling PENDING items in a different way than - // backend. Backend only cound them after LAn SDK received the changes - // in checkpoint response. - // assertEventSignatures(execution); + assertEventSignatures(execution); }, 10000); }, }); diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/anonymous/wait-for-callback-anonymous.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/anonymous/wait-for-callback-anonymous.history.json index 8aaf5a96..bb6cee8e 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/anonymous/wait-for-callback-anonymous.history.json +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/anonymous/wait-for-callback-anonymous.history.json @@ -2,8 +2,8 @@ { "EventType": "ExecutionStarted", "EventId": 1, - "Id": "c954be46-0465-4285-86db-4cf750e9b3bb", - "EventTimestamp": "2025-12-10T00:15:09.611Z", + "Id": "cc06ac41-91c7-4b7b-b760-0c28d6b28c83", + "EventTimestamp": "2025-12-17T01:34:40.186Z", "ExecutionStartedDetails": { "Input": { "Payload": "{}" @@ -15,7 +15,7 @@ "SubType": "WaitForCallback", "EventId": 2, "Id": "c4ca4238a0b92382", - "EventTimestamp": "2025-12-10T00:15:09.648Z", + "EventTimestamp": "2025-12-17T01:34:40.208Z", "ContextStartedDetails": {} }, { @@ -23,56 +23,56 @@ "SubType": "Callback", "EventId": 3, "Id": "ea66c06c1e1c05fa", - "EventTimestamp": "2025-12-10T00:15:09.648Z", + "EventTimestamp": "2025-12-17T01:34:40.208Z", "ParentId": "c4ca4238a0b92382", "CallbackStartedDetails": { - "CallbackId": "eyJleGVjdXRpb25JZCI6ImRiOGE5OTIwLTJjZWUtNDE0YS1hOWFjLWM0NzY0YWQzZWRkNiIsIm9wZXJhdGlvbklkIjoiZWE2NmMwNmMxZTFjMDVmYSIsInRva2VuIjoiZGJhYWZkZmEtYjEwOS00M2VkLTljNGEtMjkzMmRlOWVlOTI2In0=", + "CallbackId": "eyJleGVjdXRpb25JZCI6IjM5ODEwMGI3LTgzZjAtNDcxMi04ZWQ0LTY2MmIxYzllODI3NCIsIm9wZXJhdGlvbklkIjoiZWE2NmMwNmMxZTFjMDVmYSIsInRva2VuIjoiM2QwMzE5NmEtZWU5Ni00ZjAzLTg0YjctYjJiM2EwZDk1N2Y4In0=", "Input": {} } }, - { - "EventType": "CallbackSucceeded", - "SubType": "Callback", - "EventId": 4, - "Id": "ea66c06c1e1c05fa", - "EventTimestamp": "2025-12-10T00:15:09.650Z", - "ParentId": "c4ca4238a0b92382", - "CallbackSucceededDetails": { - "Result": { - "Payload": "{\"data\":\"callback_completed\"}" - } - } - }, { "EventType": "StepStarted", "SubType": "Step", - "EventId": 5, + "EventId": 4, "Id": "98c6f2c2287f4c73", - "EventTimestamp": "2025-12-10T00:15:09.668Z", + "EventTimestamp": "2025-12-17T01:34:40.212Z", "ParentId": "c4ca4238a0b92382", "StepStartedDetails": {} }, { "EventType": "StepSucceeded", "SubType": "Step", - "EventId": 6, + "EventId": 5, "Id": "98c6f2c2287f4c73", - "EventTimestamp": "2025-12-10T00:15:10.717Z", + "EventTimestamp": "2025-12-17T01:34:41.212Z", "ParentId": "c4ca4238a0b92382", "StepSucceededDetails": { "Result": {}, "RetryDetails": {} } }, + { + "EventType": "CallbackSucceeded", + "SubType": "Callback", + "EventId": 6, + "Id": "ea66c06c1e1c05fa", + "EventTimestamp": "2025-12-17T01:34:41.217Z", + "ParentId": "c4ca4238a0b92382", + "CallbackSucceededDetails": { + "Result": { + "Payload": "{\"data\":\"callback_completed\"}" + } + } + }, { "EventType": "InvocationCompleted", "EventId": 7, - "EventTimestamp": "2025-12-10T00:15:10.779Z", + "EventTimestamp": "2025-12-17T01:34:41.265Z", "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-10T00:15:09.611Z", - "EndTimestamp": "2025-12-10T00:15:10.779Z", + "StartTimestamp": "2025-12-17T01:34:40.186Z", + "EndTimestamp": "2025-12-17T01:34:41.265Z", "Error": {}, - "RequestId": "6923bcad-b4d5-488f-b094-b2f4de03ae93" + "RequestId": "5a473cf5-ba99-48b6-b2b5-ac9c9534ec8b" } }, { @@ -80,7 +80,7 @@ "SubType": "WaitForCallback", "EventId": 8, "Id": "c4ca4238a0b92382", - "EventTimestamp": "2025-12-10T00:15:10.828Z", + "EventTimestamp": "2025-12-17T01:34:41.270Z", "ContextSucceededDetails": { "Result": { "Payload": "\"{\\\"data\\\":\\\"callback_completed\\\"}\"" @@ -90,19 +90,19 @@ { "EventType": "InvocationCompleted", "EventId": 9, - "EventTimestamp": "2025-12-10T00:15:10.831Z", + "EventTimestamp": "2025-12-17T01:34:41.271Z", "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-10T00:15:10.803Z", - "EndTimestamp": "2025-12-10T00:15:10.831Z", + "StartTimestamp": "2025-12-17T01:34:41.268Z", + "EndTimestamp": "2025-12-17T01:34:41.271Z", "Error": {}, - "RequestId": "e0bbc1ff-2bc5-4b36-a891-c2a5fb9f5aff" + "RequestId": "1e468c7e-18f2-4291-a508-d5604de74b30" } }, { "EventType": "ExecutionSucceeded", "EventId": 10, - "Id": "c954be46-0465-4285-86db-4cf750e9b3bb", - "EventTimestamp": "2025-12-10T00:15:10.832Z", + "Id": "cc06ac41-91c7-4b7b-b760-0c28d6b28c83", + "EventTimestamp": "2025-12-17T01:34:41.272Z", "ExecutionSucceededDetails": { "Result": { "Payload": "{\"callbackResult\":\"{\\\"data\\\":\\\"callback_completed\\\"}\",\"completed\":true}" diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/anonymous/wait-for-callback-anonymous.test.ts b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/anonymous/wait-for-callback-anonymous.test.ts index cbd83977..e0bae396 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/anonymous/wait-for-callback-anonymous.test.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/anonymous/wait-for-callback-anonymous.test.ts @@ -13,10 +13,10 @@ createTests({ // Start the execution (this will pause at the callback) const executionPromise = runner.run(); - const callbackOperation = runner.getOperationByIndex(1); + const callbackOperation = runner.getOperationByIndex(0); // Wait for the operation to be available - await callbackOperation.waitForData(WaitingOperationStatus.STARTED); + await callbackOperation.waitForData(WaitingOperationStatus.SUBMITTED); const callbackResult = JSON.stringify({ data: "callback_completed", }); diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/basic/wait-for-callback-failure.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/basic/wait-for-callback-failure.history.json index 726e660e..9b010965 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/basic/wait-for-callback-failure.history.json +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/basic/wait-for-callback-failure.history.json @@ -2,8 +2,8 @@ { "EventType": "ExecutionStarted", "EventId": 1, - "Id": "9c5860c6-b007-4679-aa02-960bfb103fa3", - "EventTimestamp": "2025-12-10T00:15:08.871Z", + "Id": "0d01822b-178c-4cc1-ac18-ab30c35ad0bf", + "EventTimestamp": "2025-12-17T01:32:07.613Z", "ExecutionStartedDetails": { "Input": { "Payload": "{}" @@ -16,7 +16,7 @@ "EventId": 2, "Id": "c4ca4238a0b92382", "Name": "my callback function", - "EventTimestamp": "2025-12-10T00:15:08.912Z", + "EventTimestamp": "2025-12-17T01:32:07.617Z", "ContextStartedDetails": {} }, { @@ -24,59 +24,59 @@ "SubType": "Callback", "EventId": 3, "Id": "ea66c06c1e1c05fa", - "EventTimestamp": "2025-12-10T00:15:08.912Z", + "EventTimestamp": "2025-12-17T01:32:07.617Z", "ParentId": "c4ca4238a0b92382", "CallbackStartedDetails": { - "CallbackId": "eyJleGVjdXRpb25JZCI6ImJlZDZjM2FmLTdiM2QtNDY1NS1hZDhhLTQ4ZjQ5MjA0YzBhZiIsIm9wZXJhdGlvbklkIjoiZWE2NmMwNmMxZTFjMDVmYSIsInRva2VuIjoiYTI5YTlhNWUtYTVlYS00MjMxLWJhYzUtOTZhMDM5NjMyYTFkIn0=", + "CallbackId": "eyJleGVjdXRpb25JZCI6IjdiYTI4MzQyLTUyNzctNDJmMS1hMTBkLWI4ZTJhNGI4OTE4ZCIsIm9wZXJhdGlvbklkIjoiZWE2NmMwNmMxZTFjMDVmYSIsInRva2VuIjoiMTVkZDYwYTgtNDY0Ny00YTIxLThkMzQtYTc0YzMxMDVkMjM3In0=", "Timeout": 5, "Input": {} } }, - { - "EventType": "CallbackFailed", - "SubType": "Callback", - "EventId": 4, - "Id": "ea66c06c1e1c05fa", - "EventTimestamp": "2025-12-10T00:15:08.913Z", - "ParentId": "c4ca4238a0b92382", - "CallbackFailedDetails": { - "Error": { - "Payload": { - "ErrorMessage": "ERROR" - } - } - } - }, { "EventType": "StepStarted", "SubType": "Step", - "EventId": 5, + "EventId": 4, "Id": "98c6f2c2287f4c73", - "EventTimestamp": "2025-12-10T00:15:08.933Z", + "EventTimestamp": "2025-12-17T01:32:07.621Z", "ParentId": "c4ca4238a0b92382", "StepStartedDetails": {} }, { "EventType": "StepSucceeded", "SubType": "Step", - "EventId": 6, + "EventId": 5, "Id": "98c6f2c2287f4c73", - "EventTimestamp": "2025-12-10T00:15:08.933Z", + "EventTimestamp": "2025-12-17T01:32:07.621Z", "ParentId": "c4ca4238a0b92382", "StepSucceededDetails": { "Result": {}, "RetryDetails": {} } }, + { + "EventType": "CallbackFailed", + "SubType": "Callback", + "EventId": 6, + "Id": "ea66c06c1e1c05fa", + "EventTimestamp": "2025-12-17T01:32:07.622Z", + "ParentId": "c4ca4238a0b92382", + "CallbackFailedDetails": { + "Error": { + "Payload": { + "ErrorMessage": "ERROR" + } + } + } + }, { "EventType": "InvocationCompleted", "EventId": 7, - "EventTimestamp": "2025-12-10T00:15:08.994Z", + "EventTimestamp": "2025-12-17T01:32:07.673Z", "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-10T00:15:08.871Z", - "EndTimestamp": "2025-12-10T00:15:08.994Z", + "StartTimestamp": "2025-12-17T01:32:07.613Z", + "EndTimestamp": "2025-12-17T01:32:07.673Z", "Error": {}, - "RequestId": "361449f1-38f7-4f4f-a4f1-880d7a0d3afb" + "RequestId": "def76f19-dc23-415d-bee7-6f4c2d42fa0a" } }, { @@ -85,7 +85,7 @@ "EventId": 8, "Id": "c4ca4238a0b92382", "Name": "my callback function", - "EventTimestamp": "2025-12-10T00:15:09.036Z", + "EventTimestamp": "2025-12-17T01:32:07.676Z", "ContextFailedDetails": { "Error": { "Payload": { @@ -98,24 +98,24 @@ { "EventType": "InvocationCompleted", "EventId": 9, - "EventTimestamp": "2025-12-10T00:15:09.037Z", + "EventTimestamp": "2025-12-17T01:32:07.677Z", "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-10T00:15:09.015Z", - "EndTimestamp": "2025-12-10T00:15:09.037Z", + "StartTimestamp": "2025-12-17T01:32:07.674Z", + "EndTimestamp": "2025-12-17T01:32:07.677Z", "Error": { "Payload": { "ErrorType": "ChildContextError", "ErrorMessage": "ERROR" } }, - "RequestId": "d8e44864-d425-4631-8cfa-ef8f3a70747f" + "RequestId": "0e1243f5-7653-4b38-af7b-13aab9b8a1ae" } }, { "EventType": "ExecutionFailed", "EventId": 10, - "Id": "9c5860c6-b007-4679-aa02-960bfb103fa3", - "EventTimestamp": "2025-12-10T00:15:09.037Z", + "Id": "0d01822b-178c-4cc1-ac18-ab30c35ad0bf", + "EventTimestamp": "2025-12-17T01:32:07.677Z", "ExecutionFailedDetails": { "Error": { "Payload": { diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/basic/wait-for-callback-success.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/basic/wait-for-callback-success.history.json index e70c7ef7..2ab829e8 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/basic/wait-for-callback-success.history.json +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/basic/wait-for-callback-success.history.json @@ -2,8 +2,8 @@ { "EventType": "ExecutionStarted", "EventId": 1, - "Id": "e1dd2330-e452-4524-8f4f-2576431ff6a3", - "EventTimestamp": "2025-12-10T00:15:08.596Z", + "Id": "029e457a-5045-4355-8c25-b60ec1e15f14", + "EventTimestamp": "2025-12-17T01:32:07.447Z", "ExecutionStartedDetails": { "Input": { "Payload": "{}" @@ -16,7 +16,7 @@ "EventId": 2, "Id": "c4ca4238a0b92382", "Name": "my callback function", - "EventTimestamp": "2025-12-10T00:15:08.637Z", + "EventTimestamp": "2025-12-17T01:32:07.453Z", "ContextStartedDetails": {} }, { @@ -24,57 +24,57 @@ "SubType": "Callback", "EventId": 3, "Id": "ea66c06c1e1c05fa", - "EventTimestamp": "2025-12-10T00:15:08.638Z", + "EventTimestamp": "2025-12-17T01:32:07.453Z", "ParentId": "c4ca4238a0b92382", "CallbackStartedDetails": { - "CallbackId": "eyJleGVjdXRpb25JZCI6ImQwZmNjNTQ2LTg1YTItNGZjMS05OGEwLWM3YzdmYWRkZmZhOSIsIm9wZXJhdGlvbklkIjoiZWE2NmMwNmMxZTFjMDVmYSIsInRva2VuIjoiYjE3MjkwODktOTc0YS00NTVlLWIzYmYtODJiOWUwZGFmYWMzIn0=", + "CallbackId": "eyJleGVjdXRpb25JZCI6ImE2ZTk0YTE3LWM1NzItNDgyNi1hZTRlLTFlMWFhOGYzODFkNCIsIm9wZXJhdGlvbklkIjoiZWE2NmMwNmMxZTFjMDVmYSIsInRva2VuIjoiODBkNzMzM2YtM2M3ZC00YzU4LWE5MzAtNzcyNzU3ZDlhYjVlIn0=", "Timeout": 5, "Input": {} } }, - { - "EventType": "CallbackSucceeded", - "SubType": "Callback", - "EventId": 4, - "Id": "ea66c06c1e1c05fa", - "EventTimestamp": "2025-12-10T00:15:08.640Z", - "ParentId": "c4ca4238a0b92382", - "CallbackSucceededDetails": { - "Result": { - "Payload": "succeeded" - } - } - }, { "EventType": "StepStarted", "SubType": "Step", - "EventId": 5, + "EventId": 4, "Id": "98c6f2c2287f4c73", - "EventTimestamp": "2025-12-10T00:15:08.658Z", + "EventTimestamp": "2025-12-17T01:32:07.455Z", "ParentId": "c4ca4238a0b92382", "StepStartedDetails": {} }, { "EventType": "StepSucceeded", "SubType": "Step", - "EventId": 6, + "EventId": 5, "Id": "98c6f2c2287f4c73", - "EventTimestamp": "2025-12-10T00:15:08.658Z", + "EventTimestamp": "2025-12-17T01:32:07.455Z", "ParentId": "c4ca4238a0b92382", "StepSucceededDetails": { "Result": {}, "RetryDetails": {} } }, + { + "EventType": "CallbackSucceeded", + "SubType": "Callback", + "EventId": 6, + "Id": "ea66c06c1e1c05fa", + "EventTimestamp": "2025-12-17T01:32:07.457Z", + "ParentId": "c4ca4238a0b92382", + "CallbackSucceededDetails": { + "Result": { + "Payload": "succeeded" + } + } + }, { "EventType": "InvocationCompleted", "EventId": 7, - "EventTimestamp": "2025-12-10T00:15:08.720Z", + "EventTimestamp": "2025-12-17T01:32:07.506Z", "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-10T00:15:08.596Z", - "EndTimestamp": "2025-12-10T00:15:08.720Z", + "StartTimestamp": "2025-12-17T01:32:07.447Z", + "EndTimestamp": "2025-12-17T01:32:07.506Z", "Error": {}, - "RequestId": "6d705aa0-f050-4028-b679-22cbba2d8f23" + "RequestId": "28e33431-d3b3-4538-b739-f748baf82673" } }, { @@ -83,7 +83,7 @@ "EventId": 8, "Id": "c4ca4238a0b92382", "Name": "my callback function", - "EventTimestamp": "2025-12-10T00:15:08.763Z", + "EventTimestamp": "2025-12-17T01:32:07.510Z", "ContextSucceededDetails": { "Result": { "Payload": "\"succeeded\"" @@ -93,19 +93,19 @@ { "EventType": "InvocationCompleted", "EventId": 9, - "EventTimestamp": "2025-12-10T00:15:08.764Z", + "EventTimestamp": "2025-12-17T01:32:07.510Z", "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-10T00:15:08.741Z", - "EndTimestamp": "2025-12-10T00:15:08.764Z", + "StartTimestamp": "2025-12-17T01:32:07.508Z", + "EndTimestamp": "2025-12-17T01:32:07.510Z", "Error": {}, - "RequestId": "bf3f4e39-e7a4-47d6-8414-1d0a1d94640b" + "RequestId": "5b41d29a-c670-4fad-9959-a1755517a006" } }, { "EventType": "ExecutionSucceeded", "EventId": 10, - "Id": "e1dd2330-e452-4524-8f4f-2576431ff6a3", - "EventTimestamp": "2025-12-10T00:15:08.764Z", + "Id": "029e457a-5045-4355-8c25-b60ec1e15f14", + "EventTimestamp": "2025-12-17T01:32:07.510Z", "ExecutionSucceededDetails": { "Result": { "Payload": "\"succeeded\"" diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/basic/wait-for-callback-timed-out.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/basic/wait-for-callback-timed-out.history.json index 441c5476..ded99392 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/basic/wait-for-callback-timed-out.history.json +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/basic/wait-for-callback-timed-out.history.json @@ -2,8 +2,8 @@ { "EventType": "ExecutionStarted", "EventId": 1, - "Id": "a97f0be2-220c-4b7c-99c5-8fb9d3349d93", - "EventTimestamp": "2025-12-12T00:23:39.528Z", + "Id": "0a98778e-42b0-436e-b9ee-d4e558034c8e", + "EventTimestamp": "2025-12-17T01:32:07.780Z", "ExecutionStartedDetails": { "Input": { "Payload": "{\"timeoutSeconds\":1}" @@ -16,7 +16,7 @@ "EventId": 2, "Id": "c4ca4238a0b92382", "Name": "my callback function", - "EventTimestamp": "2025-12-12T00:23:39.533Z", + "EventTimestamp": "2025-12-17T01:32:07.783Z", "ContextStartedDetails": {} }, { @@ -24,10 +24,10 @@ "SubType": "Callback", "EventId": 3, "Id": "ea66c06c1e1c05fa", - "EventTimestamp": "2025-12-12T00:23:39.533Z", + "EventTimestamp": "2025-12-17T01:32:07.783Z", "ParentId": "c4ca4238a0b92382", "CallbackStartedDetails": { - "CallbackId": "eyJleGVjdXRpb25JZCI6IjQ5Y2QzYjI5LTRhODYtNDQxZi1hNDRmLWNiZjBlZmJiNWEzNiIsIm9wZXJhdGlvbklkIjoiZWE2NmMwNmMxZTFjMDVmYSIsInRva2VuIjoiMmU5YTUwMWMtYmU1NS00ZjJlLTkzMjYtMjc4M2ZiYzhiYzcxIn0=", + "CallbackId": "eyJleGVjdXRpb25JZCI6IjJhYjE0YTE2LWVkYTAtNDc1YS04MmM0LTZhNWIxM2ZkYjY2MSIsIm9wZXJhdGlvbklkIjoiZWE2NmMwNmMxZTFjMDVmYSIsInRva2VuIjoiZWMzM2M5MWUtZTIyMi00ZDYyLWI0ZjMtNzMzN2Q0ZTE0YWQwIn0=", "Timeout": 1, "Input": {} } @@ -37,7 +37,7 @@ "SubType": "Step", "EventId": 4, "Id": "98c6f2c2287f4c73", - "EventTimestamp": "2025-12-12T00:23:39.535Z", + "EventTimestamp": "2025-12-17T01:32:07.784Z", "ParentId": "c4ca4238a0b92382", "StepStartedDetails": {} }, @@ -46,7 +46,7 @@ "SubType": "Step", "EventId": 5, "Id": "98c6f2c2287f4c73", - "EventTimestamp": "2025-12-12T00:23:39.535Z", + "EventTimestamp": "2025-12-17T01:32:07.784Z", "ParentId": "c4ca4238a0b92382", "StepSucceededDetails": { "Result": {}, @@ -56,12 +56,12 @@ { "EventType": "InvocationCompleted", "EventId": 6, - "EventTimestamp": "2025-12-12T00:23:39.537Z", + "EventTimestamp": "2025-12-17T01:32:07.835Z", "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-12T00:23:39.528Z", - "EndTimestamp": "2025-12-12T00:23:39.537Z", + "StartTimestamp": "2025-12-17T01:32:07.780Z", + "EndTimestamp": "2025-12-17T01:32:07.835Z", "Error": {}, - "RequestId": "d83611bc-3327-49f0-9d78-08246956e0cb" + "RequestId": "0055c968-a6d4-44ff-9d1e-7711fed4c6e5" } }, { @@ -69,7 +69,7 @@ "SubType": "Callback", "EventId": 7, "Id": "ea66c06c1e1c05fa", - "EventTimestamp": "2025-12-12T00:23:40.536Z", + "EventTimestamp": "2025-12-17T01:32:08.784Z", "ParentId": "c4ca4238a0b92382", "CallbackTimedOutDetails": { "Error": { @@ -85,7 +85,7 @@ "EventId": 8, "Id": "c4ca4238a0b92382", "Name": "my callback function", - "EventTimestamp": "2025-12-12T00:23:40.546Z", + "EventTimestamp": "2025-12-17T01:32:08.788Z", "ContextFailedDetails": { "Error": { "Payload": { @@ -98,24 +98,24 @@ { "EventType": "InvocationCompleted", "EventId": 9, - "EventTimestamp": "2025-12-12T00:23:40.547Z", + "EventTimestamp": "2025-12-17T01:32:08.788Z", "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-12T00:23:40.542Z", - "EndTimestamp": "2025-12-12T00:23:40.547Z", + "StartTimestamp": "2025-12-17T01:32:08.786Z", + "EndTimestamp": "2025-12-17T01:32:08.788Z", "Error": { "Payload": { "ErrorType": "ChildContextError", "ErrorMessage": "Callback timed out" } }, - "RequestId": "0172677d-1faf-4949-a894-c5e96ee500eb" + "RequestId": "cfe94925-3bd4-4aec-81d4-9b103fbc1645" } }, { "EventType": "ExecutionFailed", "EventId": 10, - "Id": "a97f0be2-220c-4b7c-99c5-8fb9d3349d93", - "EventTimestamp": "2025-12-12T00:23:40.547Z", + "Id": "0a98778e-42b0-436e-b9ee-d4e558034c8e", + "EventTimestamp": "2025-12-17T01:32:08.788Z", "ExecutionFailedDetails": { "Error": { "Payload": { diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/basic/wait-for-callback.test.ts b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/basic/wait-for-callback.test.ts index e188d34d..f6ba6e37 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/basic/wait-for-callback.test.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/basic/wait-for-callback.test.ts @@ -13,7 +13,7 @@ createTests({ const executionPromise = runner.run(); const waitForCallbackOp = runner.getOperationByIndex(0); - await waitForCallbackOp.waitForData(WaitingOperationStatus.STARTED); + await waitForCallbackOp.waitForData(WaitingOperationStatus.SUBMITTED); await waitForCallbackOp.sendCallbackSuccess("succeeded"); const execution = await executionPromise; @@ -27,7 +27,7 @@ createTests({ const executionPromise = runner.run(); const waitForCallbackOp = runner.getOperationByIndex(0); - await waitForCallbackOp.waitForData(WaitingOperationStatus.STARTED); + await waitForCallbackOp.waitForData(WaitingOperationStatus.SUBMITTED); await waitForCallbackOp.sendCallbackFailure({ ErrorMessage: "ERROR" }); const execution = await executionPromise; diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/child-context/wait-for-callback-child-context.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/child-context/wait-for-callback-child-context.history.json index 9367686e..a968f86d 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/child-context/wait-for-callback-child-context.history.json +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/child-context/wait-for-callback-child-context.history.json @@ -2,8 +2,8 @@ { "EventType": "ExecutionStarted", "EventId": 1, - "Id": "e39cc4cc-0f5b-4a91-8775-38b3a26c2f00", - "EventTimestamp": "2025-12-10T00:15:09.667Z", + "Id": "6e1aef8e-d080-4307-8baf-b3a4a46c1cd1", + "EventTimestamp": "2025-12-17T01:31:15.834Z", "ExecutionStartedDetails": { "Input": { "Payload": "{\"test\":\"child-context-callbacks\"}" @@ -16,7 +16,7 @@ "EventId": 2, "Id": "c4ca4238a0b92382", "Name": "parent-callback-op", - "EventTimestamp": "2025-12-10T00:15:09.704Z", + "EventTimestamp": "2025-12-17T01:31:15.859Z", "ContextStartedDetails": {} }, { @@ -24,56 +24,56 @@ "SubType": "Callback", "EventId": 3, "Id": "ea66c06c1e1c05fa", - "EventTimestamp": "2025-12-10T00:15:09.704Z", + "EventTimestamp": "2025-12-17T01:31:15.859Z", "ParentId": "c4ca4238a0b92382", "CallbackStartedDetails": { - "CallbackId": "eyJleGVjdXRpb25JZCI6IjZkMzJlYmJmLTliM2EtNDc2Ni05YTM2LTZlZDBlMzk5OTM4YSIsIm9wZXJhdGlvbklkIjoiZWE2NmMwNmMxZTFjMDVmYSIsInRva2VuIjoiZDJhMTUzMmEtYWVhMy00Y2M4LTk3MjQtNmU4N2QxZTRkNDNhIn0=", + "CallbackId": "eyJleGVjdXRpb25JZCI6Ijc4YzZkMzZiLTkxODktNDMxYy05ZjhhLWNjOTQyZDQ2NzkzMSIsIm9wZXJhdGlvbklkIjoiZWE2NmMwNmMxZTFjMDVmYSIsInRva2VuIjoiNmUyYTEyZmYtNzJmNy00OGY2LThlMmYtNTFlNzQ1NWZkNDA5In0=", "Input": {} } }, - { - "EventType": "CallbackSucceeded", - "SubType": "Callback", - "EventId": 4, - "Id": "ea66c06c1e1c05fa", - "EventTimestamp": "2025-12-10T00:15:09.705Z", - "ParentId": "c4ca4238a0b92382", - "CallbackSucceededDetails": { - "Result": { - "Payload": "{\"parentData\":\"parent-completed\"}" - } - } - }, { "EventType": "StepStarted", "SubType": "Step", - "EventId": 5, + "EventId": 4, "Id": "98c6f2c2287f4c73", - "EventTimestamp": "2025-12-10T00:15:09.723Z", + "EventTimestamp": "2025-12-17T01:31:15.863Z", "ParentId": "c4ca4238a0b92382", "StepStartedDetails": {} }, { "EventType": "StepSucceeded", "SubType": "Step", - "EventId": 6, + "EventId": 5, "Id": "98c6f2c2287f4c73", - "EventTimestamp": "2025-12-10T00:15:09.723Z", + "EventTimestamp": "2025-12-17T01:31:15.863Z", "ParentId": "c4ca4238a0b92382", "StepSucceededDetails": { "Result": {}, "RetryDetails": {} } }, + { + "EventType": "CallbackSucceeded", + "SubType": "Callback", + "EventId": 6, + "Id": "ea66c06c1e1c05fa", + "EventTimestamp": "2025-12-17T01:31:15.866Z", + "ParentId": "c4ca4238a0b92382", + "CallbackSucceededDetails": { + "Result": { + "Payload": "{\"parentData\":\"parent-completed\"}" + } + } + }, { "EventType": "InvocationCompleted", "EventId": 7, - "EventTimestamp": "2025-12-10T00:15:09.785Z", + "EventTimestamp": "2025-12-17T01:31:15.916Z", "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-10T00:15:09.667Z", - "EndTimestamp": "2025-12-10T00:15:09.785Z", + "StartTimestamp": "2025-12-17T01:31:15.834Z", + "EndTimestamp": "2025-12-17T01:31:15.916Z", "Error": {}, - "RequestId": "b66163d6-6deb-4777-a62d-82f20e7de3f0" + "RequestId": "aea0c9a1-0639-48bf-81a2-ecdd986f1257" } }, { @@ -82,7 +82,7 @@ "EventId": 8, "Id": "c4ca4238a0b92382", "Name": "parent-callback-op", - "EventTimestamp": "2025-12-10T00:15:09.828Z", + "EventTimestamp": "2025-12-17T01:31:15.940Z", "ContextSucceededDetails": { "Result": { "Payload": "\"{\\\"parentData\\\":\\\"parent-completed\\\"}\"" @@ -95,7 +95,7 @@ "EventId": 9, "Id": "c81e728d9d4c2f63", "Name": "child-context-with-callback", - "EventTimestamp": "2025-12-10T00:15:09.828Z", + "EventTimestamp": "2025-12-17T01:31:15.940Z", "ContextStartedDetails": {} }, { @@ -104,43 +104,43 @@ "EventId": 10, "Id": "8fbdbf5573b18fae", "Name": "child-wait", - "EventTimestamp": "2025-12-10T00:15:09.828Z", + "EventTimestamp": "2025-12-17T01:31:15.940Z", "ParentId": "c81e728d9d4c2f63", "WaitStartedDetails": { "Duration": 1, - "ScheduledEndTimestamp": "2025-12-10T00:15:10.828Z" + "ScheduledEndTimestamp": "2025-12-17T01:31:16.940Z" + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 11, + "EventTimestamp": "2025-12-17T01:31:15.992Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-17T01:31:15.918Z", + "EndTimestamp": "2025-12-17T01:31:15.992Z", + "Error": {}, + "RequestId": "6b3c6ff5-d09d-4ff7-bb0f-6b30354e7ec3" } }, { "EventType": "WaitSucceeded", "SubType": "Wait", - "EventId": 11, + "EventId": 12, "Id": "8fbdbf5573b18fae", "Name": "child-wait", - "EventTimestamp": "2025-12-10T00:15:09.829Z", + "EventTimestamp": "2025-12-17T01:31:16.948Z", "ParentId": "c81e728d9d4c2f63", "WaitSucceededDetails": { "Duration": 1 } }, - { - "EventType": "InvocationCompleted", - "EventId": 12, - "EventTimestamp": "2025-12-10T00:15:09.829Z", - "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-10T00:15:09.805Z", - "EndTimestamp": "2025-12-10T00:15:09.829Z", - "Error": {}, - "RequestId": "71857a1f-96f5-4f24-9e94-ec88d3828a35" - } - }, { "EventType": "ContextStarted", "SubType": "WaitForCallback", "EventId": 13, "Id": "3c46a0407be60a1f", "Name": "child-callback-op", - "EventTimestamp": "2025-12-10T00:15:09.869Z", + "EventTimestamp": "2025-12-17T01:31:16.956Z", "ParentId": "c81e728d9d4c2f63", "ContextStartedDetails": {} }, @@ -149,56 +149,56 @@ "SubType": "Callback", "EventId": 14, "Id": "61e70e07c25ca2dd", - "EventTimestamp": "2025-12-10T00:15:09.869Z", + "EventTimestamp": "2025-12-17T01:31:16.956Z", "ParentId": "3c46a0407be60a1f", "CallbackStartedDetails": { - "CallbackId": "eyJleGVjdXRpb25JZCI6IjZkMzJlYmJmLTliM2EtNDc2Ni05YTM2LTZlZDBlMzk5OTM4YSIsIm9wZXJhdGlvbklkIjoiNjFlNzBlMDdjMjVjYTJkZCIsInRva2VuIjoiMTZkZTVjZmItOTZjZC00YmEyLTllYjAtNjhiZGNkY2VjOGI0In0=", + "CallbackId": "eyJleGVjdXRpb25JZCI6Ijc4YzZkMzZiLTkxODktNDMxYy05ZjhhLWNjOTQyZDQ2NzkzMSIsIm9wZXJhdGlvbklkIjoiNjFlNzBlMDdjMjVjYTJkZCIsInRva2VuIjoiMGM2ZTQ4ODItZGM1Mi00MzMzLTg4YTYtMDUyNDZkNjc0NTY5In0=", "Input": {} } }, - { - "EventType": "CallbackSucceeded", - "SubType": "Callback", - "EventId": 15, - "Id": "61e70e07c25ca2dd", - "EventTimestamp": "2025-12-10T00:15:09.870Z", - "ParentId": "3c46a0407be60a1f", - "CallbackSucceededDetails": { - "Result": { - "Payload": "{\"childData\":42}" - } - } - }, { "EventType": "StepStarted", "SubType": "Step", - "EventId": 16, + "EventId": 15, "Id": "c2f098f784fd6490", - "EventTimestamp": "2025-12-10T00:15:09.888Z", + "EventTimestamp": "2025-12-17T01:31:16.959Z", "ParentId": "3c46a0407be60a1f", "StepStartedDetails": {} }, { "EventType": "StepSucceeded", "SubType": "Step", - "EventId": 17, + "EventId": 16, "Id": "c2f098f784fd6490", - "EventTimestamp": "2025-12-10T00:15:09.888Z", + "EventTimestamp": "2025-12-17T01:31:16.959Z", "ParentId": "3c46a0407be60a1f", "StepSucceededDetails": { "Result": {}, "RetryDetails": {} } }, + { + "EventType": "CallbackSucceeded", + "SubType": "Callback", + "EventId": 17, + "Id": "61e70e07c25ca2dd", + "EventTimestamp": "2025-12-17T01:31:16.961Z", + "ParentId": "3c46a0407be60a1f", + "CallbackSucceededDetails": { + "Result": { + "Payload": "{\"childData\":42}" + } + } + }, { "EventType": "InvocationCompleted", "EventId": 18, - "EventTimestamp": "2025-12-10T00:15:09.950Z", + "EventTimestamp": "2025-12-17T01:31:17.011Z", "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-10T00:15:09.848Z", - "EndTimestamp": "2025-12-10T00:15:09.950Z", + "StartTimestamp": "2025-12-17T01:31:16.948Z", + "EndTimestamp": "2025-12-17T01:31:17.011Z", "Error": {}, - "RequestId": "3e11c40b-b4cf-49bb-90f0-ac2e3958e5bb" + "RequestId": "e405d72c-c01f-4b62-b4f5-e56b5b264492" } }, { @@ -207,7 +207,7 @@ "EventId": 19, "Id": "3c46a0407be60a1f", "Name": "child-callback-op", - "EventTimestamp": "2025-12-10T00:15:09.994Z", + "EventTimestamp": "2025-12-17T01:31:17.019Z", "ParentId": "c81e728d9d4c2f63", "ContextSucceededDetails": { "Result": { @@ -221,7 +221,7 @@ "EventId": 20, "Id": "c81e728d9d4c2f63", "Name": "child-context-with-callback", - "EventTimestamp": "2025-12-10T00:15:09.994Z", + "EventTimestamp": "2025-12-17T01:31:17.019Z", "ContextSucceededDetails": { "Result": { "Payload": "{\"childResult\":\"{\\\"childData\\\":42}\",\"childProcessed\":true}" @@ -231,19 +231,19 @@ { "EventType": "InvocationCompleted", "EventId": 21, - "EventTimestamp": "2025-12-10T00:15:09.994Z", + "EventTimestamp": "2025-12-17T01:31:17.020Z", "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-10T00:15:09.971Z", - "EndTimestamp": "2025-12-10T00:15:09.994Z", + "StartTimestamp": "2025-12-17T01:31:17.014Z", + "EndTimestamp": "2025-12-17T01:31:17.020Z", "Error": {}, - "RequestId": "7c0f94cc-e457-496c-86c8-d11c44c5a152" + "RequestId": "b880e204-13aa-4b54-8142-c063fbc2eaa1" } }, { "EventType": "ExecutionSucceeded", "EventId": 22, - "Id": "e39cc4cc-0f5b-4a91-8775-38b3a26c2f00", - "EventTimestamp": "2025-12-10T00:15:09.994Z", + "Id": "6e1aef8e-d080-4307-8baf-b3a4a46c1cd1", + "EventTimestamp": "2025-12-17T01:31:17.021Z", "ExecutionSucceededDetails": { "Result": { "Payload": "{\"parentResult\":\"{\\\"parentData\\\":\\\"parent-completed\\\"}\",\"childContextResult\":{\"childResult\":\"{\\\"childData\\\":42}\",\"childProcessed\":true}}" diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/child-context/wait-for-callback-child-context.test.ts b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/child-context/wait-for-callback-child-context.test.ts index 048af041..859f8f41 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/child-context/wait-for-callback-child-context.test.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/child-context/wait-for-callback-child-context.test.ts @@ -21,15 +21,14 @@ createTests({ }); // Wait for parent callback to start - await parentCallbackOp.waitForData(WaitingOperationStatus.STARTED); + await parentCallbackOp.waitForData(WaitingOperationStatus.SUBMITTED); const parentCallbackResult = JSON.stringify({ parentData: "parent-completed", }); - console.log("parent callback op", parentCallbackOp.getOperationData()); await parentCallbackOp.sendCallbackSuccess(parentCallbackResult); // Wait for child callback to start - await childCallbackOp.waitForData(WaitingOperationStatus.STARTED); + await childCallbackOp.waitForData(WaitingOperationStatus.SUBMITTED); const childCallbackResult = JSON.stringify({ childData: 42 }); console.log("child callback op", childCallbackOp.getOperationData()); await childCallbackOp.sendCallbackSuccess(childCallbackResult); diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/failing-submitter/wait-for-callback-failing-submitter.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/failing-submitter/wait-for-callback-failing-submitter.history.json new file mode 100644 index 00000000..21798a2f --- /dev/null +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/failing-submitter/wait-for-callback-failing-submitter.history.json @@ -0,0 +1,180 @@ +[ + { + "EventType": "ExecutionStarted", + "EventId": 1, + "Id": "d5253d21-0f15-4ed8-8633-9a2a90edc893", + "EventTimestamp": "2025-12-17T01:25:17.521Z", + "ExecutionStartedDetails": { + "Input": { + "Payload": "{}" + } + } + }, + { + "EventType": "ContextStarted", + "SubType": "WaitForCallback", + "EventId": 2, + "Id": "c4ca4238a0b92382", + "Name": "failing-submitter-callback", + "EventTimestamp": "2025-12-17T01:25:17.526Z", + "ContextStartedDetails": {} + }, + { + "EventType": "CallbackStarted", + "SubType": "Callback", + "EventId": 3, + "Id": "ea66c06c1e1c05fa", + "EventTimestamp": "2025-12-17T01:25:17.526Z", + "ParentId": "c4ca4238a0b92382", + "CallbackStartedDetails": { + "CallbackId": "eyJleGVjdXRpb25JZCI6Ijk0Yzc0OTkzLWZmYmEtNDNlNC04ZTA4LTBiM2RlNmMwYjVhNyIsIm9wZXJhdGlvbklkIjoiZWE2NmMwNmMxZTFjMDVmYSIsInRva2VuIjoiYTM0ZTE4OGQtMzIzYy00ZjY5LWIxODgtMDc1Yzc1NDU5OTdmIn0=", + "Input": {} + } + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 4, + "Id": "98c6f2c2287f4c73", + "EventTimestamp": "2025-12-17T01:25:17.528Z", + "ParentId": "c4ca4238a0b92382", + "StepStartedDetails": {} + }, + { + "EventType": "StepFailed", + "SubType": "Step", + "EventId": 5, + "Id": "98c6f2c2287f4c73", + "EventTimestamp": "2025-12-17T01:25:18.028Z", + "ParentId": "c4ca4238a0b92382", + "StepFailedDetails": { + "Error": { + "Payload": { + "ErrorMessage": "Submitter failed", + "ErrorType": "Error" + } + }, + "RetryDetails": { + "NextAttemptDelaySeconds": 1, + "CurrentAttempt": 1 + } + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 6, + "EventTimestamp": "2025-12-17T01:25:18.080Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-17T01:25:17.521Z", + "EndTimestamp": "2025-12-17T01:25:18.080Z", + "Error": {}, + "RequestId": "cb720151-0cbc-484b-a32c-0d9078283320" + } + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 7, + "Id": "98c6f2c2287f4c73", + "EventTimestamp": "2025-12-17T01:25:19.036Z", + "ParentId": "c4ca4238a0b92382", + "StepStartedDetails": {} + }, + { + "EventType": "StepFailed", + "SubType": "Step", + "EventId": 8, + "Id": "98c6f2c2287f4c73", + "EventTimestamp": "2025-12-17T01:25:19.536Z", + "ParentId": "c4ca4238a0b92382", + "StepFailedDetails": { + "Error": { + "Payload": { + "ErrorMessage": "Submitter failed", + "ErrorType": "Error" + } + }, + "RetryDetails": { + "NextAttemptDelaySeconds": 1, + "CurrentAttempt": 1 + } + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 9, + "EventTimestamp": "2025-12-17T01:25:19.587Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-17T01:25:19.032Z", + "EndTimestamp": "2025-12-17T01:25:19.587Z", + "Error": {}, + "RequestId": "91fec513-bef8-4879-a33c-25a54119e620" + } + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 10, + "Id": "98c6f2c2287f4c73", + "EventTimestamp": "2025-12-17T01:25:20.540Z", + "ParentId": "c4ca4238a0b92382", + "StepStartedDetails": {} + }, + { + "EventType": "StepFailed", + "SubType": "Step", + "EventId": 11, + "Id": "98c6f2c2287f4c73", + "EventTimestamp": "2025-12-17T01:25:21.041Z", + "ParentId": "c4ca4238a0b92382", + "StepFailedDetails": { + "Error": { + "Payload": { + "ErrorMessage": "Submitter failed", + "ErrorType": "Error" + } + }, + "RetryDetails": { + "CurrentAttempt": 2 + } + } + }, + { + "EventType": "ContextFailed", + "SubType": "WaitForCallback", + "EventId": 12, + "Id": "c4ca4238a0b92382", + "Name": "failing-submitter-callback", + "EventTimestamp": "2025-12-17T01:25:21.042Z", + "ContextFailedDetails": { + "Error": { + "Payload": { + "ErrorType": "StepError", + "ErrorMessage": "Submitter failed" + } + } + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 13, + "EventTimestamp": "2025-12-17T01:25:21.043Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-17T01:25:20.538Z", + "EndTimestamp": "2025-12-17T01:25:21.043Z", + "Error": {}, + "RequestId": "65fa9367-2b4a-4747-a956-8e8617192c82" + } + }, + { + "EventType": "ExecutionSucceeded", + "EventId": 14, + "Id": "d5253d21-0f15-4ed8-8633-9a2a90edc893", + "EventTimestamp": "2025-12-17T01:25:21.043Z", + "ExecutionSucceededDetails": { + "Result": { + "Payload": "{\"success\":false,\"error\":\"Submitter failed\"}" + } + } + } +] diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/failing-submitter/wait-for-callback-failing-submitter.test.ts b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/failing-submitter/wait-for-callback-failing-submitter.test.ts index 203b5d5c..9e87eb7f 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/failing-submitter/wait-for-callback-failing-submitter.test.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/failing-submitter/wait-for-callback-failing-submitter.test.ts @@ -5,15 +5,16 @@ import { createTests } from "../../../utils/test-helper"; createTests({ handler, invocationType: InvocationType.Event, - tests: (runner) => { - // Pending resolution of https://github.com/aws/aws-durable-execution-sdk-js/issues/199 - it.skip("should handle waitForCallback with failing submitter function errors", async () => { + tests: (runner, { assertEventSignatures }) => { + it("should handle waitForCallback with failing submitter function errors", async () => { const execution = await runner.run(); expect(execution.getResult()).toEqual({ success: false, error: "Submitter failed", }); + + assertEventSignatures(execution); }); }, }); diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/failures/wait-for-callback-failures.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/failures/wait-for-callback-failures.history.json index 3a7d7cd4..7d93f6ba 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/failures/wait-for-callback-failures.history.json +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/failures/wait-for-callback-failures.history.json @@ -2,8 +2,8 @@ { "EventType": "ExecutionStarted", "EventId": 1, - "Id": "b9117e67-76c4-453f-b9b4-136f52e60076", - "EventTimestamp": "2025-12-10T00:15:10.030Z", + "Id": "0a5e7aff-c2df-4012-b91e-6cbeb48303b5", + "EventTimestamp": "2025-12-17T01:35:04.393Z", "ExecutionStartedDetails": { "Input": { "Payload": "{}" @@ -15,7 +15,7 @@ "SubType": "WaitForCallback", "EventId": 2, "Id": "c4ca4238a0b92382", - "EventTimestamp": "2025-12-10T00:15:10.062Z", + "EventTimestamp": "2025-12-17T01:35:04.398Z", "ContextStartedDetails": {} }, { @@ -23,59 +23,59 @@ "SubType": "Callback", "EventId": 3, "Id": "ea66c06c1e1c05fa", - "EventTimestamp": "2025-12-10T00:15:10.062Z", + "EventTimestamp": "2025-12-17T01:35:04.398Z", "ParentId": "c4ca4238a0b92382", "CallbackStartedDetails": { - "CallbackId": "eyJleGVjdXRpb25JZCI6IjNiMDU4Njk2LTI3MjctNGM1Zi05MDZiLTUxZjEwMDRkNTY1ZSIsIm9wZXJhdGlvbklkIjoiZWE2NmMwNmMxZTFjMDVmYSIsInRva2VuIjoiOWEyYTdhMjYtNTc1YS00YTljLWI1ZjctNjJkNWNkMzBhMDgzIn0=", + "CallbackId": "eyJleGVjdXRpb25JZCI6ImIzNGFkMDNkLTBlYzQtNDViMC1iNzRkLWM2NjRjMWM1M2E5MCIsIm9wZXJhdGlvbklkIjoiZWE2NmMwNmMxZTFjMDVmYSIsInRva2VuIjoiZTVkOWE1NzUtOGZiNy00OGVlLTk1ZTgtMzIwZmUxNDVlNTUwIn0=", "Input": {} } }, - { - "EventType": "CallbackFailed", - "SubType": "Callback", - "EventId": 4, - "Id": "ea66c06c1e1c05fa", - "EventTimestamp": "2025-12-10T00:15:10.071Z", - "ParentId": "c4ca4238a0b92382", - "CallbackFailedDetails": { - "Error": { - "Payload": { - "ErrorMessage": "External API failure", - "ErrorType": "APIException" - } - } - } - }, { "EventType": "StepStarted", "SubType": "Step", - "EventId": 5, + "EventId": 4, "Id": "98c6f2c2287f4c73", - "EventTimestamp": "2025-12-10T00:15:10.076Z", + "EventTimestamp": "2025-12-17T01:35:04.401Z", "ParentId": "c4ca4238a0b92382", "StepStartedDetails": {} }, { "EventType": "StepSucceeded", "SubType": "Step", - "EventId": 6, + "EventId": 5, "Id": "98c6f2c2287f4c73", - "EventTimestamp": "2025-12-10T00:15:11.120Z", + "EventTimestamp": "2025-12-17T01:35:05.402Z", "ParentId": "c4ca4238a0b92382", "StepSucceededDetails": { "Result": {}, "RetryDetails": {} } }, + { + "EventType": "CallbackFailed", + "SubType": "Callback", + "EventId": 6, + "Id": "ea66c06c1e1c05fa", + "EventTimestamp": "2025-12-17T01:35:05.403Z", + "ParentId": "c4ca4238a0b92382", + "CallbackFailedDetails": { + "Error": { + "Payload": { + "ErrorMessage": "External API failure", + "ErrorType": "APIException" + } + } + } + }, { "EventType": "InvocationCompleted", "EventId": 7, - "EventTimestamp": "2025-12-10T00:15:11.180Z", + "EventTimestamp": "2025-12-17T01:35:05.453Z", "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-10T00:15:10.030Z", - "EndTimestamp": "2025-12-10T00:15:11.180Z", + "StartTimestamp": "2025-12-17T01:35:04.392Z", + "EndTimestamp": "2025-12-17T01:35:05.453Z", "Error": {}, - "RequestId": "92fa7e21-950a-42c3-8356-d863115841a0" + "RequestId": "451d2465-a24d-4a16-bc97-354d29f45654" } }, { @@ -83,7 +83,7 @@ "SubType": "WaitForCallback", "EventId": 8, "Id": "c4ca4238a0b92382", - "EventTimestamp": "2025-12-10T00:15:11.220Z", + "EventTimestamp": "2025-12-17T01:35:05.457Z", "ContextFailedDetails": { "Error": { "Payload": { @@ -96,19 +96,19 @@ { "EventType": "InvocationCompleted", "EventId": 9, - "EventTimestamp": "2025-12-10T00:15:11.220Z", + "EventTimestamp": "2025-12-17T01:35:05.457Z", "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-10T00:15:11.200Z", - "EndTimestamp": "2025-12-10T00:15:11.220Z", + "StartTimestamp": "2025-12-17T01:35:05.455Z", + "EndTimestamp": "2025-12-17T01:35:05.457Z", "Error": {}, - "RequestId": "ac2c194a-1c2c-43c0-931f-100e2731cd30" + "RequestId": "7aedc1b8-7558-4289-ab0f-0ad1fce314e5" } }, { "EventType": "ExecutionSucceeded", "EventId": 10, - "Id": "b9117e67-76c4-453f-b9b4-136f52e60076", - "EventTimestamp": "2025-12-10T00:15:11.221Z", + "Id": "0a5e7aff-c2df-4012-b91e-6cbeb48303b5", + "EventTimestamp": "2025-12-17T01:35:05.458Z", "ExecutionSucceededDetails": { "Result": { "Payload": "{\"success\":false,\"error\":\"External API failure\"}" diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/failures/wait-for-callback-failures.test.ts b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/failures/wait-for-callback-failures.test.ts index b507e324..f5fec204 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/failures/wait-for-callback-failures.test.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/failures/wait-for-callback-failures.test.ts @@ -13,10 +13,10 @@ createTests({ // Start the execution (this will pause at the callback) const executionPromise = runner.run(); - const callbackOperation = runner.getOperationByIndex(1); + const callbackOperation = runner.getOperationByIndex(0); // Wait for the operation to be available (submitter succeeded) - await callbackOperation.waitForData(WaitingOperationStatus.STARTED); + await callbackOperation.waitForData(WaitingOperationStatus.SUBMITTED); // Simulate external system failing the callback await callbackOperation.sendCallbackFailure({ diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/heartbeat-sends/wait-for-callback-heartbeat-sends.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/heartbeat-sends/wait-for-callback-heartbeat-sends.history.json index b742282f..81f19067 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/heartbeat-sends/wait-for-callback-heartbeat-sends.history.json +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/heartbeat-sends/wait-for-callback-heartbeat-sends.history.json @@ -2,8 +2,8 @@ { "EventType": "ExecutionStarted", "EventId": 1, - "Id": "398c39ed-5087-4e5f-84de-ea20fc7bae53", - "EventTimestamp": "2025-12-10T00:12:29.567Z", + "Id": "366670b4-092a-4e24-b0b7-db1df32ce975", + "EventTimestamp": "2025-12-17T01:36:45.169Z", "ExecutionStartedDetails": { "Input": { "Payload": "{\"isCloud\":false}" @@ -15,7 +15,7 @@ "SubType": "WaitForCallback", "EventId": 2, "Id": "c4ca4238a0b92382", - "EventTimestamp": "2025-12-10T00:12:29.572Z", + "EventTimestamp": "2025-12-17T01:36:45.175Z", "ContextStartedDetails": {} }, { @@ -23,10 +23,10 @@ "SubType": "Callback", "EventId": 3, "Id": "ea66c06c1e1c05fa", - "EventTimestamp": "2025-12-10T00:12:29.572Z", + "EventTimestamp": "2025-12-17T01:36:45.175Z", "ParentId": "c4ca4238a0b92382", "CallbackStartedDetails": { - "CallbackId": "eyJleGVjdXRpb25JZCI6Ijk2NjIxNTY2LTIxODktNDJkNC1hMWI3LTQ1OTBhOWFmY2E1NSIsIm9wZXJhdGlvbklkIjoiZWE2NmMwNmMxZTFjMDVmYSIsInRva2VuIjoiMjE5MmIzYTItZmVjZC00ODI1LWIyNTUtMGJiOWZhZmE3YjMyIn0=", + "CallbackId": "eyJleGVjdXRpb25JZCI6IjUyZDBiMmMxLTFkZTMtNGU2Ni1hYjBiLTE4NDg2NjQzZjZlNSIsIm9wZXJhdGlvbklkIjoiZWE2NmMwNmMxZTFjMDVmYSIsInRva2VuIjoiN2NlYjQ5ZjAtYWJjMS00MzUwLWJhMTItNzA3YmRhYmM3YjNjIn0=", "HeartbeatTimeout": 1, "Input": {} } @@ -36,7 +36,7 @@ "SubType": "Step", "EventId": 4, "Id": "98c6f2c2287f4c73", - "EventTimestamp": "2025-12-10T00:12:29.575Z", + "EventTimestamp": "2025-12-17T01:36:45.178Z", "ParentId": "c4ca4238a0b92382", "StepStartedDetails": {} }, @@ -45,7 +45,7 @@ "SubType": "Step", "EventId": 5, "Id": "98c6f2c2287f4c73", - "EventTimestamp": "2025-12-10T00:12:29.675Z", + "EventTimestamp": "2025-12-17T01:36:45.278Z", "ParentId": "c4ca4238a0b92382", "StepSucceededDetails": { "Result": {}, @@ -55,12 +55,12 @@ { "EventType": "InvocationCompleted", "EventId": 6, - "EventTimestamp": "2025-12-10T00:12:29.726Z", + "EventTimestamp": "2025-12-17T01:36:45.330Z", "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-10T00:12:29.567Z", - "EndTimestamp": "2025-12-10T00:12:29.726Z", + "StartTimestamp": "2025-12-17T01:36:45.169Z", + "EndTimestamp": "2025-12-17T01:36:45.330Z", "Error": {}, - "RequestId": "b4363077-0440-431c-8cae-47b1047abc66" + "RequestId": "40e5f340-72b3-4015-837e-80457e105fe3" } }, { @@ -68,7 +68,7 @@ "SubType": "Callback", "EventId": 7, "Id": "ea66c06c1e1c05fa", - "EventTimestamp": "2025-12-10T00:12:30.175Z", + "EventTimestamp": "2025-12-17T01:36:45.881Z", "ParentId": "c4ca4238a0b92382", "CallbackSucceededDetails": { "Result": { @@ -81,7 +81,7 @@ "SubType": "WaitForCallback", "EventId": 8, "Id": "c4ca4238a0b92382", - "EventTimestamp": "2025-12-10T00:12:30.179Z", + "EventTimestamp": "2025-12-17T01:36:45.884Z", "ContextSucceededDetails": { "Result": { "Payload": "\"{\\\"processed\\\":1000}\"" @@ -91,19 +91,19 @@ { "EventType": "InvocationCompleted", "EventId": 9, - "EventTimestamp": "2025-12-10T00:12:30.179Z", + "EventTimestamp": "2025-12-17T01:36:45.884Z", "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-10T00:12:30.177Z", - "EndTimestamp": "2025-12-10T00:12:30.179Z", + "StartTimestamp": "2025-12-17T01:36:45.882Z", + "EndTimestamp": "2025-12-17T01:36:45.884Z", "Error": {}, - "RequestId": "36949279-c127-43a4-8554-8b43073402ed" + "RequestId": "1c0fabd1-0be3-45c3-8ddb-f264ece1a691" } }, { "EventType": "ExecutionSucceeded", "EventId": 10, - "Id": "398c39ed-5087-4e5f-84de-ea20fc7bae53", - "EventTimestamp": "2025-12-10T00:12:30.179Z", + "Id": "366670b4-092a-4e24-b0b7-db1df32ce975", + "EventTimestamp": "2025-12-17T01:36:45.884Z", "ExecutionSucceededDetails": { "Result": { "Payload": "{\"callbackResult\":\"{\\\"processed\\\":1000}\",\"completed\":true}" diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/heartbeat-sends/wait-for-callback-heartbeat-sends.test.ts b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/heartbeat-sends/wait-for-callback-heartbeat-sends.test.ts index e3d3ab5d..395deaa9 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/heartbeat-sends/wait-for-callback-heartbeat-sends.test.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/heartbeat-sends/wait-for-callback-heartbeat-sends.test.ts @@ -18,10 +18,10 @@ createTests({ payload: { isCloud }, }); - const callbackOperation = runner.getOperationByIndex(1); + const callbackOperation = runner.getOperationByIndex(0); // Wait for the operation to be available - await callbackOperation.waitForData(WaitingOperationStatus.STARTED); + await callbackOperation.waitForData(WaitingOperationStatus.SUBMITTED); // Send heartbeat to keep the callback alive during processing await callbackOperation.sendCallbackHeartbeat(); diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/mixed-ops/wait-for-callback-mixed-ops.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/mixed-ops/wait-for-callback-mixed-ops.history.json index e06c22e1..000c5d14 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/mixed-ops/wait-for-callback-mixed-ops.history.json +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/mixed-ops/wait-for-callback-mixed-ops.history.json @@ -2,8 +2,8 @@ { "EventType": "ExecutionStarted", "EventId": 1, - "Id": "306a63fb-bb71-4c48-a20c-f42d50f446b7", - "EventTimestamp": "2025-12-10T00:15:09.246Z", + "Id": "12f88eec-8d4c-462f-868f-07c55f796667", + "EventTimestamp": "2025-12-17T01:32:01.560Z", "ExecutionStartedDetails": { "Input": { "Payload": "{}" @@ -16,41 +16,41 @@ "EventId": 2, "Id": "c4ca4238a0b92382", "Name": "initial-wait", - "EventTimestamp": "2025-12-10T00:15:09.277Z", + "EventTimestamp": "2025-12-17T01:32:01.569Z", "WaitStartedDetails": { "Duration": 1, - "ScheduledEndTimestamp": "2025-12-10T00:15:10.277Z" + "ScheduledEndTimestamp": "2025-12-17T01:32:02.570Z" + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 3, + "EventTimestamp": "2025-12-17T01:32:01.621Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-17T01:32:01.560Z", + "EndTimestamp": "2025-12-17T01:32:01.621Z", + "Error": {}, + "RequestId": "55ecc33c-ed2b-4910-8418-acbc77823dc3" } }, { "EventType": "WaitSucceeded", "SubType": "Wait", - "EventId": 3, + "EventId": 4, "Id": "c4ca4238a0b92382", "Name": "initial-wait", - "EventTimestamp": "2025-12-10T00:15:09.278Z", + "EventTimestamp": "2025-12-17T01:32:02.568Z", "WaitSucceededDetails": { "Duration": 1 } }, - { - "EventType": "InvocationCompleted", - "EventId": 4, - "EventTimestamp": "2025-12-10T00:15:09.278Z", - "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-10T00:15:09.246Z", - "EndTimestamp": "2025-12-10T00:15:09.278Z", - "Error": {}, - "RequestId": "f6e1ab7f-5851-4c2b-97b2-b9476adf5535" - } - }, { "EventType": "StepStarted", "SubType": "Step", "EventId": 5, "Id": "c81e728d9d4c2f63", "Name": "fetch-user-data", - "EventTimestamp": "2025-12-10T00:15:09.322Z", + "EventTimestamp": "2025-12-17T01:32:02.573Z", "StepStartedDetails": {} }, { @@ -59,7 +59,7 @@ "EventId": 6, "Id": "c81e728d9d4c2f63", "Name": "fetch-user-data", - "EventTimestamp": "2025-12-10T00:15:09.322Z", + "EventTimestamp": "2025-12-17T01:32:02.573Z", "StepSucceededDetails": { "Result": { "Payload": "{\"userId\":123,\"name\":\"John Doe\"}" @@ -73,7 +73,7 @@ "EventId": 7, "Id": "eccbc87e4b5ce2fe", "Name": "wait-for-callback", - "EventTimestamp": "2025-12-10T00:15:09.342Z", + "EventTimestamp": "2025-12-17T01:32:02.576Z", "ContextStartedDetails": {} }, { @@ -81,56 +81,56 @@ "SubType": "Callback", "EventId": 8, "Id": "c9e6e7b69f98f516", - "EventTimestamp": "2025-12-10T00:15:09.343Z", + "EventTimestamp": "2025-12-17T01:32:02.576Z", "ParentId": "eccbc87e4b5ce2fe", "CallbackStartedDetails": { - "CallbackId": "eyJleGVjdXRpb25JZCI6ImUyMzRhYjkyLThjNTItNDkxNC1hMjkwLWY3ZjY2ODY2YjAyMSIsIm9wZXJhdGlvbklkIjoiYzllNmU3YjY5Zjk4ZjUxNiIsInRva2VuIjoiMjEyODMwNjAtMDc2ZC00NmY5LTkzYWEtOTE2ZjUxYzhkZjQ2In0=", + "CallbackId": "eyJleGVjdXRpb25JZCI6ImJlOTg4ZjkyLTgyNTYtNDdkYy04MzA4LTExZmIzN2VjZDg1ZCIsIm9wZXJhdGlvbklkIjoiYzllNmU3YjY5Zjk4ZjUxNiIsInRva2VuIjoiNWYyODA5NzgtMGViOC00YWEyLTljYjItZjU3ZTdmNDI1ZjQxIn0=", "Input": {} } }, - { - "EventType": "CallbackSucceeded", - "SubType": "Callback", - "EventId": 9, - "Id": "c9e6e7b69f98f516", - "EventTimestamp": "2025-12-10T00:15:09.345Z", - "ParentId": "eccbc87e4b5ce2fe", - "CallbackSucceededDetails": { - "Result": { - "Payload": "{\"processed\":true}" - } - } - }, { "EventType": "StepStarted", "SubType": "Step", - "EventId": 10, + "EventId": 9, "Id": "b772d43b49bb57b5", - "EventTimestamp": "2025-12-10T00:15:09.362Z", + "EventTimestamp": "2025-12-17T01:32:02.579Z", "ParentId": "eccbc87e4b5ce2fe", "StepStartedDetails": {} }, { "EventType": "StepSucceeded", "SubType": "Step", - "EventId": 11, + "EventId": 10, "Id": "b772d43b49bb57b5", - "EventTimestamp": "2025-12-10T00:15:09.467Z", + "EventTimestamp": "2025-12-17T01:32:02.679Z", "ParentId": "eccbc87e4b5ce2fe", "StepSucceededDetails": { "Result": {}, "RetryDetails": {} } }, + { + "EventType": "CallbackSucceeded", + "SubType": "Callback", + "EventId": 11, + "Id": "c9e6e7b69f98f516", + "EventTimestamp": "2025-12-17T01:32:02.680Z", + "ParentId": "eccbc87e4b5ce2fe", + "CallbackSucceededDetails": { + "Result": { + "Payload": "{\"processed\":true}" + } + } + }, { "EventType": "InvocationCompleted", "EventId": 12, - "EventTimestamp": "2025-12-10T00:15:09.527Z", + "EventTimestamp": "2025-12-17T01:32:02.730Z", "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-10T00:15:09.298Z", - "EndTimestamp": "2025-12-10T00:15:09.527Z", + "StartTimestamp": "2025-12-17T01:32:02.569Z", + "EndTimestamp": "2025-12-17T01:32:02.730Z", "Error": {}, - "RequestId": "a32fd7f6-2436-4ee8-a2ea-09dfd118a5ee" + "RequestId": "951053cb-2ed1-43d9-9606-0e513b72b4bc" } }, { @@ -139,7 +139,7 @@ "EventId": 13, "Id": "eccbc87e4b5ce2fe", "Name": "wait-for-callback", - "EventTimestamp": "2025-12-10T00:15:09.569Z", + "EventTimestamp": "2025-12-17T01:32:02.734Z", "ContextSucceededDetails": { "Result": { "Payload": "\"{\\\"processed\\\":true}\"" @@ -152,41 +152,41 @@ "EventId": 14, "Id": "a87ff679a2f3e71d", "Name": "final-wait", - "EventTimestamp": "2025-12-10T00:15:09.569Z", + "EventTimestamp": "2025-12-17T01:32:02.734Z", "WaitStartedDetails": { "Duration": 2, - "ScheduledEndTimestamp": "2025-12-10T00:15:11.569Z" + "ScheduledEndTimestamp": "2025-12-17T01:32:04.734Z" + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 15, + "EventTimestamp": "2025-12-17T01:32:02.785Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-17T01:32:02.731Z", + "EndTimestamp": "2025-12-17T01:32:02.785Z", + "Error": {}, + "RequestId": "49bb41e6-7491-44ea-8eb1-7daecbe8efff" } }, { "EventType": "WaitSucceeded", "SubType": "Wait", - "EventId": 15, + "EventId": 16, "Id": "a87ff679a2f3e71d", "Name": "final-wait", - "EventTimestamp": "2025-12-10T00:15:09.570Z", + "EventTimestamp": "2025-12-17T01:32:04.735Z", "WaitSucceededDetails": { "Duration": 2 } }, - { - "EventType": "InvocationCompleted", - "EventId": 16, - "EventTimestamp": "2025-12-10T00:15:09.570Z", - "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-10T00:15:09.547Z", - "EndTimestamp": "2025-12-10T00:15:09.570Z", - "Error": {}, - "RequestId": "42c5f388-4f12-42a3-a9d3-05e6171d613c" - } - }, { "EventType": "StepStarted", "SubType": "Step", "EventId": 17, "Id": "e4da3b7fbbce2345", "Name": "finalize-processing", - "EventTimestamp": "2025-12-10T00:15:09.610Z", + "EventTimestamp": "2025-12-17T01:32:04.738Z", "StepStartedDetails": {} }, { @@ -195,10 +195,10 @@ "EventId": 18, "Id": "e4da3b7fbbce2345", "Name": "finalize-processing", - "EventTimestamp": "2025-12-10T00:15:09.610Z", + "EventTimestamp": "2025-12-17T01:32:04.738Z", "StepSucceededDetails": { "Result": { - "Payload": "{\"status\":\"completed\",\"timestamp\":1765325711589}" + "Payload": "{\"status\":\"completed\",\"timestamp\":1765935124736}" }, "RetryDetails": {} } @@ -206,22 +206,22 @@ { "EventType": "InvocationCompleted", "EventId": 19, - "EventTimestamp": "2025-12-10T00:15:09.611Z", + "EventTimestamp": "2025-12-17T01:32:04.738Z", "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-10T00:15:09.588Z", - "EndTimestamp": "2025-12-10T00:15:09.611Z", + "StartTimestamp": "2025-12-17T01:32:04.735Z", + "EndTimestamp": "2025-12-17T01:32:04.738Z", "Error": {}, - "RequestId": "398dc4a0-cf48-4e10-8c4d-819bc50fa404" + "RequestId": "bfd26a9b-a587-43e8-bc6b-c97fd2e849ec" } }, { "EventType": "ExecutionSucceeded", "EventId": 20, - "Id": "306a63fb-bb71-4c48-a20c-f42d50f446b7", - "EventTimestamp": "2025-12-10T00:15:09.611Z", + "Id": "12f88eec-8d4c-462f-868f-07c55f796667", + "EventTimestamp": "2025-12-17T01:32:04.738Z", "ExecutionSucceededDetails": { "Result": { - "Payload": "{\"stepResult\":{\"userId\":123,\"name\":\"John Doe\"},\"callbackResult\":\"{\\\"processed\\\":true}\",\"finalStep\":{\"status\":\"completed\",\"timestamp\":1765325711589},\"workflowCompleted\":true}" + "Payload": "{\"stepResult\":{\"userId\":123,\"name\":\"John Doe\"},\"callbackResult\":\"{\\\"processed\\\":true}\",\"finalStep\":{\"status\":\"completed\",\"timestamp\":1765935124736},\"workflowCompleted\":true}" } } } diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/mixed-ops/wait-for-callback-mixed-ops.test.ts b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/mixed-ops/wait-for-callback-mixed-ops.test.ts index 2dad0f39..fa2bbe7a 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/mixed-ops/wait-for-callback-mixed-ops.test.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/mixed-ops/wait-for-callback-mixed-ops.test.ts @@ -16,7 +16,7 @@ createTests({ const executionPromise = runner.run(); // Wait for callback to start (other operations complete synchronously with skipTime) - await callbackOperation.waitForData(WaitingOperationStatus.STARTED); + await callbackOperation.waitForData(WaitingOperationStatus.SUBMITTED); // Complete the callback const callbackResult = JSON.stringify({ processed: true }); diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/multiple-invocations/wait-for-callback-multiple-invocations.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/multiple-invocations/wait-for-callback-multiple-invocations.history.json index 7f0ab556..696e25e3 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/multiple-invocations/wait-for-callback-multiple-invocations.history.json +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/multiple-invocations/wait-for-callback-multiple-invocations.history.json @@ -2,8 +2,8 @@ { "EventType": "ExecutionStarted", "EventId": 1, - "Id": "7e96946b-8064-40a3-9775-52df4461a1a0", - "EventTimestamp": "2025-12-11T00:57:48.416Z", + "Id": "aedf8054-8978-4b32-9aea-c96ccbd44f8d", + "EventTimestamp": "2025-12-17T01:32:04.622Z", "ExecutionStartedDetails": { "Input": { "Payload": "{\"test\":\"multiple-invocations\"}" @@ -16,21 +16,21 @@ "EventId": 2, "Id": "c4ca4238a0b92382", "Name": "wait-invocation-1", - "EventTimestamp": "2025-12-11T00:57:48.422Z", + "EventTimestamp": "2025-12-17T01:32:04.627Z", "WaitStartedDetails": { "Duration": 1, - "ScheduledEndTimestamp": "2025-12-11T00:57:49.422Z" + "ScheduledEndTimestamp": "2025-12-17T01:32:05.627Z" } }, { "EventType": "InvocationCompleted", "EventId": 3, - "EventTimestamp": "2025-12-11T00:57:48.425Z", + "EventTimestamp": "2025-12-17T01:32:04.678Z", "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-11T00:57:48.416Z", - "EndTimestamp": "2025-12-11T00:57:48.425Z", + "StartTimestamp": "2025-12-17T01:32:04.622Z", + "EndTimestamp": "2025-12-17T01:32:04.678Z", "Error": {}, - "RequestId": "1f306733-3ca0-44fa-81e2-70c2d4d9a80d" + "RequestId": "a261c255-3a31-43dc-938f-39cf415c3387" } }, { @@ -39,7 +39,7 @@ "EventId": 4, "Id": "c4ca4238a0b92382", "Name": "wait-invocation-1", - "EventTimestamp": "2025-12-11T00:57:49.422Z", + "EventTimestamp": "2025-12-17T01:32:05.628Z", "WaitSucceededDetails": { "Duration": 1 } @@ -50,7 +50,7 @@ "EventId": 5, "Id": "c81e728d9d4c2f63", "Name": "first-callback", - "EventTimestamp": "2025-12-11T00:57:49.424Z", + "EventTimestamp": "2025-12-17T01:32:05.630Z", "ContextStartedDetails": {} }, { @@ -58,10 +58,10 @@ "SubType": "Callback", "EventId": 6, "Id": "8fbdbf5573b18fae", - "EventTimestamp": "2025-12-11T00:57:49.424Z", + "EventTimestamp": "2025-12-17T01:32:05.630Z", "ParentId": "c81e728d9d4c2f63", "CallbackStartedDetails": { - "CallbackId": "eyJleGVjdXRpb25JZCI6ImU0ZGVhNzBmLTk3ZmEtNDg0Yy04ZTM3LTMzOGZkM2FjZTQxYiIsIm9wZXJhdGlvbklkIjoiOGZiZGJmNTU3M2IxOGZhZSIsInRva2VuIjoiOTAwZTkyZjQtY2UzZC00ZDg5LWJiOWUtZmQxMGY2NDFhMjg5In0=", + "CallbackId": "eyJleGVjdXRpb25JZCI6ImJjMGViOGE2LTUwNDAtNGQ2Yi05MGM0LThkMTA1ZmI3ZTIxZCIsIm9wZXJhdGlvbklkIjoiOGZiZGJmNTU3M2IxOGZhZSIsInRva2VuIjoiN2I2MGIyY2YtNzZjZi00ZGFhLWIyNWUtZWM4NGRiYWIzODk4In0=", "Input": {} } }, @@ -70,7 +70,7 @@ "SubType": "Step", "EventId": 7, "Id": "3c46a0407be60a1f", - "EventTimestamp": "2025-12-11T00:57:49.426Z", + "EventTimestamp": "2025-12-17T01:32:05.632Z", "ParentId": "c81e728d9d4c2f63", "StepStartedDetails": {} }, @@ -79,7 +79,7 @@ "SubType": "Step", "EventId": 8, "Id": "3c46a0407be60a1f", - "EventTimestamp": "2025-12-11T00:57:49.427Z", + "EventTimestamp": "2025-12-17T01:32:05.632Z", "ParentId": "c81e728d9d4c2f63", "StepSucceededDetails": { "Result": {}, @@ -91,7 +91,7 @@ "SubType": "Callback", "EventId": 9, "Id": "8fbdbf5573b18fae", - "EventTimestamp": "2025-12-11T00:57:49.428Z", + "EventTimestamp": "2025-12-17T01:32:05.633Z", "ParentId": "c81e728d9d4c2f63", "CallbackSucceededDetails": { "Result": { @@ -102,12 +102,12 @@ { "EventType": "InvocationCompleted", "EventId": 10, - "EventTimestamp": "2025-12-11T00:57:49.428Z", + "EventTimestamp": "2025-12-17T01:32:05.683Z", "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-11T00:57:49.422Z", - "EndTimestamp": "2025-12-11T00:57:49.428Z", + "StartTimestamp": "2025-12-17T01:32:05.628Z", + "EndTimestamp": "2025-12-17T01:32:05.683Z", "Error": {}, - "RequestId": "4c10a9dd-5aec-411e-b797-6ecb46aa9fa6" + "RequestId": "e2d3c3b6-9778-4be7-9ee6-4506be27a516" } }, { @@ -116,7 +116,7 @@ "EventId": 11, "Id": "c81e728d9d4c2f63", "Name": "first-callback", - "EventTimestamp": "2025-12-11T00:57:49.431Z", + "EventTimestamp": "2025-12-17T01:32:05.687Z", "ContextSucceededDetails": { "Result": { "Payload": "\"{\\\"step\\\":1}\"" @@ -129,7 +129,7 @@ "EventId": 12, "Id": "eccbc87e4b5ce2fe", "Name": "process-callback-data", - "EventTimestamp": "2025-12-11T00:57:49.432Z", + "EventTimestamp": "2025-12-17T01:32:05.687Z", "StepStartedDetails": {} }, { @@ -138,7 +138,7 @@ "EventId": 13, "Id": "eccbc87e4b5ce2fe", "Name": "process-callback-data", - "EventTimestamp": "2025-12-11T00:57:49.432Z", + "EventTimestamp": "2025-12-17T01:32:05.687Z", "StepSucceededDetails": { "Result": { "Payload": "{\"processed\":true,\"step\":1}" @@ -152,21 +152,21 @@ "EventId": 14, "Id": "a87ff679a2f3e71d", "Name": "wait-invocation-2", - "EventTimestamp": "2025-12-11T00:57:49.433Z", + "EventTimestamp": "2025-12-17T01:32:05.689Z", "WaitStartedDetails": { "Duration": 1, - "ScheduledEndTimestamp": "2025-12-11T00:57:50.433Z" + "ScheduledEndTimestamp": "2025-12-17T01:32:06.689Z" } }, { "EventType": "InvocationCompleted", "EventId": 15, - "EventTimestamp": "2025-12-11T00:57:49.435Z", + "EventTimestamp": "2025-12-17T01:32:05.740Z", "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-11T00:57:49.429Z", - "EndTimestamp": "2025-12-11T00:57:49.435Z", + "StartTimestamp": "2025-12-17T01:32:05.685Z", + "EndTimestamp": "2025-12-17T01:32:05.740Z", "Error": {}, - "RequestId": "ccc0514b-782f-4768-af1d-69c0d5d8670c" + "RequestId": "166a08e5-abe9-449a-8b52-eff68056b62f" } }, { @@ -175,7 +175,7 @@ "EventId": 16, "Id": "a87ff679a2f3e71d", "Name": "wait-invocation-2", - "EventTimestamp": "2025-12-11T00:57:50.433Z", + "EventTimestamp": "2025-12-17T01:32:06.691Z", "WaitSucceededDetails": { "Duration": 1 } @@ -186,7 +186,7 @@ "EventId": 17, "Id": "e4da3b7fbbce2345", "Name": "second-callback", - "EventTimestamp": "2025-12-11T00:57:50.436Z", + "EventTimestamp": "2025-12-17T01:32:06.695Z", "ContextStartedDetails": {} }, { @@ -194,10 +194,10 @@ "SubType": "Callback", "EventId": 18, "Id": "19a1de167122a18a", - "EventTimestamp": "2025-12-11T00:57:50.436Z", + "EventTimestamp": "2025-12-17T01:32:06.695Z", "ParentId": "e4da3b7fbbce2345", "CallbackStartedDetails": { - "CallbackId": "eyJleGVjdXRpb25JZCI6ImU0ZGVhNzBmLTk3ZmEtNDg0Yy04ZTM3LTMzOGZkM2FjZTQxYiIsIm9wZXJhdGlvbklkIjoiMTlhMWRlMTY3MTIyYTE4YSIsInRva2VuIjoiNThhYTIzMzUtYWZkYi00N2M0LTk4NzQtY2E5NjE1ZDU5MzNmIn0=", + "CallbackId": "eyJleGVjdXRpb25JZCI6ImJjMGViOGE2LTUwNDAtNGQ2Yi05MGM0LThkMTA1ZmI3ZTIxZCIsIm9wZXJhdGlvbklkIjoiMTlhMWRlMTY3MTIyYTE4YSIsInRva2VuIjoiZDcwYjdkZmYtYWQ4Ny00N2I3LWI0NzItOGZlYzE5M2U3ZmE1In0=", "Input": {} } }, @@ -206,7 +206,7 @@ "SubType": "Step", "EventId": 19, "Id": "dca19ffa163054fe", - "EventTimestamp": "2025-12-11T00:57:50.437Z", + "EventTimestamp": "2025-12-17T01:32:06.697Z", "ParentId": "e4da3b7fbbce2345", "StepStartedDetails": {} }, @@ -215,7 +215,7 @@ "SubType": "Step", "EventId": 20, "Id": "dca19ffa163054fe", - "EventTimestamp": "2025-12-11T00:57:50.437Z", + "EventTimestamp": "2025-12-17T01:32:06.697Z", "ParentId": "e4da3b7fbbce2345", "StepSucceededDetails": { "Result": {}, @@ -227,7 +227,7 @@ "SubType": "Callback", "EventId": 21, "Id": "19a1de167122a18a", - "EventTimestamp": "2025-12-11T00:57:50.438Z", + "EventTimestamp": "2025-12-17T01:32:06.698Z", "ParentId": "e4da3b7fbbce2345", "CallbackSucceededDetails": { "Result": { @@ -238,12 +238,12 @@ { "EventType": "InvocationCompleted", "EventId": 22, - "EventTimestamp": "2025-12-11T00:57:50.439Z", + "EventTimestamp": "2025-12-17T01:32:06.759Z", "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-11T00:57:50.433Z", - "EndTimestamp": "2025-12-11T00:57:50.439Z", + "StartTimestamp": "2025-12-17T01:32:06.691Z", + "EndTimestamp": "2025-12-17T01:32:06.759Z", "Error": {}, - "RequestId": "bfded0ba-76dc-4900-bbcd-7abb62cff2bc" + "RequestId": "36c5226a-a7ff-4f5e-b127-7977d6b7828d" } }, { @@ -252,7 +252,7 @@ "EventId": 23, "Id": "e4da3b7fbbce2345", "Name": "second-callback", - "EventTimestamp": "2025-12-11T00:57:50.441Z", + "EventTimestamp": "2025-12-17T01:32:06.764Z", "ContextSucceededDetails": { "Result": { "Payload": "\"{\\\"step\\\":2}\"" @@ -262,19 +262,19 @@ { "EventType": "InvocationCompleted", "EventId": 24, - "EventTimestamp": "2025-12-11T00:57:50.441Z", + "EventTimestamp": "2025-12-17T01:32:06.764Z", "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-11T00:57:50.439Z", - "EndTimestamp": "2025-12-11T00:57:50.441Z", + "StartTimestamp": "2025-12-17T01:32:06.760Z", + "EndTimestamp": "2025-12-17T01:32:06.764Z", "Error": {}, - "RequestId": "51b1bff4-216b-4f2f-8045-486656ba5667" + "RequestId": "96fcde41-72c7-4340-a2a3-852c74d91046" } }, { "EventType": "ExecutionSucceeded", "EventId": 25, - "Id": "7e96946b-8064-40a3-9775-52df4461a1a0", - "EventTimestamp": "2025-12-11T00:57:50.441Z", + "Id": "aedf8054-8978-4b32-9aea-c96ccbd44f8d", + "EventTimestamp": "2025-12-17T01:32:06.764Z", "ExecutionSucceededDetails": { "Result": { "Payload": "{\"firstCallback\":\"{\\\"step\\\":1}\",\"secondCallback\":\"{\\\"step\\\":2}\",\"stepResult\":{\"processed\":true,\"step\":1},\"invocationCount\":\"multiple\"}" diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/nested/wait-for-callback-nested.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/nested/wait-for-callback-nested.history.json index 30aead16..e9eb2dc0 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/nested/wait-for-callback-nested.history.json +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/nested/wait-for-callback-nested.history.json @@ -2,8 +2,8 @@ { "EventType": "ExecutionStarted", "EventId": 1, - "Id": "f66e69d4-c309-4df7-be6b-9164dacd1e6c", - "EventTimestamp": "2025-12-10T00:15:09.629Z", + "Id": "a725121d-cded-4f6d-b21f-748bb0009026", + "EventTimestamp": "2025-12-17T01:31:50.804Z", "ExecutionStartedDetails": { "Input": { "Payload": "{}" @@ -16,7 +16,7 @@ "EventId": 2, "Id": "c4ca4238a0b92382", "Name": "outer-callback-op", - "EventTimestamp": "2025-12-10T00:15:09.656Z", + "EventTimestamp": "2025-12-17T01:31:50.808Z", "ContextStartedDetails": {} }, { @@ -24,56 +24,56 @@ "SubType": "Callback", "EventId": 3, "Id": "ea66c06c1e1c05fa", - "EventTimestamp": "2025-12-10T00:15:09.656Z", + "EventTimestamp": "2025-12-17T01:31:50.808Z", "ParentId": "c4ca4238a0b92382", "CallbackStartedDetails": { - "CallbackId": "eyJleGVjdXRpb25JZCI6IjJiNjM3MjA4LWUzNmEtNGFlNS04NGU3LWIxNzQ1MDc5NTg2NyIsIm9wZXJhdGlvbklkIjoiZWE2NmMwNmMxZTFjMDVmYSIsInRva2VuIjoiYzY4Njk4NjYtNjk4ZS00NzU4LTlmNTYtM2IzNmQzYjk3ODEyIn0=", + "CallbackId": "eyJleGVjdXRpb25JZCI6IjQ1YWMzOGMxLWQzYmYtNDhkYy05Mzc2LTMwY2ZhYzhjNzVlMCIsIm9wZXJhdGlvbklkIjoiZWE2NmMwNmMxZTFjMDVmYSIsInRva2VuIjoiOGRmNmYzNzAtNDllNC00NDNmLWFmYTUtYzM2NmUwMzM1N2JkIn0=", "Input": {} } }, - { - "EventType": "CallbackSucceeded", - "SubType": "Callback", - "EventId": 4, - "Id": "ea66c06c1e1c05fa", - "EventTimestamp": "2025-12-10T00:15:09.657Z", - "ParentId": "c4ca4238a0b92382", - "CallbackSucceededDetails": { - "Result": { - "Payload": "{\"level\":\"outer-completed\"}" - } - } - }, { "EventType": "StepStarted", "SubType": "Step", - "EventId": 5, + "EventId": 4, "Id": "98c6f2c2287f4c73", - "EventTimestamp": "2025-12-10T00:15:09.676Z", + "EventTimestamp": "2025-12-17T01:31:50.810Z", "ParentId": "c4ca4238a0b92382", "StepStartedDetails": {} }, { "EventType": "StepSucceeded", "SubType": "Step", - "EventId": 6, + "EventId": 5, "Id": "98c6f2c2287f4c73", - "EventTimestamp": "2025-12-10T00:15:09.676Z", + "EventTimestamp": "2025-12-17T01:31:50.810Z", "ParentId": "c4ca4238a0b92382", "StepSucceededDetails": { "Result": {}, "RetryDetails": {} } }, + { + "EventType": "CallbackSucceeded", + "SubType": "Callback", + "EventId": 6, + "Id": "ea66c06c1e1c05fa", + "EventTimestamp": "2025-12-17T01:31:50.811Z", + "ParentId": "c4ca4238a0b92382", + "CallbackSucceededDetails": { + "Result": { + "Payload": "{\"level\":\"outer-completed\"}" + } + } + }, { "EventType": "InvocationCompleted", "EventId": 7, - "EventTimestamp": "2025-12-10T00:15:09.737Z", + "EventTimestamp": "2025-12-17T01:31:50.861Z", "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-10T00:15:09.629Z", - "EndTimestamp": "2025-12-10T00:15:09.737Z", + "StartTimestamp": "2025-12-17T01:31:50.803Z", + "EndTimestamp": "2025-12-17T01:31:50.861Z", "Error": {}, - "RequestId": "7d351710-35b3-4557-92b9-d04a3bae3960" + "RequestId": "6c495daa-02e1-4341-b229-6333ce129ddb" } }, { @@ -82,7 +82,7 @@ "EventId": 8, "Id": "c4ca4238a0b92382", "Name": "outer-callback-op", - "EventTimestamp": "2025-12-10T00:15:09.780Z", + "EventTimestamp": "2025-12-17T01:31:50.864Z", "ContextSucceededDetails": { "Result": { "Payload": "\"{\\\"level\\\":\\\"outer-completed\\\"}\"" @@ -95,7 +95,7 @@ "EventId": 9, "Id": "c81e728d9d4c2f63", "Name": "outer-child-context", - "EventTimestamp": "2025-12-10T00:15:09.780Z", + "EventTimestamp": "2025-12-17T01:31:50.864Z", "ContextStartedDetails": {} }, { @@ -104,7 +104,7 @@ "EventId": 10, "Id": "8fbdbf5573b18fae", "Name": "inner-callback-op", - "EventTimestamp": "2025-12-10T00:15:09.780Z", + "EventTimestamp": "2025-12-17T01:31:50.864Z", "ParentId": "c81e728d9d4c2f63", "ContextStartedDetails": {} }, @@ -113,56 +113,56 @@ "SubType": "Callback", "EventId": 11, "Id": "de9160b4a2cf6c27", - "EventTimestamp": "2025-12-10T00:15:09.780Z", + "EventTimestamp": "2025-12-17T01:31:50.865Z", "ParentId": "8fbdbf5573b18fae", "CallbackStartedDetails": { - "CallbackId": "eyJleGVjdXRpb25JZCI6IjJiNjM3MjA4LWUzNmEtNGFlNS04NGU3LWIxNzQ1MDc5NTg2NyIsIm9wZXJhdGlvbklkIjoiZGU5MTYwYjRhMmNmNmMyNyIsInRva2VuIjoiZjI0Y2VmZDQtNWRiMC00NDJhLWE2OTUtYzFmYzhlYjRiMTZkIn0=", + "CallbackId": "eyJleGVjdXRpb25JZCI6IjQ1YWMzOGMxLWQzYmYtNDhkYy05Mzc2LTMwY2ZhYzhjNzVlMCIsIm9wZXJhdGlvbklkIjoiZGU5MTYwYjRhMmNmNmMyNyIsInRva2VuIjoiNTMzMzM0YmQtMGUyMy00MGI3LTljZTctMjE5ZWU1NjZhMzg5In0=", "Input": {} } }, - { - "EventType": "CallbackSucceeded", - "SubType": "Callback", - "EventId": 12, - "Id": "de9160b4a2cf6c27", - "EventTimestamp": "2025-12-10T00:15:09.781Z", - "ParentId": "8fbdbf5573b18fae", - "CallbackSucceededDetails": { - "Result": { - "Payload": "{\"level\":\"inner-completed\"}" - } - } - }, { "EventType": "StepStarted", "SubType": "Step", - "EventId": 13, + "EventId": 12, "Id": "0d9f92bdd748d70d", - "EventTimestamp": "2025-12-10T00:15:09.801Z", + "EventTimestamp": "2025-12-17T01:31:50.866Z", "ParentId": "8fbdbf5573b18fae", "StepStartedDetails": {} }, { "EventType": "StepSucceeded", "SubType": "Step", - "EventId": 14, + "EventId": 13, "Id": "0d9f92bdd748d70d", - "EventTimestamp": "2025-12-10T00:15:09.801Z", + "EventTimestamp": "2025-12-17T01:31:50.866Z", "ParentId": "8fbdbf5573b18fae", "StepSucceededDetails": { "Result": {}, "RetryDetails": {} } }, + { + "EventType": "CallbackSucceeded", + "SubType": "Callback", + "EventId": 14, + "Id": "de9160b4a2cf6c27", + "EventTimestamp": "2025-12-17T01:31:50.867Z", + "ParentId": "8fbdbf5573b18fae", + "CallbackSucceededDetails": { + "Result": { + "Payload": "{\"level\":\"inner-completed\"}" + } + } + }, { "EventType": "InvocationCompleted", "EventId": 15, - "EventTimestamp": "2025-12-10T00:15:09.861Z", + "EventTimestamp": "2025-12-17T01:31:50.919Z", "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-10T00:15:09.757Z", - "EndTimestamp": "2025-12-10T00:15:09.861Z", + "StartTimestamp": "2025-12-17T01:31:50.862Z", + "EndTimestamp": "2025-12-17T01:31:50.919Z", "Error": {}, - "RequestId": "9f5ddc83-7ed8-491a-a760-65267b039fae" + "RequestId": "60bb9e84-bed0-46b5-a586-904db11177c8" } }, { @@ -171,7 +171,7 @@ "EventId": 16, "Id": "8fbdbf5573b18fae", "Name": "inner-callback-op", - "EventTimestamp": "2025-12-10T00:15:09.904Z", + "EventTimestamp": "2025-12-17T01:31:50.923Z", "ParentId": "c81e728d9d4c2f63", "ContextSucceededDetails": { "Result": { @@ -185,7 +185,7 @@ "EventId": 17, "Id": "3c46a0407be60a1f", "Name": "inner-child-context", - "EventTimestamp": "2025-12-10T00:15:09.905Z", + "EventTimestamp": "2025-12-17T01:31:50.923Z", "ParentId": "c81e728d9d4c2f63", "ContextStartedDetails": {} }, @@ -195,43 +195,43 @@ "EventId": 18, "Id": "61e70e07c25ca2dd", "Name": "deep-wait", - "EventTimestamp": "2025-12-10T00:15:09.905Z", + "EventTimestamp": "2025-12-17T01:31:50.925Z", "ParentId": "3c46a0407be60a1f", "WaitStartedDetails": { "Duration": 5, - "ScheduledEndTimestamp": "2025-12-10T00:15:14.905Z" + "ScheduledEndTimestamp": "2025-12-17T01:31:55.925Z" + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 19, + "EventTimestamp": "2025-12-17T01:31:50.977Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-17T01:31:50.920Z", + "EndTimestamp": "2025-12-17T01:31:50.977Z", + "Error": {}, + "RequestId": "223470a7-654c-41d3-8068-605b2db97dd1" } }, { "EventType": "WaitSucceeded", "SubType": "Wait", - "EventId": 19, + "EventId": 20, "Id": "61e70e07c25ca2dd", "Name": "deep-wait", - "EventTimestamp": "2025-12-10T00:15:09.905Z", + "EventTimestamp": "2025-12-17T01:31:55.925Z", "ParentId": "3c46a0407be60a1f", "WaitSucceededDetails": { "Duration": 5 } }, - { - "EventType": "InvocationCompleted", - "EventId": 20, - "EventTimestamp": "2025-12-10T00:15:09.906Z", - "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-10T00:15:09.882Z", - "EndTimestamp": "2025-12-10T00:15:09.906Z", - "Error": {}, - "RequestId": "362090dc-fb23-4727-99de-966c358a3d9e" - } - }, { "EventType": "ContextStarted", "SubType": "WaitForCallback", "EventId": 21, "Id": "c2f098f784fd6490", "Name": "nested-callback-op", - "EventTimestamp": "2025-12-10T00:15:09.945Z", + "EventTimestamp": "2025-12-17T01:31:55.927Z", "ParentId": "3c46a0407be60a1f", "ContextStartedDetails": {} }, @@ -240,56 +240,56 @@ "SubType": "Callback", "EventId": 22, "Id": "1d03fc80da7b6145", - "EventTimestamp": "2025-12-10T00:15:09.945Z", + "EventTimestamp": "2025-12-17T01:31:55.927Z", "ParentId": "c2f098f784fd6490", "CallbackStartedDetails": { - "CallbackId": "eyJleGVjdXRpb25JZCI6IjJiNjM3MjA4LWUzNmEtNGFlNS04NGU3LWIxNzQ1MDc5NTg2NyIsIm9wZXJhdGlvbklkIjoiMWQwM2ZjODBkYTdiNjE0NSIsInRva2VuIjoiZmFkNTZjNmYtZTRmNS00NzYwLTkzMDgtYzQxZGI5NzMyOTUxIn0=", + "CallbackId": "eyJleGVjdXRpb25JZCI6IjQ1YWMzOGMxLWQzYmYtNDhkYy05Mzc2LTMwY2ZhYzhjNzVlMCIsIm9wZXJhdGlvbklkIjoiMWQwM2ZjODBkYTdiNjE0NSIsInRva2VuIjoiYzllNTRhMGMtNDc1Yy00OWUyLThjZDgtN2UwYWRjYWZkNWZjIn0=", "Input": {} } }, - { - "EventType": "CallbackSucceeded", - "SubType": "Callback", - "EventId": 23, - "Id": "1d03fc80da7b6145", - "EventTimestamp": "2025-12-10T00:15:09.946Z", - "ParentId": "c2f098f784fd6490", - "CallbackSucceededDetails": { - "Result": { - "Payload": "{\"level\":\"nested-completed\"}" - } - } - }, { "EventType": "StepStarted", "SubType": "Step", - "EventId": 24, + "EventId": 23, "Id": "8976069e5d6bb1a6", - "EventTimestamp": "2025-12-10T00:15:09.966Z", + "EventTimestamp": "2025-12-17T01:31:55.929Z", "ParentId": "c2f098f784fd6490", "StepStartedDetails": {} }, { "EventType": "StepSucceeded", "SubType": "Step", - "EventId": 25, + "EventId": 24, "Id": "8976069e5d6bb1a6", - "EventTimestamp": "2025-12-10T00:15:09.966Z", + "EventTimestamp": "2025-12-17T01:31:55.929Z", "ParentId": "c2f098f784fd6490", "StepSucceededDetails": { "Result": {}, "RetryDetails": {} } }, + { + "EventType": "CallbackSucceeded", + "SubType": "Callback", + "EventId": 25, + "Id": "1d03fc80da7b6145", + "EventTimestamp": "2025-12-17T01:31:55.930Z", + "ParentId": "c2f098f784fd6490", + "CallbackSucceededDetails": { + "Result": { + "Payload": "{\"level\":\"nested-completed\"}" + } + } + }, { "EventType": "InvocationCompleted", "EventId": 26, - "EventTimestamp": "2025-12-10T00:15:10.026Z", + "EventTimestamp": "2025-12-17T01:31:55.980Z", "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-10T00:15:09.922Z", - "EndTimestamp": "2025-12-10T00:15:10.026Z", + "StartTimestamp": "2025-12-17T01:31:55.925Z", + "EndTimestamp": "2025-12-17T01:31:55.980Z", "Error": {}, - "RequestId": "f2d7cae6-9602-495a-874e-810097662393" + "RequestId": "4513aaed-d1d5-46b4-9463-b7d6af20c141" } }, { @@ -298,7 +298,7 @@ "EventId": 27, "Id": "c2f098f784fd6490", "Name": "nested-callback-op", - "EventTimestamp": "2025-12-10T00:15:10.072Z", + "EventTimestamp": "2025-12-17T01:31:55.984Z", "ParentId": "3c46a0407be60a1f", "ContextSucceededDetails": { "Result": { @@ -312,7 +312,7 @@ "EventId": 28, "Id": "3c46a0407be60a1f", "Name": "inner-child-context", - "EventTimestamp": "2025-12-10T00:15:10.072Z", + "EventTimestamp": "2025-12-17T01:31:55.984Z", "ParentId": "c81e728d9d4c2f63", "ContextSucceededDetails": { "Result": { @@ -326,7 +326,7 @@ "EventId": 29, "Id": "c81e728d9d4c2f63", "Name": "outer-child-context", - "EventTimestamp": "2025-12-10T00:15:10.072Z", + "EventTimestamp": "2025-12-17T01:31:55.984Z", "ContextSucceededDetails": { "Result": { "Payload": "{\"innerCallback\":\"{\\\"level\\\":\\\"inner-completed\\\"}\",\"deepNested\":{\"nestedCallback\":\"{\\\"level\\\":\\\"nested-completed\\\"}\",\"deepLevel\":\"inner-child\"},\"level\":\"outer-child\"}" @@ -336,19 +336,19 @@ { "EventType": "InvocationCompleted", "EventId": 30, - "EventTimestamp": "2025-12-10T00:15:10.074Z", + "EventTimestamp": "2025-12-17T01:31:55.984Z", "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-10T00:15:10.052Z", - "EndTimestamp": "2025-12-10T00:15:10.074Z", + "StartTimestamp": "2025-12-17T01:31:55.982Z", + "EndTimestamp": "2025-12-17T01:31:55.984Z", "Error": {}, - "RequestId": "77d1ae8c-8613-4c67-8955-dab858f60b5f" + "RequestId": "7ab25379-4c29-4a07-b823-f45c39499142" } }, { "EventType": "ExecutionSucceeded", "EventId": 31, - "Id": "f66e69d4-c309-4df7-be6b-9164dacd1e6c", - "EventTimestamp": "2025-12-10T00:15:10.074Z", + "Id": "a725121d-cded-4f6d-b21f-748bb0009026", + "EventTimestamp": "2025-12-17T01:31:55.984Z", "ExecutionSucceededDetails": { "Result": { "Payload": "{\"outerCallback\":\"{\\\"level\\\":\\\"outer-completed\\\"}\",\"nestedResults\":{\"innerCallback\":\"{\\\"level\\\":\\\"inner-completed\\\"}\",\"deepNested\":{\"nestedCallback\":\"{\\\"level\\\":\\\"nested-completed\\\"}\",\"deepLevel\":\"inner-child\"},\"level\":\"outer-child\"}}" diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/nested/wait-for-callback-nested.test.ts b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/nested/wait-for-callback-nested.test.ts index b2b615a1..16304c5a 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/nested/wait-for-callback-nested.test.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/nested/wait-for-callback-nested.test.ts @@ -20,15 +20,15 @@ createTests({ const executionPromise = runner.run(); // Complete callbacks in sequence - await outerCallbackOp.waitForData(WaitingOperationStatus.STARTED); + await outerCallbackOp.waitForData(WaitingOperationStatus.SUBMITTED); const outerCallbackResult = JSON.stringify({ level: "outer-completed" }); await outerCallbackOp.sendCallbackSuccess(outerCallbackResult); - await innerCallbackOp.waitForData(WaitingOperationStatus.STARTED); + await innerCallbackOp.waitForData(WaitingOperationStatus.SUBMITTED); const innerCallbackResult = JSON.stringify({ level: "inner-completed" }); await innerCallbackOp.sendCallbackSuccess(innerCallbackResult); - await nestedCallbackOp.waitForData(WaitingOperationStatus.STARTED); + await nestedCallbackOp.waitForData(WaitingOperationStatus.SUBMITTED); const nestedCallbackResult = JSON.stringify({ level: "nested-completed", }); diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/quick-completion/wait-for-callback-quick-completion.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/quick-completion/wait-for-callback-quick-completion.history.json new file mode 100644 index 00000000..815d9c12 --- /dev/null +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/quick-completion/wait-for-callback-quick-completion.history.json @@ -0,0 +1,101 @@ +[ + { + "EventType": "ExecutionStarted", + "EventId": 1, + "Id": "c2e05e1f-5301-4132-8be7-527e626911b8", + "EventTimestamp": "2025-12-17T01:24:56.729Z", + "ExecutionStartedDetails": { + "Input": { + "Payload": "{}" + } + } + }, + { + "EventType": "ContextStarted", + "SubType": "WaitForCallback", + "EventId": 2, + "Id": "c4ca4238a0b92382", + "EventTimestamp": "2025-12-17T01:24:56.736Z", + "ContextStartedDetails": {} + }, + { + "EventType": "CallbackStarted", + "SubType": "Callback", + "EventId": 3, + "Id": "ea66c06c1e1c05fa", + "EventTimestamp": "2025-12-17T01:24:56.736Z", + "ParentId": "c4ca4238a0b92382", + "CallbackStartedDetails": { + "CallbackId": "eyJleGVjdXRpb25JZCI6ImIwNjY2YzJiLTViY2ItNGVkZC1hYTdjLWQ3NGJkMGNkNTE1ZSIsIm9wZXJhdGlvbklkIjoiZWE2NmMwNmMxZTFjMDVmYSIsInRva2VuIjoiN2Y2MmU5NjQtYzMxMy00ZDQyLWEzODMtOWUzNTY0NDA5ZjNiIn0=", + "Input": {} + } + }, + { + "EventType": "CallbackSucceeded", + "SubType": "Callback", + "EventId": 4, + "Id": "ea66c06c1e1c05fa", + "EventTimestamp": "2025-12-17T01:24:56.738Z", + "ParentId": "c4ca4238a0b92382", + "CallbackSucceededDetails": { + "Result": { + "Payload": "{}" + } + } + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 5, + "Id": "98c6f2c2287f4c73", + "EventTimestamp": "2025-12-17T01:24:56.740Z", + "ParentId": "c4ca4238a0b92382", + "StepStartedDetails": {} + }, + { + "EventType": "StepSucceeded", + "SubType": "Step", + "EventId": 6, + "Id": "98c6f2c2287f4c73", + "EventTimestamp": "2025-12-17T01:24:56.740Z", + "ParentId": "c4ca4238a0b92382", + "StepSucceededDetails": { + "Result": {}, + "RetryDetails": {} + } + }, + { + "EventType": "ContextSucceeded", + "SubType": "WaitForCallback", + "EventId": 7, + "Id": "c4ca4238a0b92382", + "EventTimestamp": "2025-12-17T01:24:56.742Z", + "ContextSucceededDetails": { + "Result": { + "Payload": "\"{}\"" + } + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 8, + "EventTimestamp": "2025-12-17T01:24:56.743Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-17T01:24:56.729Z", + "EndTimestamp": "2025-12-17T01:24:56.743Z", + "Error": {}, + "RequestId": "991c3b2a-c7a8-4332-9d0b-41a34462b3a6" + } + }, + { + "EventType": "ExecutionSucceeded", + "EventId": 9, + "Id": "c2e05e1f-5301-4132-8be7-527e626911b8", + "EventTimestamp": "2025-12-17T01:24:56.743Z", + "ExecutionSucceededDetails": { + "Result": { + "Payload": "{\"callbackResult\":\"{}\",\"success\":true}" + } + } + } +] diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/quick-completion/wait-for-callback-quick-completion.test.ts b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/quick-completion/wait-for-callback-quick-completion.test.ts index 26775d42..3f0d596c 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/quick-completion/wait-for-callback-quick-completion.test.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/quick-completion/wait-for-callback-quick-completion.test.ts @@ -8,7 +8,7 @@ createTests({ localRunnerConfig: { skipTime: false, }, - tests: (runner, { isCloud }) => { + tests: (runner, { isCloud, assertEventSignatures }) => { it("should handle waitForCallback when callback completes before ", async () => { const callbackOp = runner.getOperationByIndex(0); @@ -32,6 +32,8 @@ createTests({ success: true, }); expect(result.getInvocations().length).toBe(1); + + assertEventSignatures(result); }); }, }); diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/serdes/wait-for-callback-serdes.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/serdes/wait-for-callback-serdes.history.json index fa3a6b15..273fc368 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/serdes/wait-for-callback-serdes.history.json +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/serdes/wait-for-callback-serdes.history.json @@ -2,8 +2,8 @@ { "EventType": "ExecutionStarted", "EventId": 1, - "Id": "75f3d6bf-ca37-415d-af6f-d010babfc6ea", - "EventTimestamp": "2025-12-10T00:15:10.516Z", + "Id": "b7b9d820-06c9-4fed-9cd1-72d8bd961f9c", + "EventTimestamp": "2025-12-17T01:32:12.230Z", "ExecutionStartedDetails": { "Input": { "Payload": "{}" @@ -16,7 +16,7 @@ "EventId": 2, "Id": "c4ca4238a0b92382", "Name": "custom-serdes-callback", - "EventTimestamp": "2025-12-10T00:15:10.554Z", + "EventTimestamp": "2025-12-17T01:32:12.234Z", "ContextStartedDetails": {} }, { @@ -24,57 +24,57 @@ "SubType": "Callback", "EventId": 3, "Id": "ea66c06c1e1c05fa", - "EventTimestamp": "2025-12-10T00:15:10.554Z", + "EventTimestamp": "2025-12-17T01:32:12.234Z", "ParentId": "c4ca4238a0b92382", "CallbackStartedDetails": { - "CallbackId": "eyJleGVjdXRpb25JZCI6IjEwOWM2MzM3LTc5ZGQtNDFmNi05MGYxLWE4MWU5NDdiYTZmYSIsIm9wZXJhdGlvbklkIjoiZWE2NmMwNmMxZTFjMDVmYSIsInRva2VuIjoiNmNjMjM4MDMtY2QwNy00N2YxLTlkNjYtOTA3OTZlNDVlYTNjIn0=", + "CallbackId": "eyJleGVjdXRpb25JZCI6ImMwNzZjMzNhLWU3MjAtNDkwMy05NjUyLWVhODIwYWU3OWVhYiIsIm9wZXJhdGlvbklkIjoiZWE2NmMwNmMxZTFjMDVmYSIsInRva2VuIjoiOGRkNDM3OTItM2NmMS00NDA3LWEzYjEtNTE4ZTRkZTM3MmVlIn0=", "Timeout": 300, "Input": {} } }, - { - "EventType": "CallbackSucceeded", - "SubType": "Callback", - "EventId": 4, - "Id": "ea66c06c1e1c05fa", - "EventTimestamp": "2025-12-10T00:15:10.555Z", - "ParentId": "c4ca4238a0b92382", - "CallbackSucceededDetails": { - "Result": { - "Payload": "{\"id\":42,\"message\":\"Hello Custom Serdes\",\"timestamp\":\"2025-06-15T12:30:45Z\",\"metadata\":{\"version\":\"2.0.0\",\"processed\":false}}" - } - } - }, { "EventType": "StepStarted", "SubType": "Step", - "EventId": 5, + "EventId": 4, "Id": "98c6f2c2287f4c73", - "EventTimestamp": "2025-12-10T00:15:10.575Z", + "EventTimestamp": "2025-12-17T01:32:12.236Z", "ParentId": "c4ca4238a0b92382", "StepStartedDetails": {} }, { "EventType": "StepSucceeded", "SubType": "Step", - "EventId": 6, + "EventId": 5, "Id": "98c6f2c2287f4c73", - "EventTimestamp": "2025-12-10T00:15:10.575Z", + "EventTimestamp": "2025-12-17T01:32:12.236Z", "ParentId": "c4ca4238a0b92382", "StepSucceededDetails": { "Result": {}, "RetryDetails": {} } }, + { + "EventType": "CallbackSucceeded", + "SubType": "Callback", + "EventId": 6, + "Id": "ea66c06c1e1c05fa", + "EventTimestamp": "2025-12-17T01:32:12.237Z", + "ParentId": "c4ca4238a0b92382", + "CallbackSucceededDetails": { + "Result": { + "Payload": "{\"id\":42,\"message\":\"Hello Custom Serdes\",\"timestamp\":\"2025-06-15T12:30:45Z\",\"metadata\":{\"version\":\"2.0.0\",\"processed\":false}}" + } + } + }, { "EventType": "InvocationCompleted", "EventId": 7, - "EventTimestamp": "2025-12-10T00:15:10.637Z", + "EventTimestamp": "2025-12-17T01:32:12.287Z", "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-10T00:15:10.516Z", - "EndTimestamp": "2025-12-10T00:15:10.637Z", + "StartTimestamp": "2025-12-17T01:32:12.230Z", + "EndTimestamp": "2025-12-17T01:32:12.287Z", "Error": {}, - "RequestId": "0634e555-0d4e-47d6-b3c3-611339ca2ae3" + "RequestId": "caf770b4-6754-454a-abdd-6b2da81e263e" } }, { @@ -83,7 +83,7 @@ "EventId": 8, "Id": "c4ca4238a0b92382", "Name": "custom-serdes-callback", - "EventTimestamp": "2025-12-10T00:15:10.680Z", + "EventTimestamp": "2025-12-17T01:32:12.291Z", "ContextSucceededDetails": { "Result": { "Payload": "\"{\\\"id\\\":42,\\\"message\\\":\\\"Hello Custom Serdes\\\",\\\"timestamp\\\":\\\"2025-06-15T12:30:45Z\\\",\\\"metadata\\\":{\\\"version\\\":\\\"2.0.0\\\",\\\"processed\\\":false}}\"" @@ -95,7 +95,7 @@ "SubType": "Step", "EventId": 9, "Id": "c81e728d9d4c2f63", - "EventTimestamp": "2025-12-10T00:15:10.680Z", + "EventTimestamp": "2025-12-17T01:32:12.291Z", "StepStartedDetails": {} }, { @@ -103,7 +103,7 @@ "SubType": "Step", "EventId": 10, "Id": "c81e728d9d4c2f63", - "EventTimestamp": "2025-12-10T00:15:10.680Z", + "EventTimestamp": "2025-12-17T01:32:12.291Z", "StepSucceededDetails": { "Result": { "Payload": "true" @@ -116,7 +116,7 @@ "SubType": "Step", "EventId": 11, "Id": "eccbc87e4b5ce2fe", - "EventTimestamp": "2025-12-10T00:15:10.701Z", + "EventTimestamp": "2025-12-17T01:32:12.293Z", "StepStartedDetails": {} }, { @@ -124,7 +124,7 @@ "SubType": "Step", "EventId": 12, "Id": "eccbc87e4b5ce2fe", - "EventTimestamp": "2025-12-10T00:15:10.701Z", + "EventTimestamp": "2025-12-17T01:32:12.293Z", "StepSucceededDetails": { "Result": { "Payload": "true" @@ -137,49 +137,49 @@ "SubType": "Wait", "EventId": 13, "Id": "a87ff679a2f3e71d", - "EventTimestamp": "2025-12-10T00:15:10.722Z", + "EventTimestamp": "2025-12-17T01:32:12.295Z", "WaitStartedDetails": { "Duration": 1, - "ScheduledEndTimestamp": "2025-12-10T00:15:11.722Z" + "ScheduledEndTimestamp": "2025-12-17T01:32:13.295Z" } }, { - "EventType": "WaitSucceeded", - "SubType": "Wait", + "EventType": "InvocationCompleted", "EventId": 14, - "Id": "a87ff679a2f3e71d", - "EventTimestamp": "2025-12-10T00:15:10.723Z", - "WaitSucceededDetails": { - "Duration": 1 + "EventTimestamp": "2025-12-17T01:32:12.346Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-17T01:32:12.288Z", + "EndTimestamp": "2025-12-17T01:32:12.346Z", + "Error": {}, + "RequestId": "d6d10523-f288-464a-a7e5-24055edeea39" } }, { - "EventType": "InvocationCompleted", + "EventType": "WaitSucceeded", + "SubType": "Wait", "EventId": 15, - "EventTimestamp": "2025-12-10T00:15:10.723Z", - "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-10T00:15:10.658Z", - "EndTimestamp": "2025-12-10T00:15:10.723Z", - "Error": {}, - "RequestId": "5493eaa1-a356-41c8-9f76-987552b1feba" + "Id": "a87ff679a2f3e71d", + "EventTimestamp": "2025-12-17T01:32:13.295Z", + "WaitSucceededDetails": { + "Duration": 1 } }, { "EventType": "InvocationCompleted", "EventId": 16, - "EventTimestamp": "2025-12-10T00:15:10.743Z", + "EventTimestamp": "2025-12-17T01:32:13.297Z", "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-10T00:15:10.742Z", - "EndTimestamp": "2025-12-10T00:15:10.743Z", + "StartTimestamp": "2025-12-17T01:32:13.296Z", + "EndTimestamp": "2025-12-17T01:32:13.297Z", "Error": {}, - "RequestId": "037d7bc0-b9e3-4b3b-b87e-d74f06ee5911" + "RequestId": "d46a7ac9-9e20-48c5-b435-ac30b9426be3" } }, { "EventType": "ExecutionSucceeded", "EventId": 17, - "Id": "75f3d6bf-ca37-415d-af6f-d010babfc6ea", - "EventTimestamp": "2025-12-10T00:15:10.743Z", + "Id": "b7b9d820-06c9-4fed-9cd1-72d8bd961f9c", + "EventTimestamp": "2025-12-17T01:32:13.297Z", "ExecutionSucceededDetails": { "Result": { "Payload": "{\"receivedData\":{\"id\":42,\"message\":\"Hello Custom Serdes\",\"timestamp\":\"2025-06-15T12:30:45.000Z\",\"metadata\":{\"version\":\"2.0.0\",\"processed\":true}},\"hasCircularReference\":true,\"isDateAfterReplay\":true,\"isDateBeforeReplay\":true,\"isSerdesProcessedBefore\":true,\"isSerdesProcessedAfter\":true}" diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/serdes/wait-for-callback-serdes.test.ts b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/serdes/wait-for-callback-serdes.test.ts index a38adb00..a9c061ae 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/serdes/wait-for-callback-serdes.test.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/serdes/wait-for-callback-serdes.test.ts @@ -15,7 +15,7 @@ createTests({ const callbackOperation = runner.getOperation("custom-serdes-callback"); - await callbackOperation.waitForData(WaitingOperationStatus.STARTED); + await callbackOperation.waitForData(WaitingOperationStatus.SUBMITTED); // Serialize the data using custom serdes for sending await callbackOperation.sendCallbackSuccess( diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/submitter-failure-catchable/wait-for-callback-submitter-failure-catchable.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/submitter-failure-catchable/wait-for-callback-submitter-failure-catchable.history.json index 37470321..a598571a 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/submitter-failure-catchable/wait-for-callback-submitter-failure-catchable.history.json +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/submitter-failure-catchable/wait-for-callback-submitter-failure-catchable.history.json @@ -2,8 +2,8 @@ { "EventType": "ExecutionStarted", "EventId": 1, - "Id": "a0408aae-cfa0-4909-821a-2cb9af2a770a", - "EventTimestamp": "2025-12-10T00:12:24.018Z", + "Id": "58450fb8-93f5-489e-95a6-97fb0be142ef", + "EventTimestamp": "2025-12-17T01:25:17.659Z", "ExecutionStartedDetails": { "Input": { "Payload": "{}" @@ -16,7 +16,7 @@ "EventId": 2, "Id": "c4ca4238a0b92382", "Name": "failing-submitter-callback", - "EventTimestamp": "2025-12-10T00:12:24.023Z", + "EventTimestamp": "2025-12-17T01:25:17.663Z", "ContextStartedDetails": {} }, { @@ -24,10 +24,10 @@ "SubType": "Callback", "EventId": 3, "Id": "ea66c06c1e1c05fa", - "EventTimestamp": "2025-12-10T00:12:24.023Z", + "EventTimestamp": "2025-12-17T01:25:17.664Z", "ParentId": "c4ca4238a0b92382", "CallbackStartedDetails": { - "CallbackId": "eyJleGVjdXRpb25JZCI6IjRkZTBmYzA2LTlkYjMtNGMxNi1iNGVjLWJmYTFkYjUzM2QyOSIsIm9wZXJhdGlvbklkIjoiZWE2NmMwNmMxZTFjMDVmYSIsInRva2VuIjoiM2I3ZWJjZDItMmNkYy00NjlhLWI4OWYtMzM4ZGU5NWEwMGEyIn0=", + "CallbackId": "eyJleGVjdXRpb25JZCI6ImUyMTgzNjA1LTZkYWEtNDA5NS04ZDljLWEzYjczM2IwMGNlYSIsIm9wZXJhdGlvbklkIjoiZWE2NmMwNmMxZTFjMDVmYSIsInRva2VuIjoiNWQyYjNhNzUtMTkyNS00ZTE5LTg5MGItYjYyMWQ5MmM3MWZiIn0=", "Input": {} } }, @@ -36,7 +36,7 @@ "SubType": "Step", "EventId": 4, "Id": "98c6f2c2287f4c73", - "EventTimestamp": "2025-12-10T00:12:24.025Z", + "EventTimestamp": "2025-12-17T01:25:17.666Z", "ParentId": "c4ca4238a0b92382", "StepStartedDetails": {} }, @@ -45,7 +45,7 @@ "SubType": "Step", "EventId": 5, "Id": "98c6f2c2287f4c73", - "EventTimestamp": "2025-12-10T00:12:24.525Z", + "EventTimestamp": "2025-12-17T01:25:18.166Z", "ParentId": "c4ca4238a0b92382", "StepFailedDetails": { "Error": { @@ -63,12 +63,12 @@ { "EventType": "InvocationCompleted", "EventId": 6, - "EventTimestamp": "2025-12-10T00:12:24.577Z", + "EventTimestamp": "2025-12-17T01:25:18.217Z", "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-10T00:12:24.018Z", - "EndTimestamp": "2025-12-10T00:12:24.577Z", + "StartTimestamp": "2025-12-17T01:25:17.659Z", + "EndTimestamp": "2025-12-17T01:25:18.217Z", "Error": {}, - "RequestId": "6cf15bbe-b7a4-419e-b917-4520102ba5d7" + "RequestId": "fcfae06a-e795-4b7f-aef3-a76769107835" } }, { @@ -76,7 +76,7 @@ "SubType": "Step", "EventId": 7, "Id": "98c6f2c2287f4c73", - "EventTimestamp": "2025-12-10T00:12:25.527Z", + "EventTimestamp": "2025-12-17T01:25:19.173Z", "ParentId": "c4ca4238a0b92382", "StepStartedDetails": {} }, @@ -85,7 +85,7 @@ "SubType": "Step", "EventId": 8, "Id": "98c6f2c2287f4c73", - "EventTimestamp": "2025-12-10T00:12:26.028Z", + "EventTimestamp": "2025-12-17T01:25:19.673Z", "ParentId": "c4ca4238a0b92382", "StepFailedDetails": { "Error": { @@ -103,12 +103,12 @@ { "EventType": "InvocationCompleted", "EventId": 9, - "EventTimestamp": "2025-12-10T00:12:26.080Z", + "EventTimestamp": "2025-12-17T01:25:19.724Z", "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-10T00:12:25.525Z", - "EndTimestamp": "2025-12-10T00:12:26.080Z", + "StartTimestamp": "2025-12-17T01:25:19.169Z", + "EndTimestamp": "2025-12-17T01:25:19.724Z", "Error": {}, - "RequestId": "1f652da1-15c2-4ce2-a395-c78800314198" + "RequestId": "e80e3e94-8173-4777-aea2-789937e8d9c4" } }, { @@ -116,7 +116,7 @@ "SubType": "Step", "EventId": 10, "Id": "98c6f2c2287f4c73", - "EventTimestamp": "2025-12-10T00:12:27.032Z", + "EventTimestamp": "2025-12-17T01:25:20.677Z", "ParentId": "c4ca4238a0b92382", "StepStartedDetails": {} }, @@ -125,7 +125,7 @@ "SubType": "Step", "EventId": 11, "Id": "98c6f2c2287f4c73", - "EventTimestamp": "2025-12-10T00:12:27.533Z", + "EventTimestamp": "2025-12-17T01:25:21.178Z", "ParentId": "c4ca4238a0b92382", "StepFailedDetails": { "Error": { @@ -145,7 +145,7 @@ "EventId": 12, "Id": "c4ca4238a0b92382", "Name": "failing-submitter-callback", - "EventTimestamp": "2025-12-10T00:12:27.534Z", + "EventTimestamp": "2025-12-17T01:25:21.179Z", "ContextFailedDetails": { "Error": { "Payload": { @@ -158,19 +158,19 @@ { "EventType": "InvocationCompleted", "EventId": 13, - "EventTimestamp": "2025-12-10T00:12:27.534Z", + "EventTimestamp": "2025-12-17T01:25:21.180Z", "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-10T00:12:27.030Z", - "EndTimestamp": "2025-12-10T00:12:27.534Z", + "StartTimestamp": "2025-12-17T01:25:20.675Z", + "EndTimestamp": "2025-12-17T01:25:21.180Z", "Error": {}, - "RequestId": "8da70025-3134-42db-878f-a72e3c4c8d0a" + "RequestId": "32469a68-c78e-45fb-bf32-1ce29705b33e" } }, { "EventType": "ExecutionSucceeded", "EventId": 14, - "Id": "a0408aae-cfa0-4909-821a-2cb9af2a770a", - "EventTimestamp": "2025-12-10T00:12:27.534Z", + "Id": "58450fb8-93f5-489e-95a6-97fb0be142ef", + "EventTimestamp": "2025-12-17T01:25:21.180Z", "ExecutionSucceededDetails": { "Result": { "Payload": "{\"success\":false,\"error\":\"Submitter failed\"}" diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/submitter-retry-success/wait-for-callback-submitter-retry-success-failure.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/submitter-retry-success/wait-for-callback-submitter-retry-success-failure.history.json new file mode 100644 index 00000000..39ae5d67 --- /dev/null +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/submitter-retry-success/wait-for-callback-submitter-retry-success-failure.history.json @@ -0,0 +1,228 @@ +[ + { + "EventType": "ExecutionStarted", + "EventId": 1, + "Id": "c177dac0-e23a-4d45-b4e7-60a4674de60e", + "EventTimestamp": "2025-12-17T01:31:50.685Z", + "ExecutionStartedDetails": { + "Input": { + "Payload": "{\"shouldFail\":true}" + } + } + }, + { + "EventType": "ContextStarted", + "SubType": "WaitForCallback", + "EventId": 2, + "Id": "c4ca4238a0b92382", + "Name": "retry-submitter-callback", + "EventTimestamp": "2025-12-17T01:31:50.688Z", + "ContextStartedDetails": {} + }, + { + "EventType": "CallbackStarted", + "SubType": "Callback", + "EventId": 3, + "Id": "ea66c06c1e1c05fa", + "EventTimestamp": "2025-12-17T01:31:50.688Z", + "ParentId": "c4ca4238a0b92382", + "CallbackStartedDetails": { + "CallbackId": "eyJleGVjdXRpb25JZCI6ImE5MzU3MjNkLTU0OTktNGMxYi04NjAxLTdkZWU4YzA2NWM4NCIsIm9wZXJhdGlvbklkIjoiZWE2NmMwNmMxZTFjMDVmYSIsInRva2VuIjoiZDI0MTU5ZTEtMWExYS00ZDc4LTk5YmYtZWU4NDAzOTUyN2FmIn0=", + "Input": {} + } + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 4, + "Id": "98c6f2c2287f4c73", + "EventTimestamp": "2025-12-17T01:31:50.690Z", + "ParentId": "c4ca4238a0b92382", + "StepStartedDetails": {} + }, + { + "EventType": "StepFailed", + "SubType": "Step", + "EventId": 5, + "Id": "98c6f2c2287f4c73", + "EventTimestamp": "2025-12-17T01:31:50.690Z", + "ParentId": "c4ca4238a0b92382", + "StepFailedDetails": { + "Error": { + "Payload": { + "ErrorMessage": "Simulated submitter failure", + "ErrorType": "Error" + } + }, + "RetryDetails": { + "NextAttemptDelaySeconds": 1, + "CurrentAttempt": 1 + } + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 6, + "EventTimestamp": "2025-12-17T01:31:50.740Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-17T01:31:50.685Z", + "EndTimestamp": "2025-12-17T01:31:50.740Z", + "Error": {}, + "RequestId": "977115ce-2fb1-4aac-a5ad-c39e1bf014a1" + } + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 7, + "Id": "98c6f2c2287f4c73", + "EventTimestamp": "2025-12-17T01:31:51.692Z", + "ParentId": "c4ca4238a0b92382", + "StepStartedDetails": {} + }, + { + "EventType": "StepFailed", + "SubType": "Step", + "EventId": 8, + "Id": "98c6f2c2287f4c73", + "EventTimestamp": "2025-12-17T01:31:51.692Z", + "ParentId": "c4ca4238a0b92382", + "StepFailedDetails": { + "Error": { + "Payload": { + "ErrorMessage": "Simulated submitter failure", + "ErrorType": "Error" + } + }, + "RetryDetails": { + "NextAttemptDelaySeconds": 2, + "CurrentAttempt": 1 + } + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 9, + "EventTimestamp": "2025-12-17T01:31:51.744Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-17T01:31:51.690Z", + "EndTimestamp": "2025-12-17T01:31:51.744Z", + "Error": {}, + "RequestId": "711936cd-ab76-4c25-831f-aa8cde98f63d" + } + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 10, + "Id": "98c6f2c2287f4c73", + "EventTimestamp": "2025-12-17T01:31:53.696Z", + "ParentId": "c4ca4238a0b92382", + "StepStartedDetails": {} + }, + { + "EventType": "StepFailed", + "SubType": "Step", + "EventId": 11, + "Id": "98c6f2c2287f4c73", + "EventTimestamp": "2025-12-17T01:31:53.696Z", + "ParentId": "c4ca4238a0b92382", + "StepFailedDetails": { + "Error": { + "Payload": { + "ErrorMessage": "Simulated submitter failure", + "ErrorType": "Error" + } + }, + "RetryDetails": { + "NextAttemptDelaySeconds": 4, + "CurrentAttempt": 2 + } + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 12, + "EventTimestamp": "2025-12-17T01:31:53.747Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-17T01:31:53.694Z", + "EndTimestamp": "2025-12-17T01:31:53.747Z", + "Error": {}, + "RequestId": "c5fa6425-23d7-4cbe-a4dc-afc6259ca67d" + } + }, + { + "EventType": "StepStarted", + "SubType": "Step", + "EventId": 13, + "Id": "98c6f2c2287f4c73", + "EventTimestamp": "2025-12-17T01:31:57.701Z", + "ParentId": "c4ca4238a0b92382", + "StepStartedDetails": {} + }, + { + "EventType": "StepFailed", + "SubType": "Step", + "EventId": 14, + "Id": "98c6f2c2287f4c73", + "EventTimestamp": "2025-12-17T01:31:57.701Z", + "ParentId": "c4ca4238a0b92382", + "StepFailedDetails": { + "Error": { + "Payload": { + "ErrorMessage": "Simulated submitter failure", + "ErrorType": "Error" + } + }, + "RetryDetails": { + "CurrentAttempt": 3 + } + } + }, + { + "EventType": "ContextFailed", + "SubType": "WaitForCallback", + "EventId": 15, + "Id": "c4ca4238a0b92382", + "Name": "retry-submitter-callback", + "EventTimestamp": "2025-12-17T01:31:57.703Z", + "ContextFailedDetails": { + "Error": { + "Payload": { + "ErrorType": "StepError", + "ErrorMessage": "Simulated submitter failure" + } + } + } + }, + { + "EventType": "InvocationCompleted", + "EventId": 16, + "EventTimestamp": "2025-12-17T01:31:57.703Z", + "InvocationCompletedDetails": { + "StartTimestamp": "2025-12-17T01:31:57.698Z", + "EndTimestamp": "2025-12-17T01:31:57.703Z", + "Error": { + "Payload": { + "ErrorType": "ChildContextError", + "ErrorMessage": "Simulated submitter failure" + } + }, + "RequestId": "68df3353-a355-4609-8fde-e6f8e8258382" + } + }, + { + "EventType": "ExecutionFailed", + "EventId": 17, + "Id": "c177dac0-e23a-4d45-b4e7-60a4674de60e", + "EventTimestamp": "2025-12-17T01:31:57.704Z", + "ExecutionFailedDetails": { + "Error": { + "Payload": { + "ErrorType": "ChildContextError", + "ErrorMessage": "Simulated submitter failure" + } + } + } + } +] diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/submitter-retry-success/wait-for-callback-submitter-retry-success.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/submitter-retry-success/wait-for-callback-submitter-retry-success-success.history.json similarity index 64% rename from packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/submitter-retry-success/wait-for-callback-submitter-retry-success.history.json rename to packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/submitter-retry-success/wait-for-callback-submitter-retry-success-success.history.json index 14cce7e6..a31f41be 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/submitter-retry-success/wait-for-callback-submitter-retry-success.history.json +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/submitter-retry-success/wait-for-callback-submitter-retry-success-success.history.json @@ -2,8 +2,8 @@ { "EventType": "ExecutionStarted", "EventId": 1, - "Id": "e2067af3-c418-4d3b-96df-a5ca4e117a49", - "EventTimestamp": "2025-12-10T00:15:08.608Z", + "Id": "86de452a-714e-4bf4-b77b-89871388873f", + "EventTimestamp": "2025-12-17T01:31:50.517Z", "ExecutionStartedDetails": { "Input": { "Payload": "{\"shouldFail\":false}" @@ -16,7 +16,7 @@ "EventId": 2, "Id": "c4ca4238a0b92382", "Name": "retry-submitter-callback", - "EventTimestamp": "2025-12-10T00:15:08.636Z", + "EventTimestamp": "2025-12-17T01:31:50.522Z", "ContextStartedDetails": {} }, { @@ -24,56 +24,56 @@ "SubType": "Callback", "EventId": 3, "Id": "ea66c06c1e1c05fa", - "EventTimestamp": "2025-12-10T00:15:08.636Z", + "EventTimestamp": "2025-12-17T01:31:50.522Z", "ParentId": "c4ca4238a0b92382", "CallbackStartedDetails": { - "CallbackId": "eyJleGVjdXRpb25JZCI6ImU2NjQwYzRiLTllMmYtNDI1Ny1hOTAxLWUxMTZhMjUxMTg4OCIsIm9wZXJhdGlvbklkIjoiZWE2NmMwNmMxZTFjMDVmYSIsInRva2VuIjoiMjNkZWE0NTEtM2NmNC00YTkwLTg5NjctYmVlNjdhMjQ0ZjY2In0=", + "CallbackId": "eyJleGVjdXRpb25JZCI6ImUwMWIyMTQ0LWMzZGYtNGY1NS05NzFmLTljNTgxZWFiOGUxYyIsIm9wZXJhdGlvbklkIjoiZWE2NmMwNmMxZTFjMDVmYSIsInRva2VuIjoiYzIzMjUwMjMtZmVhZi00ZGM1LThiZDgtODExZjIxNzAyZGRkIn0=", "Input": {} } }, - { - "EventType": "CallbackSucceeded", - "SubType": "Callback", - "EventId": 4, - "Id": "ea66c06c1e1c05fa", - "EventTimestamp": "2025-12-10T00:15:08.641Z", - "ParentId": "c4ca4238a0b92382", - "CallbackSucceededDetails": { - "Result": { - "Payload": "{\"data\":\"completed\"}" - } - } - }, { "EventType": "StepStarted", "SubType": "Step", - "EventId": 5, + "EventId": 4, "Id": "98c6f2c2287f4c73", - "EventTimestamp": "2025-12-10T00:15:08.656Z", + "EventTimestamp": "2025-12-17T01:31:50.526Z", "ParentId": "c4ca4238a0b92382", "StepStartedDetails": {} }, { "EventType": "StepSucceeded", "SubType": "Step", - "EventId": 6, + "EventId": 5, "Id": "98c6f2c2287f4c73", - "EventTimestamp": "2025-12-10T00:15:08.656Z", + "EventTimestamp": "2025-12-17T01:31:50.526Z", "ParentId": "c4ca4238a0b92382", "StepSucceededDetails": { "Result": {}, "RetryDetails": {} } }, + { + "EventType": "CallbackSucceeded", + "SubType": "Callback", + "EventId": 6, + "Id": "ea66c06c1e1c05fa", + "EventTimestamp": "2025-12-17T01:31:50.527Z", + "ParentId": "c4ca4238a0b92382", + "CallbackSucceededDetails": { + "Result": { + "Payload": "{\"data\":\"completed\"}" + } + } + }, { "EventType": "InvocationCompleted", "EventId": 7, - "EventTimestamp": "2025-12-10T00:15:08.718Z", + "EventTimestamp": "2025-12-17T01:31:50.578Z", "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-10T00:15:08.608Z", - "EndTimestamp": "2025-12-10T00:15:08.718Z", + "StartTimestamp": "2025-12-17T01:31:50.517Z", + "EndTimestamp": "2025-12-17T01:31:50.578Z", "Error": {}, - "RequestId": "2b3250a6-0803-44d8-bab2-ce40cdb66d85" + "RequestId": "a747a496-11e1-4009-bdaf-285de8e60d13" } }, { @@ -82,7 +82,7 @@ "EventId": 8, "Id": "c4ca4238a0b92382", "Name": "retry-submitter-callback", - "EventTimestamp": "2025-12-10T00:15:08.760Z", + "EventTimestamp": "2025-12-17T01:31:50.582Z", "ContextSucceededDetails": { "Result": { "Payload": "\"{\\\"data\\\":\\\"completed\\\"}\"" @@ -92,19 +92,19 @@ { "EventType": "InvocationCompleted", "EventId": 9, - "EventTimestamp": "2025-12-10T00:15:08.760Z", + "EventTimestamp": "2025-12-17T01:31:50.582Z", "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-10T00:15:08.737Z", - "EndTimestamp": "2025-12-10T00:15:08.760Z", + "StartTimestamp": "2025-12-17T01:31:50.580Z", + "EndTimestamp": "2025-12-17T01:31:50.582Z", "Error": {}, - "RequestId": "80e9ce8f-15e1-4ac6-b75f-f2efe9b7bec9" + "RequestId": "c642bd7d-cee1-4fee-b5fd-f93034a95ab0" } }, { "EventType": "ExecutionSucceeded", "EventId": 10, - "Id": "e2067af3-c418-4d3b-96df-a5ca4e117a49", - "EventTimestamp": "2025-12-10T00:15:08.761Z", + "Id": "86de452a-714e-4bf4-b77b-89871388873f", + "EventTimestamp": "2025-12-17T01:31:50.582Z", "ExecutionSucceededDetails": { "Result": { "Payload": "{\"result\":\"{\\\"data\\\":\\\"completed\\\"}\",\"success\":true}" diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/submitter-retry-success/wait-for-callback-submitter-retry-success.test.ts b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/submitter-retry-success/wait-for-callback-submitter-retry-success.test.ts index 4d964ada..1d1ab4cf 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/submitter-retry-success/wait-for-callback-submitter-retry-success.test.ts +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/submitter-retry-success/wait-for-callback-submitter-retry-success.test.ts @@ -13,7 +13,7 @@ createTests({ const executionPromise = runner.run({ payload: { shouldFail: false } }); const waitForCallbackOp = runner.getOperationByIndex(0); - await waitForCallbackOp.waitForData(WaitingOperationStatus.STARTED); + await waitForCallbackOp.waitForData(WaitingOperationStatus.SUBMITTED); await waitForCallbackOp.sendCallbackSuccess( JSON.stringify({ data: "completed" }), ); @@ -25,7 +25,7 @@ createTests({ success: true, }); - assertEventSignatures(execution); + assertEventSignatures(execution, "success"); }); it("should fail after exhausting retries when submitter always fails", async () => { @@ -34,6 +34,8 @@ createTests({ const error = execution.getError(); expect(error).toBeDefined(); expect(error?.errorMessage).toContain("Simulated submitter failure"); + + assertEventSignatures(execution, "failure"); }); }, }); diff --git a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/timeout/wait-for-callback-timeout.history.json b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/timeout/wait-for-callback-timeout.history.json index 56e01aac..f6fbbe07 100644 --- a/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/timeout/wait-for-callback-timeout.history.json +++ b/packages/aws-durable-execution-sdk-js-examples/src/examples/wait-for-callback/timeout/wait-for-callback-timeout.history.json @@ -2,8 +2,8 @@ { "EventType": "ExecutionStarted", "EventId": 1, - "Id": "e1121610-07ff-4850-8c04-b98532a3bee4", - "EventTimestamp": "2025-12-10T00:12:28.109Z", + "Id": "006ef00e-e1c5-416a-a4f4-a5efd4240928", + "EventTimestamp": "2025-12-17T01:25:49.079Z", "ExecutionStartedDetails": { "Input": { "Payload": "{\"test\":\"timeout-scenario\"}" @@ -15,7 +15,7 @@ "SubType": "WaitForCallback", "EventId": 2, "Id": "c4ca4238a0b92382", - "EventTimestamp": "2025-12-10T00:12:28.114Z", + "EventTimestamp": "2025-12-17T01:25:49.083Z", "ContextStartedDetails": {} }, { @@ -23,10 +23,10 @@ "SubType": "Callback", "EventId": 3, "Id": "ea66c06c1e1c05fa", - "EventTimestamp": "2025-12-10T00:12:28.114Z", + "EventTimestamp": "2025-12-17T01:25:49.083Z", "ParentId": "c4ca4238a0b92382", "CallbackStartedDetails": { - "CallbackId": "eyJleGVjdXRpb25JZCI6ImYwNmZjMDU5LWI5NTEtNDllNS05YTUwLWM5OWRmZTNhYjJjNCIsIm9wZXJhdGlvbklkIjoiZWE2NmMwNmMxZTFjMDVmYSIsInRva2VuIjoiYjE4MGEzN2EtMDdjMC00MDQ4LTlmZjktMzNiODlkNTJhNDU1In0=", + "CallbackId": "eyJleGVjdXRpb25JZCI6Ijg3M2E2NDY0LWZmYTQtNDQ1YS1hZWFmLTY0MjU2ZWZmZWY1MSIsIm9wZXJhdGlvbklkIjoiZWE2NmMwNmMxZTFjMDVmYSIsInRva2VuIjoiMmJkNGQ1YWItM2M0Zi00YjViLTg3YjgtZGI5NWNkOWJjYjUzIn0=", "Timeout": 1, "Input": {} } @@ -36,7 +36,7 @@ "SubType": "Step", "EventId": 4, "Id": "98c6f2c2287f4c73", - "EventTimestamp": "2025-12-10T00:12:28.116Z", + "EventTimestamp": "2025-12-17T01:25:49.085Z", "ParentId": "c4ca4238a0b92382", "StepStartedDetails": {} }, @@ -45,7 +45,7 @@ "SubType": "Step", "EventId": 5, "Id": "98c6f2c2287f4c73", - "EventTimestamp": "2025-12-10T00:12:28.116Z", + "EventTimestamp": "2025-12-17T01:25:49.086Z", "ParentId": "c4ca4238a0b92382", "StepSucceededDetails": { "Result": {}, @@ -55,12 +55,12 @@ { "EventType": "InvocationCompleted", "EventId": 6, - "EventTimestamp": "2025-12-10T00:12:28.168Z", + "EventTimestamp": "2025-12-17T01:25:49.136Z", "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-10T00:12:28.109Z", - "EndTimestamp": "2025-12-10T00:12:28.168Z", + "StartTimestamp": "2025-12-17T01:25:49.079Z", + "EndTimestamp": "2025-12-17T01:25:49.136Z", "Error": {}, - "RequestId": "e6aceb7f-54ec-457b-bf82-38c62b68c8ab" + "RequestId": "fce1a131-085e-4973-9056-4077b83d4783" } }, { @@ -68,7 +68,7 @@ "SubType": "Callback", "EventId": 7, "Id": "ea66c06c1e1c05fa", - "EventTimestamp": "2025-12-10T00:12:29.115Z", + "EventTimestamp": "2025-12-17T01:25:50.087Z", "ParentId": "c4ca4238a0b92382", "CallbackTimedOutDetails": { "Error": { @@ -83,7 +83,7 @@ "SubType": "WaitForCallback", "EventId": 8, "Id": "c4ca4238a0b92382", - "EventTimestamp": "2025-12-10T00:12:29.119Z", + "EventTimestamp": "2025-12-17T01:25:50.093Z", "ContextFailedDetails": { "Error": { "Payload": { @@ -96,19 +96,19 @@ { "EventType": "InvocationCompleted", "EventId": 9, - "EventTimestamp": "2025-12-10T00:12:29.119Z", + "EventTimestamp": "2025-12-17T01:25:50.094Z", "InvocationCompletedDetails": { - "StartTimestamp": "2025-12-10T00:12:29.117Z", - "EndTimestamp": "2025-12-10T00:12:29.119Z", + "StartTimestamp": "2025-12-17T01:25:50.090Z", + "EndTimestamp": "2025-12-17T01:25:50.094Z", "Error": {}, - "RequestId": "b40a9b97-60fe-4a61-97cf-6cf8c8b9d72a" + "RequestId": "4cad9d93-a742-44ef-9198-776704bf513a" } }, { "EventType": "ExecutionSucceeded", "EventId": 10, - "Id": "e1121610-07ff-4850-8c04-b98532a3bee4", - "EventTimestamp": "2025-12-10T00:12:29.119Z", + "Id": "006ef00e-e1c5-416a-a4f4-a5efd4240928", + "EventTimestamp": "2025-12-17T01:25:50.094Z", "ExecutionSucceededDetails": { "Result": { "Payload": "{\"success\":false,\"error\":\"Callback timed out\"}"