16
16
package software .amazon .awssdk .http .crt .internal ;
17
17
18
18
import static org .assertj .core .api .Assertions .assertThat ;
19
+ import static org .assertj .core .api .Assertions .assertThatThrownBy ;
19
20
import static software .amazon .awssdk .http .HttpTestUtils .createProvider ;
20
21
import static software .amazon .awssdk .http .crt .CrtHttpClientTestUtils .createRequest ;
21
22
33
34
import software .amazon .awssdk .crt .CrtRuntimeException ;
34
35
import software .amazon .awssdk .crt .http .HttpClientConnection ;
35
36
import software .amazon .awssdk .crt .http .HttpClientConnectionManager ;
37
+ import software .amazon .awssdk .crt .http .HttpException ;
36
38
import software .amazon .awssdk .crt .http .HttpRequest ;
37
39
import software .amazon .awssdk .http .SdkCancellationException ;
38
40
import software .amazon .awssdk .http .SdkHttpFullRequest ;
39
41
import software .amazon .awssdk .http .async .AsyncExecuteRequest ;
40
42
import software .amazon .awssdk .http .async .SdkAsyncHttpResponseHandler ;
41
43
import software .amazon .awssdk .http .crt .internal .response .CrtResponseAdapter ;
44
+ import software .amazon .awssdk .utils .CompletableFutureUtils ;
42
45
43
46
@ RunWith (MockitoJUnitRunner .class )
44
47
public class CrtRequestExecutorTest {
@@ -91,16 +94,7 @@ public void acquireConnectionThrowException_shouldInvokeOnError() {
91
94
@ Test
92
95
public void makeRequestThrowException_shouldInvokeOnError () {
93
96
CrtRuntimeException exception = new CrtRuntimeException ("" );
94
- SdkHttpFullRequest request = createRequest (URI .create ("http://localhost" ));
95
- CrtRequestContext context = CrtRequestContext .builder ()
96
- .readBufferSize (2000 )
97
- .crtConnPool (connectionManager )
98
- .request (AsyncExecuteRequest .builder ()
99
- .request (request )
100
- .requestContentPublisher (createProvider ("" ))
101
- .responseHandler (responseHandler )
102
- .build ())
103
- .build ();
97
+ CrtRequestContext context = crtRequestContext ();
104
98
CompletableFuture <HttpClientConnection > completableFuture = new CompletableFuture <>();
105
99
106
100
Mockito .when (connectionManager .acquireConnection ()).thenReturn (completableFuture );
@@ -122,16 +116,7 @@ public void makeRequestThrowException_shouldInvokeOnError() {
122
116
123
117
@ Test
124
118
public void makeRequest_success () {
125
- SdkHttpFullRequest request = createRequest (URI .create ("http://localhost" ));
126
- CrtRequestContext context = CrtRequestContext .builder ()
127
- .readBufferSize (2000 )
128
- .crtConnPool (connectionManager )
129
- .request (AsyncExecuteRequest .builder ()
130
- .request (request )
131
- .requestContentPublisher (createProvider ("" ))
132
- .responseHandler (responseHandler )
133
- .build ())
134
- .build ();
119
+ CrtRequestContext context = crtRequestContext ();
135
120
CompletableFuture <HttpClientConnection > completableFuture = new CompletableFuture <>();
136
121
Mockito .when (connectionManager .acquireConnection ()).thenReturn (completableFuture );
137
122
completableFuture .complete (httpClientConnection );
@@ -162,4 +147,97 @@ public void cancelRequest_shouldInvokeOnError() {
162
147
assertThat (actualException ).hasMessageContaining ("The request was cancelled" );
163
148
assertThat (actualException ).isInstanceOf (SdkCancellationException .class );
164
149
}
150
+
151
+ @ Test
152
+ public void execute_AcquireConnectionFailure_shouldAlwaysWrapIOException () {
153
+ CrtRequestContext context = crtRequestContext ();
154
+ RuntimeException exception = new RuntimeException ("some failure" );
155
+ CompletableFuture <HttpClientConnection > completableFuture = CompletableFutureUtils .failedFuture (exception );
156
+
157
+ Mockito .when (connectionManager .acquireConnection ()).thenReturn (completableFuture );
158
+
159
+ CompletableFuture <Void > executeFuture = requestExecutor .execute (context );
160
+ assertThatThrownBy (executeFuture ::join ).hasCauseInstanceOf (IOException .class ).hasRootCause (exception );
161
+ }
162
+
163
+ @ Test
164
+ public void executeRequest_failedOfIllegalStateException_shouldWrapIOException () {
165
+ IllegalStateException exception = new IllegalStateException ("connection closed" );
166
+ CrtRequestContext context = crtRequestContext ();
167
+ CompletableFuture <HttpClientConnection > completableFuture = new CompletableFuture <>();
168
+
169
+ Mockito .when (connectionManager .acquireConnection ()).thenReturn (completableFuture );
170
+ completableFuture .complete (httpClientConnection );
171
+
172
+ Mockito .when (httpClientConnection .makeRequest (Mockito .any (HttpRequest .class ), Mockito .any (CrtResponseAdapter .class )))
173
+ .thenThrow (exception );
174
+
175
+ CompletableFuture <Void > executeFuture = requestExecutor .execute (context );
176
+
177
+ ArgumentCaptor <Exception > argumentCaptor = ArgumentCaptor .forClass (Exception .class );
178
+ Mockito .verify (responseHandler ).onError (argumentCaptor .capture ());
179
+
180
+ Exception actualException = argumentCaptor .getValue ();
181
+ assertThat (actualException ).hasMessageContaining ("An exception occurred when making the request" ).hasCause (exception );
182
+ assertThatThrownBy (executeFuture ::join ).hasCauseInstanceOf (IOException .class ).hasRootCause (exception );
183
+ }
184
+
185
+ @ Test
186
+ public void executeRequest_failedOfRetryableHttpException_shouldWrapIOException () {
187
+ HttpException exception = new HttpException (0x080a ); // AWS_ERROR_HTTP_CONNECTION_CLOSED
188
+ CrtRequestContext context = crtRequestContext ();
189
+ CompletableFuture <HttpClientConnection > completableFuture = new CompletableFuture <>();
190
+
191
+ Mockito .when (connectionManager .acquireConnection ()).thenReturn (completableFuture );
192
+ completableFuture .complete (httpClientConnection );
193
+
194
+ Mockito .when (httpClientConnection .makeRequest (Mockito .any (HttpRequest .class ), Mockito .any (CrtResponseAdapter .class )))
195
+ .thenThrow (exception );
196
+
197
+ CompletableFuture <Void > executeFuture = requestExecutor .execute (context );
198
+
199
+ ArgumentCaptor <Exception > argumentCaptor = ArgumentCaptor .forClass (Exception .class );
200
+ Mockito .verify (responseHandler ).onError (argumentCaptor .capture ());
201
+
202
+ Exception actualException = argumentCaptor .getValue ();
203
+ assertThat (actualException ).hasCause (exception );
204
+ assertThatThrownBy (executeFuture ::join ).hasCauseInstanceOf (IOException .class ).hasRootCause (exception );
205
+ }
206
+
207
+
208
+ @ Test
209
+ public void executeRequest_failedOfNonRetryableHttpException_shouldNotWrapIOException () {
210
+ HttpException exception = new HttpException (0x0801 ); // AWS_ERROR_HTTP_HEADER_NOT_FOUND
211
+ CrtRequestContext context = crtRequestContext ();
212
+ CompletableFuture <HttpClientConnection > completableFuture = new CompletableFuture <>();
213
+
214
+ Mockito .when (connectionManager .acquireConnection ()).thenReturn (completableFuture );
215
+ completableFuture .complete (httpClientConnection );
216
+
217
+ Mockito .when (httpClientConnection .makeRequest (Mockito .any (HttpRequest .class ), Mockito .any (CrtResponseAdapter .class )))
218
+ .thenThrow (exception );
219
+
220
+ CompletableFuture <Void > executeFuture = requestExecutor .execute (context );
221
+
222
+ ArgumentCaptor <Exception > argumentCaptor = ArgumentCaptor .forClass (Exception .class );
223
+ Mockito .verify (responseHandler ).onError (argumentCaptor .capture ());
224
+
225
+ Exception actualException = argumentCaptor .getValue ();
226
+ assertThat (actualException ).isEqualTo (exception );
227
+ assertThatThrownBy (executeFuture ::join ).hasCause (exception );
228
+ }
229
+
230
+ private CrtRequestContext crtRequestContext () {
231
+ SdkHttpFullRequest request = createRequest (URI .create ("http://localhost" ));
232
+ return CrtRequestContext .builder ()
233
+ .readBufferSize (2000 )
234
+ .crtConnPool (connectionManager )
235
+ .request (AsyncExecuteRequest .builder ()
236
+ .request (request )
237
+ .requestContentPublisher (createProvider ("" ))
238
+ .responseHandler (responseHandler )
239
+ .build ())
240
+ .build ();
241
+ }
242
+
165
243
}
0 commit comments