13
13
*/
14
14
package software .amazon .lambda .powertools .logging .internal ;
15
15
16
+ import java .io .BufferedReader ;
16
17
import java .io .ByteArrayInputStream ;
17
18
import java .io .ByteArrayOutputStream ;
18
19
import java .io .IOException ;
20
+ import java .io .InputStreamReader ;
21
+ import java .lang .reflect .InvocationTargetException ;
22
+ import java .lang .reflect .Method ;
23
+ import java .nio .channels .FileChannel ;
19
24
import java .nio .charset .StandardCharsets ;
20
- import java .util .HashMap ;
25
+ import java .nio .file .Files ;
26
+ import java .nio .file .Paths ;
27
+ import java .nio .file .StandardOpenOption ;
21
28
import java .util .Map ;
22
29
23
30
import com .amazonaws .services .lambda .runtime .Context ;
24
31
import com .amazonaws .services .lambda .runtime .RequestHandler ;
25
32
import com .amazonaws .services .lambda .runtime .RequestStreamHandler ;
33
+ import com .amazonaws .services .lambda .runtime .events .models .s3 .S3EventNotification ;
34
+ import com .fasterxml .jackson .core .JsonProcessingException ;
26
35
import com .fasterxml .jackson .databind .ObjectMapper ;
36
+ import org .apache .logging .log4j .Level ;
27
37
import org .apache .logging .log4j .ThreadContext ;
38
+ import org .json .JSONException ;
28
39
import org .junit .jupiter .api .BeforeEach ;
29
40
import org .junit .jupiter .api .Test ;
30
41
import org .mockito .Mock ;
31
42
import org .mockito .MockedStatic ;
32
- import org .mockito .Mockito ;
33
43
import software .amazon .lambda .powertools .core .internal .LambdaHandlerProcessor ;
34
44
import software .amazon .lambda .powertools .logging .handlers .PowerLogToolEnabled ;
35
45
import software .amazon .lambda .powertools .logging .handlers .PowerLogToolEnabledForStream ;
38
48
import software .amazon .lambda .powertools .logging .handlers .PowerToolLogEventEnabled ;
39
49
import software .amazon .lambda .powertools .logging .handlers .PowerToolLogEventEnabledForStream ;
40
50
51
+ import static com .amazonaws .services .lambda .runtime .events .models .s3 .S3EventNotification .RequestParametersEntity ;
52
+ import static com .amazonaws .services .lambda .runtime .events .models .s3 .S3EventNotification .ResponseElementsEntity ;
53
+ import static com .amazonaws .services .lambda .runtime .events .models .s3 .S3EventNotification .S3BucketEntity ;
54
+ import static com .amazonaws .services .lambda .runtime .events .models .s3 .S3EventNotification .S3Entity ;
55
+ import static com .amazonaws .services .lambda .runtime .events .models .s3 .S3EventNotification .S3EventNotificationRecord ;
56
+ import static com .amazonaws .services .lambda .runtime .events .models .s3 .S3EventNotification .S3ObjectEntity ;
57
+ import static com .amazonaws .services .lambda .runtime .events .models .s3 .S3EventNotification .UserIdentityEntity ;
58
+ import static java .util .Collections .emptyMap ;
59
+ import static java .util .Collections .singletonList ;
60
+ import static java .util .stream .Collectors .joining ;
41
61
import static org .apache .commons .lang3 .reflect .FieldUtils .writeStaticField ;
42
62
import static org .assertj .core .api .Assertions .assertThat ;
63
+ import static org .assertj .core .api .Assertions .fail ;
43
64
import static org .mockito .Mockito .mockStatic ;
44
65
import static org .mockito .Mockito .when ;
45
66
import static org .mockito .MockitoAnnotations .openMocks ;
67
+ import static org .skyscreamer .jsonassert .JSONAssert .assertEquals ;
46
68
import static software .amazon .lambda .powertools .logging .internal .SystemWrapper .getenv ;
47
69
48
70
class LambdaLoggingAspectTest {
@@ -55,13 +77,16 @@ class LambdaLoggingAspectTest {
55
77
private Context context ;
56
78
57
79
@ BeforeEach
58
- void setUp () throws IllegalAccessException {
80
+ void setUp () throws IllegalAccessException , IOException , NoSuchMethodException , InvocationTargetException {
59
81
openMocks (this );
60
82
ThreadContext .clearAll ();
61
83
writeStaticField (LambdaHandlerProcessor .class , "IS_COLD_START" , null , true );
62
84
setupContext ();
63
85
requestHandler = new PowerLogToolEnabled ();
64
86
requestStreamHandler = new PowerLogToolEnabledForStream ();
87
+ //Make sure file is cleaned up before running full stack logging regression
88
+ FileChannel .open (Paths .get ("target/logfile.json" ), StandardOpenOption .WRITE ).truncate (0 ).close ();
89
+ resetLogLevel (Level .INFO );
65
90
}
66
91
67
92
@ Test
@@ -140,30 +165,41 @@ void shouldHaveNoEffectIfNotUsedOnLambdaHandler() {
140
165
}
141
166
142
167
@ Test
143
- void shouldLogEventForHandler () {
168
+ void shouldLogEventForHandler () throws IOException , JSONException {
144
169
requestHandler = new PowerToolLogEventEnabled ();
170
+ S3EventNotification s3EventNotification = s3EventNotification ();
145
171
146
- requestHandler .handleRequest (new Object () , context );
172
+ requestHandler .handleRequest (s3EventNotification , context );
147
173
148
- assertThat (ThreadContext .getImmutableContext ())
149
- .hasSize (EXPECTED_CONTEXT_SIZE );
174
+ Map <String , Object > log = parseToMap (Files .lines (Paths .get ("target/logfile.json" )).collect (joining ()));
175
+
176
+ String event = (String ) log .get ("message" );
177
+
178
+ String expectEvent = new BufferedReader (new InputStreamReader (this .getClass ().getResourceAsStream ("/s3EventNotification.json" )))
179
+ .lines ().collect (joining ("\n " ));
180
+
181
+ assertEquals (expectEvent , event , false );
150
182
}
151
183
152
184
@ Test
153
- void shouldLogEventForStreamAndLambdaStreamIsValid () throws IOException {
185
+ void shouldLogEventForStreamAndLambdaStreamIsValid () throws IOException , JSONException {
154
186
requestStreamHandler = new PowerToolLogEventEnabledForStream ();
155
187
ByteArrayOutputStream output = new ByteArrayOutputStream ();
188
+ S3EventNotification s3EventNotification = s3EventNotification ();
156
189
157
- Map <String , String > testPayload = new HashMap <>();
158
- testPayload .put ("test" , "payload" );
159
-
160
- requestStreamHandler .handleRequest (new ByteArrayInputStream (new ObjectMapper ().writeValueAsBytes (testPayload )), output , context );
190
+ requestStreamHandler .handleRequest (new ByteArrayInputStream (new ObjectMapper ().writeValueAsBytes (s3EventNotification )), output , context );
161
191
162
192
assertThat (new String (output .toByteArray (), StandardCharsets .UTF_8 ))
163
- .isEqualTo ( "{ \" test \" : \" payload \" }" );
193
+ .isNotEmpty ( );
164
194
165
- assertThat (ThreadContext .getImmutableContext ())
166
- .hasSize (EXPECTED_CONTEXT_SIZE );
195
+ Map <String , Object > log = parseToMap (Files .lines (Paths .get ("target/logfile.json" )).collect (joining ()));
196
+
197
+ String event = (String ) log .get ("message" );
198
+
199
+ String expectEvent = new BufferedReader (new InputStreamReader (this .getClass ().getResourceAsStream ("/s3EventNotification.json" )))
200
+ .lines ().collect (joining ("\n " ));
201
+
202
+ assertEquals (expectEvent , event , false );
167
203
}
168
204
169
205
@ Test
@@ -197,4 +233,44 @@ private void setupContext() {
197
233
when (context .getFunctionVersion ()).thenReturn ("1" );
198
234
when (context .getMemoryLimitInMB ()).thenReturn (10 );
199
235
}
236
+
237
+ private void resetLogLevel (Level level ) throws NoSuchMethodException , IllegalAccessException , InvocationTargetException {
238
+ Method resetLogLevels = LambdaLoggingAspect .class .getDeclaredMethod ("resetLogLevels" , Level .class );
239
+ resetLogLevels .setAccessible (true );
240
+ resetLogLevels .invoke (null , level );
241
+ writeStaticField (LambdaLoggingAspect .class , "LEVEL_AT_INITIALISATION" , level , true );
242
+ }
243
+
244
+ private S3EventNotification s3EventNotification () {
245
+ S3EventNotificationRecord record = new S3EventNotificationRecord ("us-west-2" ,
246
+ "ObjectCreated:Put" ,
247
+ "aws:s3" ,
248
+ null ,
249
+ "2.1" ,
250
+ new RequestParametersEntity ("127.0.0.1" ),
251
+ new ResponseElementsEntity ("C3D13FE58DE4C810" , "FMyUVURIY8/IgAtTv8xRjskZQpcIZ9KG4V5Wp6S7S/JRWeUWerMUE5JgHvANOjpD" ),
252
+ new S3Entity ("testConfigRule" ,
253
+ new S3BucketEntity ("mybucket" ,
254
+ new UserIdentityEntity ("A3NL1KOZZKExample" ),
255
+ "arn:aws:s3:::mybucket" ),
256
+ new S3ObjectEntity ("HappyFace.jpg" ,
257
+ 1024L ,
258
+ "d41d8cd98f00b204e9800998ecf8427e" ,
259
+ "096fKKXTRTtl3on89fVO.nfljtsv6qko" ,
260
+ "0055AED6DCD90281E5" ),
261
+ "1.0" ),
262
+ new UserIdentityEntity ("AIDAJDPLRKLG7UEXAMPLE" )
263
+ );
264
+
265
+ return new S3EventNotification (singletonList (record ));
266
+ }
267
+
268
+ private Map <String , Object > parseToMap (String stringAsJson ) {
269
+ try {
270
+ return new ObjectMapper ().readValue (stringAsJson , Map .class );
271
+ } catch (JsonProcessingException e ) {
272
+ fail ("Failed parsing logger line " + stringAsJson );
273
+ return emptyMap ();
274
+ }
275
+ }
200
276
}
0 commit comments