Skip to content

Commit 61a3a86

Browse files
msailesPankaj Agrawal
authored and
Pankaj Agrawal
committed
new test-suite module for testing multi module use cases.
1 parent 3ff232f commit 61a3a86

File tree

7 files changed

+378
-1
lines changed

7 files changed

+378
-1
lines changed

pom.xml

+16
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
<module>powertools-metrics</module>
3535
<module>powertools-parameters</module>
3636
<module>powertools-validation</module>
37+
<module>powertools-test-suite</module>
3738
</modules>
3839

3940
<scm>
@@ -88,6 +89,21 @@
8889
<artifactId>powertools-core</artifactId>
8990
<version>${project.version}</version>
9091
</dependency>
92+
<dependency>
93+
<groupId>software.amazon.lambda</groupId>
94+
<artifactId>powertools-logging</artifactId>
95+
<version>${project.version}</version>
96+
</dependency>
97+
<dependency>
98+
<groupId>software.amazon.lambda</groupId>
99+
<artifactId>powertools-sqs</artifactId>
100+
<version>${project.version}</version>
101+
</dependency>
102+
<dependency>
103+
<groupId>software.amazon.lambda</groupId>
104+
<artifactId>powertools-tracing</artifactId>
105+
<version>${project.version}</version>
106+
</dependency>
91107
<dependency>
92108
<groupId>com.amazonaws</groupId>
93109
<artifactId>aws-lambda-java-core</artifactId>

powertools-logging/src/main/java/software/amazon/lambda/powertools/logging/internal/LambdaLoggingAspect.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@
5858
import static software.amazon.lambda.powertools.logging.LoggingUtils.objectMapper;
5959

