From db42970e5f035eb86eb2e632304285db2c4f1f48 Mon Sep 17 00:00:00 2001 From: Jerome Van Der Linden Date: Wed, 2 Dec 2020 16:43:06 +0100 Subject: [PATCH 1/6] test module --- aws-lambda-java-tests/README.md | 198 ++++++++++++ aws-lambda-java-tests/pom.xml | 97 ++++++ .../runtime/tests/EventArgumentsProvider.java | 29 ++ .../lambda/runtime/tests/EventLoader.java | 124 ++++++++ .../runtime/tests/EventLoadingException.java | 18 ++ .../tests/EventsArgumentsProvider.java | 52 ++++ .../tests/HandlerParamsArgumentsProvider.java | 130 ++++++++ .../runtime/tests/annotations/Event.java | 39 +++ .../runtime/tests/annotations/Events.java | 81 +++++ .../tests/annotations/HandlerParams.java | 63 ++++ .../runtime/tests/annotations/Response.java | 25 ++ .../runtime/tests/annotations/Responses.java | 31 ++ .../lambda/runtime/tests/EventLoaderTest.java | 293 ++++++++++++++++++ .../lambda/runtime/tests/EventTest.java | 18 ++ .../lambda/runtime/tests/EventsTest.java | 45 +++ .../runtime/tests/HandlerParamsTest.java | 71 +++++ .../resources/apigw/events/apigw_event.json | 62 ++++ .../resources/apigw/events/apigw_event2.json | 62 ++++ .../apigw/responses/apigw_response.json | 16 + .../apigw/responses/apigw_response2.json | 16 + .../src/test/resources/apigw_auth.json | 41 +++ .../src/test/resources/apigw_auth_v2.json | 35 +++ .../src/test/resources/apigw_http_event.json | 69 +++++ .../src/test/resources/apigw_rest_event.json | 80 +++++ .../test/resources/cloudformation_event.json | 24 ++ .../src/test/resources/cloudfront_event.json | 37 +++ .../src/test/resources/cloudwatch_event.json | 15 + .../test/resources/cloudwatchlogs_event.json | 5 + .../src/test/resources/codecommit_event.json | 27 ++ .../src/test/resources/config_event.json | 12 + .../src/test/resources/connect_event.json | 33 ++ .../src/test/resources/dynamo_event.json | 97 ++++++ .../src/test/resources/elb_event.json | 26 ++ .../src/test/resources/firehose_event.json | 12 + .../src/test/resources/kafka_event.json | 16 + .../src/test/resources/kinesis_event.json | 21 ++ .../resources/lambda_destination_event.json | 23 ++ .../src/test/resources/lex_event.json | 24 ++ .../src/test/resources/s3_event.json | 38 +++ .../resources/secrets_rotation_event.json | 5 + .../src/test/resources/sns_event.json | 27 ++ .../src/test/resources/sqs/sqs_event.json | 22 ++ .../src/test/resources/sqs/sqs_event2.json | 22 ++ 43 files changed, 2181 insertions(+) create mode 100644 aws-lambda-java-tests/README.md create mode 100644 aws-lambda-java-tests/pom.xml create mode 100644 aws-lambda-java-tests/src/main/java/com/amazonaws/services/lambda/runtime/tests/EventArgumentsProvider.java create mode 100644 aws-lambda-java-tests/src/main/java/com/amazonaws/services/lambda/runtime/tests/EventLoader.java create mode 100644 aws-lambda-java-tests/src/main/java/com/amazonaws/services/lambda/runtime/tests/EventLoadingException.java create mode 100644 aws-lambda-java-tests/src/main/java/com/amazonaws/services/lambda/runtime/tests/EventsArgumentsProvider.java create mode 100644 aws-lambda-java-tests/src/main/java/com/amazonaws/services/lambda/runtime/tests/HandlerParamsArgumentsProvider.java create mode 100644 aws-lambda-java-tests/src/main/java/com/amazonaws/services/lambda/runtime/tests/annotations/Event.java create mode 100644 aws-lambda-java-tests/src/main/java/com/amazonaws/services/lambda/runtime/tests/annotations/Events.java create mode 100644 aws-lambda-java-tests/src/main/java/com/amazonaws/services/lambda/runtime/tests/annotations/HandlerParams.java create mode 100644 aws-lambda-java-tests/src/main/java/com/amazonaws/services/lambda/runtime/tests/annotations/Response.java create mode 100644 aws-lambda-java-tests/src/main/java/com/amazonaws/services/lambda/runtime/tests/annotations/Responses.java create mode 100644 aws-lambda-java-tests/src/test/java/com/amazonaws/services/lambda/runtime/tests/EventLoaderTest.java create mode 100644 aws-lambda-java-tests/src/test/java/com/amazonaws/services/lambda/runtime/tests/EventTest.java create mode 100644 aws-lambda-java-tests/src/test/java/com/amazonaws/services/lambda/runtime/tests/EventsTest.java create mode 100644 aws-lambda-java-tests/src/test/java/com/amazonaws/services/lambda/runtime/tests/HandlerParamsTest.java create mode 100644 aws-lambda-java-tests/src/test/resources/apigw/events/apigw_event.json create mode 100644 aws-lambda-java-tests/src/test/resources/apigw/events/apigw_event2.json create mode 100644 aws-lambda-java-tests/src/test/resources/apigw/responses/apigw_response.json create mode 100644 aws-lambda-java-tests/src/test/resources/apigw/responses/apigw_response2.json create mode 100644 aws-lambda-java-tests/src/test/resources/apigw_auth.json create mode 100644 aws-lambda-java-tests/src/test/resources/apigw_auth_v2.json create mode 100644 aws-lambda-java-tests/src/test/resources/apigw_http_event.json create mode 100644 aws-lambda-java-tests/src/test/resources/apigw_rest_event.json create mode 100644 aws-lambda-java-tests/src/test/resources/cloudformation_event.json create mode 100644 aws-lambda-java-tests/src/test/resources/cloudfront_event.json create mode 100644 aws-lambda-java-tests/src/test/resources/cloudwatch_event.json create mode 100644 aws-lambda-java-tests/src/test/resources/cloudwatchlogs_event.json create mode 100644 aws-lambda-java-tests/src/test/resources/codecommit_event.json create mode 100644 aws-lambda-java-tests/src/test/resources/config_event.json create mode 100644 aws-lambda-java-tests/src/test/resources/connect_event.json create mode 100644 aws-lambda-java-tests/src/test/resources/dynamo_event.json create mode 100644 aws-lambda-java-tests/src/test/resources/elb_event.json create mode 100644 aws-lambda-java-tests/src/test/resources/firehose_event.json create mode 100644 aws-lambda-java-tests/src/test/resources/kafka_event.json create mode 100644 aws-lambda-java-tests/src/test/resources/kinesis_event.json create mode 100644 aws-lambda-java-tests/src/test/resources/lambda_destination_event.json create mode 100644 aws-lambda-java-tests/src/test/resources/lex_event.json create mode 100644 aws-lambda-java-tests/src/test/resources/s3_event.json create mode 100644 aws-lambda-java-tests/src/test/resources/secrets_rotation_event.json create mode 100644 aws-lambda-java-tests/src/test/resources/sns_event.json create mode 100644 aws-lambda-java-tests/src/test/resources/sqs/sqs_event.json create mode 100644 aws-lambda-java-tests/src/test/resources/sqs/sqs_event2.json diff --git a/aws-lambda-java-tests/README.md b/aws-lambda-java-tests/README.md new file mode 100644 index 00000000..780717fe --- /dev/null +++ b/aws-lambda-java-tests/README.md @@ -0,0 +1,198 @@ + +# Tests utility + +The `aws-lambda-java-tests` module provides opinionated tools to ease Java Lambda testing. This is a test dependency. + +**Key features** + +* Load events from json files and get them deserialized into Java Events. +* Inject Events directly in JUnit 5 tests, using the `@ParameterizedTest` annotation. + + +## Background + +When using Java for a Lambda function, you must implement the RequestHandler interface and provide input and output types: + +```java +public interface RequestHandler { + public O handleRequest(I input, Context context); +} +``` + +The input is automatically deserialized by the Lambda Java Runtime from a json event into the type you define, +and the output is serialized into JSON from the output type. More info in the [docs](https://docs.aws.amazon.com/lambda/latest/dg/java-handler.html). + +When you want to test your Lambda function and your handleRequest method, you cannot simply use JSON events files +as some of the event fields may not be deserialized correctly. + +For example, an SQS JSON event contains a list of "Records", while the [`SQSEvent`](https://github.com/aws/aws-lambda-java-libs/blob/master/aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/events/SQSEvent.java) use "records" with a lowercase. +You can choose to modify the JSON input but it can be tedious and you generally want to keep the JSON event as you get it +in the doc, the Lambda console or in your logs. + +Now you can use the [aws-lambda-java-serialization](https://github.com/aws/aws-lambda-java-libs/tree/master/aws-lambda-java-serialization) module to deserialize events. And this test library is using this module as a dependency to ease tests of lambda function handlers. + +## Installation + +To install this utility, add the following dependency to your project. Note that it's a test dependency. + +```xml + + com.amazonaws + aws-lambda-java-tests + 1.0.0 + test + +``` + +Also have surefire in your plugins: + +```xml + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.22.2 + + + +``` + +## Usage + +### Events injection + +A set of annotations can be used to inject Events and/or to validate handler responses against those Events. +**All those annotations must be used in conjunction with the [`@ParameterizedTest`](https://junit.org/junit5/docs/current/api/org.junit.jupiter.params/org/junit/jupiter/params/ParameterizedTest.html) annotation from Junit 5.** + +`ParameterizedTest` enables to inject arguments into a unit test, so you can run the same test one or more time with different parameters. +See [the doc](https://junit.org/junit5/docs/current/user-guide/#writing-tests-parameterized-tests) for more details on this. + +**Event** + +The `@Event` annotation permits to inject one Event into a Junit test. + +Example: + +```java +// the json file must be in the classpath (most often in src/test/resources) +@ParameterizedTest +@Event(value = "sqs/sqs_event.json", type = SQSEvent.class) +public void testInjectSQSEvent(SQSEvent event) { + // test your handleRequest method with this event as parameter +} +``` + +**Events** + +The `@Events` annotation permits to inject multiple Events into a Junit test + +Examples: + +```java +@ParameterizedTest +@Events( + events = { + @Event("sqs/sqs_event.json"), + @Event("sqs/sqs_event2.json"), + }, + type = SQSEvent.class +) +public void testInjectEvents(SQSEvent event) { + // test your handleRequest method with all the JSON events available in the sqs folder +} + +// OR simpler + +// sqs folder must be in the classpath (most often in src/test/resources) +@ParameterizedTest +@Events(folder = "sqs", type = SQSEvent.class) +public void testInjectEventsFromFolder(SQSEvent event) { + // test your handleRequest method with all the JSON events available in the sqs folder +} +``` + +**HandlerParams** + +The `@HandlerParams` is the most advanced one as it permits to provide both input and output as arguments to your tests. +Thus you can validate your `handlerRequest` method by providing the output and asserting on the expected output. + +```java + +// Single event +@ParameterizedTest +@HandlerParams( + event = @Event(value = "apigw/events/apigw_event.json", type = APIGatewayProxyRequestEvent.class), + response = @Response(value = "apigw/responses/apigw_response.json", type = APIGatewayProxyResponseEvent.class)) +public void testSingleEventResponse(APIGatewayProxyRequestEvent event, APIGatewayProxyResponseEvent response) { +} + +// Multiple events in folder +@ParameterizedTest +@HandlerParams( + events = @Events(folder = "apigw/events/", type = APIGatewayProxyRequestEvent.class), + responses = @Responses(folder = "apigw/responses/", type = APIGatewayProxyResponseEvent.class)) +public void testMultipleEventsResponsesInFolder(APIGatewayProxyRequestEvent event, APIGatewayProxyResponseEvent response) { +} + +// Multiple events +@HandlerParams( + events = @Events( + events = { + @Event("apigw/events/apigw_event.json"), + @Event("apigw/events/apigw_event2.json"), + }, + type = APIGatewayProxyRequestEvent.class + ), + responses = @Responses( + responses = { + @Response("apigw/responses/apigw_response.json"), + @Response("apigw/responses/apigw_response2.json") + }, + type = APIGatewayProxyResponseEvent.class + ) +) +public void testMultipleEventsResponses(APIGatewayProxyRequestEvent event, APIGatewayProxyResponseEvent response) { +} +``` + +If you cannot use those annotations (for example if you use TestNG), or if you want to load the events on your own, you can directly use the `EventLoader`, which is the underlying class that load the json events. + +### EventLoader + +`EventLoader` enables to load any Event from a JSON file and deserialize it into a Java Object. +Either one from the [aws-lambda-java-events](https://github.com/aws/aws-lambda-java-libs/tree/master/aws-lambda-java-events) library +or your own Event. + +EventLoader provides a load method for most of the pre-defined events: + +```java +APIGatewayV2HTTPEvent httpEvent = + EventLoader.loadApiGatewayHttpEvent("apigw_http_event.json"); + +APIGatewayProxyRequestEvent restEvent = + EventLoader.loadApiGatewayRestEvent("apigw_rest_event.json"); + +DynamodbEvent ddbEvent = EventLoader.loadDynamoDbEvent("ddb_event.json"); + +KinesisEvent kinesisEvent = + EventLoader.loadKinesisEvent("kinesis_event.json"); + +ScheduledEvent eventBridgeEvent = + EventLoader.loadScheduledEvent("eb_event.json"); + +S3Event s3Event = EventLoader.loadS3Event("s3_event.json"); + +SNSEvent snsEvent = EventLoader.loadSNSEvent("sns_event.json"); + +SQSEvent sqsEvent = EventLoader.loadSQSEvent("sqs_event.json"); + +// ... and many others +``` + +Or you can load what you prefer with the generic method: + +```java +MyEvent myEvent = EventLoader.loadEvent("my_event.json", MyEvent.class); +``` + diff --git a/aws-lambda-java-tests/pom.xml b/aws-lambda-java-tests/pom.xml new file mode 100644 index 00000000..35febdb2 --- /dev/null +++ b/aws-lambda-java-tests/pom.xml @@ -0,0 +1,97 @@ + + 4.0.0 + + com.amazonaws + aws-lambda-java-tests + 1.0.0 + jar + + AWS Lambda Java Tests + Testing module for the AWS Lambda Java Runtime + https://aws.amazon.com/lambda/ + + + Apache License, Version 2.0 + https://aws.amazon.com/apache2.0 + repo + + + + https://github.com/aws/aws-lambda-java-libs.git + + + + AWS Lambda team + Amazon Web Services + https://aws.amazon.com/ + + + + + 1.8 + 1.8 + UTF-8 + 5.7.0 + + + + + com.amazonaws + aws-lambda-java-serialization + 1.0.0 + + + com.amazonaws + aws-lambda-java-events + 3.6.0 + + + org.junit.jupiter + junit-jupiter-api + ${junit.version} + + + org.junit.jupiter + junit-jupiter-engine + ${junit.version} + + + org.junit.jupiter + junit-jupiter-params + ${junit.version} + + + org.apache.commons + commons-lang3 + 3.11 + + + + org.assertj + assertj-core + 3.18.1 + test + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + ${maven.compiler.source} + ${maven.compiler.target} + false + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.22.2 + + + + \ No newline at end of file diff --git a/aws-lambda-java-tests/src/main/java/com/amazonaws/services/lambda/runtime/tests/EventArgumentsProvider.java b/aws-lambda-java-tests/src/main/java/com/amazonaws/services/lambda/runtime/tests/EventArgumentsProvider.java new file mode 100644 index 00000000..0dec6e6b --- /dev/null +++ b/aws-lambda-java-tests/src/main/java/com/amazonaws/services/lambda/runtime/tests/EventArgumentsProvider.java @@ -0,0 +1,29 @@ +/* Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ +package com.amazonaws.services.lambda.runtime.tests; + +import com.amazonaws.services.lambda.runtime.tests.annotations.Event; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.ArgumentsProvider; +import org.junit.jupiter.params.support.AnnotationConsumer; + +import java.util.stream.Stream; + +/** + * Used to process @{@link Event} com.amazonaws.services.lambda.runtime.tests.annotations + */ +public class EventArgumentsProvider implements ArgumentsProvider, AnnotationConsumer { + + private Event event; + + @Override + public Stream provideArguments(ExtensionContext extensionContext) { + Object o = EventLoader.loadEvent(event.value(), event.type()); + return Stream.of(Arguments.of(o)); + } + + @Override + public void accept(Event event) { + this.event = event; + } +} diff --git a/aws-lambda-java-tests/src/main/java/com/amazonaws/services/lambda/runtime/tests/EventLoader.java b/aws-lambda-java-tests/src/main/java/com/amazonaws/services/lambda/runtime/tests/EventLoader.java new file mode 100644 index 00000000..edec372c --- /dev/null +++ b/aws-lambda-java-tests/src/main/java/com/amazonaws/services/lambda/runtime/tests/EventLoader.java @@ -0,0 +1,124 @@ +/* Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ +package com.amazonaws.services.lambda.runtime.tests; + +import com.amazonaws.services.lambda.runtime.serialization.PojoSerializer; +import com.amazonaws.services.lambda.runtime.serialization.events.LambdaEventSerializers; + +import java.io.*; + +import com.amazonaws.services.lambda.runtime.events.*; + +/** + * Load events from json files and serialize them in Events + */ +public class EventLoader { + public static APIGatewayV2HTTPEvent loadApiGatewayHttpEvent(String filename) { + return loadEvent(filename, APIGatewayV2HTTPEvent.class); + } + + public static APIGatewayProxyRequestEvent loadApiGatewayRestEvent(String filename) { + return loadEvent(filename, APIGatewayProxyRequestEvent.class); + } + + public static APIGatewayCustomAuthorizerEvent loadAPIGatewayCustomAuthorizerEvent(String filename) { + return loadEvent(filename, APIGatewayCustomAuthorizerEvent.class); + } + + public static APIGatewayV2CustomAuthorizerEvent loadAPIGatewayV2CustomAuthorizerEvent(String filename) { + return loadEvent(filename, APIGatewayV2CustomAuthorizerEvent.class); + } + + public static ApplicationLoadBalancerRequestEvent loadApplicationLoadBalancerRequestEvent(String filename) { + return loadEvent(filename, ApplicationLoadBalancerRequestEvent.class); + } + + public static CloudFormationCustomResourceEvent loadCloudFormationCustomResourceEvent(String filename) { + return loadEvent(filename, CloudFormationCustomResourceEvent.class); + } + + public static CloudFrontEvent loadCloudFrontEvent(String filename) { + return loadEvent(filename, CloudFrontEvent.class); + } + + public static CloudWatchLogsEvent loadCloudWatchLogsEvent(String filename) { + return loadEvent(filename, CloudWatchLogsEvent.class); + } + + public static CodeCommitEvent loadCodeCommitEvent(String filename) { + return loadEvent(filename, CodeCommitEvent.class); + } + + public static ConfigEvent loadConfigEvent(String filename) { + return loadEvent(filename, ConfigEvent.class); + } + + public static ConnectEvent loadConnectEvent(String filename) { + return loadEvent(filename, ConnectEvent.class); + } + + public static DynamodbEvent loadDynamoDbEvent(String filename) { + return loadEvent(filename, DynamodbEvent.class); + } + + public static KafkaEvent loadKafkaEvent(String filename) { + return loadEvent(filename, KafkaEvent.class); + } + + public static KinesisEvent loadKinesisEvent(String filename) { + return loadEvent(filename, KinesisEvent.class); + } + + public static KinesisFirehoseEvent loadKinesisFirehoseEvent(String filename){ + return loadEvent(filename, KinesisFirehoseEvent.class); + } + + public static LambdaDestinationEvent loadLambdaDestinationEvent(String filename) { + return loadEvent(filename, LambdaDestinationEvent.class); + } + + public static LexEvent loadLexEvent(String filename) { + return loadEvent(filename, LexEvent.class); + } + + public static S3Event loadS3Event(String filename) { + return loadEvent(filename, S3Event.class); + } + + public static SecretsManagerRotationEvent loadSecretsManagerRotationEvent(String filename) { + return loadEvent(filename, SecretsManagerRotationEvent.class); + } + + public static ScheduledEvent loadScheduledEvent(String filename) { + return loadEvent(filename, ScheduledEvent.class); + } + + public static SNSEvent loadSNSEvent(String filename) { + return loadEvent(filename, SNSEvent.class); + } + + public static SQSEvent loadSQSEvent(String filename) { + return loadEvent(filename, SQSEvent.class); + } + + public static T loadEvent(String filename, Class targetClass) { + + if (!filename.endsWith("json")) { + throw new IllegalArgumentException("File " + filename + " must have json extension"); + } + + PojoSerializer serializer = LambdaEventSerializers.serializerFor(targetClass, ClassLoader.getSystemClassLoader()); + + InputStream stream = serializer.getClass().getResourceAsStream(filename); + if (stream == null) { + stream = serializer.getClass().getClassLoader().getResourceAsStream(filename); + } + if (stream == null) { + try { + stream = new FileInputStream(new File(filename)); + } catch (FileNotFoundException e) { + throw new EventLoadingException("Cannot load " + filename, e); + } + } + return serializer.fromJson(stream); + } +} diff --git a/aws-lambda-java-tests/src/main/java/com/amazonaws/services/lambda/runtime/tests/EventLoadingException.java b/aws-lambda-java-tests/src/main/java/com/amazonaws/services/lambda/runtime/tests/EventLoadingException.java new file mode 100644 index 00000000..c7b8c34d --- /dev/null +++ b/aws-lambda-java-tests/src/main/java/com/amazonaws/services/lambda/runtime/tests/EventLoadingException.java @@ -0,0 +1,18 @@ +/* Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ +package com.amazonaws.services.lambda.runtime.tests; + +public class EventLoadingException extends RuntimeException { + + private static final long serialVersionUID = 5766526909472206270L; + + public EventLoadingException() { + } + + public EventLoadingException(String message) { + super(message); + } + + public EventLoadingException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/aws-lambda-java-tests/src/main/java/com/amazonaws/services/lambda/runtime/tests/EventsArgumentsProvider.java b/aws-lambda-java-tests/src/main/java/com/amazonaws/services/lambda/runtime/tests/EventsArgumentsProvider.java new file mode 100644 index 00000000..2a3b93df --- /dev/null +++ b/aws-lambda-java-tests/src/main/java/com/amazonaws/services/lambda/runtime/tests/EventsArgumentsProvider.java @@ -0,0 +1,52 @@ +/* Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ +package com.amazonaws.services.lambda.runtime.tests; + +import com.amazonaws.services.lambda.runtime.tests.annotations.Events; +import org.apache.commons.lang3.ArrayUtils; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.ArgumentsProvider; +import org.junit.jupiter.params.support.AnnotationConsumer; + +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.stream.Stream; + +/** + * Used to process @{@link Events} com.amazonaws.services.lambda.runtime.tests.annotations + */ +public class EventsArgumentsProvider implements ArgumentsProvider, AnnotationConsumer { + + private Events events; + + @Override + public void accept(Events events) { + this.events = events; + } + + @Override + public Stream provideArguments(ExtensionContext context) throws Exception { + if (ArrayUtils.isNotEmpty(events.events())) { + return Arrays.stream(events.events()) + .map(event -> { + Class clazz = event.type() == Void.class ? events.type() : event.type(); + return Arguments.of(EventLoader.loadEvent(event.value(), clazz)); + }); + } else { + URL folderUrl = getClass().getResource(events.folder()); + if (folderUrl == null) { + folderUrl = getClass().getClassLoader().getResource(events.folder()); + } + if (folderUrl == null) { + throw new IllegalArgumentException("Path " + events.folder() + " cannot be found"); + } + Stream files = Files.list(Paths.get(folderUrl.toURI())); + return files + .filter(Files::isRegularFile) + .map(path -> Arguments.of(EventLoader.loadEvent(path.toString(), events.type()))); + } + } +} diff --git a/aws-lambda-java-tests/src/main/java/com/amazonaws/services/lambda/runtime/tests/HandlerParamsArgumentsProvider.java b/aws-lambda-java-tests/src/main/java/com/amazonaws/services/lambda/runtime/tests/HandlerParamsArgumentsProvider.java new file mode 100644 index 00000000..269180dc --- /dev/null +++ b/aws-lambda-java-tests/src/main/java/com/amazonaws/services/lambda/runtime/tests/HandlerParamsArgumentsProvider.java @@ -0,0 +1,130 @@ +/* Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ +package com.amazonaws.services.lambda.runtime.tests; + +import com.amazonaws.services.lambda.runtime.tests.annotations.*; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.StringUtils; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.ArgumentsProvider; +import org.junit.jupiter.params.support.AnnotationConsumer; + +import java.io.IOException; +import java.net.URISyntaxException; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * Used to process @{@link HandlerParams} com.amazonaws.services.lambda.runtime.tests.annotations + */ +public class HandlerParamsArgumentsProvider implements ArgumentsProvider, AnnotationConsumer { + + private Event event; + private Response response; + + private Events events; + private Responses responses; + + @Override + public void accept(HandlerParams handlerParams) { + this.event = handlerParams.event(); + this.response = handlerParams.response(); + this.events = handlerParams.events(); + this.responses = handlerParams.responses(); + } + + @Override + public Stream provideArguments(ExtensionContext context) throws Exception { + if ((!event.value().isEmpty() && response.value().isEmpty()) || + (event.value().isEmpty() && !response.value().isEmpty())) { + throw new IllegalStateException("You must use either Event & Response (singular) or Events & Responses (plural) annotations together, you cannot mix them"); + } + if (((ArrayUtils.isEmpty(events.events()) && StringUtils.isEmpty(events.folder())) + && (StringUtils.isNotEmpty(responses.folder()) || ArrayUtils.isNotEmpty(responses.responses()))) + || + ((ArrayUtils.isEmpty(responses.responses()) && StringUtils.isEmpty(responses.folder())) + && (StringUtils.isNotEmpty(events.folder()) || ArrayUtils.isNotEmpty(events.events())))) { + throw new IllegalStateException("You must use either Event & Response (singular) or Events & Responses (plural) annotations together, you cannot mix them"); + } + + // deal with one element + if (!event.value().isEmpty() && !response.value().isEmpty()) { + return Stream.of( + Arguments.of( + EventLoader.loadEvent(event.value(), event.type()), + EventLoader.loadEvent(response.value(), response.type()) + ) + ); + } + + // deal with many elements + List eventList = getEvents(); + List responseList = getResponses(); + if (eventList == null || eventList.size() == 0 || responseList == null || responseList.size() == 0 || eventList.size() != responseList.size()) { + throw new IllegalStateException("At least one event and one response should be provided, and you should have the exact same number of events and responses."); + } + + Stream.Builder streamBuilder = Stream.builder(); + for (int i = 0; i < eventList.size(); i++) { + streamBuilder.add(Arguments.of(eventList.get(i), responseList.get(i))); + } + return streamBuilder.build(); + } + + private List getResponses() throws IOException, URISyntaxException { + List responseList; + if (ArrayUtils.isNotEmpty(responses.responses())) { + responseList = Arrays.stream(responses.responses()).map( + response -> { + Class clazz = response.type() == Void.class ? responses.type() : response.type(); + return EventLoader.loadEvent(response.value(), clazz); + } + ).collect(Collectors.toList()); + } else { + Stream files = listFiles(responses.folder()); + + responseList = files + .filter(Files::isRegularFile) + .map(path -> EventLoader.loadEvent(path.toString(), responses.type())) + .collect(Collectors.toList()); + } + return responseList; + } + + private List getEvents() throws IOException, URISyntaxException { + List eventList; + if (ArrayUtils.isNotEmpty(events.events())) { + eventList = Arrays.stream(events.events()).map( + event -> { + Class clazz = event.type() == Void.class ? events.type() : event.type(); + return EventLoader.loadEvent(event.value(), clazz); + } + ).collect(Collectors.toList()); + } else { + Stream files = listFiles(events.folder()); + + eventList = files + .filter(Files::isRegularFile) + .map(path -> EventLoader.loadEvent(path.toString(), events.type())) + .collect(Collectors.toList()); + } + return eventList; + } + + private Stream listFiles(String folder) throws IOException, URISyntaxException { + URL folderUrl = getClass().getResource(folder); + if (folderUrl == null) { + folderUrl = getClass().getClassLoader().getResource(folder); + } + if (folderUrl == null) { + throw new IllegalArgumentException("Path " + folder + " cannot be found"); + } + return Files.list(Paths.get(folderUrl.toURI())); + } +} diff --git a/aws-lambda-java-tests/src/main/java/com/amazonaws/services/lambda/runtime/tests/annotations/Event.java b/aws-lambda-java-tests/src/main/java/com/amazonaws/services/lambda/runtime/tests/annotations/Event.java new file mode 100644 index 00000000..a94145eb --- /dev/null +++ b/aws-lambda-java-tests/src/main/java/com/amazonaws/services/lambda/runtime/tests/annotations/Event.java @@ -0,0 +1,39 @@ +/* Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ +package com.amazonaws.services.lambda.runtime.tests.annotations; + +import com.amazonaws.services.lambda.runtime.tests.EventArgumentsProvider; +import org.junit.jupiter.params.provider.ArgumentsSource; + +import java.lang.annotation.*; + +/** + * This annotation must be used in conjunction with {@link org.junit.jupiter.params.ParameterizedTest}.
+ * It enables to inject an event (loaded from a json file) of the desired type into the current test.
+ * Example:
+ *
{@code
+ *     @ParameterizedTest
+ *     @Event(value = "sqs_event.json", type = SQSEvent.class)
+ *     public void testInjectEvent(SQSEvent event) {
+ *         assertThat(event).isNotNull();
+ *         assertThat(event.getRecords()).hasSize(1);
+ *     }
+ * }
+ */ +@Documented +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@ArgumentsSource(EventArgumentsProvider.class) +public @interface Event { + + /** + * Path and file name of the json event + * @return the file name (including the path) + */ + String value(); + + /** + * Type of the event (for example, one of the aws-lambda-java-events), or your own type + * @return the type of the event + */ + Class type() default Void.class; +} diff --git a/aws-lambda-java-tests/src/main/java/com/amazonaws/services/lambda/runtime/tests/annotations/Events.java b/aws-lambda-java-tests/src/main/java/com/amazonaws/services/lambda/runtime/tests/annotations/Events.java new file mode 100644 index 00000000..972454e0 --- /dev/null +++ b/aws-lambda-java-tests/src/main/java/com/amazonaws/services/lambda/runtime/tests/annotations/Events.java @@ -0,0 +1,81 @@ +/* Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ +package com.amazonaws.services.lambda.runtime.tests.annotations; + +import com.amazonaws.services.lambda.runtime.tests.EventsArgumentsProvider; +import org.junit.jupiter.params.provider.ArgumentsSource; + +import java.lang.annotation.*; + +/** + * This annotation must be used in conjunction with {@link org.junit.jupiter.params.ParameterizedTest}.
+ * It enables to inject multiple events (loaded from json files) of the desired type into the current test.
+ *

+ * Several notations are possible according to what you want to do: + *

    + *
  • + * Using the folder parameter is the more straightforward, and it will use all files in the folder
    + *
    {@code
    + *     @ParameterizedTest
    + *     @Events(folder = "sqs", type = SQSEvent.class)
    + *     public void testInjectEventsFromFolder(SQSEvent event) {
    + *         assertThat(event).isNotNull();
    + *         assertThat(event.getRecords()).hasSize(1);
    + *     }
    + * }
    + *
  • + *
  • + * Or you can list all the {@link Event}s
    + *
    {@code
    + * @ParameterizedTest
    + *     @Events(
    + *             events = {
    + *                     @Event("sqs/sqs_event.json"),
    + *                     @Event("sqs/sqs_event2.json"),
    + *             },
    + *             type = SQSEvent.class
    + *     )
    + *     public void testInjectEvents(SQSEvent event) {
    + *         assertThat(event).isNotNull();
    + *         assertThat(event.getRecords()).hasSize(1);
    + *     }
    + *
    + *     @ParameterizedTest
    + *     @Events(
    + *             events = {
    + *                     @Event(value = "sqs/sqs_event.json", type = SQSEvent.class),
    + *                     @Event(value = "sqs/sqs_event2.json", type = SQSEvent.class),
    + *             }
    + *     )
    + *     public void testInjectEvents2(SQSEvent event) {
    + *         assertThat(event).isNotNull();
    + *         assertThat(event.getRecords()).hasSize(1);
    + *     }
    + * }
    + *
  • + *
+ *

+ */ +@Documented +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@ArgumentsSource(EventsArgumentsProvider.class) +public @interface Events { + + /** + * Folder where to find json files containing events + * @return the folder name + */ + String folder() default ""; + + /** + * Type of the events (for example, one of the aws-lambda-java-events), or your own type + * @return the type of the events + */ + Class type() default Void.class; + + /** + * Mutually exclusive with folder + * @return the array of events + */ + Event[] events() default {}; +} diff --git a/aws-lambda-java-tests/src/main/java/com/amazonaws/services/lambda/runtime/tests/annotations/HandlerParams.java b/aws-lambda-java-tests/src/main/java/com/amazonaws/services/lambda/runtime/tests/annotations/HandlerParams.java new file mode 100644 index 00000000..8c0d108d --- /dev/null +++ b/aws-lambda-java-tests/src/main/java/com/amazonaws/services/lambda/runtime/tests/annotations/HandlerParams.java @@ -0,0 +1,63 @@ +/* Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ +package com.amazonaws.services.lambda.runtime.tests.annotations; + +import com.amazonaws.services.lambda.runtime.tests.HandlerParamsArgumentsProvider; +import org.junit.jupiter.params.provider.ArgumentsSource; + +import java.lang.annotation.*; + +/** + * This annotation must be used in conjunction with {@link org.junit.jupiter.params.ParameterizedTest}.
+ * It enables to inject Events and Responses into the current test.
+ * Either use the {@link #event()} and {@link #response()} for a single event/response + * or {@link #events()} and {@link #responses()} for multiple ones.
+ * + * Example:
+ *
{@code
+ * @ParameterizedTest
+ * @HandlerParams(
+ *         event = @Event(value = "apigw/events/apigw_event.json", type = APIGatewayProxyRequestEvent.class),
+ *         response = @Response(value = "apigw/responses/apigw_response.json", type = APIGatewayProxyResponseEvent.class))
+ * public void testSingleEventResponse(APIGatewayProxyRequestEvent event, APIGatewayProxyResponseEvent response) {
+ * }
+ *
+ * @ParameterizedTest
+ * @HandlerParams(
+ *         events = @Events(folder = "apigw/events/", type = APIGatewayProxyRequestEvent.class),
+ *         responses = @Responses(folder = "apigw/responses/", type = APIGatewayProxyResponseEvent.class))
+ * public void testMultipleEventsResponsesInFolder(APIGatewayProxyRequestEvent event, APIGatewayProxyResponseEvent response) {
+ * }
+ *
+ * @ParameterizedTest
+ * @HandlerParams(
+ *         events = @Events(
+ *                 events = {
+ *                         @Event("apigw/events/apigw_event.json"),
+ *                         @Event("apigw/events/apigw_event2.json"),
+ *                 },
+ *                 type = APIGatewayProxyRequestEvent.class
+ *         ),
+ *         responses = @Responses(
+ *                 responses = {
+ *                         @Response("apigw/responses/apigw_response.json"),
+ *                         @Response("apigw/responses/apigw_response2.json")
+ *                 },
+ *                 type = APIGatewayProxyResponseEvent.class
+ *         )
+ * )
+ * public void testMultipleEventsResponses(APIGatewayProxyRequestEvent event, APIGatewayProxyResponseEvent response) {
+ * }
+ * }
+ */ +@Documented +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@ArgumentsSource(HandlerParamsArgumentsProvider.class) +public @interface HandlerParams { + + Event event() default @Event(""); + Response response() default @Response(""); + + Events events() default @Events; + Responses responses() default @Responses; +} diff --git a/aws-lambda-java-tests/src/main/java/com/amazonaws/services/lambda/runtime/tests/annotations/Response.java b/aws-lambda-java-tests/src/main/java/com/amazonaws/services/lambda/runtime/tests/annotations/Response.java new file mode 100644 index 00000000..d53ef128 --- /dev/null +++ b/aws-lambda-java-tests/src/main/java/com/amazonaws/services/lambda/runtime/tests/annotations/Response.java @@ -0,0 +1,25 @@ +/* Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ +package com.amazonaws.services.lambda.runtime.tests.annotations; + +import java.lang.annotation.*; + +/** + * This annotation must be used in conjunction with {@link HandlerParams}. + */ +@Documented +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface Response { + + /** + * Path and file name of the json response + * @return the file name (including the path) + */ + String value(); + + /** + * Type of the response + * @return the type of the response + */ + Class type() default Void.class; +} diff --git a/aws-lambda-java-tests/src/main/java/com/amazonaws/services/lambda/runtime/tests/annotations/Responses.java b/aws-lambda-java-tests/src/main/java/com/amazonaws/services/lambda/runtime/tests/annotations/Responses.java new file mode 100644 index 00000000..8788baa7 --- /dev/null +++ b/aws-lambda-java-tests/src/main/java/com/amazonaws/services/lambda/runtime/tests/annotations/Responses.java @@ -0,0 +1,31 @@ +/* Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ +package com.amazonaws.services.lambda.runtime.tests.annotations; + +import java.lang.annotation.*; + +/** + * This annotation must be used in conjunction with {@link HandlerParams}. + */ +@Documented +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface Responses { + + /** + * Folder where to find json files containing responses + * @return the folder name + */ + String folder() default ""; + + /** + * Type of the responses + * @return the type of the responses + */ + Class type() default Void.class; + + /** + * Mutually exclusive with folder + * @return the array of responses + */ + Response[] responses() default {}; +} diff --git a/aws-lambda-java-tests/src/test/java/com/amazonaws/services/lambda/runtime/tests/EventLoaderTest.java b/aws-lambda-java-tests/src/test/java/com/amazonaws/services/lambda/runtime/tests/EventLoaderTest.java new file mode 100644 index 00000000..5002c2f6 --- /dev/null +++ b/aws-lambda-java-tests/src/test/java/com/amazonaws/services/lambda/runtime/tests/EventLoaderTest.java @@ -0,0 +1,293 @@ +/* Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ +package com.amazonaws.services.lambda.runtime.tests; + +import com.amazonaws.services.lambda.runtime.events.models.dynamodb.AttributeValue; +import com.amazonaws.services.lambda.runtime.events.models.dynamodb.Record; +import com.amazonaws.services.lambda.runtime.events.models.dynamodb.StreamRecord; +import org.joda.time.DateTime; +import org.junit.jupiter.api.Test; + +import java.time.Instant; +import java.util.Date; +import java.util.List; +import java.util.Map; + +import static java.time.Instant.ofEpochSecond; +import static org.assertj.core.api.Assertions.*; +import static org.assertj.core.api.Assertions.from; + +import com.amazonaws.services.lambda.runtime.events.*; + +public class EventLoaderTest { + + @Test + public void testLoadApiGatewayRestEvent() { + APIGatewayProxyRequestEvent event = EventLoader.loadApiGatewayRestEvent("apigw_rest_event.json"); + + assertThat(event).isNotNull(); + assertThat(event.getBody()).isEqualTo("Hello from Lambda!"); + assertThat(event.getHeaders()).hasSize(2); + } + + @Test + public void testLoadApiGatewayHttpEvent() { + APIGatewayV2HTTPEvent event = EventLoader.loadApiGatewayHttpEvent("apigw_http_event.json"); + + assertThat(event).isNotNull(); + assertThat(event.getBody()).isEqualTo("Hello from Lambda!!"); + } + + @Test + public void testLoadAPIGatewayCustomAuthorizerEvent() { + APIGatewayCustomAuthorizerEvent event = EventLoader.loadAPIGatewayCustomAuthorizerEvent("apigw_auth.json"); + + assertThat(event).isNotNull(); + assertThat(event.getRequestContext().getHttpMethod()).isEqualTo("GET"); + assertThat(event.getHeaders()).hasSize(8); + } + + @Test + public void testLoadAPIGatewayV2CustomAuthorizerEvent() { + APIGatewayV2CustomAuthorizerEvent event = EventLoader.loadAPIGatewayV2CustomAuthorizerEvent("apigw_auth_v2.json"); + + assertThat(event).isNotNull(); + assertThat(event.getRequestContext().getHttp().getMethod()).isEqualTo("POST"); + assertThat(event.getRequestContext().getTimeEpoch()).isEqualTo(Instant.ofEpochMilli(1583348638390L)); + } + + @Test + public void testLoadApplicationLoadBalancerRequestEvent() { + ApplicationLoadBalancerRequestEvent event = EventLoader.loadApplicationLoadBalancerRequestEvent("elb_event.json"); + + assertThat(event).isNotNull(); + assertThat(event.getBody()).isEqualTo("Hello from ELB"); + } + + @Test + public void testLoadConfigEvent() { + ConfigEvent event = EventLoader.loadConfigEvent("config_event.json"); + + assertThat(event).isNotNull(); + assertThat(event.getConfigRuleArn()).isEqualTo("arn:aws:config:eu-central-1:123456789012:config-rule/config-rule-0123456"); + assertThat(event.getConfigRuleName()).isEqualTo("change-triggered-config-rule"); + } + + @Test + public void testLoadKafkaEvent() { + KafkaEvent event = EventLoader.loadKafkaEvent("kafka_event.json"); + + assertThat(event).isNotNull(); + assertThat(event.getEventSourceArn()).isEqualTo("arn:aws:kafka:us-east-1:123456789012:cluster/vpc-3432434/4834-3547-3455-9872-7929"); + + KafkaEvent.KafkaEventRecord record = event.getRecords().get("mytopic-01").get(0); + assertThat(record.getValue()).decodedAsBase64().asString().isEqualTo("Hello from Kafka !!"); + } + + @Test + public void testLoadLambdaDestinationEvent() { + LambdaDestinationEvent event = EventLoader.loadLambdaDestinationEvent("lambda_destination_event.json"); + + assertThat(event).isNotNull(); + assertThat(event.getTimestamp()).isEqualTo(DateTime.parse("2019-11-24T21:52:47.333Z")); + assertThat(event.getRequestContext().getFunctionArn()).isEqualTo("arn:aws:lambda:sa-east-1:123456678912:function:event-destinations:$LATEST"); + assertThat(event.getRequestPayload().get("Success")).isEqualTo(false); + } + + @Test + public void testLoadLexEvent() { + LexEvent event = EventLoader.loadLexEvent("lex_event.json"); + + assertThat(event).isNotNull(); + assertThat(event.getInvocationSource()).isEqualTo("DialogCodeHook"); + assertThat(event.getSessionAttributes()).hasSize(1); + assertThat(event.getCurrentIntent().getName()).isEqualTo("BookHotel"); + assertThat(event.getCurrentIntent().getSlots()).hasSize(4); + assertThat(event.getBot().getName()).isEqualTo("BookTrip"); + } + + @Test + public void testLoadKinesisFirehoseEvent() { + KinesisFirehoseEvent event = EventLoader.loadKinesisFirehoseEvent("firehose_event.json"); + + assertThat(event).isNotNull(); + assertThat(event.getDeliveryStreamArn()).isEqualTo("arn:aws:kinesis:EXAMPLE"); + assertThat(event.getRecords()).hasSize(1); + assertThat(event.getRecords().get(0).getData().array()).asString().isEqualTo("Hello, this is a test 123."); + } + + @Test + public void testLoadS3Event() { + S3Event event = EventLoader.loadS3Event("s3_event.json"); + assertThat(event).isNotNull(); + assertThat(event.getRecords()).hasSize(1); + } + + @Test + public void testLoadSQSEvent() { + SQSEvent event = EventLoader.loadSQSEvent("sqs/sqs_event.json"); + assertThat(event).isNotNull(); + assertThat(event.getRecords()).hasSize(1); + assertThat(event.getRecords().get(0).getEventSourceArn()).isEqualTo("arn:aws:sqs:eu-central-1:123456789012:TestLambda"); + } + + @Test + public void testLoadSNSEvent() { + SNSEvent event = EventLoader.loadSNSEvent("sns_event.json"); + assertThat(event).isNotNull(); + assertThat(event.getRecords()).hasSize(1); + + SNSEvent.SNSRecord record = event.getRecords().get(0); + assertThat(record.getEventSource()).isEqualTo("aws:sns"); + assertThat(record.getEventVersion()).isEqualTo("1.0"); + assertThat(record.getEventSubscriptionArn()).isEqualTo("arn:aws:sns:eu-central-1:123456789012:TopicSendToMe:e3ddc7d5-2f86-40b8-a13d-3362f94fd8dd"); + + SNSEvent.SNS sns = record.getSNS(); + assertThat(sns) + .returns("Test sns message", from(SNSEvent.SNS::getSubject)) + .returns("{\n \"id\": 42,\n \"name\": \"Bob\"\n}", from(SNSEvent.SNS::getMessage)) + .returns("arn:aws:sns:eu-central-1:123456789012:TopicSendToMe", from(SNSEvent.SNS::getTopicArn)) + .returns("dc918f50-80c6-56a2-ba33-d8a9bbf013ab", from(SNSEvent.SNS::getMessageId)) + .returns(DateTime.parse("2020-10-08T16:06:14.656Z"), from(SNSEvent.SNS::getTimestamp)) + .returns("https://sns.eu-central-1.amazonaws.com/?Action=Unsubscribe", SNSEvent.SNS::getUnsubscribeUrl); + assertThat(sns.getMessageAttributes()).containsKey("name"); + assertThat(sns.getMessageAttributes().get("name").getValue()).isEqualTo("Bob"); + assertThat(sns.getMessageAttributes().get("name").getType()).isEqualTo("String"); + } + + @Test + public void testLoadDynamoEvent() { + DynamodbEvent event = EventLoader.loadDynamoDbEvent("dynamo_event.json"); + assertThat(event).isNotNull(); + assertThat(event.getRecords()).hasSize(3); + + DynamodbEvent.DynamodbStreamRecord record = event.getRecords().get(0); + assertThat(record) + .returns("arn:aws:dynamodb:eu-central-1:123456789012:table/ExampleTableWithStream/stream/2015-06-27T00:48:05.899", from(DynamodbEvent.DynamodbStreamRecord::getEventSourceARN)) + .returns("INSERT", from(Record::getEventName)); + + StreamRecord streamRecord = record.getDynamodb(); + assertThat(streamRecord) + .returns("4421584500000000017450439091", StreamRecord::getSequenceNumber) + .returns(26L, StreamRecord::getSizeBytes) + .returns("NEW_AND_OLD_IMAGES", StreamRecord::getStreamViewType) + .returns(Date.from(ofEpochSecond(1428537600)), StreamRecord::getApproximateCreationDateTime); + + assertThat(streamRecord.getKeys()).contains(entry("Id", new AttributeValue().withN("101"))); + assertThat(streamRecord.getNewImage()).containsAnyOf( + entry("Message", new AttributeValue("New item!")), + entry("Id", new AttributeValue().withN("101")) + ); + } + + @Test + public void testLoadKinesisEvent() { + KinesisEvent event = EventLoader.loadKinesisEvent("kinesis_event.json"); + assertThat(event).isNotNull(); + assertThat(event.getRecords()).hasSize(1); + + KinesisEvent.Record record = event.getRecords().get(0).getKinesis(); + assertThat(record.getEncryptionType()).isEqualTo("NONE"); + assertThat(record.getApproximateArrivalTimestamp()).isEqualTo(Date.from(ofEpochSecond(1428537600))); + assertThat(new String(record.getData().array())).isEqualTo("Hello, this is a test 123."); + } + + @Test + public void testLoadCodeCommitEvent() { + CodeCommitEvent event = EventLoader.loadCodeCommitEvent("codecommit_event.json"); + assertThat(event).isNotNull(); + assertThat(event.getRecords()).hasSize(1); + + CodeCommitEvent.Record record = event.getRecords().get(0); + assertThat(record.getEventSourceArn()).isEqualTo("arn:aws:codecommit:eu-central-1:123456789012:my-repo"); + assertThat(record.getUserIdentityArn()).isEqualTo("arn:aws:iam::123456789012:root"); + assertThat(record.getEventTime()).isEqualTo(DateTime.parse("2016-01-01T23:59:59.000+0000")); + + assertThat(record.getCodeCommit().getReferences()).hasSize(1); + CodeCommitEvent.Reference reference = record.getCodeCommit().getReferences().get(0); + assertThat(reference.getCommit()).isEqualTo("5c4ef1049f1d27deadbeeff313e0730018be182b"); + assertThat(reference.getRef()).isEqualTo("refs/heads/master"); + } + + @Test + public void testLoadCloudWatchLogsEvent() { + CloudWatchLogsEvent cloudWatchLogsEvent = EventLoader.loadCloudWatchLogsEvent("cloudwatchlogs_event.json"); + assertThat(cloudWatchLogsEvent).isNotNull(); + assertThat(cloudWatchLogsEvent.getAwsLogs().getData()).isEqualTo("H4sIAAAAAAAAAHWPwQqCQBCGX0Xm7EFtK+smZBEUgXoLCdMhFtKV3akI8d0bLYmibvPPN3wz00CJxmQnTO41whwWQRIctmEcB6sQbFC3CjW3XW8kxpOpP+OC22d1Wml1qZkQGtoMsScxaczKN3plG8zlaHIta5KqWsozoTYw3/djzwhpLwivWFGHGpAFe7DL68JlBUk+l7KSN7tCOEJ4M3/qOI49vMHj+zCKdlFqLaU2ZHV2a4Ct/an0/ivdX8oYc1UVX860fQDQiMdxRQEAAA=="); + } + + @Test + public void testLoadCloudFrontEvent() { + CloudFrontEvent event = EventLoader.loadCloudFrontEvent("cloudfront_event.json"); + assertThat(event).isNotNull(); + assertThat(event.getRecords()).hasSize(1); + assertThat(event.getRecords().get(0).getCf().getConfig().getDistributionId()).isEqualTo("EXAMPLE"); + } + + @Test + public void testLoadScheduledEvent() { + ScheduledEvent event = EventLoader.loadScheduledEvent("cloudwatch_event.json"); + assertThat(event).isNotNull(); + assertThat(event.getDetailType()).isEqualTo("Scheduled Event"); + assertThat(event.getTime()).isEqualTo(DateTime.parse("2020-09-30T15:58:34Z")); + } + + @Test + public void testLoadConnectEvent() { + ConnectEvent event = EventLoader.loadConnectEvent("connect_event.json"); + assertThat(event).isNotNull(); + + ConnectEvent.ContactData contactData = event.getDetails().getContactData(); + assertThat(contactData) + .returns("VOICE", from(ConnectEvent.ContactData::getChannel)) + .returns("5ca32fbd-8f92-46af-92a5-6b0f970f0efe", from(ConnectEvent.ContactData::getContactId)) + .returns("6ca32fbd-8f92-46af-92a5-6b0f970f0efe", from(ConnectEvent.ContactData::getInitialContactId)) + .returns("API", from(ConnectEvent.ContactData::getInitiationMethod)) + .returns("arn:aws:connect:eu-central-1:123456789012:instance/9308c2a1-9bc6-4cea-8290-6c0b4a6d38fa", from(ConnectEvent.ContactData::getInstanceArn)) + .returns("4ca32fbd-8f92-46af-92a5-6b0f970f0efe", from(ConnectEvent.ContactData::getPreviousContactId)); + + assertThat(contactData.getCustomerEndpoint()) + .returns("+11234567890",from(ConnectEvent.CustomerEndpoint::getAddress)) + .returns("TELEPHONE_NUMBER",from(ConnectEvent.CustomerEndpoint::getType)); + + assertThat(contactData.getSystemEndpoint()) + .returns("+21234567890",from(ConnectEvent.SystemEndpoint::getAddress)) + .returns("TELEPHONE_NUMBER",from(ConnectEvent.SystemEndpoint::getType)); + } + + @Test + public void testLoadCloudFormationCustomResourceEvent() { + CloudFormationCustomResourceEvent event = EventLoader.loadCloudFormationCustomResourceEvent("cloudformation_event.json"); + assertThat(event).isNotNull(); + assertThat(event) + .returns("Update", from(CloudFormationCustomResourceEvent::getRequestType)) + .returns("http://pre-signed-S3-url-for-response", from(CloudFormationCustomResourceEvent::getResponseUrl)) + .returns("arn:aws:cloudformation:eu-central-1:123456789012:stack/MyStack/guid", from(CloudFormationCustomResourceEvent::getStackId)) + .returns("unique id for this create request", from(CloudFormationCustomResourceEvent::getRequestId)) + .returns("Custom::TestResource", from(CloudFormationCustomResourceEvent::getResourceType)) + .returns("MyTestResource", from(CloudFormationCustomResourceEvent::getLogicalResourceId)) + .returns("MyTestResourceId", from(CloudFormationCustomResourceEvent::getPhysicalResourceId)) + .returns("abcd", from(CloudFormationCustomResourceEvent::getServiceToken)); + + Map resourceProperties = event.getResourceProperties(); + assertThat(resourceProperties).hasSize(2); + assertThat(resourceProperties.get("StackName")).isEqualTo("MyStack"); + assertThat(resourceProperties.get("List")).isInstanceOf(List.class); + assertThat(resourceProperties.get("List")).asList().hasSize(3); + + Map oldResourceProperties = event.getOldResourceProperties(); + assertThat(oldResourceProperties).hasSize(2); + assertThat(oldResourceProperties.get("StackName")).isEqualTo("MyStack"); + assertThat(oldResourceProperties.get("List")).isInstanceOf(List.class); + assertThat(oldResourceProperties.get("List")).asList().hasSize(1); + } + + @Test + public void testLoadSecretsManagerRotationEvent() { + SecretsManagerRotationEvent event = EventLoader.loadSecretsManagerRotationEvent("secrets_rotation_event.json"); + assertThat(event).isNotNull(); + assertThat(event) + .returns("123e4567-e89b-12d3-a456-426614174000", from(SecretsManagerRotationEvent::getClientRequestToken)) + .returns("arn:aws:secretsmanager:eu-central-1:123456789012:secret:/powertools/secretparam-xBPaJ5", from(SecretsManagerRotationEvent::getSecretId)) + .returns("CreateSecret", from(SecretsManagerRotationEvent::getStep)); + } +} diff --git a/aws-lambda-java-tests/src/test/java/com/amazonaws/services/lambda/runtime/tests/EventTest.java b/aws-lambda-java-tests/src/test/java/com/amazonaws/services/lambda/runtime/tests/EventTest.java new file mode 100644 index 00000000..ea8f7b50 --- /dev/null +++ b/aws-lambda-java-tests/src/test/java/com/amazonaws/services/lambda/runtime/tests/EventTest.java @@ -0,0 +1,18 @@ +/* Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ +package com.amazonaws.services.lambda.runtime.tests; + +import com.amazonaws.services.lambda.runtime.events.SQSEvent; +import com.amazonaws.services.lambda.runtime.tests.annotations.Event; +import org.junit.jupiter.params.ParameterizedTest; + +import static org.assertj.core.api.Assertions.assertThat; + +public class EventTest { + + @ParameterizedTest + @Event(value = "sqs/sqs_event.json", type = SQSEvent.class) + public void testInjectEvent(SQSEvent event) { + assertThat(event).isNotNull(); + assertThat(event.getRecords()).hasSize(1); + } +} diff --git a/aws-lambda-java-tests/src/test/java/com/amazonaws/services/lambda/runtime/tests/EventsTest.java b/aws-lambda-java-tests/src/test/java/com/amazonaws/services/lambda/runtime/tests/EventsTest.java new file mode 100644 index 00000000..527e8ee0 --- /dev/null +++ b/aws-lambda-java-tests/src/test/java/com/amazonaws/services/lambda/runtime/tests/EventsTest.java @@ -0,0 +1,45 @@ +/* Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ +package com.amazonaws.services.lambda.runtime.tests; + +import com.amazonaws.services.lambda.runtime.events.SQSEvent; +import com.amazonaws.services.lambda.runtime.tests.annotations.Event; +import com.amazonaws.services.lambda.runtime.tests.annotations.Events; +import org.junit.jupiter.params.ParameterizedTest; + +import static org.assertj.core.api.Assertions.assertThat; + + +public class EventsTest { + + @ParameterizedTest + @Events( + events = { + @Event("sqs/sqs_event.json"), + @Event("sqs/sqs_event2.json"), + }, + type = SQSEvent.class + ) + public void testInjectEvents(SQSEvent event) { + assertThat(event).isNotNull(); + assertThat(event.getRecords()).hasSize(1); + } + + @ParameterizedTest + @Events( + events = { + @Event(value = "sqs/sqs_event.json", type = SQSEvent.class), + @Event(value = "sqs/sqs_event2.json", type = SQSEvent.class), + } + ) + public void testInjectEvents2(SQSEvent event) { + assertThat(event).isNotNull(); + assertThat(event.getRecords()).hasSize(1); + } + + @ParameterizedTest + @Events(folder = "sqs", type = SQSEvent.class) + public void testInjectEventsFromFolder(SQSEvent event) { + assertThat(event).isNotNull(); + assertThat(event.getRecords()).hasSize(1); + } +} diff --git a/aws-lambda-java-tests/src/test/java/com/amazonaws/services/lambda/runtime/tests/HandlerParamsTest.java b/aws-lambda-java-tests/src/test/java/com/amazonaws/services/lambda/runtime/tests/HandlerParamsTest.java new file mode 100644 index 00000000..549c70d5 --- /dev/null +++ b/aws-lambda-java-tests/src/test/java/com/amazonaws/services/lambda/runtime/tests/HandlerParamsTest.java @@ -0,0 +1,71 @@ +/* Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ +package com.amazonaws.services.lambda.runtime.tests; + +import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent; +import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent; +import com.amazonaws.services.lambda.runtime.tests.annotations.*; +import org.junit.jupiter.params.ParameterizedTest; + +import static org.assertj.core.api.Assertions.assertThat; + +public class HandlerParamsTest { + + @ParameterizedTest + @HandlerParams( + event = @Event(value = "apigw/events/apigw_event.json", type = APIGatewayProxyRequestEvent.class), + response = @Response(value = "apigw/responses/apigw_response.json", type = APIGatewayProxyResponseEvent.class)) + public void testSimpleEventResponse(APIGatewayProxyRequestEvent event, APIGatewayProxyResponseEvent response) { + assertThat(event).isNotNull(); + assertThat(event.getBody()).contains("hello world"); + assertThat(event.getHeaders()).hasSize(18); + assertThat(event.getHttpMethod()).isEqualTo("POST"); + + assertThat(response).isNotNull(); + assertThat(response.getStatusCode()).isEqualTo(200); + assertThat(response.getBody()).contains("hello world"); + } + + @ParameterizedTest + @HandlerParams( + events = @Events(folder = "apigw/events/", type = APIGatewayProxyRequestEvent.class), + responses = @Responses(folder = "apigw/responses/", type = APIGatewayProxyResponseEvent.class)) + public void testMultipleEventsResponsesinFolder(APIGatewayProxyRequestEvent event, APIGatewayProxyResponseEvent response) { + assertThat(event).isNotNull(); + assertThat(event.getHeaders()).hasSize(18); + assertThat(event.getHttpMethod()).isEqualTo("POST"); + + assertThat(response).isNotNull(); + assertThat(response.getStatusCode()).isEqualTo(200); + + assertThat(response.getBody()).isEqualTo(event.getBody()); + } + + @ParameterizedTest + @HandlerParams( + events = @Events( + events = { + @Event("apigw/events/apigw_event.json"), + @Event("apigw/events/apigw_event2.json"), + }, + type = APIGatewayProxyRequestEvent.class + ), + responses = @Responses( + responses = { + @Response("apigw/responses/apigw_response.json"), + @Response("apigw/responses/apigw_response2.json") + }, + type = APIGatewayProxyResponseEvent.class + ) + ) + public void testMultipleEventsResponses(APIGatewayProxyRequestEvent event, APIGatewayProxyResponseEvent response) { + assertThat(event).isNotNull(); + assertThat(event.getHeaders()).hasSize(18); + assertThat(event.getHttpMethod()).isEqualTo("POST"); + + assertThat(response).isNotNull(); + assertThat(response.getStatusCode()).isEqualTo(200); + + assertThat(response.getBody()).isEqualTo(event.getBody()); + } + +} diff --git a/aws-lambda-java-tests/src/test/resources/apigw/events/apigw_event.json b/aws-lambda-java-tests/src/test/resources/apigw/events/apigw_event.json new file mode 100644 index 00000000..070ad8e0 --- /dev/null +++ b/aws-lambda-java-tests/src/test/resources/apigw/events/apigw_event.json @@ -0,0 +1,62 @@ +{ + "body": "{\"message\": \"hello world\"}", + "resource": "/{proxy+}", + "path": "/path/to/resource", + "httpMethod": "POST", + "isBase64Encoded": false, + "queryStringParameters": { + "foo": "bar" + }, + "pathParameters": { + "proxy": "/path/to/resource" + }, + "stageVariables": { + "baz": "qux" + }, + "headers": { + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", + "Accept-Encoding": "gzip, deflate, sdch", + "Accept-Language": "en-US,en;q=0.8", + "Cache-Control": "max-age=0", + "CloudFront-Forwarded-Proto": "https", + "CloudFront-Is-Desktop-Viewer": "true", + "CloudFront-Is-Mobile-Viewer": "false", + "CloudFront-Is-SmartTV-Viewer": "false", + "CloudFront-Is-Tablet-Viewer": "false", + "CloudFront-Viewer-Country": "US", + "Host": "1234567890.execute-api.us-east-1.amazonaws.com", + "Upgrade-Insecure-Requests": "1", + "User-Agent": "Custom User Agent String", + "Via": "1.1 08f323deadbeefa7af34d5feb414ce27.cloudfront.net (CloudFront)", + "X-Amz-Cf-Id": "cDehVQoZnx43VYQb9j2-nvCh-9z396Uhbp027Y2JvkCPNLmGJHqlaA==", + "X-Forwarded-For": "127.0.0.1, 127.0.0.2", + "X-Forwarded-Port": "443", + "X-Forwarded-Proto": "https" + }, + "requestContext": { + "accountId": "123456789012", + "resourceId": "123456", + "stage": "prod", + "requestId": "c6af9ac6-7b61-11e6-9a41-93e8deadbeef", + "requestTime": "09/Apr/2015:12:34:56 +0000", + "requestTimeEpoch": 1428582896000, + "identity": { + "cognitoIdentityPoolId": null, + "accountId": null, + "cognitoIdentityId": null, + "caller": null, + "accessKey": null, + "sourceIp": "127.0.0.1", + "cognitoAuthenticationType": null, + "cognitoAuthenticationProvider": null, + "userArn": null, + "userAgent": "Custom User Agent String", + "user": null + }, + "path": "/prod/path/to/resource", + "resourcePath": "/{proxy+}", + "httpMethod": "POST", + "apiId": "1234567890", + "protocol": "HTTP/1.1" + } +} diff --git a/aws-lambda-java-tests/src/test/resources/apigw/events/apigw_event2.json b/aws-lambda-java-tests/src/test/resources/apigw/events/apigw_event2.json new file mode 100644 index 00000000..5a575592 --- /dev/null +++ b/aws-lambda-java-tests/src/test/resources/apigw/events/apigw_event2.json @@ -0,0 +1,62 @@ +{ + "body": "{\"message\": \"Lambda rocks\"}", + "resource": "/{proxy+}", + "path": "/path/to/resource", + "httpMethod": "POST", + "isBase64Encoded": false, + "queryStringParameters": { + "foo": "bar" + }, + "pathParameters": { + "proxy": "/path/to/resource" + }, + "stageVariables": { + "baz": "qux" + }, + "headers": { + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", + "Accept-Encoding": "gzip, deflate, sdch", + "Accept-Language": "en-US,en;q=0.8", + "Cache-Control": "max-age=0", + "CloudFront-Forwarded-Proto": "https", + "CloudFront-Is-Desktop-Viewer": "true", + "CloudFront-Is-Mobile-Viewer": "false", + "CloudFront-Is-SmartTV-Viewer": "false", + "CloudFront-Is-Tablet-Viewer": "false", + "CloudFront-Viewer-Country": "US", + "Host": "1234567890.execute-api.us-east-1.amazonaws.com", + "Upgrade-Insecure-Requests": "1", + "User-Agent": "Custom User Agent String", + "Via": "1.1 08f323deadbeefa7af34d5feb414ce27.cloudfront.net (CloudFront)", + "X-Amz-Cf-Id": "cDehVQoZnx43VYQb9j2-nvCh-9z396Uhbp027Y2JvkCPNLmGJHqlaA==", + "X-Forwarded-For": "127.0.0.1, 127.0.0.2", + "X-Forwarded-Port": "443", + "X-Forwarded-Proto": "https" + }, + "requestContext": { + "accountId": "123456789012", + "resourceId": "123456", + "stage": "prod", + "requestId": "c6af9ac6-7b61-11e6-9a41-93e8deadbeef", + "requestTime": "09/Apr/2015:12:34:56 +0000", + "requestTimeEpoch": 1428582896000, + "identity": { + "cognitoIdentityPoolId": null, + "accountId": null, + "cognitoIdentityId": null, + "caller": null, + "accessKey": null, + "sourceIp": "127.0.0.1", + "cognitoAuthenticationType": null, + "cognitoAuthenticationProvider": null, + "userArn": null, + "userAgent": "Custom User Agent String", + "user": null + }, + "path": "/prod/path/to/resource", + "resourcePath": "/{proxy+}", + "httpMethod": "POST", + "apiId": "1234567890", + "protocol": "HTTP/1.1" + } +} diff --git a/aws-lambda-java-tests/src/test/resources/apigw/responses/apigw_response.json b/aws-lambda-java-tests/src/test/resources/apigw/responses/apigw_response.json new file mode 100644 index 00000000..c8170a55 --- /dev/null +++ b/aws-lambda-java-tests/src/test/resources/apigw/responses/apigw_response.json @@ -0,0 +1,16 @@ +{ + "body": "{\"message\": \"hello world\"}", + "statusCode": 200, + "headers": { + "Cache-Control": "max-age=0", + "Host": "1234567890.execute-api.us-east-1.amazonaws.com", + "Upgrade-Insecure-Requests": "1", + "User-Agent": "Custom User Agent String", + "Via": "1.1 08f323deadbeefa7af34d5feb414ce27.cloudfront.net (CloudFront)", + "X-Amz-Cf-Id": "cDehVQoZnx43VYQb9j2-nvCh-9z396Uhbp027Y2JvkCPNLmGJHqlaA==", + "X-Forwarded-For": "127.0.0.1, 127.0.0.2", + "X-Forwarded-Port": "443", + "X-Forwarded-Proto": "https" + }, + "isBase64Encoded": false +} \ No newline at end of file diff --git a/aws-lambda-java-tests/src/test/resources/apigw/responses/apigw_response2.json b/aws-lambda-java-tests/src/test/resources/apigw/responses/apigw_response2.json new file mode 100644 index 00000000..691ca3a9 --- /dev/null +++ b/aws-lambda-java-tests/src/test/resources/apigw/responses/apigw_response2.json @@ -0,0 +1,16 @@ +{ + "body": "{\"message\": \"Lambda rocks\"}", + "statusCode": 200, + "headers": { + "Cache-Control": "max-age=0", + "Host": "1234567890.execute-api.us-east-1.amazonaws.com", + "Upgrade-Insecure-Requests": "1", + "User-Agent": "Custom User Agent String", + "Via": "1.1 08f323deadbeefa7af34d5feb414ce27.cloudfront.net (CloudFront)", + "X-Amz-Cf-Id": "cDehVQoZnx43VYQb9j2-nvCh-9z396Uhbp027Y2JvkCPNLmGJHqlaA==", + "X-Forwarded-For": "127.0.0.1, 127.0.0.2", + "X-Forwarded-Port": "443", + "X-Forwarded-Proto": "https" + }, + "isBase64Encoded": false +} \ No newline at end of file diff --git a/aws-lambda-java-tests/src/test/resources/apigw_auth.json b/aws-lambda-java-tests/src/test/resources/apigw_auth.json new file mode 100644 index 00000000..eb73956e --- /dev/null +++ b/aws-lambda-java-tests/src/test/resources/apigw_auth.json @@ -0,0 +1,41 @@ +{ + "version": "1.0", + "type": "REQUEST", + "methodArn": "arn:aws:execute-api:us-east-1:123456789012:abcdef123/test/GET/request", + "identitySource": "user1,123", + "authorizationToken": "user1,123", + "resource": "/request", + "path": "/request", + "httpMethod": "GET", + "headers": { + "X-AMZ-Date": "20170718T062915Z", + "Accept": "*/*", + "HeaderAuth1": "headerValue1", + "CloudFront-Viewer-Country": "US", + "CloudFront-Forwarded-Proto": "https", + "CloudFront-Is-Tablet-Viewer": "false", + "CloudFront-Is-Mobile-Viewer": "false", + "User-Agent": "..." + }, + "queryStringParameters": { + "QueryString1": "queryValue1" + }, + "pathParameters": {}, + "stageVariables": { + "StageVar1": "stageValue1" + }, + "requestContext": { + "path": "/request", + "accountId": "123456789012", + "resourceId": "05c7jb", + "stage": "test", + "requestId": "...", + "identity": { + "apiKey": "...", + "sourceIp": "..." + }, + "resourcePath": "/request", + "httpMethod": "GET", + "apiId": "abcdef123" + } +} \ No newline at end of file diff --git a/aws-lambda-java-tests/src/test/resources/apigw_auth_v2.json b/aws-lambda-java-tests/src/test/resources/apigw_auth_v2.json new file mode 100644 index 00000000..a603763e --- /dev/null +++ b/aws-lambda-java-tests/src/test/resources/apigw_auth_v2.json @@ -0,0 +1,35 @@ +{ + "version": "2.0", + "type": "REQUEST", + "routeArn": "arn:aws:execute-api:us-east-1:123456789012:abcdef123/test/GET/request", + "identitySource": ["user1", "123"], + "routeKey": "$default", + "rawPath": "/my/path", + "rawQueryString": "parameter1=value1¶meter1=value2¶meter2=value", + "cookies": [ "cookie1", "cookie2" ], + "headers": { + "Header1": "value1", + "Header2": "value2" + }, + "queryStringParameters": { "parameter1": "value1,value2", "parameter2": "value" }, + "requestContext": { + "accountId": "123456789012", + "apiId": "api-id", + "domainName": "id.execute-api.us-east-1.amazonaws.com", + "domainPrefix": "id", + "http": { + "method": "POST", + "path": "/my/path", + "protocol": "HTTP/1.1", + "sourceIp": "IP", + "userAgent": "agent" + }, + "requestId": "id", + "routeKey": "$default", + "stage": "$default", + "time": "12/Mar/2020:19:03:58 +0000", + "timeEpoch": 1583348638390 + }, + "pathParameters": {"parameter1": "value1"}, + "stageVariables": {"stageVariable1": "value1", "stageVariable2": "value2"} +} \ No newline at end of file diff --git a/aws-lambda-java-tests/src/test/resources/apigw_http_event.json b/aws-lambda-java-tests/src/test/resources/apigw_http_event.json new file mode 100644 index 00000000..88f4e5b4 --- /dev/null +++ b/aws-lambda-java-tests/src/test/resources/apigw_http_event.json @@ -0,0 +1,69 @@ +{ + "version": "2.0", + "routeKey": "$default", + "rawPath": "/my/path", + "rawQueryString": "parameter1=value1¶meter1=value2¶meter2=value", + "cookies": [ + "cookie1", + "cookie2" + ], + "headers": { + "Header1": "value1", + "Header2": "value1,value2" + }, + "queryStringParameters": { + "parameter1": "value1,value2", + "parameter2": "value" + }, + "requestContext": { + "accountId": "123456789012", + "apiId": "api-id", + "authentication": { + "clientCert": { + "clientCertPem": "CERT_CONTENT", + "subjectDN": "www.example.com", + "issuerDN": "Example issuer", + "serialNumber": "a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1", + "validity": { + "notBefore": "May 28 12:30:02 2019 GMT", + "notAfter": "Aug 5 09:36:04 2021 GMT" + } + } + }, + "authorizer": { + "jwt": { + "claims": { + "claim1": "value1", + "claim2": "value2" + }, + "scopes": [ + "scope1", + "scope2" + ] + } + }, + "domainName": "id.execute-api.us-east-1.amazonaws.com", + "domainPrefix": "id", + "http": { + "method": "POST", + "path": "/my/path", + "protocol": "HTTP/1.1", + "sourceIp": "IP", + "userAgent": "agent" + }, + "requestId": "id", + "routeKey": "$default", + "stage": "$default", + "time": "12/Mar/2020:19:03:58 +0000", + "timeEpoch": 1583348638390 + }, + "body": "Hello from Lambda!!", + "pathParameters": { + "parameter1": "value1" + }, + "isBase64Encoded": false, + "stageVariables": { + "stageVariable1": "value1", + "stageVariable2": "value2" + } +} \ No newline at end of file diff --git a/aws-lambda-java-tests/src/test/resources/apigw_rest_event.json b/aws-lambda-java-tests/src/test/resources/apigw_rest_event.json new file mode 100644 index 00000000..28f10c22 --- /dev/null +++ b/aws-lambda-java-tests/src/test/resources/apigw_rest_event.json @@ -0,0 +1,80 @@ +{ + "version": "1.0", + "resource": "/my/path", + "path": "/my/path", + "httpMethod": "GET", + "headers": { + "Header1": "value1", + "Header2": "value2" + }, + "multiValueHeaders": { + "Header1": [ + "value1" + ], + "Header2": [ + "value1", + "value2" + ] + }, + "queryStringParameters": { + "parameter1": "value1", + "parameter2": "value" + }, + "multiValueQueryStringParameters": { + "parameter1": [ + "value1", + "value2" + ], + "parameter2": [ + "value" + ] + }, + "requestContext": { + "accountId": "123456789012", + "apiId": "id", + "authorizer": { + "claims": null, + "scopes": null + }, + "domainName": "id.execute-api.us-east-1.amazonaws.com", + "domainPrefix": "id", + "extendedRequestId": "request-id", + "httpMethod": "GET", + "identity": { + "accessKey": null, + "accountId": null, + "caller": null, + "cognitoAuthenticationProvider": null, + "cognitoAuthenticationType": null, + "cognitoIdentityId": null, + "cognitoIdentityPoolId": null, + "principalOrgId": null, + "sourceIp": "IP", + "user": null, + "userAgent": "user-agent", + "userArn": null, + "clientCert": { + "clientCertPem": "CERT_CONTENT", + "subjectDN": "www.example.com", + "issuerDN": "Example issuer", + "serialNumber": "a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1", + "validity": { + "notBefore": "May 28 12:30:02 2019 GMT", + "notAfter": "Aug 5 09:36:04 2021 GMT" + } + } + }, + "path": "/my/path", + "protocol": "HTTP/1.1", + "requestId": "id=", + "requestTime": "04/Mar/2020:19:15:17 +0000", + "requestTimeEpoch": 1583349317135, + "resourceId": null, + "resourcePath": "/my/path", + "stage": "$default" + }, + "pathParameters": null, + "stageVariables": null, + "body": "Hello from Lambda!", + "isBase64Encoded": true +} \ No newline at end of file diff --git a/aws-lambda-java-tests/src/test/resources/cloudformation_event.json b/aws-lambda-java-tests/src/test/resources/cloudformation_event.json new file mode 100644 index 00000000..92b95b71 --- /dev/null +++ b/aws-lambda-java-tests/src/test/resources/cloudformation_event.json @@ -0,0 +1,24 @@ +{ + "RequestType": "Update", + "ResponseURL": "http://pre-signed-S3-url-for-response", + "StackId": "arn:aws:cloudformation:eu-central-1:123456789012:stack/MyStack/guid", + "RequestId": "unique id for this create request", + "ResourceType": "Custom::TestResource", + "LogicalResourceId": "MyTestResource", + "PhysicalResourceId": "MyTestResourceId", + "ServiceToken": "abcd", + "ResourceProperties": { + "StackName": "MyStack", + "List": [ + "1", + "2", + "3" + ] + }, + "OldResourceProperties": { + "StackName": "MyStack", + "List": [ + "1" + ] + } +} \ No newline at end of file diff --git a/aws-lambda-java-tests/src/test/resources/cloudfront_event.json b/aws-lambda-java-tests/src/test/resources/cloudfront_event.json new file mode 100644 index 00000000..7485310e --- /dev/null +++ b/aws-lambda-java-tests/src/test/resources/cloudfront_event.json @@ -0,0 +1,37 @@ +{ + "Records": [ + { + "cf": { + "config": { + "distributionId": "EXAMPLE" + }, + "request": { + "uri": "/test", + "querystring": "auth=test&foo=bar", + "method": "GET", + "clientIp": "2001:cdba::3257:9652", + "headers": { + "host": [ + { + "key": "Host", + "value": "d123.cf.net" + } + ], + "user-agent": [ + { + "key": "User-Agent", + "value": "Test Agent" + } + ], + "user-name": [ + { + "key": "User-Name", + "value": "aws-cloudfront" + } + ] + } + } + } + } + ] +} \ No newline at end of file diff --git a/aws-lambda-java-tests/src/test/resources/cloudwatch_event.json b/aws-lambda-java-tests/src/test/resources/cloudwatch_event.json new file mode 100644 index 00000000..a63ad046 --- /dev/null +++ b/aws-lambda-java-tests/src/test/resources/cloudwatch_event.json @@ -0,0 +1,15 @@ +{ + "version": "0", + "id": "fae0433b-7a0e-e383-7849-7e10153eaa47", + "detail-type": "Scheduled Event", + "source": "aws.events", + "account": "705456458224", + "time": "2020-09-30T15:58:34Z", + "region": "eu-central-1", + "resources": [ + "arn:aws:events:eu-central-1:705456458224:rule/demoschedule" + ], + "detail": { + + } +} \ No newline at end of file diff --git a/aws-lambda-java-tests/src/test/resources/cloudwatchlogs_event.json b/aws-lambda-java-tests/src/test/resources/cloudwatchlogs_event.json new file mode 100644 index 00000000..2b455b9b --- /dev/null +++ b/aws-lambda-java-tests/src/test/resources/cloudwatchlogs_event.json @@ -0,0 +1,5 @@ +{ + "awslogs": { + "data": "H4sIAAAAAAAAAHWPwQqCQBCGX0Xm7EFtK+smZBEUgXoLCdMhFtKV3akI8d0bLYmibvPPN3wz00CJxmQnTO41whwWQRIctmEcB6sQbFC3CjW3XW8kxpOpP+OC22d1Wml1qZkQGtoMsScxaczKN3plG8zlaHIta5KqWsozoTYw3/djzwhpLwivWFGHGpAFe7DL68JlBUk+l7KSN7tCOEJ4M3/qOI49vMHj+zCKdlFqLaU2ZHV2a4Ct/an0/ivdX8oYc1UVX860fQDQiMdxRQEAAA==" + } +} \ No newline at end of file diff --git a/aws-lambda-java-tests/src/test/resources/codecommit_event.json b/aws-lambda-java-tests/src/test/resources/codecommit_event.json new file mode 100644 index 00000000..227cac73 --- /dev/null +++ b/aws-lambda-java-tests/src/test/resources/codecommit_event.json @@ -0,0 +1,27 @@ +{ + "Records": [ + { + "awsRegion": "eu-central-1", + "codecommit": { + "references": [ + { + "commit": "5c4ef1049f1d27deadbeeff313e0730018be182b", + "ref": "refs/heads/master" + } + ] + }, + "customData": "this is custom data", + "eventId": "5a824061-17ca-46a9-bbf9-114edeadbeef", + "eventName": "TriggerEventTest", + "eventPartNumber": 1, + "eventSource": "aws:codecommit", + "eventSourceARN": "arn:aws:codecommit:eu-central-1:123456789012:my-repo", + "eventTime": "2016-01-01T23:59:59.000+0000", + "eventTotalParts": 1, + "eventTriggerConfigId": "5a824061-17ca-46a9-bbf9-114edeadbeef", + "eventTriggerName": "my-trigger", + "eventVersion": "1.0", + "userIdentityARN": "arn:aws:iam::123456789012:root" + } + ] +} \ No newline at end of file diff --git a/aws-lambda-java-tests/src/test/resources/config_event.json b/aws-lambda-java-tests/src/test/resources/config_event.json new file mode 100644 index 00000000..cf795687 --- /dev/null +++ b/aws-lambda-java-tests/src/test/resources/config_event.json @@ -0,0 +1,12 @@ +{ + "invokingEvent": "{\"configurationItem\":{\"configurationItemCaptureTime\":\"2016-10-06T16:46:16.261Z\",\"awsAccountId\":\"123456789012\",\"configurationItemStatus\":\"OK\",\"resourceId\":\"i-00000000\",\"resourceName\":\"foo\",\"configurationStateMd5Hash\":\"8f1ee69b297895a0f8bc5753eca68e96\",\"resourceCreationTime\":\"2016-10-06T16:46:10.489Z\",\"configurationStateId\":0,\"configurationItemVersion\":\"1.2\",\"ARN\":\"arn:aws:ec2:eu-central-1:123456789012:instance/i-00000000\",\"awsRegion\":\"eu-central-1\",\"availabilityZone\":\"eu-central-1\",\"resourceType\":\"AWS::EC2::Instance\",\"tags\":{\"\":\"\"},\"relationships\":[{\"resourceId\":\"eipalloc-00000000\",\"resourceType\":\"AWS::EC2::EIP\",\"name\":\"Is attached to ElasticIp\"}],\"configuration\":{\"\":\"\"}},\"messageType\":\"ConfigurationItemChangeNotification\"}", + "ruleParameters": "{\"\":\"\"}", + "resultToken": "myResultToken", + "eventLeftScope": false, + "executionRoleArn": "arn:aws:iam::123456789012:role/config-role", + "configRuleArn": "arn:aws:config:eu-central-1:123456789012:config-rule/config-rule-0123456", + "configRuleName": "change-triggered-config-rule", + "configRuleId": "config-rule-0123456", + "accountId": "123456789012", + "version": "1.0" +} \ No newline at end of file diff --git a/aws-lambda-java-tests/src/test/resources/connect_event.json b/aws-lambda-java-tests/src/test/resources/connect_event.json new file mode 100644 index 00000000..a9e04f7f --- /dev/null +++ b/aws-lambda-java-tests/src/test/resources/connect_event.json @@ -0,0 +1,33 @@ +{ + "Name": "ContactFlowEvent", + "Details": { + "ContactData": { + "Attributes": {}, + "Channel": "VOICE", + "ContactId": "5ca32fbd-8f92-46af-92a5-6b0f970f0efe", + "CustomerEndpoint": { + "Address": "+11234567890", + "Type": "TELEPHONE_NUMBER" + }, + "InitialContactId": "6ca32fbd-8f92-46af-92a5-6b0f970f0efe", + "InitiationMethod": "API", + "InstanceARN": "arn:aws:connect:eu-central-1:123456789012:instance/9308c2a1-9bc6-4cea-8290-6c0b4a6d38fa", + "MediaStreams": { + "Customer": { + "Audio": { + "StartFragmentNumber": "91343852333181432392682062622220590765191907586", + "StartTimestamp": "1565781909613", + "StreamARN": "arn:aws:kinesisvideo:eu-central-1:123456789012:stream/connect-contact-a3d73b84-ce0e-479a-a9dc-5637c9d30ac9/1565272947806" + } + } + }, + "PreviousContactId": "4ca32fbd-8f92-46af-92a5-6b0f970f0efe", + "Queue": null, + "SystemEndpoint": { + "Address": "+21234567890", + "Type": "TELEPHONE_NUMBER" + } + }, + "Parameters": {} + } +} \ No newline at end of file diff --git a/aws-lambda-java-tests/src/test/resources/dynamo_event.json b/aws-lambda-java-tests/src/test/resources/dynamo_event.json new file mode 100644 index 00000000..f28ce0e6 --- /dev/null +++ b/aws-lambda-java-tests/src/test/resources/dynamo_event.json @@ -0,0 +1,97 @@ +{ + "Records": [ + { + "eventID": "c4ca4238a0b923820dcc509a6f75849b", + "eventName": "INSERT", + "eventVersion": "1.1", + "eventSource": "aws:dynamodb", + "awsRegion": "eu-central-1", + "dynamodb": { + "Keys": { + "Id": { + "N": "101" + } + }, + "NewImage": { + "Message": { + "S": "New item!" + }, + "Id": { + "N": "101" + } + }, + "ApproximateCreationDateTime": 1428537600, + "SequenceNumber": "4421584500000000017450439091", + "SizeBytes": 26, + "StreamViewType": "NEW_AND_OLD_IMAGES" + }, + "eventSourceARN": "arn:aws:dynamodb:eu-central-1:123456789012:table/ExampleTableWithStream/stream/2015-06-27T00:48:05.899", + "userIdentity": { + "principalId": "dynamodb.amazonaws.com", + "type": "Service" + } + }, + { + "eventID": "c81e728d9d4c2f636f067f89cc14862c", + "eventName": "MODIFY", + "eventVersion": "1.1", + "eventSource": "aws:dynamodb", + "awsRegion": "eu-central-1", + "dynamodb": { + "Keys": { + "Id": { + "N": "101" + } + }, + "NewImage": { + "Message": { + "S": "This item has changed" + }, + "Id": { + "N": "101" + } + }, + "OldImage": { + "Message": { + "S": "New item!" + }, + "Id": { + "N": "101" + } + }, + "ApproximateCreationDateTime": 1428537600, + "SequenceNumber": "4421584500000000017450439092", + "SizeBytes": 59, + "StreamViewType": "NEW_AND_OLD_IMAGES" + }, + "eventSourceARN": "arn:aws:dynamodb:eu-central-1:123456789012:table/ExampleTableWithStream/stream/2015-06-27T00:48:05.899" + }, + { + "eventID": "eccbc87e4b5ce2fe28308fd9f2a7baf3", + "eventName": "REMOVE", + "eventVersion": "1.1", + "eventSource": "aws:dynamodb", + "awsRegion": "eu-central-1", + "dynamodb": { + "Keys": { + "Id": { + "N": "101" + } + }, + "OldImage": { + "Message": { + "S": "This item has changed" + }, + "Id": { + "N": "101" + } + }, + "ApproximateCreationDateTime": 1428537600, + "SequenceNumber": "4421584500000000017450439093", + "SizeBytes": 38, + "StreamViewType": "NEW_AND_OLD_IMAGES" + }, + "eventSourceARN": "arn:aws:dynamodb:eu-central-1:123456789012:table/ExampleTableWithStream/stream/2015-06-27T00:48:05.899" + } + ] +} \ No newline at end of file diff --git a/aws-lambda-java-tests/src/test/resources/elb_event.json b/aws-lambda-java-tests/src/test/resources/elb_event.json new file mode 100644 index 00000000..23f599f4 --- /dev/null +++ b/aws-lambda-java-tests/src/test/resources/elb_event.json @@ -0,0 +1,26 @@ +{ + "requestContext": { + "elb": { + "targetGroupArn": "arn:aws:elasticloadbalancing:us-east-1:XXXXXXXXXXX:targetgroup/sample/6d0ecf831eec9f09" + } + }, + "httpMethod": "GET", + "path": "/", + "queryStringParameters": {}, + "headers": { + "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", + "accept-encoding": "gzip", + "accept-language": "en-US,en;q=0.5", + "connection": "keep-alive", + "cookie": "name=value", + "host": "lambda-YYYYYYYY.elb.amazonaws.com", + "upgrade-insecure-requests": "1", + "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:60.0) Gecko/20100101 Firefox/60.0", + "x-amzn-trace-id": "Root=1-5bdb40ca-556d8b0c50dc66f0511bf520", + "x-forwarded-for": "192.0.2.1", + "x-forwarded-port": "80", + "x-forwarded-proto": "http" + }, + "body": "Hello from ELB", + "isBase64Encoded": false +} \ No newline at end of file diff --git a/aws-lambda-java-tests/src/test/resources/firehose_event.json b/aws-lambda-java-tests/src/test/resources/firehose_event.json new file mode 100644 index 00000000..df235839 --- /dev/null +++ b/aws-lambda-java-tests/src/test/resources/firehose_event.json @@ -0,0 +1,12 @@ +{ + "invocationId": "invocationIdExample", + "deliveryStreamArn": "arn:aws:kinesis:EXAMPLE", + "region": "eu-central-1", + "records": [ + { + "recordId": "49546986683135544286507457936321625675700192471156785154", + "approximateArrivalTimestamp": 1495072949453, + "data": "SGVsbG8sIHRoaXMgaXMgYSB0ZXN0IDEyMy4=" + } + ] +} \ No newline at end of file diff --git a/aws-lambda-java-tests/src/test/resources/kafka_event.json b/aws-lambda-java-tests/src/test/resources/kafka_event.json new file mode 100644 index 00000000..ad089134 --- /dev/null +++ b/aws-lambda-java-tests/src/test/resources/kafka_event.json @@ -0,0 +1,16 @@ +{ + "eventSource": "aws:kafka", + "eventSourceArn": "arn:aws:kafka:us-east-1:123456789012:cluster/vpc-3432434/4834-3547-3455-9872-7929", + "records": { + "mytopic-01": [ + { + "topic": "mytopic", + "partition": 0, + "offset": 15, + "timestamp": 1596480920837, + "timestampType": "CREATE_TIME", + "value": "SGVsbG8gZnJvbSBLYWZrYSAhIQ==" + } + ] + } +} \ No newline at end of file diff --git a/aws-lambda-java-tests/src/test/resources/kinesis_event.json b/aws-lambda-java-tests/src/test/resources/kinesis_event.json new file mode 100644 index 00000000..5e083f49 --- /dev/null +++ b/aws-lambda-java-tests/src/test/resources/kinesis_event.json @@ -0,0 +1,21 @@ +{ + "Records": [ + { + "kinesis": { + "partitionKey": "partitionKey-03", + "kinesisSchemaVersion": "1.0", + "data": "SGVsbG8sIHRoaXMgaXMgYSB0ZXN0IDEyMy4=", + "sequenceNumber": "49545115243490985018280067714973144582180062593244200961", + "approximateArrivalTimestamp": 1428537600, + "encryptionType": "NONE" + }, + "eventSource": "aws:kinesis", + "eventID": "shardId-000000000000:49545115243490985018280067714973144582180062593244200961", + "invokeIdentityArn": "arn:aws:iam::EXAMPLE", + "eventVersion": "1.0", + "eventName": "aws:kinesis:record", + "eventSourceARN": "arn:aws:kinesis:EXAMPLE", + "awsRegion": "eu-central-1" + } + ] +} \ No newline at end of file diff --git a/aws-lambda-java-tests/src/test/resources/lambda_destination_event.json b/aws-lambda-java-tests/src/test/resources/lambda_destination_event.json new file mode 100644 index 00000000..30dea813 --- /dev/null +++ b/aws-lambda-java-tests/src/test/resources/lambda_destination_event.json @@ -0,0 +1,23 @@ +{ + "version": "1.0", + "timestamp": "2019-11-24T21:52:47.333Z", + "requestContext": { + "requestId": "8ea123e4-1db7-4aca-ad10-d9ca1234c1fd", + "functionArn": "arn:aws:lambda:sa-east-1:123456678912:function:event-destinations:$LATEST", + "condition": "RetriesExhausted", + "approximateInvokeCount": 3 + }, + "requestPayload": { + "Success": false + }, + "responseContext": { + "statusCode": 200, + "executedVersion": "$LATEST", + "functionError": "Handled" + }, + "responsePayload": { + "errorMessage": "Failure from event, Success = false, I am failing!", + "errorType": "Error", + "stackTrace": [ "exports.handler (/var/task/index.js:18:18)" ] + } +} \ No newline at end of file diff --git a/aws-lambda-java-tests/src/test/resources/lex_event.json b/aws-lambda-java-tests/src/test/resources/lex_event.json new file mode 100644 index 00000000..880baa15 --- /dev/null +++ b/aws-lambda-java-tests/src/test/resources/lex_event.json @@ -0,0 +1,24 @@ +{ + "messageVersion": "1.0", + "invocationSource": "DialogCodeHook", + "userId": "John", + "sessionAttributes": { + "key": "value" + }, + "bot": { + "name": "BookTrip", + "alias": "$LATEST", + "version": "$LATEST" + }, + "outputDialogMode": "Text", + "currentIntent": { + "name": "BookHotel", + "slots": { + "Location": "Chicago", + "CheckInDate": "2030-11-08", + "Nights": 4, + "RoomType": "queen" + }, + "confirmationStatus": "None" + } +} \ No newline at end of file diff --git a/aws-lambda-java-tests/src/test/resources/s3_event.json b/aws-lambda-java-tests/src/test/resources/s3_event.json new file mode 100644 index 00000000..89e0bd31 --- /dev/null +++ b/aws-lambda-java-tests/src/test/resources/s3_event.json @@ -0,0 +1,38 @@ +{ + "Records": [ + { + "eventVersion": "2.0", + "eventSource": "aws:s3", + "awsRegion": "eu-central-1", + "eventTime": "1970-01-01T00:00:00.000Z", + "eventName": "ObjectCreated:Put", + "userIdentity": { + "principalId": "EXAMPLE" + }, + "requestParameters": { + "sourceIPAddress": "127.0.0.1" + }, + "responseElements": { + "x-amz-request-id": "EXAMPLE123456789", + "x-amz-id-2": "EXAMPLE123/5678abcdefghijklambdaisawesome/mnopqrstuvwxyzABCDEFGH" + }, + "s3": { + "s3SchemaVersion": "1.0", + "configurationId": "testConfigRule", + "bucket": { + "name": "example-bucket", + "ownerIdentity": { + "principalId": "EXAMPLE" + }, + "arn": "arn:aws:s3:::example-bucket" + }, + "object": { + "key": "test/key", + "size": 1024, + "eTag": "0123456789abcdef0123456789abcdef", + "sequencer": "0A1B2C3D4E5F678901" + } + } + } + ] +} \ No newline at end of file diff --git a/aws-lambda-java-tests/src/test/resources/secrets_rotation_event.json b/aws-lambda-java-tests/src/test/resources/secrets_rotation_event.json new file mode 100644 index 00000000..38440fac --- /dev/null +++ b/aws-lambda-java-tests/src/test/resources/secrets_rotation_event.json @@ -0,0 +1,5 @@ +{ + "Step" : "CreateSecret", + "SecretId" : "arn:aws:secretsmanager:eu-central-1:123456789012:secret:/powertools/secretparam-xBPaJ5", + "ClientRequestToken" : "123e4567-e89b-12d3-a456-426614174000" +} \ No newline at end of file diff --git a/aws-lambda-java-tests/src/test/resources/sns_event.json b/aws-lambda-java-tests/src/test/resources/sns_event.json new file mode 100644 index 00000000..25e123c4 --- /dev/null +++ b/aws-lambda-java-tests/src/test/resources/sns_event.json @@ -0,0 +1,27 @@ +{ + "Records": [ + { + "EventSource": "aws:sns", + "EventVersion": "1.0", + "EventSubscriptionArn": "arn:aws:sns:eu-central-1:123456789012:TopicSendToMe:e3ddc7d5-2f86-40b8-a13d-3362f94fd8dd", + "Sns": { + "Type": "Notification", + "MessageId": "dc918f50-80c6-56a2-ba33-d8a9bbf013ab", + "TopicArn": "arn:aws:sns:eu-central-1:123456789012:TopicSendToMe", + "Subject": "Test sns message", + "Message": "{\n \"id\": 42,\n \"name\": \"Bob\"\n}", + "Timestamp": "2020-10-08T16:06:14.656Z", + "SignatureVersion": "1", + "Signature": "UWnPpkqPAphyr+6PXzUF9++4zJcw==", + "SigningCertUrl": "https://sns.eu-central-1.amazonaws.com/SimpleNotificationService-a86cb10b4e1f29c941702d737128f7b6.pem", + "UnsubscribeUrl": "https://sns.eu-central-1.amazonaws.com/?Action=Unsubscribe", + "MessageAttributes": { + "name": { + "Type": "String", + "Value": "Bob" + } + } + } + } + ] +} \ No newline at end of file diff --git a/aws-lambda-java-tests/src/test/resources/sqs/sqs_event.json b/aws-lambda-java-tests/src/test/resources/sqs/sqs_event.json new file mode 100644 index 00000000..129e79bb --- /dev/null +++ b/aws-lambda-java-tests/src/test/resources/sqs/sqs_event.json @@ -0,0 +1,22 @@ +{ + "Records": [ + { + "messageId": "d9144555-9a4f-4ec3-99a0-fc4e625a8db2", + "receiptHandle": "7kam5bfzbDsjtcjElvhSbxeLJbeey3A==", + "body": "{\n \"id\": 43242,\n \"name\": \"FooBar XY\",\n \"price\": 258\n}", + "attributes": { + "ApproximateReceiveCount": "1", + "SentTimestamp": "1601975709495", + "SenderId": "AROAIFU457DVZ5L2J53F2", + "ApproximateFirstReceiveTimestamp": "1601975709499" + }, + "messageAttributes": { + + }, + "md5OfBody": "0f96e88a291edb4429f2f7b9fdc3df96", + "eventSource": "aws:sqs", + "eventSourceARN": "arn:aws:sqs:eu-central-1:123456789012:TestLambda", + "awsRegion": "eu-central-1" + } + ] +} \ No newline at end of file diff --git a/aws-lambda-java-tests/src/test/resources/sqs/sqs_event2.json b/aws-lambda-java-tests/src/test/resources/sqs/sqs_event2.json new file mode 100644 index 00000000..129e79bb --- /dev/null +++ b/aws-lambda-java-tests/src/test/resources/sqs/sqs_event2.json @@ -0,0 +1,22 @@ +{ + "Records": [ + { + "messageId": "d9144555-9a4f-4ec3-99a0-fc4e625a8db2", + "receiptHandle": "7kam5bfzbDsjtcjElvhSbxeLJbeey3A==", + "body": "{\n \"id\": 43242,\n \"name\": \"FooBar XY\",\n \"price\": 258\n}", + "attributes": { + "ApproximateReceiveCount": "1", + "SentTimestamp": "1601975709495", + "SenderId": "AROAIFU457DVZ5L2J53F2", + "ApproximateFirstReceiveTimestamp": "1601975709499" + }, + "messageAttributes": { + + }, + "md5OfBody": "0f96e88a291edb4429f2f7b9fdc3df96", + "eventSource": "aws:sqs", + "eventSourceARN": "arn:aws:sqs:eu-central-1:123456789012:TestLambda", + "awsRegion": "eu-central-1" + } + ] +} \ No newline at end of file From cde5fc76f62987184de8106dd707113d270fdaf4 Mon Sep 17 00:00:00 2001 From: Jerome Van Der Linden Date: Thu, 3 Dec 2020 13:55:40 +0100 Subject: [PATCH 2/6] review + javadoc + release --- README.md | 14 ++ aws-lambda-java-tests/RELEASE.CHANGELOG.md | 3 + aws-lambda-java-tests/pom.xml | 159 ++++++++++++++++++ .../runtime/tests/annotations/Event.java | 8 +- .../runtime/tests/annotations/Events.java | 28 +-- .../tests/annotations/HandlerParams.java | 36 ++-- .../lambda/runtime/tests/EventLoaderTest.java | 2 +- .../lambda/runtime/tests/EventTest.java | 2 +- .../lambda/runtime/tests/EventsTest.java | 8 +- .../runtime/tests/HandlerParamsTest.java | 6 +- .../resources/apigw/events/apigw_event.json | 2 +- ...gw_event2.json => apigw_event_nobody.json} | 2 +- .../apigw/responses/apigw_response.json | 2 +- .../apigw/responses/apigw_response2.json | 2 +- .../src/test/resources/sqs/sqs_event2.json | 22 --- .../{sqs_event.json => sqs_event_nobody.json} | 2 +- .../test/resources/sqs/sqs_event_product.json | 22 +++ 17 files changed, 248 insertions(+), 72 deletions(-) create mode 100644 aws-lambda-java-tests/RELEASE.CHANGELOG.md rename aws-lambda-java-tests/src/test/resources/apigw/events/{apigw_event2.json => apigw_event_nobody.json} (97%) delete mode 100644 aws-lambda-java-tests/src/test/resources/sqs/sqs_event2.json rename aws-lambda-java-tests/src/test/resources/sqs/{sqs_event.json => sqs_event_nobody.json} (87%) create mode 100644 aws-lambda-java-tests/src/test/resources/sqs/sqs_event_product.json diff --git a/README.md b/README.md index 44215219..3c386922 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,7 @@ Check out the per-module release notes: - [aws-lambda-java-log4j2](aws-lambda-java-log4j2/RELEASE.CHANGELOG.md) - [aws-lambda-java-runtime-interface-client](aws-lambda-java-runtime-interface-client/RELEASE.CHANGELOG.md) - [aws-lambda-java-serialization](aws-lambda-java-serialization/RELEASE.CHANGELOG.md) +- [aws-lambda-java-test](aws-lambda-java-tests/RELEASE.CHANGELOG.md) # Where to get packages ___ @@ -53,6 +54,12 @@ ___ aws-lambda-java-runtime-interface-client 1.0.0 + + com.amazonaws + aws-lambda-java-tests + 1.0.0 + test + ``` [Gradle](https://gradle.org) @@ -63,6 +70,7 @@ ___ 'com.amazonaws:aws-lambda-java-events-sdk-transformer:3.0.1' 'com.amazonaws:aws-lambda-java-log4j2:1.2.0' 'com.amazonaws:aws-lambda-java-runtime-interface-client:1.0.0' +'com.amazonaws:aws-lambda-java-tests:1.0.0' ``` [Leiningen](http://leiningen.org) and [Boot](http://boot-clj.com) @@ -73,6 +81,7 @@ ___ [com.amazonaws/aws-lambda-java-events-sdk-transformer "3.0.1"] [com.amazonaws/aws-lambda-java-log4j2 "1.2.0"] [com.amazonaws/aws-lambda-java-runtime-interface-client "1.0.0"] +[com.amazonaws/aws-lambda-java-tests "1.0.0"] ``` [sbt](http://www.scala-sbt.org) @@ -83,6 +92,7 @@ ___ "com.amazonaws" % "aws-lambda-java-events-sdk-transformer" % "3.0.1" "com.amazonaws" % "aws-lambda-java-log4j2" % "1.2.0" "com.amazonaws" % "aws-lambda-java-runtime-interface-client" % "1.0.0" +"com.amazonaws" % "aws-lambda-java-tests" % "1.0.0" ``` # Using aws-lambda-java-core @@ -114,3 +124,7 @@ The purpose of this package is to allow developers to deploy their applications # Using aws-lambda-java-serialization This package defines the Lambda serialization logic using in the aws-lambda-java-runtime-client library. It has no current standalone usage. + +# Using aws-lambda-java-tests + +This package provides utils to ease Lambda Java testing. Used with `aws-lambda-java-serialization` and `aws-lambda-java-events` to inject events in your JUnit tests. diff --git a/aws-lambda-java-tests/RELEASE.CHANGELOG.md b/aws-lambda-java-tests/RELEASE.CHANGELOG.md new file mode 100644 index 00000000..60b92247 --- /dev/null +++ b/aws-lambda-java-tests/RELEASE.CHANGELOG.md @@ -0,0 +1,3 @@ +### December 03, 2020 +`1.0.0`: +- Initial release of AWS Lambda Java Tests \ No newline at end of file diff --git a/aws-lambda-java-tests/pom.xml b/aws-lambda-java-tests/pom.xml index 35febdb2..0b734a9b 100644 --- a/aws-lambda-java-tests/pom.xml +++ b/aws-lambda-java-tests/pom.xml @@ -75,6 +75,165 @@ + + + checkDependencies + + + checkDependencies + + + + + + org.owasp + dependency-check-maven + 5.3.2 + + + validate + + check + + + + + + + + + dev + + + + org.apache.maven.plugins + maven-javadoc-plugin + 3.2.0 + + none + false + 8 + false + + + + attach-javadocs + + jar + + + + + + org.jacoco + jacoco-maven-plugin + 0.8.6 + + + default-prepare-agent + + prepare-agent + + + + default-report + test + + report + + + + default-check + test + + check + + + + + PACKAGE + + + LINE + COVEREDRATIO + 0 + + + + + + + + + + + + + release + + + + org.apache.maven.plugins + maven-source-plugin + 2.2.1 + + + attach-sources + + jar-no-fork + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 3.2.0 + + none + false + 8 + false + + + + attach-javadocs + + jar + + + + + + org.apache.maven.plugins + maven-gpg-plugin + 1.5 + + + sign-artifacts + verify + + sign + + + + + + org.sonatype.plugins + nexus-staging-maven-plugin + 1.6.3 + true + + sonatype-nexus-staging + https://aws.oss.sonatype.org/ + false + + + + + + + diff --git a/aws-lambda-java-tests/src/main/java/com/amazonaws/services/lambda/runtime/tests/annotations/Event.java b/aws-lambda-java-tests/src/main/java/com/amazonaws/services/lambda/runtime/tests/annotations/Event.java index a94145eb..d5011290 100644 --- a/aws-lambda-java-tests/src/main/java/com/amazonaws/services/lambda/runtime/tests/annotations/Event.java +++ b/aws-lambda-java-tests/src/main/java/com/amazonaws/services/lambda/runtime/tests/annotations/Event.java @@ -10,14 +10,14 @@ * This annotation must be used in conjunction with {@link org.junit.jupiter.params.ParameterizedTest}.
* It enables to inject an event (loaded from a json file) of the desired type into the current test.
* Example:
- *
{@code
- *     @ParameterizedTest
- *     @Event(value = "sqs_event.json", type = SQSEvent.class)
+ * 
+ *     @ParameterizedTest
+ *     @Event(value = "sqs_event.json", type = SQSEvent.class)
  *     public void testInjectEvent(SQSEvent event) {
  *         assertThat(event).isNotNull();
  *         assertThat(event.getRecords()).hasSize(1);
  *     }
- * }
+ *
*/ @Documented @Target(ElementType.METHOD) diff --git a/aws-lambda-java-tests/src/main/java/com/amazonaws/services/lambda/runtime/tests/annotations/Events.java b/aws-lambda-java-tests/src/main/java/com/amazonaws/services/lambda/runtime/tests/annotations/Events.java index 972454e0..240caab4 100644 --- a/aws-lambda-java-tests/src/main/java/com/amazonaws/services/lambda/runtime/tests/annotations/Events.java +++ b/aws-lambda-java-tests/src/main/java/com/amazonaws/services/lambda/runtime/tests/annotations/Events.java @@ -14,23 +14,23 @@ *
    *
  • * Using the folder parameter is the more straightforward, and it will use all files in the folder
    - *
    {@code
    - *     @ParameterizedTest
    - *     @Events(folder = "sqs", type = SQSEvent.class)
    + * 
    + *     @ParameterizedTest
    + *     @Events(folder = "sqs", type = SQSEvent.class)
      *     public void testInjectEventsFromFolder(SQSEvent event) {
      *         assertThat(event).isNotNull();
      *         assertThat(event.getRecords()).hasSize(1);
      *     }
    - * }
    + *
    *
  • *
  • * Or you can list all the {@link Event}s
    - *
    {@code
    - * @ParameterizedTest
    - *     @Events(
    + * 
    + * @ParameterizedTest
    + *     @Events(
      *             events = {
    - *                     @Event("sqs/sqs_event.json"),
    - *                     @Event("sqs/sqs_event2.json"),
    + *                     @Event("sqs/sqs_event.json"),
    + *                     @Event("sqs/sqs_event2.json"),
      *             },
      *             type = SQSEvent.class
      *     )
    @@ -39,18 +39,18 @@
      *         assertThat(event.getRecords()).hasSize(1);
      *     }
      *
    - *     @ParameterizedTest
    - *     @Events(
    + *     @ParameterizedTest
    + *     @Events(
      *             events = {
    - *                     @Event(value = "sqs/sqs_event.json", type = SQSEvent.class),
    - *                     @Event(value = "sqs/sqs_event2.json", type = SQSEvent.class),
    + *                     @Event(value = "sqs/sqs_event.json", type = SQSEvent.class),
    + *                     @Event(value = "sqs/sqs_event2.json", type = SQSEvent.class),
      *             }
      *     )
      *     public void testInjectEvents2(SQSEvent event) {
      *         assertThat(event).isNotNull();
      *         assertThat(event.getRecords()).hasSize(1);
      *     }
    - * }
    + *
    *
  • *
*

diff --git a/aws-lambda-java-tests/src/main/java/com/amazonaws/services/lambda/runtime/tests/annotations/HandlerParams.java b/aws-lambda-java-tests/src/main/java/com/amazonaws/services/lambda/runtime/tests/annotations/HandlerParams.java index 8c0d108d..3e656cc9 100644 --- a/aws-lambda-java-tests/src/main/java/com/amazonaws/services/lambda/runtime/tests/annotations/HandlerParams.java +++ b/aws-lambda-java-tests/src/main/java/com/amazonaws/services/lambda/runtime/tests/annotations/HandlerParams.java @@ -13,41 +13,41 @@ * or {@link #events()} and {@link #responses()} for multiple ones.
* * Example:
- *
{@code
- * @ParameterizedTest
- * @HandlerParams(
- *         event = @Event(value = "apigw/events/apigw_event.json", type = APIGatewayProxyRequestEvent.class),
- *         response = @Response(value = "apigw/responses/apigw_response.json", type = APIGatewayProxyResponseEvent.class))
+ * 
+ * @ParameterizedTest
+ * @HandlerParams(
+ *         event = @Event(value = "apigw/events/apigw_event.json", type = APIGatewayProxyRequestEvent.class),
+ *         response = @Response(value = "apigw/responses/apigw_response.json", type = APIGatewayProxyResponseEvent.class))
  * public void testSingleEventResponse(APIGatewayProxyRequestEvent event, APIGatewayProxyResponseEvent response) {
  * }
  *
- * @ParameterizedTest
- * @HandlerParams(
- *         events = @Events(folder = "apigw/events/", type = APIGatewayProxyRequestEvent.class),
- *         responses = @Responses(folder = "apigw/responses/", type = APIGatewayProxyResponseEvent.class))
+ * @ParameterizedTest
+ * @HandlerParams(
+ *         events = @Events(folder = "apigw/events/", type = APIGatewayProxyRequestEvent.class),
+ *         responses = @Responses(folder = "apigw/responses/", type = APIGatewayProxyResponseEvent.class))
  * public void testMultipleEventsResponsesInFolder(APIGatewayProxyRequestEvent event, APIGatewayProxyResponseEvent response) {
  * }
  *
- * @ParameterizedTest
- * @HandlerParams(
- *         events = @Events(
+ * @ParameterizedTest
+ * @HandlerParams(
+ *         events = @Events(
  *                 events = {
- *                         @Event("apigw/events/apigw_event.json"),
- *                         @Event("apigw/events/apigw_event2.json"),
+ *                         @Event("apigw/events/apigw_event.json"),
+ *                         @Event("apigw/events/apigw_event2.json"),
  *                 },
  *                 type = APIGatewayProxyRequestEvent.class
  *         ),
- *         responses = @Responses(
+ *         responses = @Responses(
  *                 responses = {
- *                         @Response("apigw/responses/apigw_response.json"),
- *                         @Response("apigw/responses/apigw_response2.json")
+ *                         @Response("apigw/responses/apigw_response.json"),
+ *                         @Response("apigw/responses/apigw_response2.json")
  *                 },
  *                 type = APIGatewayProxyResponseEvent.class
  *         )
  * )
  * public void testMultipleEventsResponses(APIGatewayProxyRequestEvent event, APIGatewayProxyResponseEvent response) {
  * }
- * }
+ *
*/ @Documented @Target(ElementType.METHOD) diff --git a/aws-lambda-java-tests/src/test/java/com/amazonaws/services/lambda/runtime/tests/EventLoaderTest.java b/aws-lambda-java-tests/src/test/java/com/amazonaws/services/lambda/runtime/tests/EventLoaderTest.java index 5002c2f6..bbecccc0 100644 --- a/aws-lambda-java-tests/src/test/java/com/amazonaws/services/lambda/runtime/tests/EventLoaderTest.java +++ b/aws-lambda-java-tests/src/test/java/com/amazonaws/services/lambda/runtime/tests/EventLoaderTest.java @@ -124,7 +124,7 @@ public void testLoadS3Event() { @Test public void testLoadSQSEvent() { - SQSEvent event = EventLoader.loadSQSEvent("sqs/sqs_event.json"); + SQSEvent event = EventLoader.loadSQSEvent("sqs/sqs_event_nobody.json"); assertThat(event).isNotNull(); assertThat(event.getRecords()).hasSize(1); assertThat(event.getRecords().get(0).getEventSourceArn()).isEqualTo("arn:aws:sqs:eu-central-1:123456789012:TestLambda"); diff --git a/aws-lambda-java-tests/src/test/java/com/amazonaws/services/lambda/runtime/tests/EventTest.java b/aws-lambda-java-tests/src/test/java/com/amazonaws/services/lambda/runtime/tests/EventTest.java index ea8f7b50..af94bcc3 100644 --- a/aws-lambda-java-tests/src/test/java/com/amazonaws/services/lambda/runtime/tests/EventTest.java +++ b/aws-lambda-java-tests/src/test/java/com/amazonaws/services/lambda/runtime/tests/EventTest.java @@ -10,7 +10,7 @@ public class EventTest { @ParameterizedTest - @Event(value = "sqs/sqs_event.json", type = SQSEvent.class) + @Event(value = "sqs/sqs_event_nobody.json", type = SQSEvent.class) public void testInjectEvent(SQSEvent event) { assertThat(event).isNotNull(); assertThat(event.getRecords()).hasSize(1); diff --git a/aws-lambda-java-tests/src/test/java/com/amazonaws/services/lambda/runtime/tests/EventsTest.java b/aws-lambda-java-tests/src/test/java/com/amazonaws/services/lambda/runtime/tests/EventsTest.java index 527e8ee0..0861878e 100644 --- a/aws-lambda-java-tests/src/test/java/com/amazonaws/services/lambda/runtime/tests/EventsTest.java +++ b/aws-lambda-java-tests/src/test/java/com/amazonaws/services/lambda/runtime/tests/EventsTest.java @@ -14,8 +14,8 @@ public class EventsTest { @ParameterizedTest @Events( events = { - @Event("sqs/sqs_event.json"), - @Event("sqs/sqs_event2.json"), + @Event("sqs/sqs_event_nobody.json"), + @Event("sqs/sqs_event_product.json"), }, type = SQSEvent.class ) @@ -27,8 +27,8 @@ public void testInjectEvents(SQSEvent event) { @ParameterizedTest @Events( events = { - @Event(value = "sqs/sqs_event.json", type = SQSEvent.class), - @Event(value = "sqs/sqs_event2.json", type = SQSEvent.class), + @Event(value = "sqs/sqs_event_nobody.json", type = SQSEvent.class), + @Event(value = "sqs/sqs_event_product.json", type = SQSEvent.class), } ) public void testInjectEvents2(SQSEvent event) { diff --git a/aws-lambda-java-tests/src/test/java/com/amazonaws/services/lambda/runtime/tests/HandlerParamsTest.java b/aws-lambda-java-tests/src/test/java/com/amazonaws/services/lambda/runtime/tests/HandlerParamsTest.java index 549c70d5..a7c3c6e0 100644 --- a/aws-lambda-java-tests/src/test/java/com/amazonaws/services/lambda/runtime/tests/HandlerParamsTest.java +++ b/aws-lambda-java-tests/src/test/java/com/amazonaws/services/lambda/runtime/tests/HandlerParamsTest.java @@ -16,13 +16,13 @@ public class HandlerParamsTest { response = @Response(value = "apigw/responses/apigw_response.json", type = APIGatewayProxyResponseEvent.class)) public void testSimpleEventResponse(APIGatewayProxyRequestEvent event, APIGatewayProxyResponseEvent response) { assertThat(event).isNotNull(); - assertThat(event.getBody()).contains("hello world"); + assertThat(event.getBody()).contains("Lambda rocks"); assertThat(event.getHeaders()).hasSize(18); assertThat(event.getHttpMethod()).isEqualTo("POST"); assertThat(response).isNotNull(); assertThat(response.getStatusCode()).isEqualTo(200); - assertThat(response.getBody()).contains("hello world"); + assertThat(response.getBody()).contains("Lambda rocks"); } @ParameterizedTest @@ -45,7 +45,7 @@ public void testMultipleEventsResponsesinFolder(APIGatewayProxyRequestEvent even events = @Events( events = { @Event("apigw/events/apigw_event.json"), - @Event("apigw/events/apigw_event2.json"), + @Event("apigw/events/apigw_event_nobody.json"), }, type = APIGatewayProxyRequestEvent.class ), diff --git a/aws-lambda-java-tests/src/test/resources/apigw/events/apigw_event.json b/aws-lambda-java-tests/src/test/resources/apigw/events/apigw_event.json index 070ad8e0..5a575592 100644 --- a/aws-lambda-java-tests/src/test/resources/apigw/events/apigw_event.json +++ b/aws-lambda-java-tests/src/test/resources/apigw/events/apigw_event.json @@ -1,5 +1,5 @@ { - "body": "{\"message\": \"hello world\"}", + "body": "{\"message\": \"Lambda rocks\"}", "resource": "/{proxy+}", "path": "/path/to/resource", "httpMethod": "POST", diff --git a/aws-lambda-java-tests/src/test/resources/apigw/events/apigw_event2.json b/aws-lambda-java-tests/src/test/resources/apigw/events/apigw_event_nobody.json similarity index 97% rename from aws-lambda-java-tests/src/test/resources/apigw/events/apigw_event2.json rename to aws-lambda-java-tests/src/test/resources/apigw/events/apigw_event_nobody.json index 5a575592..e5677441 100644 --- a/aws-lambda-java-tests/src/test/resources/apigw/events/apigw_event2.json +++ b/aws-lambda-java-tests/src/test/resources/apigw/events/apigw_event_nobody.json @@ -1,5 +1,5 @@ { - "body": "{\"message\": \"Lambda rocks\"}", + "body": "", "resource": "/{proxy+}", "path": "/path/to/resource", "httpMethod": "POST", diff --git a/aws-lambda-java-tests/src/test/resources/apigw/responses/apigw_response.json b/aws-lambda-java-tests/src/test/resources/apigw/responses/apigw_response.json index c8170a55..691ca3a9 100644 --- a/aws-lambda-java-tests/src/test/resources/apigw/responses/apigw_response.json +++ b/aws-lambda-java-tests/src/test/resources/apigw/responses/apigw_response.json @@ -1,5 +1,5 @@ { - "body": "{\"message\": \"hello world\"}", + "body": "{\"message\": \"Lambda rocks\"}", "statusCode": 200, "headers": { "Cache-Control": "max-age=0", diff --git a/aws-lambda-java-tests/src/test/resources/apigw/responses/apigw_response2.json b/aws-lambda-java-tests/src/test/resources/apigw/responses/apigw_response2.json index 691ca3a9..365d9ca5 100644 --- a/aws-lambda-java-tests/src/test/resources/apigw/responses/apigw_response2.json +++ b/aws-lambda-java-tests/src/test/resources/apigw/responses/apigw_response2.json @@ -1,5 +1,5 @@ { - "body": "{\"message\": \"Lambda rocks\"}", + "body": "", "statusCode": 200, "headers": { "Cache-Control": "max-age=0", diff --git a/aws-lambda-java-tests/src/test/resources/sqs/sqs_event2.json b/aws-lambda-java-tests/src/test/resources/sqs/sqs_event2.json deleted file mode 100644 index 129e79bb..00000000 --- a/aws-lambda-java-tests/src/test/resources/sqs/sqs_event2.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "Records": [ - { - "messageId": "d9144555-9a4f-4ec3-99a0-fc4e625a8db2", - "receiptHandle": "7kam5bfzbDsjtcjElvhSbxeLJbeey3A==", - "body": "{\n \"id\": 43242,\n \"name\": \"FooBar XY\",\n \"price\": 258\n}", - "attributes": { - "ApproximateReceiveCount": "1", - "SentTimestamp": "1601975709495", - "SenderId": "AROAIFU457DVZ5L2J53F2", - "ApproximateFirstReceiveTimestamp": "1601975709499" - }, - "messageAttributes": { - - }, - "md5OfBody": "0f96e88a291edb4429f2f7b9fdc3df96", - "eventSource": "aws:sqs", - "eventSourceARN": "arn:aws:sqs:eu-central-1:123456789012:TestLambda", - "awsRegion": "eu-central-1" - } - ] -} \ No newline at end of file diff --git a/aws-lambda-java-tests/src/test/resources/sqs/sqs_event.json b/aws-lambda-java-tests/src/test/resources/sqs/sqs_event_nobody.json similarity index 87% rename from aws-lambda-java-tests/src/test/resources/sqs/sqs_event.json rename to aws-lambda-java-tests/src/test/resources/sqs/sqs_event_nobody.json index 129e79bb..bff825bd 100644 --- a/aws-lambda-java-tests/src/test/resources/sqs/sqs_event.json +++ b/aws-lambda-java-tests/src/test/resources/sqs/sqs_event_nobody.json @@ -3,7 +3,7 @@ { "messageId": "d9144555-9a4f-4ec3-99a0-fc4e625a8db2", "receiptHandle": "7kam5bfzbDsjtcjElvhSbxeLJbeey3A==", - "body": "{\n \"id\": 43242,\n \"name\": \"FooBar XY\",\n \"price\": 258\n}", + "body": "", "attributes": { "ApproximateReceiveCount": "1", "SentTimestamp": "1601975709495", diff --git a/aws-lambda-java-tests/src/test/resources/sqs/sqs_event_product.json b/aws-lambda-java-tests/src/test/resources/sqs/sqs_event_product.json new file mode 100644 index 00000000..150d52ba --- /dev/null +++ b/aws-lambda-java-tests/src/test/resources/sqs/sqs_event_product.json @@ -0,0 +1,22 @@ +{ + "Records": [ + { + "messageId": "d9144555-9a4f-4ec3-99a0-34ce359b4b54", + "receiptHandle": "13e7f7851d2eaa5c01f208ebadbf1e72==", + "body": "{\n \"id\": 1234,\n \"name\": \"Playstation 5\",\n \"price\": 450\n}", + "attributes": { + "ApproximateReceiveCount": "1", + "SentTimestamp": "1601975706495", + "SenderId": "AROAIFU437PVZ5L2J53F5", + "ApproximateFirstReceiveTimestamp": "1601975706499" + }, + "messageAttributes": { + + }, + "md5OfBody": "13e7f7851d2eaa5c01f208ebadbf1e72", + "eventSource": "aws:sqs", + "eventSourceARN": "arn:aws:sqs:eu-central-1:123456789012:TestLambda", + "awsRegion": "eu-central-1" + } + ] +} \ No newline at end of file From 952c194c8572627c2d14b5786b0bd809f525b113 Mon Sep 17 00:00:00 2001 From: Jerome Van Der Linden Date: Fri, 4 Dec 2020 13:18:41 +0100 Subject: [PATCH 3/6] review #2 --- .github/workflows/aws-lambda-java-events.yml | 2 +- .../src/test/resources/sqs/sqs_event_product.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/aws-lambda-java-events.yml b/.github/workflows/aws-lambda-java-events.yml index 6b7e2f81..df2a06be 100644 --- a/.github/workflows/aws-lambda-java-events.yml +++ b/.github/workflows/aws-lambda-java-events.yml @@ -34,4 +34,4 @@ jobs: run: mvn -B package --file aws-lambda-java-serialization/pom.xml - name: Build events-sdk-transformer with Maven run: mvn -B package --file aws-lambda-java-events-sdk-transformer/pom.xml - + diff --git a/aws-lambda-java-tests/src/test/resources/sqs/sqs_event_product.json b/aws-lambda-java-tests/src/test/resources/sqs/sqs_event_product.json index 150d52ba..d97bf2c9 100644 --- a/aws-lambda-java-tests/src/test/resources/sqs/sqs_event_product.json +++ b/aws-lambda-java-tests/src/test/resources/sqs/sqs_event_product.json @@ -3,7 +3,7 @@ { "messageId": "d9144555-9a4f-4ec3-99a0-34ce359b4b54", "receiptHandle": "13e7f7851d2eaa5c01f208ebadbf1e72==", - "body": "{\n \"id\": 1234,\n \"name\": \"Playstation 5\",\n \"price\": 450\n}", + "body": "{\n \"id\": 1234,\n \"name\": \"Product1234\",\n \"price\": 450\n}", "attributes": { "ApproximateReceiveCount": "1", "SentTimestamp": "1601975706495", From 70ac5345e6f5977bb71b8c7c2c1e8ea450c36143 Mon Sep 17 00:00:00 2001 From: Jerome Van Der Linden Date: Sun, 6 Dec 2020 18:21:32 +0100 Subject: [PATCH 4/6] close stream --- .../services/lambda/runtime/tests/EventLoader.java | 12 ++++++++++-- .../src/test/resources/cloudwatch_event.json | 4 ++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/aws-lambda-java-tests/src/main/java/com/amazonaws/services/lambda/runtime/tests/EventLoader.java b/aws-lambda-java-tests/src/main/java/com/amazonaws/services/lambda/runtime/tests/EventLoader.java index edec372c..f542fbe1 100644 --- a/aws-lambda-java-tests/src/main/java/com/amazonaws/services/lambda/runtime/tests/EventLoader.java +++ b/aws-lambda-java-tests/src/main/java/com/amazonaws/services/lambda/runtime/tests/EventLoader.java @@ -68,7 +68,7 @@ public static KinesisEvent loadKinesisEvent(String filename) { return loadEvent(filename, KinesisEvent.class); } - public static KinesisFirehoseEvent loadKinesisFirehoseEvent(String filename){ + public static KinesisFirehoseEvent loadKinesisFirehoseEvent(String filename) { return loadEvent(filename, KinesisFirehoseEvent.class); } @@ -119,6 +119,14 @@ public static T loadEvent(String filename, Class targetClass) { throw new EventLoadingException("Cannot load " + filename, e); } } - return serializer.fromJson(stream); + try { + return serializer.fromJson(stream); + } finally { + try { + stream.close(); + } catch (IOException ioe) { + ioe.printStackTrace(); + } + } } } diff --git a/aws-lambda-java-tests/src/test/resources/cloudwatch_event.json b/aws-lambda-java-tests/src/test/resources/cloudwatch_event.json index a63ad046..0573f3fe 100644 --- a/aws-lambda-java-tests/src/test/resources/cloudwatch_event.json +++ b/aws-lambda-java-tests/src/test/resources/cloudwatch_event.json @@ -3,11 +3,11 @@ "id": "fae0433b-7a0e-e383-7849-7e10153eaa47", "detail-type": "Scheduled Event", "source": "aws.events", - "account": "705456458224", + "account": "123456789012", "time": "2020-09-30T15:58:34Z", "region": "eu-central-1", "resources": [ - "arn:aws:events:eu-central-1:705456458224:rule/demoschedule" + "arn:aws:events:eu-central-1:123456789012:rule/demoschedule" ], "detail": { From 27c86c076594507410d5cda57e912857be0b3ef6 Mon Sep 17 00:00:00 2001 From: Jerome Van Der Linden Date: Mon, 7 Dec 2020 09:05:19 +0100 Subject: [PATCH 5/6] add activeMQ event --- .../lambda/runtime/tests/EventLoader.java | 5 +++ .../lambda/runtime/tests/EventLoaderTest.java | 10 ++++++ .../src/test/resources/mq_event.json | 32 +++++++++++++++++++ 3 files changed, 47 insertions(+) create mode 100644 aws-lambda-java-tests/src/test/resources/mq_event.json diff --git a/aws-lambda-java-tests/src/main/java/com/amazonaws/services/lambda/runtime/tests/EventLoader.java b/aws-lambda-java-tests/src/main/java/com/amazonaws/services/lambda/runtime/tests/EventLoader.java index f542fbe1..0216d5e3 100644 --- a/aws-lambda-java-tests/src/main/java/com/amazonaws/services/lambda/runtime/tests/EventLoader.java +++ b/aws-lambda-java-tests/src/main/java/com/amazonaws/services/lambda/runtime/tests/EventLoader.java @@ -12,6 +12,11 @@ * Load events from json files and serialize them in Events */ public class EventLoader { + + public static ActiveMQEvent loadActiveMQEvent(String filename) { + return loadEvent(filename, ActiveMQEvent.class); + } + public static APIGatewayV2HTTPEvent loadApiGatewayHttpEvent(String filename) { return loadEvent(filename, APIGatewayV2HTTPEvent.class); } diff --git a/aws-lambda-java-tests/src/test/java/com/amazonaws/services/lambda/runtime/tests/EventLoaderTest.java b/aws-lambda-java-tests/src/test/java/com/amazonaws/services/lambda/runtime/tests/EventLoaderTest.java index bbecccc0..61d9eaf1 100644 --- a/aws-lambda-java-tests/src/test/java/com/amazonaws/services/lambda/runtime/tests/EventLoaderTest.java +++ b/aws-lambda-java-tests/src/test/java/com/amazonaws/services/lambda/runtime/tests/EventLoaderTest.java @@ -191,6 +191,16 @@ public void testLoadKinesisEvent() { assertThat(new String(record.getData().array())).isEqualTo("Hello, this is a test 123."); } + @Test + public void testLoadActiveMQEvent() { + ActiveMQEvent event = EventLoader.loadActiveMQEvent("mq_event.json"); + assertThat(event).isNotNull(); + assertThat(event.getMessages()).hasSize(2); + + assertThat(event.getMessages().get(0).getMessageID()).isEqualTo("ID:b-9bcfa592-423a-4942-879d-eb284b418fc8-1.mq.us-west-2.amazonaws.com-37557-1234520418293-4:1:1:1:1"); + assertThat(event.getMessages().get(1).getMessageID()).isEqualTo("ID:b-8bcfa572-428a-4642-879d-eb284b418fc8-1.mq.us-west-2.amazonaws.com-37557-1234520418293-4:1:1:1:1"); + } + @Test public void testLoadCodeCommitEvent() { CodeCommitEvent event = EventLoader.loadCodeCommitEvent("codecommit_event.json"); diff --git a/aws-lambda-java-tests/src/test/resources/mq_event.json b/aws-lambda-java-tests/src/test/resources/mq_event.json new file mode 100644 index 00000000..a9a79854 --- /dev/null +++ b/aws-lambda-java-tests/src/test/resources/mq_event.json @@ -0,0 +1,32 @@ +{ + "eventSource": "aws:amq", + "eventSourceArn": "arn:aws:mq:us-west-2:112556298976:broker:test:b-9bcfa592-423a-4942-879d-eb284b418fc8", + "messages": [ + { + "messageID": "ID:b-9bcfa592-423a-4942-879d-eb284b418fc8-1.mq.us-west-2.amazonaws.com-37557-1234520418293-4:1:1:1:1", + "messageType": "jms/text-message", + "data": "QUJDOkFBQUE=", + "connectionId": "myJMSCoID", + "redelivered": false, + "destination": { + "physicalname": "testQueue" + }, + "timestamp": 1598827811958, + "brokerInTime": 1598827811958, + "brokerOutTime": 1598827811959 + }, + { + "messageID": "ID:b-8bcfa572-428a-4642-879d-eb284b418fc8-1.mq.us-west-2.amazonaws.com-37557-1234520418293-4:1:1:1:1", + "messageType": "jms/bytes-message", + "data": "3DTOOW7crj51prgVLQaGQ82S48k=", + "connectionId": "myJMSCoID1", + "persistent": false, + "destination": { + "physicalname": "testQueue" + }, + "timestamp": 1598827811958, + "brokerInTime": 1598827811958, + "brokerOutTime": 1598827811959 + } + ] +} \ No newline at end of file From bdf82fbdcf6daa0a946eecfe8f0accd747e4342b Mon Sep 17 00:00:00 2001 From: Carl Zogheib <11421173+carlzogh@users.noreply.github.com> Date: Thu, 10 Dec 2020 15:09:30 +0000 Subject: [PATCH 6/6] Add tests module workflow --- .github/workflows/aws-lambda-java-tests.yml | 37 +++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 .github/workflows/aws-lambda-java-tests.yml diff --git a/.github/workflows/aws-lambda-java-tests.yml b/.github/workflows/aws-lambda-java-tests.yml new file mode 100644 index 00000000..b00b3781 --- /dev/null +++ b/.github/workflows/aws-lambda-java-tests.yml @@ -0,0 +1,37 @@ +# This workflow will be triggered if there will be changes to aws-lambda-java-tests +# package and it builds the package and the packages that depend on it. + +name: Java CI aws-lambda-java-tests + +on: + push: + branches: [ master ] + paths: + - 'aws-lambda-java-tests/**' + pull_request: + branches: [ '*' ] + paths: + - 'aws-lambda-java-tests/**' + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: Set up JDK 1.8 + uses: actions/setup-java@v1 + with: + java-version: 1.8 + + # Install base module + - name: Install events with Maven + run: mvn -B install --file aws-lambda-java-events/pom.xml + - name: Install serialization with Maven + run: mvn -B install --file aws-lambda-java-serialization/pom.xml + + # Package target module + - name: Package tests with Maven + run: mvn -B package --file aws-lambda-java-tests/pom.xml +