Skip to content

Commit b9438b7

Browse files
committed
chore: add cloud based integration tests for withRetry, add missing resources to template.yml
1 parent f54d8a4 commit b9438b7

2 files changed

Lines changed: 307 additions & 0 deletions

File tree

examples/src/test/java/software/amazon/lambda/durable/examples/CloudBasedIntegrationTest.java

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -710,6 +710,89 @@ void testComplexFlatMapExample() {
710710
assertTrue(output.contains("reason=MIN_SUCCESSFUL_REACHED"));
711711
}
712712

713+
@Test
714+
void testRetryInvokeExample() {
715+
var runner = CloudDurableTestRunner.create(
716+
arn("retry-invoke-example"), GreetingRequest.class, String.class, lambdaClient);
717+
// The handler invokes "simple-step-example" + input.getName() + ":$LATEST",
718+
// so passing the functionNameSuffix as the name targets the deployed simple-step-example function
719+
var result = runner.run(new GreetingRequest(functionNameSuffix));
720+
721+
assertEquals(ExecutionStatus.SUCCEEDED, result.getStatus());
722+
assertNotNull(result.getResult());
723+
}
724+
725+
@Test
726+
void testRetryWaitForCallbackExampleSucceeds() {
727+
var runner = CloudDurableTestRunner.create(
728+
arn("retry-wait-for-callback-example"), ApprovalRequest.class, String.class, lambdaClient);
729+
730+
var execution = runner.startAsync(new ApprovalRequest("Server upgrade", 5000.0));
731+
732+
// Wait for the first callback from attempt 1
733+
execution.pollUntil(exec -> exec.hasCallback("approval-1-callback"));
734+
var callbackId = execution.getCallbackId("approval-1-callback");
735+
assertNotNull(callbackId);
736+
737+
// Complete the callback on the first attempt
738+
execution.completeCallback(callbackId, "\"approved\"");
739+
740+
var result = execution.pollUntilComplete();
741+
assertEquals(ExecutionStatus.SUCCEEDED, result.getStatus());
742+
743+
var finalResult = result.getResult();
744+
assertNotNull(finalResult);
745+
assertTrue(finalResult.contains("Approval for: Server upgrade"));
746+
assertTrue(finalResult.contains("5000"));
747+
assertTrue(finalResult.contains("approved"));
748+
749+
// Verify operations
750+
assertNotNull(execution.getOperation("prepare"));
751+
assertNotNull(execution.getOperation("process-result"));
752+
}
753+
754+
@Test
755+
void testRetryWaitForCallbackExampleRetriesAfterFailure() {
756+
var runner = CloudDurableTestRunner.create(
757+
arn("retry-wait-for-callback-example"), ApprovalRequest.class, String.class, lambdaClient);
758+
759+
var execution = runner.startAsync(new ApprovalRequest("Expensive item", 10000.0));
760+
761+
// Wait for the first callback from attempt 1
762+
execution.pollUntil(exec -> exec.hasCallback("approval-1-callback"));
763+
var callbackId1 = execution.getCallbackId("approval-1-callback");
764+
assertNotNull(callbackId1);
765+
766+
// Fail the first attempt
767+
execution.failCallback(
768+
callbackId1,
769+
ErrorObject.builder()
770+
.errorType("Rejected")
771+
.errorMessage("denied by reviewer")
772+
.build());
773+
774+
// Wait for the second callback from attempt 2 (after backoff)
775+
execution.pollUntil(exec -> exec.hasCallback("approval-2-callback"));
776+
var callbackId2 = execution.getCallbackId("approval-2-callback");
777+
assertNotNull(callbackId2);
778+
779+
// Complete the second attempt
780+
execution.completeCallback(callbackId2, "\"approved on retry\"");
781+
782+
var result = execution.pollUntilComplete();
783+
assertEquals(ExecutionStatus.SUCCEEDED, result.getStatus());
784+
785+
var finalResult = result.getResult();
786+
assertNotNull(finalResult);
787+
assertTrue(finalResult.contains("Approval for: Expensive item"));
788+
assertTrue(finalResult.contains("10000"));
789+
assertTrue(finalResult.contains("approved on retry"));
790+
791+
// Verify operations
792+
assertNotNull(execution.getOperation("prepare"));
793+
assertNotNull(execution.getOperation("process-result"));
794+
}
795+
713796
@Test
714797
void testWaitForConditionExample() {
715798
var runner = CloudDurableTestRunner.create(

examples/template.yaml

Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,186 @@ Resources:
432432
- lambda:GetDurableExecutionState
433433
Resource: !Sub "arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:concurrent-wait-for-condition-example-${JavaVersion}-runtime"
434434

435+
RetryWaitForCallbackExampleFunction:
436+
Type: AWS::Serverless::Function
437+
Properties:
438+
FunctionName: !Join
439+
- '-'
440+
- - 'retry-wait-for-callback-example'
441+
- !Ref JavaVersion
442+
- runtime
443+
Handler: "software.amazon.lambda.durable.examples.callback.RetryWaitForCallbackExample"
444+
Policies:
445+
- Statement:
446+
- Effect: Allow
447+
Action:
448+
- lambda:CheckpointDurableExecutions
449+
- lambda:GetDurableExecutionState
450+
Resource: !Sub "arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:retry-wait-for-callback-example-${JavaVersion}-runtime"
451+
452+
WaitForCallbackFailedExampleFunction:
453+
Type: AWS::Serverless::Function
454+
Properties:
455+
FunctionName: !Join
456+
- '-'
457+
- - 'wait-for-callback-failed-example'
458+
- !Ref JavaVersion
459+
- runtime
460+
Handler: "software.amazon.lambda.durable.examples.callback.WaitForCallbackFailedExample"
461+
Policies:
462+
- Statement:
463+
- Effect: Allow
464+
Action:
465+
- lambda:CheckpointDurableExecutions
466+
- lambda:GetDurableExecutionState
467+
Resource: !Sub "arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:wait-for-callback-failed-example-${JavaVersion}-runtime"
468+
469+
CustomPollingExampleFunction:
470+
Type: AWS::Serverless::Function
471+
Properties:
472+
FunctionName: !Join
473+
- '-'
474+
- - 'custom-polling-example'
475+
- !Ref JavaVersion
476+
- runtime
477+
Handler: "software.amazon.lambda.durable.examples.general.CustomPollingExample"
478+
Policies:
479+
- Statement:
480+
- Effect: Allow
481+
Action:
482+
- lambda:CheckpointDurableExecutions
483+
- lambda:GetDurableExecutionState
484+
- lambda:InvokeFunction
485+
Resource: !Sub "arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:custom-polling-example-${JavaVersion}-runtime"
486+
- Effect: Allow
487+
Action:
488+
- lambda:InvokeFunction
489+
Resource: '*'
490+
491+
RetryInvokeExampleFunction:
492+
Type: AWS::Serverless::Function
493+
Properties:
494+
FunctionName: !Join
495+
- '-'
496+
- - 'retry-invoke-example'
497+
- !Ref JavaVersion
498+
- runtime
499+
Handler: "software.amazon.lambda.durable.examples.invoke.RetryInvokeExample"
500+
Policies:
501+
- Statement:
502+
- Effect: Allow
503+
Action:
504+
- lambda:CheckpointDurableExecutions
505+
- lambda:GetDurableExecutionState
506+
- lambda:InvokeFunction
507+
Resource: !Sub "arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:retry-invoke-example-${JavaVersion}-runtime"
508+
- Effect: Allow
509+
Action:
510+
- lambda:InvokeFunction
511+
Resource: '*'
512+
513+
DeserializationFailedMapExampleFunction:
514+
Type: AWS::Serverless::Function
515+
Properties:
516+
FunctionName: !Join
517+
- '-'
518+
- - 'deserialization-failed-map-example'
519+
- !Ref JavaVersion
520+
- runtime
521+
Handler: "software.amazon.lambda.durable.examples.map.DeserializationFailedMapExample"
522+
Policies:
523+
- Statement:
524+
- Effect: Allow
525+
Action:
526+
- lambda:CheckpointDurableExecutions
527+
- lambda:GetDurableExecutionState
528+
Resource: !Sub "arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:deserialization-failed-map-example-${JavaVersion}-runtime"
529+
530+
ParallelExampleFunction:
531+
Type: AWS::Serverless::Function
532+
Properties:
533+
FunctionName: !Join
534+
- '-'
535+
- - 'parallel-example'
536+
- !Ref JavaVersion
537+
- runtime
538+
Handler: "software.amazon.lambda.durable.examples.parallel.ParallelExample"
539+
Policies:
540+
- Statement:
541+
- Effect: Allow
542+
Action:
543+
- lambda:CheckpointDurableExecutions
544+
- lambda:GetDurableExecutionState
545+
Resource: !Sub "arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:parallel-example-${JavaVersion}-runtime"
546+
547+
ParallelFailureToleranceExampleFunction:
548+
Type: AWS::Serverless::Function
549+
Properties:
550+
FunctionName: !Join
551+
- '-'
552+
- - 'parallel-failure-tolerance-example'
553+
- !Ref JavaVersion
554+
- runtime
555+
Handler: "software.amazon.lambda.durable.examples.parallel.ParallelFailureToleranceExample"
556+
Policies:
557+
- Statement:
558+
- Effect: Allow
559+
Action:
560+
- lambda:CheckpointDurableExecutions
561+
- lambda:GetDurableExecutionState
562+
Resource: !Sub "arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:parallel-failure-tolerance-example-${JavaVersion}-runtime"
563+
564+
ParallelWithWaitExampleFunction:
565+
Type: AWS::Serverless::Function
566+
Properties:
567+
FunctionName: !Join
568+
- '-'
569+
- - 'parallel-with-wait-example'
570+
- !Ref JavaVersion
571+
- runtime
572+
Handler: "software.amazon.lambda.durable.examples.parallel.ParallelWithWaitExample"
573+
Policies:
574+
- Statement:
575+
- Effect: Allow
576+
Action:
577+
- lambda:CheckpointDurableExecutions
578+
- lambda:GetDurableExecutionState
579+
Resource: !Sub "arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:parallel-with-wait-example-${JavaVersion}-runtime"
580+
581+
DeserializationFailedParallelExampleFunction:
582+
Type: AWS::Serverless::Function
583+
Properties:
584+
FunctionName: !Join
585+
- '-'
586+
- - 'deserialization-failed-parallel-example'
587+
- !Ref JavaVersion
588+
- runtime
589+
Handler: "software.amazon.lambda.durable.examples.parallel.DeserializationFailedParallelExample"
590+
Policies:
591+
- Statement:
592+
- Effect: Allow
593+
Action:
594+
- lambda:CheckpointDurableExecutions
595+
- lambda:GetDurableExecutionState
596+
Resource: !Sub "arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:deserialization-failed-parallel-example-${JavaVersion}-runtime"
597+
598+
DeserializationFailureExampleFunction:
599+
Type: AWS::Serverless::Function
600+
Properties:
601+
FunctionName: !Join
602+
- '-'
603+
- - 'deserialization-failure-example'
604+
- !Ref JavaVersion
605+
- runtime
606+
Handler: "software.amazon.lambda.durable.examples.step.DeserializationFailureExample"
607+
Policies:
608+
- Statement:
609+
- Effect: Allow
610+
Action:
611+
- lambda:CheckpointDurableExecutions
612+
- lambda:GetDurableExecutionState
613+
Resource: !Sub "arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:deserialization-failure-example-${JavaVersion}-runtime"
614+
435615
ManyAsyncStepsVirtualThreadPoolExampleFunction:
436616
Type: AWS::Serverless::Function
437617
Condition: IsJava21OrLater
@@ -515,6 +695,10 @@ Outputs:
515695
Description: Child Context Example Function ARN
516696
Value: !GetAtt ChildContextExampleFunction.Arn
517697

698+
VirtualChildContextExampleFunction:
699+
Description: Virtual Child Context Example Function ARN
700+
Value: !GetAtt VirtualChildContextExampleFunction.Arn
701+
518702
WaitAsyncExampleFunction:
519703
Description: Wait Async Example Function ARN
520704
Value: !GetAtt WaitAsyncExampleFunction.Arn
@@ -543,6 +727,46 @@ Outputs:
543727
Description: Concurrent Wait For Condition Example Function ARN
544728
Value: !GetAtt ConcurrentWaitForConditionExampleFunction.Arn
545729

730+
RetryWaitForCallbackExampleFunction:
731+
Description: Retry Wait For Callback Example Function ARN
732+
Value: !GetAtt RetryWaitForCallbackExampleFunction.Arn
733+
734+
WaitForCallbackFailedExampleFunction:
735+
Description: Wait For Callback Failed Example Function ARN
736+
Value: !GetAtt WaitForCallbackFailedExampleFunction.Arn
737+
738+
CustomPollingExampleFunction:
739+
Description: Custom Polling Example Function ARN
740+
Value: !GetAtt CustomPollingExampleFunction.Arn
741+
742+
RetryInvokeExampleFunction:
743+
Description: Retry Invoke Example Function ARN
744+
Value: !GetAtt RetryInvokeExampleFunction.Arn
745+
746+
DeserializationFailedMapExampleFunction:
747+
Description: Deserialization Failed Map Example Function ARN
748+
Value: !GetAtt DeserializationFailedMapExampleFunction.Arn
749+
750+
ParallelExampleFunction:
751+
Description: Parallel Example Function ARN
752+
Value: !GetAtt ParallelExampleFunction.Arn
753+
754+
ParallelFailureToleranceExampleFunction:
755+
Description: Parallel Failure Tolerance Example Function ARN
756+
Value: !GetAtt ParallelFailureToleranceExampleFunction.Arn
757+
758+
ParallelWithWaitExampleFunction:
759+
Description: Parallel With Wait Example Function ARN
760+
Value: !GetAtt ParallelWithWaitExampleFunction.Arn
761+
762+
DeserializationFailedParallelExampleFunction:
763+
Description: Deserialization Failed Parallel Example Function ARN
764+
Value: !GetAtt DeserializationFailedParallelExampleFunction.Arn
765+
766+
DeserializationFailureExampleFunction:
767+
Description: Deserialization Failure Example Function ARN
768+
Value: !GetAtt DeserializationFailureExampleFunction.Arn
769+
546770
ManyAsyncStepsVirtualThreadPoolExampleFunction:
547771
Condition: IsJava21OrLater
548772
Description: Many Async Steps Virtual Thread Pool Example Function ARN

0 commit comments

Comments
 (0)