22// SPDX-License-Identifier: Apache-2.0
33package software .amazon .lambda .durable ;
44
5- import static org .junit .jupiter .api .Assertions .* ;
5+ import static org .junit .jupiter .api .Assertions .assertEquals ;
66
77import java .util .concurrent .atomic .AtomicInteger ;
88import org .junit .jupiter .api .Test ;
@@ -18,29 +18,6 @@ class StepSemanticsIntegrationTest {
1818 void testAtLeastOnceCompletesSuccessfully () {
1919 var executionCount = new AtomicInteger (0 );
2020
21- var runner = LocalDurableTestRunner .create (
22- String .class ,
23- (input , ctx ) -> ctx .step (
24- "my-step" ,
25- String .class ,
26- stepCtx -> {
27- executionCount .incrementAndGet ();
28- return "result" ;
29- },
30- StepConfig .builder ()
31- .semantics (StepSemantics .AT_LEAST_ONCE_PER_RETRY )
32- .build ()));
33-
34- var result = runner .run ("test-input" );
35-
36- assertEquals (ExecutionStatus .SUCCEEDED , result .getStatus ());
37- assertEquals (1 , executionCount .get ());
38- }
39-
40- @ Test
41- void testSemanticsPerRetry_atLeastOnceCompletesSuccessfully () {
42- var executionCount = new AtomicInteger (0 );
43-
4421 var runner = LocalDurableTestRunner .create (
4522 String .class ,
4623 (input , ctx ) -> ctx .step (
@@ -64,29 +41,6 @@ void testSemanticsPerRetry_atLeastOnceCompletesSuccessfully() {
6441 void testAtMostOnceCompletesSuccessfully () {
6542 var executionCount = new AtomicInteger (0 );
6643
67- var runner = LocalDurableTestRunner .create (
68- String .class ,
69- (input , ctx ) -> ctx .step (
70- "my-step" ,
71- String .class ,
72- stepCtx -> {
73- executionCount .incrementAndGet ();
74- return "result" ;
75- },
76- StepConfig .builder ()
77- .semantics (StepSemantics .AT_MOST_ONCE_PER_RETRY )
78- .build ()));
79-
80- var result = runner .run ("test-input" );
81-
82- assertEquals (ExecutionStatus .SUCCEEDED , result .getStatus ());
83- assertEquals (1 , executionCount .get ());
84- }
85-
86- @ Test
87- void testSemanticsPerRetry_atMostOnceCompletesSuccessfully () {
88- var executionCount = new AtomicInteger (0 );
89-
9044 var runner = LocalDurableTestRunner .create (
9145 String .class ,
9246 (input , ctx ) -> ctx .step (
@@ -110,30 +64,6 @@ void testSemanticsPerRetry_atMostOnceCompletesSuccessfully() {
11064 void testAtMostOnceNoRetryFailsImmediately () {
11165 var executionCount = new AtomicInteger (0 );
11266
113- var runner = LocalDurableTestRunner .create (
114- String .class ,
115- (input , ctx ) -> ctx .step (
116- "my-step" ,
117- String .class ,
118- stepCtx -> {
119- executionCount .incrementAndGet ();
120- throw new RuntimeException ("Always fails" );
121- },
122- StepConfig .builder ()
123- .semantics (StepSemantics .AT_MOST_ONCE_PER_RETRY )
124- .retryStrategy (RetryStrategies .Presets .NO_RETRY )
125- .build ()));
126-
127- var result = runner .run ("test-input" );
128-
129- assertEquals (ExecutionStatus .FAILED , result .getStatus ());
130- assertEquals (1 , executionCount .get ());
131- }
132-
133- @ Test
134- void testSemanticsPerRetry_atMostOnceNoRetryFailsImmediately () {
135- var executionCount = new AtomicInteger (0 );
136-
13767 var runner = LocalDurableTestRunner .create (
13868 String .class ,
13969 (input , ctx ) -> ctx .step (
@@ -155,7 +85,7 @@ void testSemanticsPerRetry_atMostOnceNoRetryFailsImmediately() {
15585 }
15686
15787 @ Test
158- void testDefaultSemanticsIsAtLeastOnce () {
88+ void testDefaultSemanticsPerRetryIsAtLeastOnce () {
15989 var executionCount = new AtomicInteger (0 );
16090
16191 var runner = LocalDurableTestRunner .create (
@@ -175,46 +105,18 @@ void testDefaultSemanticsIsAtLeastOnce() {
175105 void testAtLeastOnceReExecutesAfterCheckpointLoss () {
176106 var executionCount = new AtomicInteger (0 );
177107
178- var runner = LocalDurableTestRunner .create (String .class , (input , context ) -> {
179- return context .step (
180- "step" ,
181- String .class ,
182- stepCtx -> {
183- var count = executionCount .incrementAndGet ();
184- return "Executed " + count + " times" ;
185- },
186- StepConfig .builder ()
187- .semantics (StepSemantics .AT_LEAST_ONCE_PER_RETRY )
188- .build ());
189- });
190-
191- runner .run ("test" );
192- assertEquals (1 , executionCount .get ());
193-
194- runner .simulateFireAndForgetCheckpointLoss ("step" );
195-
196- var result = runner .run ("test" );
197-
198- assertEquals (ExecutionStatus .SUCCEEDED , result .getStatus ());
199- assertEquals (2 , executionCount .get ());
200- }
201-
202- @ Test
203- void testSemanticsPerRetry_atLeastOnceReExecutesAfterCheckpointLoss () {
204- var executionCount = new AtomicInteger (0 );
205-
206- var runner = LocalDurableTestRunner .create (String .class , (input , context ) -> {
207- return context .step (
208- "step" ,
209- String .class ,
210- stepCtx -> {
211- var count = executionCount .incrementAndGet ();
212- return "Executed " + count + " times" ;
213- },
214- StepConfig .builder ()
215- .semanticsPerRetry (StepSemantics .AT_LEAST_ONCE_PER_RETRY )
216- .build ());
217- });
108+ var runner = LocalDurableTestRunner .create (
109+ String .class ,
110+ (input , context ) -> context .step (
111+ "step" ,
112+ String .class ,
113+ stepCtx -> {
114+ var count = executionCount .incrementAndGet ();
115+ return "Executed " + count + " times" ;
116+ },
117+ StepConfig .builder ()
118+ .semanticsPerRetry (StepSemantics .AT_LEAST_ONCE_PER_RETRY )
119+ .build ()));
218120
219121 runner .run ("test" );
220122 assertEquals (1 , executionCount .get ());
@@ -231,45 +133,18 @@ void testSemanticsPerRetry_atLeastOnceReExecutesAfterCheckpointLoss() {
231133 void testAtLeastOnceReExecutesAfterCheckpointFailure () {
232134 var executionCount = new AtomicInteger (0 );
233135
234- var runner = LocalDurableTestRunner .create (String .class , (input , context ) -> {
235- return context .step (
236- "step" ,
237- String .class ,
238- stepCtx -> {
239- var count = executionCount .incrementAndGet ();
240- return "Executed " + count + " times" ;
241- },
242- StepConfig .builder ()
243- .semantics (StepSemantics .AT_LEAST_ONCE_PER_RETRY )
244- .build ());
245- });
246-
247- runner .run ("test" );
248- assertEquals (1 , executionCount .get ());
249-
250- runner .resetCheckpointToStarted ("step" );
251- var result = runner .runUntilComplete ("test" );
252-
253- assertEquals (ExecutionStatus .SUCCEEDED , result .getStatus ());
254- assertEquals (2 , executionCount .get ());
255- }
256-
257- @ Test
258- void testSemanticsPerRetry_atLeastOnceReExecutesAfterCheckpointFailure () {
259- var executionCount = new AtomicInteger (0 );
260-
261- var runner = LocalDurableTestRunner .create (String .class , (input , context ) -> {
262- return context .step (
263- "step" ,
264- String .class ,
265- stepCtx -> {
266- var count = executionCount .incrementAndGet ();
267- return "Executed " + count + " times" ;
268- },
269- StepConfig .builder ()
270- .semanticsPerRetry (StepSemantics .AT_LEAST_ONCE_PER_RETRY )
271- .build ());
272- });
136+ var runner = LocalDurableTestRunner .create (
137+ String .class ,
138+ (input , context ) -> context .step (
139+ "step" ,
140+ String .class ,
141+ stepCtx -> {
142+ var count = executionCount .incrementAndGet ();
143+ return "Executed " + count + " times" ;
144+ },
145+ StepConfig .builder ()
146+ .semanticsPerRetry (StepSemantics .AT_LEAST_ONCE_PER_RETRY )
147+ .build ()));
273148
274149 runner .run ("test" );
275150 assertEquals (1 , executionCount .get ());
@@ -281,53 +156,22 @@ void testSemanticsPerRetry_atLeastOnceReExecutesAfterCheckpointFailure() {
281156 assertEquals (2 , executionCount .get ());
282157 }
283158
284- // This behavior is incorrect (the step should retry after interruption), but is kept for backward
285- // compatibility. The deprecated StepConfig.semantics() method preserves this behavior.
286- // Use StepConfig.semanticsPerRetry() for the corrected behavior (see below test).
287159 @ Test
288- void testAtMostOnceThrowsExceptionAfterCheckpointFailure_deprecatedBackwardCompatibility () {
160+ void testAtMostOnceRetriesAfterInterruption () {
289161 var executionCount = new AtomicInteger (0 );
290162
291- var runner = LocalDurableTestRunner .create (String .class , (input , context ) -> {
292- return context .step (
293- "step" ,
294- String .class ,
295- stepCtx -> {
296- executionCount .incrementAndGet ();
297- return "Should not re-execute" ;
298- },
299- StepConfig .builder ()
300- .semantics (StepSemantics .AT_MOST_ONCE_PER_RETRY )
301- .build ());
302- });
303-
304- runner .run ("test" );
305- assertEquals (1 , executionCount .get ());
306-
307- runner .resetCheckpointToStarted ("step" );
308-
309- var result = runner .run ("test" );
310-
311- assertEquals (ExecutionStatus .FAILED , result .getStatus ());
312- assertEquals (1 , executionCount .get ());
313- }
314-
315- @ Test
316- void testSemanticsPerRetry_atMostOnceRetriesAfterInterruption () {
317- var executionCount = new AtomicInteger (0 );
318-
319- var runner = LocalDurableTestRunner .create (String .class , (input , context ) -> {
320- return context .step (
321- "step" ,
322- String .class ,
323- stepCtx -> {
324- executionCount .incrementAndGet ();
325- return "result" ;
326- },
327- StepConfig .builder ()
328- .semanticsPerRetry (StepSemantics .AT_MOST_ONCE_PER_RETRY )
329- .build ());
330- });
163+ var runner = LocalDurableTestRunner .create (
164+ String .class ,
165+ (input , context ) -> context .step (
166+ "step" ,
167+ String .class ,
168+ stepCtx -> {
169+ executionCount .incrementAndGet ();
170+ return "result" ;
171+ },
172+ StepConfig .builder ()
173+ .semanticsPerRetry (StepSemantics .AT_MOST_ONCE_PER_RETRY )
174+ .build ()));
331175
332176 runner .run ("test" );
333177 assertEquals (1 , executionCount .get ());
0 commit comments