diff --git a/powertools-e2e-tests/README.md b/powertools-e2e-tests/README.md
index ea1546025..42fe9191b 100644
--- a/powertools-e2e-tests/README.md
+++ b/powertools-e2e-tests/README.md
@@ -1,10 +1,13 @@
## End-to-end tests
This module is internal and meant to be used for end-to-end (E2E) testing of Lambda Powertools for Java.
-__Prerequisites__: an AWS account is needed as well as a local environment able to reach this account
+__Prerequisites__:
+- An AWS account is needed as well as a local environment able to reach this account
([credentials](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/credentials.html)).
+- [Java 11+](https://docs.aws.amazon.com/corretto/latest/corretto-11-ug/downloads-list.html)
+- [Docker](https://docs.docker.com/engine/install/)
-To execute the E2E tests, use the following command: `mvn clean verify -Pe2e`
+To execute the E2E tests, use the following command: `export JAVA_VERSION=11 && mvn clean verify -Pe2e`
### Under the hood
This module leverages the following components:
diff --git a/powertools-e2e-tests/src/test/java/software/amazon/lambda/powertools/testutils/Infrastructure.java b/powertools-e2e-tests/src/test/java/software/amazon/lambda/powertools/testutils/Infrastructure.java
index 2afd6a30a..a1d17369e 100644
--- a/powertools-e2e-tests/src/test/java/software/amazon/lambda/powertools/testutils/Infrastructure.java
+++ b/powertools-e2e-tests/src/test/java/software/amazon/lambda/powertools/testutils/Infrastructure.java
@@ -33,13 +33,22 @@
import java.io.File;
import java.io.IOException;
-import java.io.InputStream;
import java.nio.file.Path;
import java.util.*;
import java.util.stream.Collectors;
import static java.util.Collections.singletonList;
+/**
+ * This class is in charge of bootstrapping the infrastructure for the tests.
+ *
+ * Tests are actually run on AWS, so we need to provision Lambda functions, DynamoDB table (for Idempotency),
+ * CloudWatch log groups, ...
+ *
+ * It uses the Cloud Development Kit (CDK) to define required resources. The CDK stack is then synthesized to retrieve
+ * the CloudFormation templates and the assets (function jars). Assets are uploaded to S3 (with the SDK `PutObjectRequest`)
+ * and the CloudFormation stack is created (with the SDK `createStack`)
+ */
public class Infrastructure {
private static final Logger LOG = LoggerFactory.getLogger(Infrastructure.class);
@@ -92,6 +101,10 @@ private Infrastructure(Builder builder) {
.build();
}
+ /**
+ * Use the CloudFormation SDK to create the stack
+ * @return the name of the function deployed part of the stack
+ */
public String deploy() {
uploadAssets();
LOG.info("Deploying '" + stackName + "' on account " + account);
@@ -111,6 +124,9 @@ public String deploy() {
return functionName;
}
+ /**
+ * Destroy the CloudFormation stack
+ */
public void destroy() {
LOG.info("Deleting '" + stackName + "' on account " + account);
cfn.deleteStack(DeleteStackRequest.builder().stackName(stackName).build());
@@ -193,6 +209,10 @@ public Builder timeoutInSeconds(long timeoutInSeconds) {
}
}
+ /**
+ * Build the CDK Stack containing the required resources (Lambda function, LogGroup, DDB Table)
+ * @return the CDK stack
+ */
private Stack createStackWithLambda() {
Stack stack = new Stack(app, stackName);
List packagingInstruction = Arrays.asList(
@@ -261,12 +281,18 @@ private Stack createStackWithLambda() {
return stack;
}
+ /**
+ * cdk synth to retrieve the CloudFormation template and assets directory
+ */
private void synthesize() {
CloudAssembly synth = app.synth();
cfnTemplate = synth.getStackByName(stack.getStackName()).getTemplate();
cfnAssetDirectory = synth.getDirectory();
}
+ /**
+ * Upload assets (mainly lambda function jars) to S3
+ */
private void uploadAssets() {
Map assets = findAssets();
assets.forEach((objectKey, asset) -> {
@@ -283,6 +309,10 @@ private void uploadAssets() {
});
}
+ /**
+ * Reading the cdk assets.json file to retrieve the list of assets to push to S3
+ * @return a map of assets
+ */
private Map findAssets() {
Map assets = new HashMap<>();
try {
diff --git a/powertools-e2e-tests/src/test/java/software/amazon/lambda/powertools/testutils/logging/InvocationLogs.java b/powertools-e2e-tests/src/test/java/software/amazon/lambda/powertools/testutils/logging/InvocationLogs.java
index bad4c4bcb..1ae1cfad7 100644
--- a/powertools-e2e-tests/src/test/java/software/amazon/lambda/powertools/testutils/logging/InvocationLogs.java
+++ b/powertools-e2e-tests/src/test/java/software/amazon/lambda/powertools/testutils/logging/InvocationLogs.java
@@ -5,9 +5,12 @@
import java.util.Base64;
import java.util.stream.IntStream;
+/**
+ * Logs for a specific Lambda invocation
+ */
public class InvocationLogs {
- private String[] logs;
- private String[] functionLogs;
+ private final String[] logs;
+ private final String[] functionLogs;
public InvocationLogs(String base64Logs, String requestId) {
String rawLogs = new String(Base64.getDecoder().decode(base64Logs), StandardCharsets.UTF_8);
diff --git a/powertools-e2e-tests/src/test/java/software/amazon/lambda/powertools/testutils/metrics/MetricsFetcher.java b/powertools-e2e-tests/src/test/java/software/amazon/lambda/powertools/testutils/metrics/MetricsFetcher.java
index da44e4206..eb3cd63a4 100644
--- a/powertools-e2e-tests/src/test/java/software/amazon/lambda/powertools/testutils/metrics/MetricsFetcher.java
+++ b/powertools-e2e-tests/src/test/java/software/amazon/lambda/powertools/testutils/metrics/MetricsFetcher.java
@@ -20,6 +20,10 @@
import java.util.concurrent.Callable;
import static java.time.Duration.ofSeconds;
+
+/**
+ * Class in charge of retrieving the actual metrics of a Lambda execution on CloudWatch
+ */
public class MetricsFetcher {
private static final Logger LOG = LoggerFactory.getLogger(MetricsFetcher.class);
@@ -30,6 +34,17 @@ public class MetricsFetcher {
.region(region)
.build();
+ /**
+ * Retrieve the metric values from start to end. Different parameters are required (see {@link CloudWatchClient#getMetricData} for more info).
+ * Use a retry mechanism as metrics may not be available instantaneously after a function runs.
+ * @param start
+ * @param end
+ * @param period
+ * @param namespace
+ * @param metricName
+ * @param dimensions
+ * @return
+ */
public List fetchMetrics(Instant start, Instant end, int period, String namespace, String metricName, Map dimensions) {
List dimensionsList = new ArrayList<>();
if (dimensions != null)
diff --git a/powertools-e2e-tests/src/test/java/software/amazon/lambda/powertools/testutils/tracing/TraceFetcher.java b/powertools-e2e-tests/src/test/java/software/amazon/lambda/powertools/testutils/tracing/TraceFetcher.java
index 4433876a1..b26dbd0fe 100644
--- a/powertools-e2e-tests/src/test/java/software/amazon/lambda/powertools/testutils/tracing/TraceFetcher.java
+++ b/powertools-e2e-tests/src/test/java/software/amazon/lambda/powertools/testutils/tracing/TraceFetcher.java
@@ -26,6 +26,9 @@
import static java.time.Duration.ofSeconds;
+/**
+ * Class in charge of retrieving the actual traces of a Lambda execution on X-Ray
+ */
public class TraceFetcher {
private static final ObjectMapper MAPPER = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
@@ -36,6 +39,12 @@ public class TraceFetcher {
private final String filterExpression;
private final List excludedSegments;
+ /**
+ * @param start beginning of the time slot to search in
+ * @param end end of the time slot to search in
+ * @param filterExpression eventual filter for the search
+ * @param excludedSegments list of segment to exclude from the search
+ */
public TraceFetcher(Instant start, Instant end, String filterExpression, List excludedSegments) {
this.start = start;
this.end = end;
@@ -47,6 +56,12 @@ public static Builder builder() {
return new Builder();
}
+ /**
+ * Retrieve the traces corresponding to a specific function during a specific time slot.
+ * Use a retry mechanism as traces may not be available instantaneously after a function runs.
+ *
+ * @return traces
+ */
public Trace fetchTrace() {
Callable callable = () -> {
List traceIds = getTraceIds();
@@ -67,6 +82,11 @@ public Trace fetchTrace() {
return status.getResult();
}
+ /**
+ * Retrieve traces from trace ids.
+ * @param traceIds
+ * @return
+ */
private Trace getTrace(List traceIds) {
BatchGetTracesResponse tracesResponse = xray.batchGetTraces(BatchGetTracesRequest.builder()
.traceIds(traceIds)
@@ -110,6 +130,10 @@ private void getNestedSubSegments(List subsegments, Trace traceRes,
});
}
+ /**
+ * Use the X-Ray SDK to retrieve the trace ids corresponding to a specific function during a specific time slot
+ * @return a list of trace ids
+ */
private List getTraceIds() {
GetTraceSummariesResponse traceSummaries = xray.getTraceSummaries(GetTraceSummariesRequest.builder()
.startTime(start)