6060
@Aspect
61-
@DeclarePrecedence("*, LambdaLoggingAspect")
61+
@DeclarePrecedence("*, SqsLargeMessageAspect, LambdaLoggingAspect")
6262
public final class LambdaLoggingAspect {
6363
private static final Logger LOG = LogManager.getLogger(LambdaLoggingAspect.class);
6464
private static final Random SAMPLER = new Random();

powertools-test-suite/pom.xml

+142
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
7+
<artifactId>powertools-test-suite</artifactId>
8+
<packaging>jar</packaging>
9+
10+
<parent>
11+
<artifactId>powertools-parent</artifactId>
12+
<groupId>software.amazon.lambda</groupId>
13+
<version>1.7.3</version>
14+
</parent>
15+
16+
<name>AWS Lambda Powertools Java library Test Suite</name>
17+
<description>
18+
A suite of tests for interactions between the various Powertools modules.
19+
</description>
20+
<url>https://aws.amazon.com/lambda/</url>
21+
<issueManagement>
22+
<system>GitHub Issues</system>
23+
<url>https://github.com/awslabs/aws-lambda-powertools-java/issues</url>
24+
</issueManagement>
25+
<scm>
26+
<url>https://github.com/awslabs/aws-lambda-powertools-java.git</url>
27+
</scm>
28+
<developers>
29+
<developer>
30+
<name>AWS Lambda Powertools team</name>
31+
<organization>Amazon Web Services</organization>
32+
<organizationUrl>https://aws.amazon.com/</organizationUrl>
33+
</developer>
34+
</developers>
35+
36+
<distributionManagement>
37+
<snapshotRepository>
38+
<id>ossrh</id>
39+
<url>https://aws.oss.sonatype.org/content/repositories/snapshots</url>
40+
</snapshotRepository>
41+
</distributionManagement>
42+
43+
<dependencies>
44+
<dependency>
45+
<groupId>software.amazon.lambda</groupId>
46+
<artifactId>powertools-core</artifactId>
47+
</dependency>
48+
<dependency>
49+
<groupId>com.amazonaws</groupId>
50+
<artifactId>aws-lambda-java-core</artifactId>
51+
</dependency>
52+
<dependency>
53+
<groupId>com.amazonaws</groupId>
54+
<artifactId>aws-lambda-java-events</artifactId>
55+
</dependency>
56+
<dependency>
57+
<groupId>software.amazon.lambda</groupId>
58+
<artifactId>powertools-logging</artifactId>
59+
</dependency>
60+
<dependency>
61+
<groupId>software.amazon.lambda</groupId>
62+
<artifactId>powertools-tracing</artifactId>
63+
</dependency>
64+
<dependency>
65+
<groupId>software.amazon.lambda</groupId>
66+
<artifactId>powertools-sqs</artifactId>
67+
</dependency>
68+
69+
<!-- Test dependencies -->
70+
<dependency>
71+
<groupId>org.junit.jupiter</groupId>
72+
<artifactId>junit-jupiter-api</artifactId>
73+
<scope>test</scope>
74+
</dependency>
75+
<dependency>
76+
<groupId>org.junit.jupiter</groupId>
77+
<artifactId>junit-jupiter-engine</artifactId>
78+
<scope>test</scope>
79+
</dependency>
80+
<dependency>
81+
<groupId>org.apache.commons</groupId>
82+
<artifactId>commons-lang3</artifactId>
83+
<scope>test</scope>
84+
</dependency>
85+
<dependency>
86+
<groupId>org.mockito</groupId>
87+
<artifactId>mockito-core</artifactId>
88+
<scope>test</scope>
89+
</dependency>
90+
<dependency>
91+
<groupId>org.aspectj</groupId>
92+
<artifactId>aspectjweaver</artifactId>
93+
<scope>test</scope>
94+
</dependency>
95+
<dependency>
96+
<groupId>org.assertj</groupId>
97+
<artifactId>assertj-core</artifactId>
98+
<scope>test</scope>
99+
</dependency>
100+
<dependency>
101+
<groupId>org.skyscreamer</groupId>
102+
<artifactId>jsonassert</artifactId>
103+
<scope>test</scope>
104+
</dependency>
105+
</dependencies>
106+
107+
<build>
108+
<plugins>
109+
<plugin>
110+
<groupId>org.codehaus.mojo</groupId>
111+
<artifactId>aspectj-maven-plugin</artifactId>
112+
<version>1.14.0</version>
113+
<configuration>
114+
<source>${maven.compiler.source}</source>
115+
<target>${maven.compiler.target}</target>
116+
<complianceLevel>${maven.compiler.target}</complianceLevel>
117+
<aspectLibraries>
118+
<aspectLibrary>
119+
<groupId>software.amazon.lambda</groupId>
120+
<artifactId>powertools-logging</artifactId>
121+
</aspectLibrary>
122+
<aspectLibrary>
123+
<groupId>software.amazon.lambda</groupId>
124+
<artifactId>powertools-tracing</artifactId>
125+
</aspectLibrary>
126+
<aspectLibrary>
127+
<groupId>software.amazon.lambda</groupId>
128+
<artifactId>powertools-sqs</artifactId>
129+
</aspectLibrary>
130+
</aspectLibraries>
131+
</configuration>
132+
<executions>
133+
<execution>
134+
<goals>
135+
<goal>compile</goal>
136+
</goals>
137+
</execution>
138+
</executions>
139+
</plugin>
140+
</plugins>
141+
</build>
142+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
package software.amazon.lambda.powertools.testsuite;
2+
3+
4+
import java.io.ByteArrayInputStream;
5+
import java.io.ByteArrayOutputStream;
6+
import java.io.IOException;
7+
import java.lang.reflect.InvocationTargetException;
8+
import java.lang.reflect.Method;
9+
import java.nio.channels.FileChannel;
10+
import java.nio.charset.StandardCharsets;
11+
import java.nio.file.Files;
12+
import java.nio.file.Paths;
13+
import java.nio.file.StandardOpenOption;
14+
import java.util.Map;
15+
16+
import com.amazonaws.services.lambda.runtime.Context;
17+
import com.amazonaws.services.lambda.runtime.events.SQSEvent;
18+
import com.amazonaws.services.lambda.runtime.events.models.s3.S3EventNotification;
19+
import com.amazonaws.services.s3.AmazonS3;
20+
import com.amazonaws.services.s3.model.S3Object;
21+
import com.amazonaws.xray.AWSXRay;
22+
import com.fasterxml.jackson.core.JsonProcessingException;
23+
import com.fasterxml.jackson.databind.ObjectMapper;
24+
import org.apache.logging.log4j.Level;
25+
import org.apache.logging.log4j.ThreadContext;
26+
import org.junit.jupiter.api.BeforeEach;
27+
import org.junit.jupiter.api.Test;
28+
import org.mockito.Mock;
29+
import software.amazon.lambda.powertools.core.internal.LambdaHandlerProcessor;
30+
import software.amazon.lambda.powertools.logging.internal.LambdaLoggingAspect;
31+
import software.amazon.lambda.powertools.sqs.internal.SqsLargeMessageAspect;
32+
import software.amazon.lambda.powertools.testsuite.handler.LoggingOrderMessageHandler;
33+
import software.amazon.lambda.powertools.testsuite.handler.TracingLoggingStreamMessageHandler;
34+
35+
import static java.util.Collections.emptyMap;
36+
import static java.util.Collections.singletonList;
37+
import static org.apache.commons.lang3.reflect.FieldUtils.writeStaticField;
38+
import static org.assertj.core.api.Assertions.assertThat;
39+
import static org.assertj.core.api.Assertions.fail;
40+
import static org.mockito.Mockito.when;
41+
import static org.mockito.MockitoAnnotations.openMocks;
42+
43+
public class LoggingOrderTest {
44+
45+
private static final String BUCKET_NAME = "ms-extended-sqs-client";
46+
private static final String BUCKET_KEY = "c71eb2ae-37e0-4265-8909-32f4153faddf";
47+
48+
@Mock
49+
private Context context;
50+
51+
@Mock
52+
private AmazonS3 amazonS3;
53+
54+
@BeforeEach
55+
void setUp() throws IllegalAccessException, IOException, NoSuchMethodException, InvocationTargetException {
56+
openMocks(this);
57+
writeStaticField(SqsLargeMessageAspect.class, "amazonS3", amazonS3, true);
58+
ThreadContext.clearAll();
59+
writeStaticField(LambdaHandlerProcessor.class, "IS_COLD_START", null, true);
60+
setupContext();
61+
//Make sure file is cleaned up before running full stack logging regression
62+
FileChannel.open(Paths.get("target/logfile.json"), StandardOpenOption.WRITE).truncate(0).close();
63+
resetLogLevel(Level.INFO);
64+
AWSXRay.beginSegment(LoggingOrderTest.class.getName());
65+
}
66+
67+
/**
68+
* The SQSEvent payload will be altered by the @SqsLargeMessage annotation. Logging of the event should happen
69+
* after the event has been altered
70+
*/
71+
@Test
72+
public void testThatLoggingAnnotationActsLast() throws IOException {
73+
S3Object s3Response = new S3Object();
74+
s3Response.setObjectContent(new ByteArrayInputStream("A big message".getBytes()));
75+
76+
when(amazonS3.getObject(BUCKET_NAME, BUCKET_KEY)).thenReturn(s3Response);
77+
SQSEvent sqsEvent = messageWithBody("[\"software.amazon.payloadoffloading.PayloadS3Pointer\",{\"s3BucketName\":\"" + BUCKET_NAME + "\",\"s3Key\":\"" + BUCKET_KEY + "\"}]");
78+
79+
LoggingOrderMessageHandler requestHandler = new LoggingOrderMessageHandler();
80+
requestHandler.handleRequest(sqsEvent, context);
81+
82+
assertThat(Files.lines(Paths.get("target/logfile.json")))
83+
.hasSize(2)
84+
.satisfies(line -> {
85+
Map<String, Object> actual = parseToMap(line.get(0));
86+
87+
String message = actual.get("message").toString();
88+
89+
assertThat(message)
90+
.contains("A big message");
91+
});
92+
}
93+
94+
@Test
95+
public void testLoggingAnnotationActsAfterTracingForStreamingHandler() throws IOException {
96+
97+
ByteArrayOutputStream output = new ByteArrayOutputStream();
98+
S3EventNotification s3EventNotification = s3EventNotification();
99+
100+
TracingLoggingStreamMessageHandler handler = new TracingLoggingStreamMessageHandler();
101+
handler.handleRequest(new ByteArrayInputStream(new ObjectMapper().writeValueAsBytes(s3EventNotification)), output, context);
102+
103+
assertThat(new String(output.toByteArray(), StandardCharsets.UTF_8))
104+
.isNotEmpty();
105+
}
106+
107+
private void setupContext() {
108+
when(context.getFunctionName()).thenReturn("testFunction");
109+
when(context.getInvokedFunctionArn()).thenReturn("testArn");
110+
when(context.getFunctionVersion()).thenReturn("1");
111+
when(context.getMemoryLimitInMB()).thenReturn(10);
112+
when(context.getAwsRequestId()).thenReturn("RequestId");
113+
}
114+
115+
private void resetLogLevel(Level level) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
116+
Method resetLogLevels = LambdaLoggingAspect.class.getDeclaredMethod("resetLogLevels", Level.class);
117+
resetLogLevels.setAccessible(true);
118+
resetLogLevels.invoke(null, level);
119+
writeStaticField(LambdaLoggingAspect.class, "LEVEL_AT_INITIALISATION", level, true);
120+
}
121+
122+
private Map<String, Object> parseToMap(String stringAsJson) {
123+
try {
124+
return new ObjectMapper().readValue(stringAsJson, Map.class);
125+
} catch (JsonProcessingException e) {
126+
fail("Failed parsing logger line " + stringAsJson);
127+
return emptyMap();
128+
}
129+
}
130+
131+
private S3EventNotification s3EventNotification() {
132+
S3EventNotification.S3EventNotificationRecord record = new S3EventNotification.S3EventNotificationRecord("us-west-2",
133+
"ObjectCreated:Put",
134+
"aws:s3",
135+
null,
136+
"2.1",
137+
new S3EventNotification.RequestParametersEntity("127.0.0.1"),
138+
new S3EventNotification.ResponseElementsEntity("C3D13FE58DE4C810", "FMyUVURIY8/IgAtTv8xRjskZQpcIZ9KG4V5Wp6S7S/JRWeUWerMUE5JgHvANOjpD"),
139+
new S3EventNotification.S3Entity("testConfigRule",
140+
new S3EventNotification.S3BucketEntity("mybucket",
141+
new S3EventNotification.UserIdentityEntity("A3NL1KOZZKExample"),
142+
"arn:aws:s3:::mybucket"),
143+
new S3EventNotification.S3ObjectEntity("HappyFace.jpg",
144+
1024L,
145+
"d41d8cd98f00b204e9800998ecf8427e",
146+
"096fKKXTRTtl3on89fVO.nfljtsv6qko",
147+
"0055AED6DCD90281E5"),
148+
"1.0"),
149+
new S3EventNotification.UserIdentityEntity("AIDAJDPLRKLG7UEXAMPLE")
150+
);
151+
152+
return new S3EventNotification(singletonList(record));
153+
}
154+
155+
private SQSEvent messageWithBody(String messageBody) {
156+
SQSEvent.SQSMessage sqsMessage = new SQSEvent.SQSMessage();
157+
sqsMessage.setBody(messageBody);
158+
SQSEvent sqsEvent = new SQSEvent();
159+
sqsEvent.setRecords(singletonList(sqsMessage));
160+
return sqsEvent;
161+
}
162+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package software.amazon.lambda.powertools.testsuite.handler;
2+
3+
import com.amazonaws.services.lambda.runtime.Context;
4+
import com.amazonaws.services.lambda.runtime.RequestHandler;
5+
import com.amazonaws.services.lambda.runtime.events.SQSEvent;
6+
import software.amazon.lambda.powertools.logging.Logging;
7+
import software.amazon.lambda.powertools.sqs.SqsLargeMessage;
8+
9+
public class LoggingOrderMessageHandler implements RequestHandler<SQSEvent, String> {
10+
11+
@Override
12+
@SqsLargeMessage
13+
@Logging(logEvent = true)
14+
public String handleRequest(SQSEvent sqsEvent, Context context) {
15+
System.out.println(sqsEvent.getRecords().get(0).getBody());
16+
return sqsEvent.getRecords().get(0).getBody();
17+
}
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package software.amazon.lambda.powertools.testsuite.handler;
2+
3+
import java.io.IOException;
4+
import java.io.InputStream;
5+
import java.io.OutputStream;
6+
import java.util.Map;
7+
8+
import com.amazonaws.services.lambda.runtime.Context;
9+
import com.amazonaws.services.lambda.runtime.RequestStreamHandler;
10+
import com.fasterxml.jackson.databind.ObjectMapper;
11+
import software.amazon.lambda.powertools.logging.Logging;
12+
import software.amazon.lambda.powertools.tracing.Tracing;
13+
14+
public class TracingLoggingStreamMessageHandler implements RequestStreamHandler {
15+
16+
@Logging(logEvent = true)
17+
@Tracing
18+
@Override
19+
public void handleRequest(InputStream input, OutputStream output, Context context) throws IOException {
20+
ObjectMapper mapper = new ObjectMapper();
21+
mapper.writeValue(output, mapper.readValue(input, Map.class));
22+
}
23+
}

0 commit comments

Comments
 (0)