|
20 | 20 | import static com.github.tomakehurst.wiremock.client.WireMock.any; |
21 | 21 | import static com.github.tomakehurst.wiremock.client.WireMock.containing; |
22 | 22 | import static com.github.tomakehurst.wiremock.client.WireMock.equalTo; |
23 | | -import static com.github.tomakehurst.wiremock.client.WireMock.getRequestedFor; |
24 | 23 | import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor; |
25 | 24 | import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; |
26 | 25 | import static com.github.tomakehurst.wiremock.client.WireMock.urlMatching; |
27 | 26 | import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo; |
28 | 27 | import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig; |
29 | 28 | import static org.assertj.core.api.Assertions.assertThat; |
30 | 29 | import static org.assertj.core.api.Assertions.assertThatThrownBy; |
31 | | -import static org.assertj.core.api.AssertionsForClassTypes.assertThatCode; |
32 | 30 |
|
33 | 31 | import com.github.tomakehurst.wiremock.WireMockServer; |
34 | 32 | import com.github.tomakehurst.wiremock.client.ResponseDefinitionBuilder; |
@@ -238,148 +236,6 @@ public void doesNotRetryOn429StatusCode() throws Exception { |
238 | 236 | } |
239 | 237 | } |
240 | 238 |
|
241 | | - @Test |
242 | | - public void handlesNoContentResponse() throws Exception { |
243 | | - SdkHttpClient client = createSdkHttpClient(); |
244 | | - |
245 | | - mockServer.stubFor(any(urlPathEqualTo("/no-content")) |
246 | | - .willReturn(aResponse() |
247 | | - .withStatus(204))); |
248 | | - |
249 | | - SdkHttpFullRequest req = mockSdkRequest("http://localhost:" + mockServer.port() + "/no-content", |
250 | | - SdkHttpMethod.DELETE); |
251 | | - HttpExecuteResponse rsp = client.prepareRequest(HttpExecuteRequest.builder() |
252 | | - .request(req) |
253 | | - .build()) |
254 | | - .call(); |
255 | | - |
256 | | - assertThat(rsp.httpResponse().statusCode()).isEqualTo(204); |
257 | | - assertThat(rsp.responseBody()).isEmpty(); |
258 | | - } |
259 | | - |
260 | | - @Test |
261 | | - public void handlesLargeResponseBody() throws Exception { |
262 | | - SdkHttpClient client = createSdkHttpClient(); |
263 | | - // Create a large response body (1MB) |
264 | | - byte[] largeBody = new byte[1024 * 1024]; |
265 | | - for (int i = 0; i < largeBody.length; i++) { |
266 | | - largeBody[i] = (byte) (i % 256); |
267 | | - } |
268 | | - mockServer.stubFor(any(urlPathEqualTo("/large")) |
269 | | - .willReturn(aResponse() |
270 | | - .withStatus(200) |
271 | | - .withBody(largeBody))); |
272 | | - |
273 | | - SdkHttpFullRequest req = mockSdkRequest("http://localhost:" + mockServer.port() + "/large", SdkHttpMethod.GET); |
274 | | - HttpExecuteResponse rsp = client.prepareRequest(HttpExecuteRequest.builder() |
275 | | - .request(req) |
276 | | - .build()) |
277 | | - .call(); |
278 | | - |
279 | | - assertThat(rsp.httpResponse().statusCode()).isEqualTo(200); |
280 | | - assertThat(rsp.responseBody()).isPresent(); |
281 | | - |
282 | | - // Read the entire response and verify |
283 | | - byte[] readBuffer = IoUtils.toByteArray(rsp.responseBody().get()); |
284 | | - assertThat(readBuffer).isEqualTo(largeBody); |
285 | | - } |
286 | | - |
287 | | - @Test |
288 | | - public void testAbortResponseStream() throws Exception { |
289 | | - SdkHttpClient client = createSdkHttpClient(); |
290 | | - |
291 | | - mockServer.stubFor(any(urlPathEqualTo("/streaming")) |
292 | | - .willReturn(aResponse() |
293 | | - .withStatus(200) |
294 | | - .withBody("This is a streaming response that should be aborted"))); |
295 | | - |
296 | | - SdkHttpFullRequest req = mockSdkRequest("http://localhost:" + mockServer.port() + "/streaming", SdkHttpMethod.POST); |
297 | | - ExecutableHttpRequest executableRequest = client.prepareRequest( |
298 | | - HttpExecuteRequest.builder() |
299 | | - .request(req) |
300 | | - .contentStreamProvider(req.contentStreamProvider() |
301 | | - .orElse(null)) |
302 | | - .build()); |
303 | | - HttpExecuteResponse rsp = executableRequest.call(); |
304 | | - |
305 | | - assertThat(rsp.httpResponse().statusCode()).isEqualTo(200); |
306 | | - assertThat(rsp.responseBody()).isPresent(); |
307 | | - |
308 | | - // Verify the stream is abortable |
309 | | - AbortableInputStream stream = rsp.responseBody().get(); |
310 | | - assertThat(stream).isInstanceOf(AbortableInputStream.class); |
311 | | - |
312 | | - // Read a few bytes |
313 | | - byte[] buffer = new byte[10]; |
314 | | - int bytesRead = stream.read(buffer); |
315 | | - assertThat(bytesRead).isGreaterThan(0); |
316 | | - assertThatCode(() -> stream.abort()).doesNotThrowAnyException(); |
317 | | - stream.close(); |
318 | | - } |
319 | | - |
320 | | - @Test |
321 | | - public void handlesMultipleSequentialRequests() throws Exception { |
322 | | - SdkHttpClient client = createSdkHttpClient(); |
323 | | - |
324 | | - mockServer.stubFor(any(urlPathEqualTo("/sequential")) |
325 | | - .willReturn(aResponse() |
326 | | - .withStatus(200) |
327 | | - .withBody("Response body"))); |
328 | | - |
329 | | - // Execute multiple requests sequentially |
330 | | - for (int i = 0; i < 5; i++) { |
331 | | - SdkHttpFullRequest req = mockSdkRequest("http://localhost:" + mockServer.port() + "/sequential", SdkHttpMethod.GET); |
332 | | - HttpExecuteResponse rsp = client.prepareRequest(HttpExecuteRequest.builder() |
333 | | - .request(req) |
334 | | - .build()) |
335 | | - .call(); |
336 | | - |
337 | | - assertThat(rsp.httpResponse().statusCode()).isEqualTo(200); |
338 | | - assertThat(IoUtils.toUtf8String(rsp.responseBody().orElse(null))).isEqualTo("Response body"); |
339 | | - } |
340 | | - mockServer.verify(5, getRequestedFor(urlEqualTo("/sequential"))); |
341 | | - } |
342 | | - |
343 | | - @Test |
344 | | - public void handlesVariousContentLengths() throws Exception { |
345 | | - SdkHttpClient client = createSdkHttpClient(); |
346 | | - int[] contentLengths = {0, 1, 100, 1024, 65536}; |
347 | | - |
348 | | - for (int length : contentLengths) { |
349 | | - String path = "/content-length-" + length; |
350 | | - byte[] body = new byte[length]; |
351 | | - for (int i = 0; i < length; i++) { |
352 | | - body[i] = (byte) ('A' + (i % 26)); |
353 | | - } |
354 | | - |
355 | | - mockServer.stubFor(any(urlPathEqualTo(path)) |
356 | | - .willReturn(aResponse() |
357 | | - .withStatus(200) |
358 | | - .withHeader("Content-Length", String.valueOf(length)) |
359 | | - .withBody(body))); |
360 | | - |
361 | | - SdkHttpFullRequest req = mockSdkRequest("http://localhost:" + mockServer.port() + path, SdkHttpMethod.GET); |
362 | | - HttpExecuteResponse rsp = client.prepareRequest(HttpExecuteRequest.builder() |
363 | | - .request(req) |
364 | | - .build()) |
365 | | - .call(); |
366 | | - |
367 | | - assertThat(rsp.httpResponse().statusCode()).isEqualTo(200); |
368 | | - |
369 | | - if (length == 0) { |
370 | | - // Empty body should still have a response body present, but EOF immediately |
371 | | - if (rsp.responseBody().isPresent()) { |
372 | | - assertThat(rsp.responseBody().get().read()).isEqualTo(-1); |
373 | | - } |
374 | | - } else { |
375 | | - assertThat(rsp.responseBody()).isPresent(); |
376 | | - byte[] readBody = IoUtils.toByteArray(rsp.responseBody().get()); |
377 | | - assertThat(readBody).isEqualTo(body); |
378 | | - } |
379 | | - } |
380 | | - } |
381 | | - |
382 | | - |
383 | 239 | private void validateStatusCodeWithRetryCheck(SdkHttpClient client, |
384 | 240 | int expectedStatusCode, |
385 | 241 | int expectedRequestCount) throws IOException { |
@@ -503,23 +359,13 @@ private static SdkHttpFullRequest.Builder mockSdkRequestBuilder(String uriString |
503 | 359 | return requestBuilder; |
504 | 360 | } |
505 | 361 |
|
506 | | - protected SdkHttpFullRequest mockSdkRequest(String uriString, SdkHttpMethod method) { |
507 | | - URI uri = URI.create(uriString); |
508 | | - SdkHttpFullRequest.Builder requestBuilder = SdkHttpFullRequest.builder() |
509 | | - .uri(uri) |
510 | | - .method(method) |
511 | | - .putHeader("Host", uri.getHost()) |
512 | | - .putHeader("User-Agent", "hello-world!"); |
513 | 362 |
|
514 | | - // Only add body for methods that typically have a body |
515 | | - if (method != SdkHttpMethod.HEAD && method != SdkHttpMethod.GET && method != SdkHttpMethod.DELETE) { |
| 363 | + protected SdkHttpFullRequest mockSdkRequest(String uriString, SdkHttpMethod method) { |
| 364 | + SdkHttpFullRequest.Builder requestBuilder = mockSdkRequestBuilder(uriString, method); |
| 365 | + if (method != SdkHttpMethod.HEAD) { |
516 | 366 | byte[] content = "Body".getBytes(StandardCharsets.UTF_8); |
517 | 367 | requestBuilder.putHeader("Content-Length", Integer.toString(content.length)); |
518 | 368 | requestBuilder.contentStreamProvider(() -> new ByteArrayInputStream(content)); |
519 | | - } else if (method == SdkHttpMethod.GET || method == SdkHttpMethod.DELETE) { |
520 | | - // For GET and DELETE, explicitly set Content-Length to 0 or don't set it at all |
521 | | - // Some clients like AWS CRT are strict about this |
522 | | - requestBuilder.contentStreamProvider(() -> new ByteArrayInputStream(new byte[0])); |
523 | 369 | } |
524 | 370 |
|
525 | 371 | return requestBuilder.build(); |
|
0 commit comments