org.everit.http.client.testbase.HttpClientTest Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of org.everit.http.client.testbase Show documentation
Show all versions of org.everit.http.client.testbase Show documentation
Asynchronous HTTP Client API that can be a wrapper around any of the well known HTTP client libraries in Java.
/*
* Copyright © 2011 Everit Kft. (http://www.everit.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.everit.http.client.testbase;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.NetworkConnector;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.everit.http.client.FormUrlencodedAsyncContentProvider;
import org.everit.http.client.HttpClient;
import org.everit.http.client.HttpMethod;
import org.everit.http.client.HttpRequest;
import org.everit.http.client.HttpResponse;
import org.everit.http.client.async.AsyncContentUtil;
import org.json.JSONObject;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import io.reactivex.Single;
/**
* JUnit tst class that contains generic tests for the HTTP client library.
*/
public abstract class HttpClientTest {
private static final int BUFFER_SIZE = 8096;
public static final String CONTEXT_PATH = "/test";
private static final Logger LOGGER = Logger.getLogger(HttpClientTest.class.getName());
private static int port;
private static Server server;
private static final HttpClientTestServlet TEST_SERVLET = new HttpClientTestServlet();
/**
* Stops the HTTP server that the tests communicate with.
*/
@AfterClass
public static void afterClass() {
if (HttpClientTest.server != null) {
try {
HttpClientTest.server.stop();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
/**
* Starts up an HTTP server and registers {@link HttpClientTestServlet} on it to let the tests
* communicate with the servlet.
*/
@BeforeClass
public static void beforeClass() {
HttpClientTest.server = new Server();
ServletContextHandler servletContextHandler =
new ServletContextHandler(HttpClientTest.server, HttpClientTest.CONTEXT_PATH);
servletContextHandler.addServlet(new ServletHolder(HttpClientTest.TEST_SERVLET), "/*");
HttpClientTest.server.setHandler(servletContextHandler);
ServerConnector serverConnector = new ServerConnector(HttpClientTest.server);
final int thirtySecondsInMillisecs = 30000;
serverConnector.setIdleTimeout(thirtySecondsInMillisecs);
HttpClientTest.server.addConnector(serverConnector);
try {
HttpClientTest.server.start();
} catch (Exception e) {
throw new RuntimeException(e);
}
Connector[] connectors = HttpClientTest.server.getConnectors();
for (Connector connector : connectors) {
if (connector instanceof NetworkConnector) {
HttpClientTest.port = ((NetworkConnector) connector).getLocalPort();
}
}
}
private static String uriForPath(String path) {
return "http://localhost:" + HttpClientTest.port + HttpClientTest.CONTEXT_PATH + path;
}
private HttpClient httpClient;
/**
* Closes the created {@link HttpClient} instance after running the test.
*/
@After
public void after() {
if (this.httpClient != null) {
this.httpClient.close();
}
}
@Before
public void before() {
this.httpClient = createHttpClient();
}
protected abstract HttpClient createHttpClient();
private byte[] createTestByteArray() {
final int oneMegabyte = 1024 * 1024;
byte[] result = new byte[oneMegabyte];
for (int i = 0, n = result.length; i < n; i++) {
final int byteValueRestartPoint = 128;
result[i] = (byte) (i % byteValueRestartPoint);
}
return result;
}
private byte[][] createTestChunks(byte[] byteArray, int chunkSize) {
List result = new ArrayList<>();
int n = byteArray.length;
int position = 0;
while (position < n) {
int currentChunkSize = n - position;
if (currentChunkSize > chunkSize) {
currentChunkSize = chunkSize;
}
byte[] chunk = new byte[currentChunkSize];
System.arraycopy(byteArray, position, chunk, 0, currentChunkSize);
result.add(chunk);
position += currentChunkSize;
}
return result.toArray(new byte[0][]);
}
@Test
public void testBody() {
byte[] testByteArray = createTestByteArray();
byte[][] chunks = createTestChunks(testByteArray, HttpClientTest.BUFFER_SIZE);
Single single = this.httpClient.send(HttpRequest.builder().method(HttpMethod.GET)
.url(HttpClientTest.uriForPath(HttpClientTestServlet.PATH_TEST_WITH_BODY))
.body(Optional
.of(new ChunkedAsyncContentProvider(chunks, Optional.empty(), false)))
.build());
try (HttpResponse response = single.blockingGet()) {
Assert.assertEquals(Optional.of((long) testByteArray.length),
response.getBody().getContentLength());
Single bodySingle = AsyncContentUtil.readAllBytes(response.getBody());
byte[] body = bodySingle.blockingGet();
Assert.assertArrayEquals(testByteArray, body);
}
}
@Test
public void testBodyReceiveFailViaCallback() {
byte[] testByteArray = createTestByteArray();
byte[][] chunks = createTestChunks(testByteArray, HttpClientTest.BUFFER_SIZE);
Single single = this.httpClient.send(HttpRequest.builder().method(HttpMethod.GET)
.url(HttpClientTest.uriForPath(HttpClientTestServlet.PATH_TEST_WITH_BODY))
.body(Optional
.of(new ChunkedAsyncContentProvider(chunks, Optional.empty(), false)))
.build());
String errorMessage = "Error via callback";
try (HttpResponse httpResponse = single.blockingGet()) {
Single bodySingle = Single.create((emitter) -> {
httpResponse.getBody().onSuccess(() -> emitter.onSuccess(new byte[0]))
.onContent((content, callback) -> {
callback.failed(new RuntimeException(errorMessage));
})
.onError((error) -> emitter.onError(error));
});
try {
byte[] body = bodySingle.blockingGet();
Assert.fail(
"Exception should have been thrown, instead body arrived: " + Arrays.toString(body));
} catch (RuntimeException e) {
Assert.assertEquals(errorMessage, e.getMessage());
}
}
}
@Test
public void testBodyReceiveFailViaErrorInOnContent() {
byte[] testByteArray = createTestByteArray();
byte[][] chunks = createTestChunks(testByteArray, HttpClientTest.BUFFER_SIZE);
Single single = this.httpClient.send(HttpRequest.builder().method(HttpMethod.GET)
.url(HttpClientTest.uriForPath(HttpClientTestServlet.PATH_TEST_WITH_BODY))
.body(Optional.of(new ChunkedAsyncContentProvider(chunks, Optional.empty(), false)))
.build());
String errorMessage = "Error with throw exception";
try (HttpResponse httpResponse = single.blockingGet()) {
Single bodySingle = Single.create((emitter) -> {
httpResponse.getBody().onSuccess(() -> emitter.onSuccess(new byte[0]))
.onContent((content, callback) -> {
throw new RuntimeException(errorMessage);
})
.onError((error) -> emitter.onError(error));
});
try {
byte[] body = bodySingle.blockingGet();
Assert.fail(
"Exception should have been thrown, instead body arrived: " + Arrays.toString(body));
} catch (RuntimeException e) {
Assert.assertEquals(errorMessage, e.getMessage());
}
}
}
@Test
public void testBodySendFail() {
byte[] testByteArray = createTestByteArray();
byte[][] chunks = createTestChunks(testByteArray, HttpClientTest.BUFFER_SIZE);
Single single = this.httpClient.send(HttpRequest.builder().method(HttpMethod.GET)
.url(HttpClientTest.uriForPath(HttpClientTestServlet.PATH_TEST_WITH_BODY))
.body(Optional
.of(new ChunkedAsyncContentProvider(chunks, Optional.empty(), true)))
.build());
try (HttpResponse response = single.blockingGet()) {
Assert.fail("Exception should have been thrown");
} catch (BodySendException e) {
// Successful test
}
}
@Test
public void testConnectionClosedAfterHeaders() {
Single single =
this.httpClient.send(HttpRequest.builder().method(HttpMethod.GET)
.url(
HttpClientTest
.uriForPath(
HttpClientTestServlet.PATH_TEST_CONNECTION_ERROR_DURING_RESPONSE_BODY))
.build());
try (HttpResponse httpResponse = single.blockingGet()) {
Single bodySingle = AsyncContentUtil.readAllBytes(httpResponse.getBody());
try {
byte[] body = bodySingle.blockingGet();
Assert
.fail(
"Exception should have been thrown, instead body with length came: "
+ body.length);
} catch (RuntimeException e) {
Assert.assertNotNull(e);
}
}
}
@Test
public void testConnectionClosedBeforeHeaders() {
Single single = this.httpClient.send(HttpRequest.builder().method(HttpMethod.GET)
.url(HttpClientTest.uriForPath(HttpClientTestServlet.PATH_TEST_CONNECTION_ERROR_ON_ARRIVE))
.build());
try (HttpResponse httpResponse = single.blockingGet()) {
Assert.fail("Exception should have been thrown");
} catch (RuntimeException e) {
Assert.assertNotNull(e);
}
}
@Test
public void testFailureOnResponseCallback() {
byte[] testByteArray = createTestByteArray();
byte[][] chunks = createTestChunks(testByteArray, HttpClientTest.BUFFER_SIZE);
Single single = this.httpClient.send(HttpRequest.builder().method(HttpMethod.GET)
.url(HttpClientTest.uriForPath(HttpClientTestServlet.PATH_TEST_WITH_BODY))
.body(Optional
.of(new ChunkedAsyncContentProvider(chunks, Optional.empty(), false)))
.build());
try (HttpResponse response = single.blockingGet()) {
Assert.assertEquals(Optional.of((long) testByteArray.length),
response.getBody().getContentLength());
Single
© 2015 - 2025 Weber Informatics LLC | Privacy Policy