Skip to content

Commit e6c9a9d

Browse files
author
Pankaj Agrawal
committed
Full Test cases coverage
1 parent 97e2860 commit e6c9a9d

File tree

8 files changed

+367
-60
lines changed

8 files changed

+367
-60
lines changed

powertools-sqs/src/main/java/software/amazon/lambda/powertools/sqs/PowertoolsSqs.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,11 @@ public static SqsClient defaultSqsClient() {
9797
return client;
9898
}
9999

100+
public static <R> List<R> partialBatchProcessor(final SQSEvent event,
101+
final Class<? extends SqsMessageHandler<R>> handler) {
102+
return partialBatchProcessor(event, false, handler);
103+
}
104+
100105
public static <R> List<R> partialBatchProcessor(final SQSEvent event,
101106
final boolean suppressException,
102107
final Class<? extends SqsMessageHandler<R>> handler) {
@@ -118,6 +123,11 @@ public static <R> List<R> partialBatchProcessor(final SQSEvent event,
118123
}
119124
}
120125

126+
public static <R> List<R> partialBatchProcessor(final SQSEvent event,
127+
final SqsMessageHandler<R> handler) {
128+
return partialBatchProcessor(event, false, handler);
129+
}
130+
121131
public static <R> List<R> partialBatchProcessor(final SQSEvent event,
122132
final boolean suppressException,
123133
final SqsMessageHandler<R> handler) {

powertools-sqs/src/main/java/software/amazon/lambda/powertools/sqs/SQSBatchProcessingException.java

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ public class SQSBatchProcessingException extends RuntimeException {
1616
public <T> SQSBatchProcessingException(final List<Exception> exceptions,
1717
final List<SQSEvent.SQSMessage> failures,
1818
final List<T> successReturns) {
19+
super(exceptions.stream()
20+
.map(Throwable::toString)
21+
.collect(joining("\n")));
22+
1923
this.exceptions = new ArrayList<>(exceptions);
2024
this.failures = new ArrayList<>(failures);
2125
this.returnValues = new ArrayList<>(successReturns);
@@ -33,25 +37,13 @@ public List<SQSEvent.SQSMessage> getFailures() {
3337
return failures;
3438
}
3539

36-
@Override
37-
public String getMessage() {
38-
return exceptions.stream()
39-
.map(Throwable::toString)
40-
.collect(joining("\n"));
41-
}
42-
4340
@Override
4441
public void printStackTrace() {
4542
for (Exception exception : exceptions) {
4643
exception.printStackTrace();
4744
}
4845
}
4946

50-
@Override
51-
public String toString() {
52-
return getMessage();
53-
}
54-
5547
<T> void addSuccessMessageReturnValues(final List<T> returnValues) {
5648
this.returnValues.addAll(returnValues);
5749
}

powertools-sqs/src/test/java/software/amazon/lambda/powertools/sqs/PowertoolsSqsBatchProcessorTest.java

Lines changed: 158 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,42 +2,53 @@
22

33
import java.io.IOException;
44
import java.util.List;
5-
import java.util.stream.Stream;
65

7-
import com.amazonaws.AmazonServiceException;
8-
import com.amazonaws.SdkClientException;
96
import com.amazonaws.services.lambda.runtime.events.SQSEvent;
107
import com.fasterxml.jackson.databind.ObjectMapper;
118
import org.junit.jupiter.api.BeforeEach;
129
import org.junit.jupiter.api.Test;
1310
import org.junit.jupiter.params.ParameterizedTest;
14-
import org.junit.jupiter.params.provider.Arguments;
1511
import org.junit.jupiter.params.provider.ValueSource;
1612
import software.amazon.awssdk.services.sqs.SqsClient;
13+
import software.amazon.awssdk.services.sqs.model.DeleteMessageBatchRequest;
14+
import software.amazon.awssdk.services.sqs.model.GetQueueUrlRequest;
15+
import software.amazon.awssdk.services.sqs.model.GetQueueUrlResponse;
1716

1817
import static com.amazonaws.services.lambda.runtime.events.SQSEvent.SQSMessage;
1918
import static org.assertj.core.api.Assertions.assertThat;
19+
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
20+
import static org.mockito.ArgumentMatchers.any;
2021
import static org.mockito.Mockito.mock;
22+
import static org.mockito.Mockito.reset;
2123
import static org.mockito.Mockito.times;
2224
import static org.mockito.Mockito.verify;
2325
import static org.mockito.Mockito.verifyNoInteractions;
26+
import static org.mockito.Mockito.when;
27+
import static software.amazon.lambda.powertools.sqs.PowertoolsSqs.defaultSqsClient;
28+
import static software.amazon.lambda.powertools.sqs.PowertoolsSqs.partialBatchProcessor;
2429

2530
class PowertoolsSqsBatchProcessorTest {
2631

27-
private final SqsClient sqsClient = mock(SqsClient.class);
28-
private final SqsClient interactionClient = mock(SqsClient.class);
32+
private static final SqsClient sqsClient = mock(SqsClient.class);
33+
private static final SqsClient interactionClient = mock(SqsClient.class);
2934
private static final ObjectMapper MAPPER = new ObjectMapper();
3035
private SQSEvent event;
3136

3237
@BeforeEach
3338
void setUp() throws IOException {
39+
reset(sqsClient, interactionClient);
3440
event = MAPPER.readValue(this.getClass().getResource("/sampleSqsBatchEvent.json"), SQSEvent.class);
35-
PowertoolsSqs.defaultSqsClient(sqsClient);
41+
42+
when(sqsClient.getQueueUrl(any(GetQueueUrlRequest.class))).thenReturn(GetQueueUrlResponse.builder()
43+
.queueUrl("test")
44+
.build());
45+
46+
defaultSqsClient(sqsClient);
3647
}
3748

3849
@Test
3950
void shouldBatchProcessAndNotDeleteMessagesWhenAllSuccess() {
40-
List<String> returnValues = PowertoolsSqs.partialBatchProcessor(event, false, (message) -> {
51+
List<String> returnValues = partialBatchProcessor(event, false, (message) -> {
4152
interactionClient.listQueues();
4253
return "Success";
4354
});
@@ -53,24 +64,159 @@ void shouldBatchProcessAndNotDeleteMessagesWhenAllSuccess() {
5364
@ParameterizedTest
5465
@ValueSource(classes = {SampleInnerSqsHandler.class, SampleSqsHandler.class})
5566
void shouldBatchProcessViaClassAndNotDeleteMessagesWhenAllSuccess(Class<? extends SqsMessageHandler<String>> handler) {
56-
List<String> returnValues = PowertoolsSqs.partialBatchProcessor(event, false, handler);
67+
List<String> returnValues = partialBatchProcessor(event, handler);
5768

5869
assertThat(returnValues)
5970
.hasSize(2)
6071
.containsExactly("0", "1");
72+
73+
verifyNoInteractions(sqsClient);
74+
}
75+
76+
@Test
77+
void shouldBatchProcessAndDeleteSuccessMessageOnPartialFailures() {
78+
String failedId = "2e1424d4-f796-459a-8184-9c92662be6da";
79+
80+
SqsMessageHandler<String> failedHandler = (message) -> {
81+
if (failedId.equals(message.getMessageId())) {
82+
throw new RuntimeException("Failed processing");
83+
}
84+
85+
interactionClient.listQueues();
86+
return "Success";
87+
};
88+
89+
assertThatExceptionOfType(SQSBatchProcessingException.class)
90+
.isThrownBy(() -> partialBatchProcessor(event, failedHandler))
91+
.satisfies(e -> {
92+
93+
assertThat(e.successMessageReturnValues())
94+
.hasSize(1)
95+
.contains("Success");
96+
97+
assertThat(e.getFailures())
98+
.hasSize(1)
99+
.extracting("messageId")
100+
.contains(failedId);
101+
102+
assertThat(e.getExceptions())
103+
.hasSize(1)
104+
.extracting("detailMessage")
105+
.contains("Failed processing");
106+
});
107+
108+
verify(interactionClient).listQueues();
109+
verify(sqsClient).deleteMessageBatch(any(DeleteMessageBatchRequest.class));
110+
}
111+
112+
@Test
113+
void shouldBatchProcessAndFullFailuresInBatch() {
114+
SqsMessageHandler<String> failedHandler = (message) -> {
115+
throw new RuntimeException(message.getMessageId());
116+
};
117+
118+
assertThatExceptionOfType(SQSBatchProcessingException.class)
119+
.isThrownBy(() -> partialBatchProcessor(event, failedHandler))
120+
.satisfies(e -> {
121+
122+
assertThat(e.successMessageReturnValues())
123+
.isEmpty();
124+
125+
assertThat(e.getFailures())
126+
.hasSize(2)
127+
.extracting("messageId")
128+
.containsExactly("059f36b4-87a3-44ab-83d2-661975830a7d",
129+
"2e1424d4-f796-459a-8184-9c92662be6da");
130+
131+
assertThat(e.getExceptions())
132+
.hasSize(2)
133+
.extracting("detailMessage")
134+
.containsExactly("059f36b4-87a3-44ab-83d2-661975830a7d",
135+
"2e1424d4-f796-459a-8184-9c92662be6da");
136+
});
137+
138+
verifyNoInteractions(sqsClient);
139+
}
140+
141+
@Test
142+
void shouldBatchProcessViaClassAndDeleteSuccessMessageOnPartialFailures() {
143+
assertThatExceptionOfType(SQSBatchProcessingException.class)
144+
.isThrownBy(() -> partialBatchProcessor(event, FailureSampleInnerSqsHandler.class))
145+
.satisfies(e -> {
146+
147+
assertThat(e.successMessageReturnValues())
148+
.hasSize(1)
149+
.contains("Success");
150+
151+
assertThat(e.getFailures())
152+
.hasSize(1)
153+
.extracting("messageId")
154+
.contains("2e1424d4-f796-459a-8184-9c92662be6da");
155+
156+
assertThat(e.getExceptions())
157+
.hasSize(1)
158+
.extracting("detailMessage")
159+
.contains("Failed processing");
160+
});
161+
162+
verify(sqsClient).deleteMessageBatch(any(DeleteMessageBatchRequest.class));
163+
}
164+
165+
166+
@Test
167+
void shouldBatchProcessAndSuppressExceptions() {
168+
String failedId = "2e1424d4-f796-459a-8184-9c92662be6da";
169+
170+
SqsMessageHandler<String> failedHandler = (message) -> {
171+
if (failedId.equals(message.getMessageId())) {
172+
throw new RuntimeException("Failed processing");
173+
}
174+
175+
interactionClient.listQueues();
176+
return "Success";
177+
};
178+
179+
List<String> returnValues = partialBatchProcessor(event, true, failedHandler);
180+
181+
assertThat(returnValues)
182+
.hasSize(1)
183+
.contains("Success");
184+
185+
verify(interactionClient).listQueues();
186+
verify(sqsClient).deleteMessageBatch(any(DeleteMessageBatchRequest.class));
61187
}
62188

63-
private static Stream<Arguments> exception() {
64-
return Stream.of(Arguments.of(new AmazonServiceException("Service Exception")),
65-
Arguments.of(new SdkClientException("Client Exception")));
189+
@Test
190+
void shouldBatchProcessViaClassAndSuppressExceptions() {
191+
List<String> returnValues = partialBatchProcessor(event, true, FailureSampleInnerSqsHandler.class);
192+
193+
assertThat(returnValues)
194+
.hasSize(1)
195+
.contains("Success");
196+
197+
verify(interactionClient).listQueues();
198+
verify(sqsClient).deleteMessageBatch(any(DeleteMessageBatchRequest.class));
66199
}
67200

68201
public class SampleInnerSqsHandler implements SqsMessageHandler<String> {
69202
private int counter;
70203

71204
@Override
72205
public String process(SQSMessage message) {
206+
interactionClient.listQueues();
73207
return String.valueOf(counter++);
74208
}
75209
}
210+
211+
public class FailureSampleInnerSqsHandler implements SqsMessageHandler<String> {
212+
@Override
213+
public String process(SQSEvent.SQSMessage message) {
214+
if ("2e1424d4-f796-459a-8184-9c92662be6da".equals(message.getMessageId())) {
215+
throw new RuntimeException("Failed processing");
216+
}
217+
218+
interactionClient.listQueues();
219+
return "Success";
220+
}
221+
}
76222
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package software.amazon.lambda.powertools.sqs.handlers;
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.sqs.SqsBatchProcessor;
7+
import software.amazon.lambda.powertools.sqs.SqsMessageHandler;
8+
9+
import static com.amazonaws.services.lambda.runtime.events.SQSEvent.SQSMessage;
10+
import static software.amazon.lambda.powertools.sqs.internal.SqsMessageBatchProcessorAspectTest.sqsClient;
11+
12+
public class PartialBatchFailureSuppressedHandler implements RequestHandler<SQSEvent, String> {
13+
@Override
14+
@SqsBatchProcessor(value = InnerMessageHandler.class, suppressException = true)
15+
public String handleRequest(final SQSEvent sqsEvent,
16+
final Context context) {
17+
return "Success";
18+
}
19+
20+
private class InnerMessageHandler implements SqsMessageHandler<Object> {
21+
22+
@Override
23+
public String process(SQSMessage message) {
24+
if ("2e1424d4-f796-459a-8184-9c92662be6da".equals(message.getMessageId())) {
25+
throw new RuntimeException("2e1424d4-f796-459a-8184-9c92662be6da");
26+
}
27+
28+
sqsClient.listQueues();
29+
return "Success";
30+
}
31+
}
32+
}

powertools-sqs/src/test/java/software/amazon/lambda/powertools/sqs/handlers/PartialBatchHandler.java

Lines changed: 0 additions & 36 deletions
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package software.amazon.lambda.powertools.sqs.handlers;
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.sqs.SqsBatchProcessor;
7+
import software.amazon.lambda.powertools.sqs.SqsMessageHandler;
8+
9+
import static com.amazonaws.services.lambda.runtime.events.SQSEvent.SQSMessage;
10+
import static software.amazon.lambda.powertools.sqs.internal.SqsMessageBatchProcessorAspectTest.sqsClient;
11+
12+
public class PartialBatchPartialFailureHandler implements RequestHandler<SQSEvent, String> {
13+
@Override
14+
@SqsBatchProcessor(InnerMessageHandler.class)
15+
public String handleRequest(final SQSEvent sqsEvent,
16+
final Context context) {
17+
return "Success";
18+
}
19+
20+
private class InnerMessageHandler implements SqsMessageHandler<Object> {
21+
22+
@Override
23+
public String process(SQSMessage message) {
24+
if ("2e1424d4-f796-459a-8184-9c92662be6da".equals(message.getMessageId())) {
25+
throw new RuntimeException("2e1424d4-f796-459a-8184-9c92662be6da");
26+
}
27+
28+
sqsClient.listQueues();
29+
return "Success";
30+
}
31+
}
32+
}

0 commit comments

Comments
 (0)