Skip to content

Commit 9b4df8f

Browse files
authored
Merge pull request #619 from aws/fabisev/integration-tests
Add end-to-end integration tests
2 parents cfefd3b + 361bbfc commit 9b4df8f

9 files changed

Lines changed: 515 additions & 0 deletions

File tree

.github/test-matrix.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"arch": [
3+
{
4+
"runner": "ubuntu-latest",
5+
"label": "x64",
6+
"sam_arch": "x86_64",
7+
"java_suffix": "X64"
8+
},
9+
{
10+
"runner": "ubuntu-24.04-arm",
11+
"label": "arm64",
12+
"sam_arch": "arm64",
13+
"java_suffix": "ARM64"
14+
}
15+
]
16+
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
# this workflow verifies that the integration test Lambda function builds successfully.
2+
# it does NOT deploy or run the tests (that requires AWS credentials and is done in
3+
# run-integration-test.yml).
4+
5+
name: Build integration tests
6+
7+
on:
8+
push:
9+
branches: [ main ]
10+
paths:
11+
- 'aws-lambda-java-log4j2/**'
12+
- 'aws-lambda-java-core/**'
13+
- 'lambda-integration-tests/**'
14+
pull_request:
15+
branches: [ '*' ]
16+
paths:
17+
- 'aws-lambda-java-log4j2/**'
18+
- 'aws-lambda-java-core/**'
19+
- 'lambda-integration-tests/**'
20+
- '.github/workflows/build-integration-test.yml'
21+
22+
permissions:
23+
contents: read
24+
25+
jobs:
26+
load-matrix:
27+
runs-on: ubuntu-latest
28+
outputs:
29+
matrix: ${{ steps.set.outputs.matrix }}
30+
steps:
31+
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
32+
33+
- name: Load test matrix
34+
id: set
35+
run: |
36+
MATRIX=$(jq -c '.' .github/test-matrix.json)
37+
echo "matrix=${MATRIX}" >> "$GITHUB_OUTPUT"
38+
39+
build-arch:
40+
needs: load-matrix
41+
runs-on: ${{ matrix.arch.runner }}
42+
strategy:
43+
fail-fast: false
44+
matrix: ${{ fromJson(needs.load-matrix.outputs.matrix) }}
45+
name: "build (${{ matrix.arch.label }})"
46+
steps:
47+
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
48+
49+
- name: Set up JDK
50+
uses: actions/setup-java@1bcf9fb12cf4aa7d266a90ae39939e61372fe520 # v5.4.0
51+
with:
52+
java-version: |
53+
8
54+
21
55+
distribution: corretto
56+
cache: maven
57+
58+
- name: Install core with Maven
59+
run: |
60+
export JAVA_HOME=$JAVA_HOME_8_${{ matrix.arch.java_suffix }}
61+
mvn -B install --file aws-lambda-java-core/pom.xml
62+
63+
- name: Install log4j2 with Maven
64+
run: |
65+
export JAVA_HOME=$JAVA_HOME_8_${{ matrix.arch.java_suffix }}
66+
mvn -B install --file aws-lambda-java-log4j2/pom.xml
67+
68+
# build the integration test function
69+
# this verifies that the function compiles and packages correctly.
70+
# the tests will run in run-integration-test.yml which deploys to AWS.
71+
- name: Package integration test function
72+
run: |
73+
export JAVA_HOME=$JAVA_HOME_21_${{ matrix.arch.java_suffix }}
74+
mvn -B package --file lambda-integration-tests/log4j2-test-function/pom.xml
75+
76+
build:
77+
needs: build-arch
78+
if: always()
79+
runs-on: ubuntu-latest
80+
steps:
81+
- name: Check build results
82+
run: |
83+
if [ "${{ needs.build-arch.result }}" != "success" ]; then
84+
echo "Build failed on one or more architectures"
85+
exit 1
86+
fi
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
# this workflow deploys a Lambda function that uses aws-lambda-java-log4j2,
2+
# invokes it, and verifies that logs arrive in CloudWatch.
3+
4+
name: Run integration tests
5+
6+
permissions:
7+
id-token: write
8+
contents: read
9+
10+
on:
11+
workflow_dispatch:
12+
push:
13+
branches: [ main ]
14+
paths:
15+
- 'aws-lambda-java-log4j2/**'
16+
- 'aws-lambda-java-core/**'
17+
- 'lambda-integration-tests/**'
18+
19+
jobs:
20+
load-matrix:
21+
runs-on: ubuntu-latest
22+
outputs:
23+
matrix: ${{ steps.set.outputs.matrix }}
24+
steps:
25+
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
26+
27+
- name: Load test matrix
28+
id: set
29+
run: |
30+
MATRIX=$(jq -c '.' .github/test-matrix.json)
31+
echo "matrix=${MATRIX}" >> "$GITHUB_OUTPUT"
32+
33+
run-integration-tests:
34+
needs: load-matrix
35+
# Only run on the main repo, not forks
36+
if: ${{ github.repository_owner == 'aws' }}
37+
runs-on: ${{ matrix.arch.runner }}
38+
strategy:
39+
fail-fast: false
40+
matrix: ${{ fromJson(needs.load-matrix.outputs.matrix) }}
41+
name: "integration-test (${{ matrix.arch.label }})"
42+
concurrency:
43+
group: integration-test-${{ matrix.arch.label }}
44+
cancel-in-progress: false
45+
steps:
46+
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
47+
48+
- name: Set up JDK
49+
uses: actions/setup-java@1bcf9fb12cf4aa7d266a90ae39939e61372fe520 # v5.4.0
50+
with:
51+
java-version: |
52+
8
53+
21
54+
distribution: corretto
55+
cache: maven
56+
57+
- name: Install SAM CLI
58+
uses: aws-actions/setup-sam@f84ec7d548307efafe33230528756de3c5841a17 # v2
59+
with:
60+
use-installer: true
61+
62+
- name: Configure AWS credentials
63+
uses: aws-actions/configure-aws-credentials@8df5847569e6427dd6c4fb1cf565c83acfa8afa7 # v6.0.0
64+
with:
65+
role-to-assume: ${{ secrets.AWS_ROLE_LOG4J2_INTEG_TEST }}
66+
role-session-name: GitHubActionsLog4j2IntegTest
67+
aws-region: ${{ secrets.AWS_REGION_LOG4J2_INTEG_TEST }}
68+
69+
- name: Install core with Maven
70+
run: |
71+
export JAVA_HOME=$JAVA_HOME_8_${{ matrix.arch.java_suffix }}
72+
mvn -B install --file aws-lambda-java-core/pom.xml
73+
74+
- name: Install log4j2 with Maven
75+
run: |
76+
export JAVA_HOME=$JAVA_HOME_8_${{ matrix.arch.java_suffix }}
77+
mvn -B install --file aws-lambda-java-log4j2/pom.xml
78+
79+
- name: Build SAM stack
80+
run: |
81+
export JAVA_HOME=$JAVA_HOME_21_${{ matrix.arch.java_suffix }}
82+
cd lambda-integration-tests && sam build
83+
84+
- name: Validate SAM stack
85+
run: cd lambda-integration-tests && sam validate --lint
86+
87+
- name: Deploy stack
88+
id: deploy_stack
89+
env:
90+
AWS_REGION: ${{ secrets.AWS_REGION_LOG4J2_INTEG_TEST }}
91+
run: |
92+
cd lambda-integration-tests
93+
stackName="aws-lambda-java-log4j2-integ-test-${{ matrix.arch.label }}-$GITHUB_RUN_ID"
94+
echo "STACK_NAME=$stackName" >> "$GITHUB_OUTPUT"
95+
echo "Stack name = $stackName"
96+
sam deploy \
97+
--stack-name "${stackName}" \
98+
--parameter-overrides "ParameterKey=LambdaRole,ParameterValue=${{ secrets.AWS_LAMBDA_ROLE_LOG4J2_INTEG_TEST }} ParameterKey=Architecture,ParameterValue=${{ matrix.arch.sam_arch }}" \
99+
--no-confirm-changeset \
100+
--no-progressbar \
101+
--s3-bucket "${{ secrets.S3_BUCKET_LOG4J2_INTEG_TEST }}" \
102+
--capabilities CAPABILITY_IAM \
103+
2>&1 | tee /tmp/sam-deploy.log | tail -n 20
104+
LOG4J2_TEST_FUNCTION=$(sam list stack-outputs --stack-name "${stackName}" --output json | jq -r '.[] | select(.OutputKey=="Log4j2TestFunction") | .OutputValue')
105+
echo "LOG4J2_TEST_FUNCTION=$LOG4J2_TEST_FUNCTION" >> "$GITHUB_OUTPUT"
106+
echo "Function name: $LOG4J2_TEST_FUNCTION"
107+
108+
- name: Run integration test
109+
env:
110+
LOG4J2_TEST_FUNCTION: ${{ steps.deploy_stack.outputs.LOG4J2_TEST_FUNCTION }}
111+
AWS_REGION: ${{ secrets.AWS_REGION_LOG4J2_INTEG_TEST }}
112+
run: ./lambda-integration-tests/run-tests.sh
113+
114+
- name: Cleanup
115+
if: always() && steps.deploy_stack.outputs.STACK_NAME
116+
env:
117+
AWS_REGION: ${{ secrets.AWS_REGION_LOG4J2_INTEG_TEST }}
118+
STACK_NAME: ${{ steps.deploy_stack.outputs.STACK_NAME }}
119+
run: |
120+
sam delete --stack-name "${STACK_NAME}" --no-prompts --region "${AWS_REGION}"
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
<project xmlns="http://maven.apache.org/POM/4.0.0"
2+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/maven-v4_0_0.xsd">
4+
<modelVersion>4.0.0</modelVersion>
5+
6+
<groupId>com.amazonaws</groupId>
7+
<artifactId>log4j2-integration-test-function</artifactId>
8+
<version>1.0.0</version>
9+
<packaging>jar</packaging>
10+
11+
<name>Log4j2 Integration Test Function</name>
12+
<description>
13+
Lambda function used to verify that aws-lambda-java-log4j2 correctly emits logs to CloudWatch.
14+
</description>
15+
16+
<properties>
17+
<maven.compiler.source>21</maven.compiler.source>
18+
<maven.compiler.target>21</maven.compiler.target>
19+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
20+
<log4j.version>2.25.4</log4j.version>
21+
</properties>
22+
23+
<dependencies>
24+
<dependency>
25+
<groupId>com.amazonaws</groupId>
26+
<artifactId>aws-lambda-java-core</artifactId>
27+
<version>1.4.0</version>
28+
</dependency>
29+
<dependency>
30+
<groupId>com.amazonaws</groupId>
31+
<artifactId>aws-lambda-java-log4j2</artifactId>
32+
<version>1.6.4</version>
33+
</dependency>
34+
<dependency>
35+
<groupId>org.apache.logging.log4j</groupId>
36+
<artifactId>log4j-core</artifactId>
37+
<version>${log4j.version}</version>
38+
</dependency>
39+
<dependency>
40+
<groupId>org.apache.logging.log4j</groupId>
41+
<artifactId>log4j-api</artifactId>
42+
<version>${log4j.version}</version>
43+
</dependency>
44+
</dependencies>
45+
46+
<build>
47+
<plugins>
48+
<plugin>
49+
<groupId>org.apache.maven.plugins</groupId>
50+
<artifactId>maven-shade-plugin</artifactId>
51+
<version>3.6.1</version>
52+
<executions>
53+
<execution>
54+
<phase>package</phase>
55+
<goals>
56+
<goal>shade</goal>
57+
</goals>
58+
<configuration>
59+
<transformers>
60+
<transformer
61+
implementation="com.github.edwgiz.mavenShadePlugin.log4j2CacheTransformer.PluginsCacheFileTransformer">
62+
</transformer>
63+
</transformers>
64+
</configuration>
65+
</execution>
66+
</executions>
67+
<dependencies>
68+
<dependency>
69+
<groupId>com.github.edwgiz</groupId>
70+
<artifactId>maven-shade-plugin.log4j2-cachefile-transformer</artifactId>
71+
<version>2.8.1</version>
72+
</dependency>
73+
</dependencies>
74+
</plugin>
75+
</plugins>
76+
</build>
77+
</project>
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package integ;
2+
3+
import com.amazonaws.services.lambda.runtime.Context;
4+
import com.amazonaws.services.lambda.runtime.RequestHandler;
5+
import org.apache.logging.log4j.LogManager;
6+
import org.apache.logging.log4j.Logger;
7+
8+
import java.util.Map;
9+
10+
/**
11+
* integration test handler that logs a marker string using Log4j2 with the LambdaAppender.
12+
* the test verifies that the marker appears in CloudWatch Logs, confirming end-to-end
13+
* log delivery through the aws-lambda-java-log4j2 library.
14+
*/
15+
public class Log4j2TestHandler implements RequestHandler<Map<String, String>, String> {
16+
17+
private static final Logger logger = LogManager.getLogger(Log4j2TestHandler.class);
18+
19+
@Override
20+
public String handleRequest(Map<String, String> event, Context context) {
21+
String marker = event.getOrDefault("marker", "NO_MARKER_PROVIDED");
22+
23+
logger.info("INTEG_TEST_MARKER: {}", marker);
24+
logger.debug("Debug level message with marker: {}", marker);
25+
logger.warn("Warning level message with marker: {}", marker);
26+
logger.error("Error level message with marker: {}", marker);
27+
28+
return "OK:" + marker;
29+
}
30+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<Configuration status="WARN">
3+
<Appenders>
4+
<Lambda name="Lambda" format="${env:AWS_LAMBDA_LOG_FORMAT:-TEXT}">
5+
<LambdaTextFormat>
6+
<PatternLayout>
7+
<pattern>%d{yyyy-MM-dd HH:mm:ss} %X{AWSRequestId} %-5p %c{1}:%L - %m%n</pattern>
8+
</PatternLayout>
9+
</LambdaTextFormat>
10+
</Lambda>
11+
</Appenders>
12+
<Loggers>
13+
<Root level="DEBUG">
14+
<AppenderRef ref="Lambda" />
15+
</Root>
16+
</Loggers>
17+
</Configuration>

0 commit comments

Comments
 (0)