1
+ /*
2
+ Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+ SPDX-License-Identifier: Apache-2.0
4
+ */
5
+
6
+ package com .amazonaws .services .lambda .runtime .api .client .runtimeapi ;
7
+
8
+ import org .junit .jupiter .api .BeforeEach ;
9
+ import org .junit .jupiter .api .Test ;
10
+ import org .junit .jupiter .api .condition .DisabledOnOs ;
11
+ import org .junit .jupiter .api .condition .OS ;
12
+
13
+ import static org .junit .jupiter .api .Assertions .assertTrue ;
14
+ import static org .junit .jupiter .api .Assertions .assertNull ;
15
+ import static org .junit .jupiter .api .Assertions .assertEquals ;
16
+ import static org .junit .jupiter .api .Assertions .assertThrows ;
17
+ import com .amazonaws .services .lambda .runtime .api .client .runtimeapi .dto .ErrorRequest ;
18
+ import com .amazonaws .services .lambda .runtime .api .client .runtimeapi .dto .StackElement ;
19
+ import com .amazonaws .services .lambda .runtime .api .client .runtimeapi .dto .XRayErrorCause ;
20
+ import com .amazonaws .services .lambda .runtime .api .client .runtimeapi .dto .XRayException ;
21
+
22
+ import java .util .ArrayList ;
23
+ import java .util .List ;
24
+
25
+ import static org .junit .jupiter .api .Assertions .fail ;
26
+ import okhttp3 .HttpUrl ;
27
+ import static java .net .HttpURLConnection .HTTP_ACCEPTED ;
28
+ import static java .net .HttpURLConnection .HTTP_OK ;
29
+ import static java .net .HttpURLConnection .HTTP_INTERNAL_ERROR ;
30
+ import okhttp3 .mockwebserver .MockWebServer ;
31
+
32
+ import okhttp3 .mockwebserver .MockResponse ;
33
+ import okhttp3 .mockwebserver .RecordedRequest ;
34
+
35
+ @ DisabledOnOs (OS .MAC )
36
+ public class LambdaRuntimeApiClientImplTest {
37
+
38
+ MockWebServer mockWebServer ;
39
+ LambdaRuntimeApiClientImpl lambdaRuntimeApiClientImpl ;
40
+
41
+ String [] errorStackStrace = { "item0" , "item1" , "item2" };
42
+ ErrorRequest errorRequest = new ErrorRequest ("testErrorMessage" , "testErrorType" , errorStackStrace );
43
+
44
+ String requestId = "1234" ;
45
+
46
+ @ BeforeEach
47
+ void setUp () {
48
+ mockWebServer = new MockWebServer ();
49
+ String hostnamePort = getHostnamePort ();
50
+ lambdaRuntimeApiClientImpl = new LambdaRuntimeApiClientImpl (hostnamePort );
51
+ }
52
+
53
+ @ Test
54
+ public void reportInitErrorTest () {
55
+ try {
56
+ RapidErrorType rapidErrorType = RapidErrorType .AfterRestoreError ;
57
+
58
+ MockResponse mockResponse = new MockResponse ();
59
+ mockResponse .setResponseCode (HTTP_ACCEPTED );
60
+ mockWebServer .enqueue (mockResponse );
61
+
62
+ LambdaError lambdaError = new LambdaError (errorRequest , rapidErrorType );
63
+ lambdaRuntimeApiClientImpl .reportInitError (lambdaError );
64
+ RecordedRequest recordedRequest = mockWebServer .takeRequest ();
65
+ HttpUrl actualUrl = recordedRequest .getRequestUrl ();
66
+ String expectedUrl = "http://" + getHostnamePort () + "/2018-06-01/runtime/init/error" ;
67
+ assertEquals (expectedUrl , actualUrl .toString ());
68
+
69
+ String userAgentHeader = recordedRequest .getHeader ("User-Agent" );
70
+ assertTrue (userAgentHeader .startsWith ("aws-lambda-java/" ));
71
+
72
+ String lambdaRuntimeErrorTypeHeader = recordedRequest .getHeader ("Lambda-Runtime-Function-Error-Type" );
73
+ assertEquals ("Runtime.AfterRestoreError" , lambdaRuntimeErrorTypeHeader );
74
+
75
+ String actualBody = recordedRequest .getBody ().readUtf8 ();
76
+ assertEquals ("{\" errorMessage\" :\" testErrorMessage\" ,\" errorType\" :\" testErrorType\" ,\" stackTrace\" :[\" item0\" ,\" item1\" ,\" item2\" ]}" , actualBody );
77
+ } catch (Exception e ) {
78
+ fail ();
79
+ }
80
+ }
81
+
82
+ @ Test
83
+ public void reportInitErrorTestWrongStatusCode () {
84
+ int errorStatusCode = HTTP_INTERNAL_ERROR ;
85
+ try {
86
+ RapidErrorType rapidErrorType = RapidErrorType .AfterRestoreError ;
87
+
88
+ MockResponse mockResponse = new MockResponse ();
89
+ mockResponse .setResponseCode (errorStatusCode );
90
+ mockWebServer .enqueue (mockResponse );
91
+
92
+ LambdaError lambdaError = new LambdaError (errorRequest , rapidErrorType );
93
+ lambdaRuntimeApiClientImpl .reportInitError (lambdaError );
94
+ fail ();
95
+ } catch (LambdaRuntimeClientException e ) {
96
+ String expectedUrl = "http://" + getHostnamePort () + "/2018-06-01/runtime/init/error" ;
97
+ String expectedMessage = expectedUrl + " Response code: '" + errorStatusCode + "'." ;
98
+ assertEquals (expectedMessage , e .getLocalizedMessage ());
99
+ } catch (Exception e ) {
100
+ fail ();
101
+ }
102
+ }
103
+
104
+ @ Test
105
+ public void reportRestoreErrorTest () {
106
+ try {
107
+ RapidErrorType rapidErrorType = RapidErrorType .AfterRestoreError ;
108
+
109
+ MockResponse mockResponse = new MockResponse ();
110
+ mockResponse .setResponseCode (HTTP_ACCEPTED );
111
+ mockWebServer .enqueue (mockResponse );
112
+
113
+ LambdaError lambdaError = new LambdaError (errorRequest , rapidErrorType );
114
+ lambdaRuntimeApiClientImpl .reportRestoreError (lambdaError );
115
+ RecordedRequest recordedRequest = mockWebServer .takeRequest ();
116
+ HttpUrl actualUrl = recordedRequest .getRequestUrl ();
117
+ String expectedUrl = "http://" + getHostnamePort () + "/2018-06-01/runtime/restore/error" ;
118
+ assertEquals (expectedUrl , actualUrl .toString ());
119
+
120
+ String userAgentHeader = recordedRequest .getHeader ("User-Agent" );
121
+ assertTrue (userAgentHeader .startsWith ("aws-lambda-java/" ));
122
+
123
+ String lambdaRuntimeErrorTypeHeader = recordedRequest .getHeader ("Lambda-Runtime-Function-Error-Type" );
124
+ assertEquals ("Runtime.AfterRestoreError" , lambdaRuntimeErrorTypeHeader );
125
+
126
+ String actualBody = recordedRequest .getBody ().readUtf8 ();
127
+ assertEquals ("{\" errorMessage\" :\" testErrorMessage\" ,\" errorType\" :\" testErrorType\" ,\" stackTrace\" :[\" item0\" ,\" item1\" ,\" item2\" ]}" , actualBody );
128
+ } catch (Exception e ) {
129
+ fail ();
130
+ }
131
+ }
132
+
133
+ @ Test
134
+ public void reportRestoreErrorTestWrongStatusCode () {
135
+ int errorStatusCode = HTTP_INTERNAL_ERROR ;
136
+ try {
137
+ RapidErrorType rapidErrorType = RapidErrorType .AfterRestoreError ;
138
+
139
+ MockResponse mockResponse = new MockResponse ();
140
+ mockResponse .setResponseCode (errorStatusCode );
141
+ mockWebServer .enqueue (mockResponse );
142
+
143
+ LambdaError lambdaError = new LambdaError (errorRequest , rapidErrorType );
144
+ lambdaRuntimeApiClientImpl .reportRestoreError (lambdaError );
145
+ fail ();
146
+ } catch (LambdaRuntimeClientException e ) {
147
+ String expectedUrl = "http://" + getHostnamePort () + "/2018-06-01/runtime/restore/error" ;
148
+ String expectedMessage = expectedUrl + " Response code: '" + errorStatusCode + "'." ;
149
+ assertEquals (expectedMessage , e .getLocalizedMessage ());
150
+ } catch (Exception e ) {
151
+ fail ();
152
+ }
153
+ }
154
+
155
+ @ Test
156
+ public void reportInvocationErrorTest () {
157
+ try {
158
+ RapidErrorType rapidErrorType = RapidErrorType .AfterRestoreError ;
159
+
160
+ MockResponse mockResponse = new MockResponse ();
161
+ mockResponse .setResponseCode (HTTP_ACCEPTED );
162
+ mockWebServer .enqueue (mockResponse );
163
+
164
+ LambdaError lambdaError = new LambdaError (errorRequest , rapidErrorType );
165
+ lambdaRuntimeApiClientImpl .reportInvocationError (requestId , lambdaError );
166
+ RecordedRequest recordedRequest = mockWebServer .takeRequest ();
167
+ HttpUrl actualUrl = recordedRequest .getRequestUrl ();
168
+ String expectedUrl = "http://" + getHostnamePort () + "/2018-06-01/runtime/invocation/1234/error" ;
169
+ assertEquals (expectedUrl , actualUrl .toString ());
170
+
171
+ String userAgentHeader = recordedRequest .getHeader ("User-Agent" );
172
+ assertTrue (userAgentHeader .startsWith ("aws-lambda-java/" ));
173
+
174
+ String lambdaRuntimeErrorTypeHeader = recordedRequest .getHeader ("Lambda-Runtime-Function-Error-Type" );
175
+ assertEquals ("Runtime.AfterRestoreError" , lambdaRuntimeErrorTypeHeader );
176
+
177
+ String actualBody = recordedRequest .getBody ().readUtf8 ();
178
+ assertEquals ("{\" errorMessage\" :\" testErrorMessage\" ,\" errorType\" :\" testErrorType\" ,\" stackTrace\" :[\" item0\" ,\" item1\" ,\" item2\" ]}" , actualBody );
179
+ } catch (Exception e ) {
180
+ fail ();
181
+ }
182
+ }
183
+
184
+ @ Test
185
+ public void reportInvocationErrorTestWrongStatusCode () {
186
+ int errorStatusCode = HTTP_INTERNAL_ERROR ;
187
+ try {
188
+ RapidErrorType rapidErrorType = RapidErrorType .AfterRestoreError ;
189
+
190
+ MockResponse mockResponse = new MockResponse ();
191
+ mockResponse .setResponseCode (errorStatusCode );
192
+ mockWebServer .enqueue (mockResponse );
193
+
194
+ LambdaError lambdaError = new LambdaError (errorRequest , rapidErrorType );
195
+ lambdaRuntimeApiClientImpl .reportInvocationError (requestId , lambdaError );
196
+ fail ();
197
+ } catch (LambdaRuntimeClientException e ) {
198
+ String expectedUrl = "http://" + getHostnamePort () + "/2018-06-01/runtime/invocation/1234/error" ;
199
+ String expectedMessage = expectedUrl + " Response code: '" + errorStatusCode + "'." ;
200
+ assertEquals (expectedMessage , e .getLocalizedMessage ());
201
+ } catch (Exception e ) {
202
+ fail ();
203
+ }
204
+ }
205
+
206
+ @ Test
207
+ public void reportLambdaErrorWithXRayTest () {
208
+ try {
209
+ RapidErrorType rapidErrorType = RapidErrorType .AfterRestoreError ;
210
+
211
+ MockResponse mockResponse = new MockResponse ();
212
+ mockResponse .setResponseCode (HTTP_ACCEPTED );
213
+ mockWebServer .enqueue (mockResponse );
214
+
215
+ String workingDirectory = "my-test-directory" ;
216
+ List <String > paths = new ArrayList <String >();
217
+ paths .add ("path-0" );
218
+ paths .add ("path-1" );
219
+ paths .add ("path-2" );
220
+
221
+ List <StackElement > stackElements0 = new ArrayList <>();
222
+ stackElements0 .add (new StackElement ("label0" , "path0" , 0 ));
223
+ stackElements0 .add (new StackElement ("label1" , "path1" , 1 ));
224
+ stackElements0 .add (new StackElement ("label2" , "path2" , 2 ));
225
+ XRayException xRayException0 = new XRayException ("my-test-message0" , "my-test-type0" , stackElements0 );
226
+
227
+ List <StackElement > stackElements1 = new ArrayList <>();
228
+ stackElements1 .add (new StackElement ("label10" , "path10" , 0 ));
229
+ stackElements1 .add (new StackElement ("label11" , "path11" , 11 ));
230
+ stackElements1 .add (new StackElement ("label12" , "path12" , 12 ));
231
+ XRayException xRayException1 = new XRayException ("my-test-message1" , "my-test-type0" , stackElements1 );
232
+
233
+ List <XRayException > exceptions = new ArrayList <>();
234
+ exceptions .add (xRayException0 );
235
+ exceptions .add (xRayException1 );
236
+
237
+ XRayErrorCause xRayErrorCause = new XRayErrorCause (workingDirectory , exceptions , paths );
238
+ LambdaError lambdaError = new LambdaError (errorRequest , xRayErrorCause , rapidErrorType );
239
+ lambdaRuntimeApiClientImpl .reportInvocationError (requestId , lambdaError );
240
+ RecordedRequest recordedRequest = mockWebServer .takeRequest ();
241
+
242
+ String xrayErrorCauseHeader = recordedRequest .getHeader ("Lambda-Runtime-Function-XRay-Error-Cause" );
243
+ assertEquals ("{\" working_directory\" :\" my-test-directory\" ,\" exceptions\" :[{\" message\" :\" my-test-message0\" ,\" type\" :\" my-test-type0\" ,\" stack\" :[{\" label\" :\" label0\" ," +
244
+ "\" path\" :\" path0\" ,\" line\" :0},{\" label\" :\" label1\" ,\" path\" :\" path1\" ,\" line\" :1},{\" label\" :\" label2\" ,\" path\" :\" path2\" ,\" line\" :2}]},{\" message\" :\" my-test-message1\" ," +
245
+ "\" type\" :\" my-test-type0\" ,\" stack\" :[{\" label\" :\" label10\" ,\" path\" :\" path10\" ,\" line\" :0},{\" label\" :\" label11\" ,\" path\" :\" path11\" ,\" line\" :11},{\" label\" :\" label12\" ," +
246
+ "\" path\" :\" path12\" ,\" line\" :12}]}],\" paths\" :[\" path-0\" ,\" path-1\" ,\" path-2\" ]}" , xrayErrorCauseHeader );
247
+ } catch (Exception e ) {
248
+ fail ();
249
+ }
250
+ }
251
+
252
+ @ Test
253
+ public void reportInvocationSuccessTest () {
254
+ try {
255
+ MockResponse mockResponse = new MockResponse ();
256
+ mockResponse .setResponseCode (HTTP_ACCEPTED );
257
+ mockWebServer .enqueue (mockResponse );
258
+
259
+ String response = "{\" msg\" :\" test\" }" ;
260
+ lambdaRuntimeApiClientImpl .reportInvocationSuccess (requestId , response .getBytes ());
261
+ RecordedRequest recordedRequest = mockWebServer .takeRequest ();
262
+ HttpUrl actualUrl = recordedRequest .getRequestUrl ();
263
+ String expectedUrl = "http://" + getHostnamePort () + "/2018-06-01/runtime/invocation/1234/response" ;
264
+ assertEquals (expectedUrl , actualUrl .toString ());
265
+
266
+ String actualBody = recordedRequest .getBody ().readUtf8 ();
267
+ assertEquals ("{\" msg\" :\" test\" }" , actualBody );
268
+ } catch (Exception e ) {
269
+ e .printStackTrace ();
270
+ fail ();
271
+ }
272
+ }
273
+
274
+ @ Test
275
+ public void restoreNextTest () {
276
+ try {
277
+ MockResponse mockResponse = new MockResponse ();
278
+ mockResponse .setResponseCode (HTTP_OK );
279
+ mockWebServer .enqueue (mockResponse );
280
+
281
+ lambdaRuntimeApiClientImpl .restoreNext ();
282
+ RecordedRequest recordedRequest = mockWebServer .takeRequest ();
283
+ HttpUrl actualUrl = recordedRequest .getRequestUrl ();
284
+ String expectedUrl = "http://" + getHostnamePort () + "/2018-06-01/runtime/restore/next" ;
285
+ assertEquals (expectedUrl , actualUrl .toString ());
286
+
287
+ String actualBody = recordedRequest .getBody ().readUtf8 ();
288
+ assertEquals ("" , actualBody );
289
+ } catch (Exception e ) {
290
+ e .printStackTrace ();
291
+ fail ();
292
+ }
293
+ }
294
+
295
+ @ Test
296
+ public void restoreNextWrongStatusCodeTest () {
297
+ int errorStatusCode = HTTP_INTERNAL_ERROR ;
298
+ try {
299
+ MockResponse mockResponse = new MockResponse ();
300
+ mockResponse .setResponseCode (errorStatusCode );
301
+ mockWebServer .enqueue (mockResponse );
302
+
303
+ lambdaRuntimeApiClientImpl .restoreNext ();
304
+ fail ();
305
+ } catch (LambdaRuntimeClientException e ) {
306
+ String expectedUrl = "http://" + getHostnamePort () + "/2018-06-01/runtime/restore/next" ;
307
+ String expectedMessage = expectedUrl + " Response code: '" + errorStatusCode + "'." ;
308
+ assertEquals (expectedMessage , e .getLocalizedMessage ());
309
+ } catch (Exception e ) {
310
+ fail ();
311
+ }
312
+ }
313
+
314
+ @ Test
315
+ public void nextTest () {
316
+ try {
317
+ MockResponse mockResponse = new MockResponse ();
318
+ mockResponse .setResponseCode (HTTP_ACCEPTED );
319
+ mockResponse .setHeader ("lambda-runtime-aws-request-id" , "1234567890" );
320
+ mockResponse .setHeader ("Content-Type" , "application/json" );
321
+ mockWebServer .enqueue (mockResponse );
322
+
323
+ lambdaRuntimeApiClientImpl .nextInvocation ();
324
+ RecordedRequest recordedRequest = mockWebServer .takeRequest ();
325
+ HttpUrl actualUrl = recordedRequest .getRequestUrl ();
326
+ String expectedUrl = "http://" + getHostnamePort () + "/2018-06-01/runtime/invocation/next" ;
327
+ assertEquals (expectedUrl , actualUrl .toString ());
328
+
329
+ String actualBody = recordedRequest .getBody ().readUtf8 ();
330
+ assertEquals ("" , actualBody );
331
+ } catch (Exception e ) {
332
+ fail ();
333
+ }
334
+ }
335
+
336
+
337
+ @ Test
338
+ public void createUrlMalformedTest () {
339
+ RapidErrorType rapidErrorType = RapidErrorType .AfterRestoreError ;
340
+ LambdaError lambdaError = new LambdaError (errorRequest , rapidErrorType );
341
+ RuntimeException thrown = assertThrows (RuntimeException .class , ()->{
342
+ lambdaRuntimeApiClientImpl .reportLambdaError ("invalidurl" , lambdaError , 100 );
343
+ });
344
+ assertTrue (thrown .getLocalizedMessage ().contains ("java.net.MalformedURLException" ));
345
+ }
346
+
347
+ @ Test
348
+ public void lambdaReportErrorXRayHeaderTooLongTest () {
349
+ try {
350
+ RapidErrorType rapidErrorType = RapidErrorType .AfterRestoreError ;
351
+
352
+ MockResponse mockResponse = new MockResponse ();
353
+ mockResponse .setResponseCode (HTTP_ACCEPTED );
354
+ mockWebServer .enqueue (mockResponse );
355
+
356
+ String workingDirectory = "my-test-directory" ;
357
+ List <String > paths = new ArrayList <String >();
358
+ paths .add ("path-0" );
359
+
360
+ List <StackElement > stackElements = new ArrayList <>();
361
+ stackElements .add (new StackElement ("label0" , "path0" , 0 ));
362
+ XRayException xRayException = new XRayException ("my-test-message0" , "my-test-type0" , stackElements );
363
+
364
+ List <XRayException > exceptions = new ArrayList <>();
365
+ exceptions .add (xRayException );
366
+
367
+ XRayErrorCause xRayErrorCause = new XRayErrorCause (workingDirectory , exceptions , paths );
368
+ LambdaError lambdaError = new LambdaError (errorRequest , xRayErrorCause , rapidErrorType );
369
+ lambdaRuntimeApiClientImpl .reportLambdaError ("http://" + getHostnamePort (), lambdaError , 10 );
370
+ RecordedRequest recordedRequest = mockWebServer .takeRequest ();
371
+
372
+ String xrayErrorCauseHeader = recordedRequest .getHeader ("Lambda-Runtime-Function-XRay-Error-Cause" );
373
+ assertNull (xrayErrorCauseHeader );
374
+ } catch (Exception e ) {
375
+ fail ();
376
+ }
377
+ }
378
+
379
+ private String getHostnamePort () {
380
+ return mockWebServer .getHostName () + ":" + mockWebServer .getPort ();
381
+ }
382
+ }
0 commit comments