Skip to content

Commit 640b766

Browse files
AntoniaSzecsiAntoniaSzecsi
andauthored
Enabling Local Testing with RIE and Improving Tests Coverability (#560)
* Add local testing support with RIE * Improve code test coverage from 0.45 to 0.5 * Replace the hardcoded versions with RELEASE versions * Replace Dockerfile base image with image that has RIE preinstalled * Change from mvn central artifacts to locally built ones * Update from java 11 to java 21 and remove duplicate entries from pom * Clean up test coverage configuration * Update README to reflect changes --------- Co-authored-by: AntoniaSzecsi <[email protected]>
1 parent e54cf69 commit 640b766

File tree

6 files changed

+140
-1
lines changed

6 files changed

+140
-1
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
FROM public.ecr.aws/lambda/java:21
2+
3+
COPY target/aws-lambda-java-runtime-interface-client-*.jar ${LAMBDA_TASK_ROOT}/
4+
COPY target/aws-lambda-java-core-*.jar ${LAMBDA_TASK_ROOT}/
5+
COPY target/aws-lambda-java-serialization-*.jar ${LAMBDA_TASK_ROOT}/
6+
COPY test-handlers/EchoHandler.class ${LAMBDA_TASK_ROOT}/
7+
8+
CMD ["EchoHandler::handleRequest"]

aws-lambda-java-runtime-interface-client/Makefile

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@ publish:
6565
test-publish:
6666
./ric-dev-environment/test-platform-specific-jar-snapshot.sh
6767

68+
.PHONY: test-rie
69+
test-rie:
70+
./scripts/test-rie.sh "EchoHandler::handleRequest"
71+
6872
define HELP_MESSAGE
6973

7074
Usage: $ make [TARGETS]
@@ -74,5 +78,5 @@ TARGETS
7478
dev Run all development tests after a change.
7579
pr Perform all checks before submitting a Pull Request.
7680
test Run the Unit tests.
77-
81+
test-rie Build and test RIC locally with Lambda Runtime Interface Emulator. (Requires building the project first)
7882
endef

aws-lambda-java-runtime-interface-client/README.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,49 @@ This command invokes the function running in the container image and returns a r
138138

139139
*Alternately, you can also include RIE as a part of your base image. See the AWS documentation on how to [Build RIE into your base image](https://docs.aws.amazon.com/lambda/latest/dg/images-test.html#images-test-alternative).*
140140

141+
### Automated Local Testing
142+
143+
For developers working on this runtime interface client, we provide an automated testing script that handles RIE setup, dependency management, and Docker orchestration.
144+
145+
*Prerequisites:*
146+
- Build the project first: `mvn clean install`
147+
- Docker must be installed and running
148+
149+
*To run automated tests:*
150+
151+
```shell script
152+
make test-rie
153+
```
154+
155+
This single command will:
156+
- Automatically download required dependencies (aws-lambda-java-core, aws-lambda-java-serialization)
157+
- Build a Docker image with RIE pre-installed
158+
- Compile and run a test Lambda function (EchoHandler)
159+
- Execute the function and validate the response
160+
- Clean up containers automatically
161+
162+
The test uses a simple EchoHandler that returns the input event, making it easy to verify the runtime interface client is working correctly.
163+
164+
## Test Coverage
165+
166+
This project uses JaCoCo for code coverage analysis. To exclude classes from JaCoCo coverage, add them to the `jacoco-maven-plugin` configuration:
167+
168+
```xml
169+
<plugin>
170+
<groupId>org.jacoco</groupId>
171+
<artifactId>jacoco-maven-plugin</artifactId>
172+
<configuration>
173+
<excludes>
174+
<exclude>**/*Exception.class</exclude>
175+
<exclude>**/dto/*.class</exclude>
176+
<exclude>**/YourClassName.class</exclude>
177+
</excludes>
178+
</configuration>
179+
</plugin>
180+
```
181+
182+
This project excludes by default: exceptions, interfaces, DTOs, constants, and runtime-only classes.
183+
141184
### Troubleshooting
142185

143186
While running integration tests, you might encounter the Docker Hub rate limit error with the following body:

aws-lambda-java-runtime-interface-client/pom.xml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,24 @@
214214
<groupId>org.jacoco</groupId>
215215
<artifactId>jacoco-maven-plugin</artifactId>
216216
<version>${jacoco.maven.plugin.version}</version>
217+
<configuration>
218+
<excludes>
219+
<!-- Exclude simple exceptions (compiler enforced) -->
220+
<exclude>**/*Exception.class</exclude>
221+
<!-- Exclude interfaces (compiler enforced) -->
222+
<exclude>**/Resource.class</exclude>
223+
<!-- Exclude simple DTOs/POJOs (data containers) -->
224+
<exclude>**/dto/*.class</exclude>
225+
<!-- Exclude constants classes (build-time values) -->
226+
<exclude>**/ReservedRuntimeEnvironmentVariables.class</exclude>
227+
<exclude>**/RapidErrorType.class</exclude>
228+
<!-- Exclude enum-like data holders -->
229+
<exclude>**/FrameType.class</exclude>
230+
<exclude>**/StructuredLogMessage.class</exclude>
231+
<!-- Exclude main entry point (runtime-only) -->
232+
<exclude>**/AWSLambda.class</exclude>
233+
</excludes>
234+
</configuration>
217235
<executions>
218236
<execution>
219237
<id>default-prepare-agent</id>
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#!/bin/bash
2+
set -euo pipefail
3+
4+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
5+
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
6+
SERIALIZATION_ROOT="$(dirname "$PROJECT_ROOT")/aws-lambda-java-serialization"
7+
8+
if ! ls "$PROJECT_ROOT"/target/aws-lambda-java-runtime-interface-client-*.jar >/dev/null 2>&1; then
9+
echo "RIC jar not found. Please build the project first with 'mvn package'."
10+
exit 1
11+
fi
12+
13+
IMAGE_TAG="java-ric-rie-test"
14+
15+
HANDLER="${1:-EchoHandler::handleRequest}"
16+
17+
echo "Starting RIE test setup for Java..."
18+
19+
# Build local dependencies if not present
20+
CORE_ROOT="$(dirname "$PROJECT_ROOT")/aws-lambda-java-core"
21+
if ! ls "$PROJECT_ROOT"/target/aws-lambda-java-core-*.jar >/dev/null 2>&1; then
22+
echo "Building local aws-lambda-java-core..."
23+
(cd "$CORE_ROOT" && mvn package -DskipTests)
24+
cp "$CORE_ROOT"/target/aws-lambda-java-core-*.jar "$PROJECT_ROOT/target/"
25+
fi
26+
27+
if ! ls "$PROJECT_ROOT"/target/aws-lambda-java-serialization-*.jar >/dev/null 2>&1; then
28+
echo "Building local aws-lambda-java-serialization..."
29+
(cd "$SERIALIZATION_ROOT" && mvn package -DskipTests)
30+
cp "$SERIALIZATION_ROOT"/target/aws-lambda-java-serialization-*.jar "$PROJECT_ROOT/target/"
31+
fi
32+
33+
echo "Compiling EchoHandler..."
34+
javac -source 21 -target 21 -cp "$(ls "$PROJECT_ROOT"/target/aws-lambda-java-runtime-interface-client-*.jar):$(ls "$PROJECT_ROOT"/target/aws-lambda-java-core-*.jar):$(ls "$PROJECT_ROOT"/target/aws-lambda-java-serialization-*.jar)" \
35+
-d "$PROJECT_ROOT/test-handlers/" "$PROJECT_ROOT/test-handlers/EchoHandler.java"
36+
37+
echo "Building test Docker image..."
38+
docker build -t "$IMAGE_TAG" -f "$PROJECT_ROOT/Dockerfile.rie" "$PROJECT_ROOT"
39+
40+
echo "Starting test container on port 9000..."
41+
echo ""
42+
echo "In another terminal, invoke with:"
43+
echo "curl -s -X POST -H 'Content-Type: application/json' \"http://localhost:9000/2015-03-31/functions/function/invocations\" -d '{\"message\":\"test\"}'"
44+
echo ""
45+
46+
exec docker run -it -p 9000:8080 -e _HANDLER="$HANDLER" "$IMAGE_TAG"
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import com.amazonaws.services.lambda.runtime.Context;
2+
import com.amazonaws.services.lambda.runtime.RequestHandler;
3+
import java.util.Map;
4+
import java.util.HashMap;
5+
6+
public class EchoHandler implements RequestHandler<Map<String, Object>, Map<String, Object>> {
7+
8+
@Override
9+
public Map<String, Object> handleRequest(Map<String, Object> event, Context context) {
10+
context.getLogger().log("Processing event: " + event);
11+
12+
Map<String, Object> response = new HashMap<>(event);
13+
response.put("timestamp", System.currentTimeMillis());
14+
response.put("requestId", context.getAwsRequestId());
15+
response.put("functionName", context.getFunctionName());
16+
response.put("remainingTimeInMillis", context.getRemainingTimeInMillis());
17+
18+
return response;
19+
}
20+
}

0 commit comments

Comments
 (0)