You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2008/03/12 20:11:14 UTC
svn commit: r636459 -
/httpcomponents/httpcore/trunk/module-nio/src/test/java/org/apache/http/nio/protocol/TestThrottlingNHttpHandlers.java
Author: olegk
Date: Wed Mar 12 12:11:10 2008
New Revision: 636459
URL: http://svn.apache.org/viewvc?rev=636459&view=rev
Log:
More test cases for throttling protocol handlers
Modified:
httpcomponents/httpcore/trunk/module-nio/src/test/java/org/apache/http/nio/protocol/TestThrottlingNHttpHandlers.java
Modified: httpcomponents/httpcore/trunk/module-nio/src/test/java/org/apache/http/nio/protocol/TestThrottlingNHttpHandlers.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/module-nio/src/test/java/org/apache/http/nio/protocol/TestThrottlingNHttpHandlers.java?rev=636459&r1=636458&r2=636459&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/module-nio/src/test/java/org/apache/http/nio/protocol/TestThrottlingNHttpHandlers.java (original)
+++ httpcomponents/httpcore/trunk/module-nio/src/test/java/org/apache/http/nio/protocol/TestThrottlingNHttpHandlers.java Wed Mar 12 12:11:10 2008
@@ -51,12 +51,14 @@
import junit.framework.TestCase;
import junit.framework.TestSuite;
+import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpException;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
+import org.apache.http.HttpVersion;
import org.apache.http.entity.InputStreamEntity;
import org.apache.http.impl.DefaultConnectionReuseStrategy;
import org.apache.http.impl.DefaultHttpResponseFactory;
@@ -64,6 +66,7 @@
import org.apache.http.message.BasicHttpRequest;
import org.apache.http.mockup.ByteSequence;
import org.apache.http.mockup.RequestCount;
+import org.apache.http.mockup.ResponseSequence;
import org.apache.http.mockup.SimpleEventListener;
import org.apache.http.mockup.SimpleHttpRequestHandlerResolver;
import org.apache.http.mockup.TestHttpClient;
@@ -92,6 +95,7 @@
import org.apache.http.protocol.ResponseContent;
import org.apache.http.protocol.ResponseDate;
import org.apache.http.protocol.ResponseServer;
+import org.apache.http.util.EncodingUtils;
import org.apache.http.util.EntityUtils;
/**
@@ -772,4 +776,589 @@
this.server.getParams().setIntParameter(
CoreConnectionPNames.SO_TIMEOUT, originalTimeout);
}
+
+ /**
+ * This test case executes a series of simple (non-pipelined) HTTP/1.0
+ * POST requests over multiple persistent connections.
+ */
+ public void testSimpleHttpPostsHTTP10() throws Exception {
+
+ final int connNo = 3;
+ final int reqNo = 20;
+ final RequestCount requestCount = new RequestCount(connNo * reqNo);
+ final ByteSequence requestData = new ByteSequence();
+ requestData.rnd(reqNo);
+
+ List<ByteSequence> responseData = new ArrayList<ByteSequence>(connNo);
+ for (int i = 0; i < connNo; i++) {
+ responseData.add(new ByteSequence());
+ }
+
+ HttpRequestHandler requestHandler = new HttpRequestHandler() {
+
+
+ public void handle(
+ final HttpRequest request,
+ final HttpResponse response,
+ final HttpContext context) throws HttpException, IOException {
+
+ if (request instanceof HttpEntityEnclosingRequest) {
+ HttpEntity incoming = ((HttpEntityEnclosingRequest) request).getEntity();
+ byte[] data = EntityUtils.toByteArray(incoming);
+
+ NByteArrayEntity outgoing = new NByteArrayEntity(data);
+ outgoing.setChunked(false);
+ response.setEntity(outgoing);
+ } else {
+ NStringEntity outgoing = new NStringEntity("No content");
+ response.setEntity(outgoing);
+ }
+ }
+
+ };
+
+ // Set protocol level to HTTP/1.0
+ this.client.getParams().setParameter(
+ CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_0);
+
+ HttpRequestExecutionHandler requestExecutionHandler = new HttpRequestExecutionHandler() {
+
+ public void initalizeContext(final HttpContext context, final Object attachment) {
+ context.setAttribute("LIST", (ByteSequence) attachment);
+ context.setAttribute("REQ-COUNT", new Integer(0));
+ context.setAttribute("RES-COUNT", new Integer(0));
+ }
+
+ public void finalizeContext(final HttpContext context) {
+ }
+
+ public HttpRequest submitRequest(final HttpContext context) {
+ int i = ((Integer) context.getAttribute("REQ-COUNT")).intValue();
+ BasicHttpEntityEnclosingRequest post = null;
+ if (i < reqNo) {
+ post = new BasicHttpEntityEnclosingRequest("POST", "/?" + i);
+ byte[] data = requestData.getBytes(i);
+ NByteArrayEntity outgoing = new NByteArrayEntity(data);
+ post.setEntity(outgoing);
+
+ context.setAttribute("REQ-COUNT", new Integer(i + 1));
+ }
+ return post;
+ }
+
+ public void handleResponse(final HttpResponse response, final HttpContext context) {
+ NHttpConnection conn = (NHttpConnection) context.getAttribute(
+ ExecutionContext.HTTP_CONNECTION);
+
+ ByteSequence list = (ByteSequence) context.getAttribute("LIST");
+ int i = ((Integer) context.getAttribute("RES-COUNT")).intValue();
+ i++;
+ context.setAttribute("RES-COUNT", new Integer(i));
+
+ try {
+ HttpEntity entity = response.getEntity();
+ byte[] data = EntityUtils.toByteArray(entity);
+ list.addBytes(data);
+ requestCount.decrement();
+ } catch (IOException ex) {
+ requestCount.abort();
+ return;
+ }
+
+ if (i < reqNo) {
+ conn.requestInput();
+ }
+ }
+
+ };
+
+ NHttpServiceHandler serviceHandler = createHttpServiceHandler(
+ requestHandler,
+ null,
+ this.execService);
+
+ NHttpClientHandler clientHandler = createHttpClientHandler(
+ requestExecutionHandler,
+ this.execService);
+
+ this.server.setRequestCount(requestCount);
+ this.client.setRequestCount(requestCount);
+
+ this.server.start(serviceHandler);
+ this.client.start(clientHandler);
+
+ ListenerEndpoint endpoint = this.server.getListenerEndpoint();
+ endpoint.waitFor();
+ InetSocketAddress serverAddress = (InetSocketAddress) endpoint.getAddress();
+
+ for (int i = 0; i < responseData.size(); i++) {
+ this.client.openConnection(
+ new InetSocketAddress("localhost", serverAddress.getPort()),
+ responseData.get(i));
+ }
+
+ requestCount.await(10000);
+ assertEquals(0, requestCount.getValue());
+
+ this.client.shutdown();
+ this.server.shutdown();
+
+ for (int c = 0; c < responseData.size(); c++) {
+ ByteSequence receivedPackets = responseData.get(c);
+ ByteSequence expectedPackets = requestData;
+ assertEquals(expectedPackets.size(), receivedPackets.size());
+ for (int p = 0; p < requestData.size(); p++) {
+ byte[] expected = requestData.getBytes(p);
+ byte[] received = receivedPackets.getBytes(p);
+
+ assertEquals(expected.length, received.length);
+ for (int i = 0; i < expected.length; i++) {
+ assertEquals(expected[i], received[i]);
+ }
+ }
+ }
+
+ }
+
+ /**
+ * This test case executes a series of simple (non-pipelined) POST requests
+ * over multiple connections using the 'expect: continue' handshake.
+ */
+ public void testHttpPostsWithExpectContinue() throws Exception {
+
+ final int connNo = 3;
+ final int reqNo = 20;
+ final RequestCount requestCount = new RequestCount(connNo * reqNo);
+ final ByteSequence requestData = new ByteSequence();
+ requestData.rnd(reqNo);
+
+ List<ByteSequence> responseData = new ArrayList<ByteSequence>(connNo);
+ for (int i = 0; i < connNo; i++) {
+ responseData.add(new ByteSequence());
+ }
+
+ HttpRequestHandler requestHandler = new HttpRequestHandler() {
+
+ public void handle(
+ final HttpRequest request,
+ final HttpResponse response,
+ final HttpContext context) throws HttpException, IOException {
+
+ if (request instanceof HttpEntityEnclosingRequest) {
+ HttpEntity incoming = ((HttpEntityEnclosingRequest) request).getEntity();
+ byte[] data = EntityUtils.toByteArray(incoming);
+ NByteArrayEntity outgoing = new NByteArrayEntity(data);
+ outgoing.setChunked(true);
+ response.setEntity(outgoing);
+ } else {
+ NStringEntity outgoing = new NStringEntity("No content");
+ response.setEntity(outgoing);
+ }
+ }
+
+ };
+
+ // Activate 'expect: continue' handshake
+ this.client.getParams().setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, true);
+
+ HttpRequestExecutionHandler requestExecutionHandler = new HttpRequestExecutionHandler() {
+
+ public void initalizeContext(final HttpContext context, final Object attachment) {
+ context.setAttribute("LIST", (ByteSequence) attachment);
+ context.setAttribute("REQ-COUNT", new Integer(0));
+ context.setAttribute("RES-COUNT", new Integer(0));
+ }
+
+ public void finalizeContext(final HttpContext context) {
+ }
+
+ public HttpRequest submitRequest(final HttpContext context) {
+ int i = ((Integer) context.getAttribute("REQ-COUNT")).intValue();
+ BasicHttpEntityEnclosingRequest post = null;
+ if (i < reqNo) {
+ post = new BasicHttpEntityEnclosingRequest("POST", "/?" + i);
+ byte[] data = requestData.getBytes(i);
+ NByteArrayEntity outgoing = new NByteArrayEntity(data);
+ outgoing.setChunked(true);
+ post.setEntity(outgoing);
+
+ context.setAttribute("REQ-COUNT", new Integer(i + 1));
+ }
+ return post;
+ }
+
+ public void handleResponse(final HttpResponse response, final HttpContext context) {
+ NHttpConnection conn = (NHttpConnection) context.getAttribute(
+ ExecutionContext.HTTP_CONNECTION);
+
+ ByteSequence list = (ByteSequence) context.getAttribute("LIST");
+ int i = ((Integer) context.getAttribute("RES-COUNT")).intValue();
+ i++;
+ context.setAttribute("RES-COUNT", new Integer(i));
+
+ try {
+ HttpEntity entity = response.getEntity();
+ byte[] data = EntityUtils.toByteArray(entity);
+ list.addBytes(data);
+ requestCount.decrement();
+ } catch (IOException ex) {
+ requestCount.abort();
+ return;
+ }
+
+ if (i < reqNo) {
+ conn.requestInput();
+ }
+ }
+
+ };
+
+ NHttpServiceHandler serviceHandler = createHttpServiceHandler(
+ requestHandler,
+ null,
+ this.execService);
+
+ NHttpClientHandler clientHandler = createHttpClientHandler(
+ requestExecutionHandler,
+ this.execService);
+
+ this.server.setRequestCount(requestCount);
+ this.client.setRequestCount(requestCount);
+
+ this.server.start(serviceHandler);
+ this.client.start(clientHandler);
+
+ ListenerEndpoint endpoint = this.server.getListenerEndpoint();
+ endpoint.waitFor();
+ InetSocketAddress serverAddress = (InetSocketAddress) endpoint.getAddress();
+
+ for (int i = 0; i < responseData.size(); i++) {
+ this.client.openConnection(
+ new InetSocketAddress("localhost", serverAddress.getPort()),
+ responseData.get(i));
+ }
+
+ requestCount.await(10000);
+ assertEquals(0, requestCount.getValue());
+
+ this.client.shutdown();
+ this.server.shutdown();
+
+ for (int c = 0; c < responseData.size(); c++) {
+ ByteSequence receivedPackets = responseData.get(c);
+ ByteSequence expectedPackets = requestData;
+ assertEquals(expectedPackets.size(), receivedPackets.size());
+ for (int p = 0; p < requestData.size(); p++) {
+ byte[] expected = requestData.getBytes(p);
+ byte[] received = receivedPackets.getBytes(p);
+
+ assertEquals(expected.length, received.length);
+ for (int i = 0; i < expected.length; i++) {
+ assertEquals(expected[i], received[i]);
+ }
+ }
+ }
+
+ }
+
+ /**
+ * This test case executes a series of simple (non-pipelined) POST requests
+ * over multiple connections that do not meet the target server expectations.
+ */
+ public void testHttpPostsWithExpectationVerification() throws Exception {
+
+ final int reqNo = 3;
+ final RequestCount requestCount = new RequestCount(reqNo);
+ final ResponseSequence responses = new ResponseSequence();
+
+ HttpRequestHandler requestHandler = new HttpRequestHandler() {
+
+ public void handle(
+ final HttpRequest request,
+ final HttpResponse response,
+ final HttpContext context) throws HttpException, IOException {
+
+ NStringEntity outgoing = new NStringEntity("No content");
+ response.setEntity(outgoing);
+ }
+
+ };
+
+ HttpExpectationVerifier expectationVerifier = new HttpExpectationVerifier() {
+
+ public void verify(
+ final HttpRequest request,
+ final HttpResponse response,
+ final HttpContext context) throws HttpException {
+ Header someheader = request.getFirstHeader("Secret");
+ if (someheader != null) {
+ int secretNumber;
+ try {
+ secretNumber = Integer.parseInt(someheader.getValue());
+ } catch (NumberFormatException ex) {
+ response.setStatusCode(HttpStatus.SC_BAD_REQUEST);
+ return;
+ }
+ if (secretNumber < 2) {
+ response.setStatusCode(HttpStatus.SC_EXPECTATION_FAILED);
+ NByteArrayEntity outgoing = new NByteArrayEntity(
+ EncodingUtils.getAsciiBytes("Wrong secret number"));
+ response.setEntity(outgoing);
+ }
+ }
+ }
+
+ };
+
+ // Activate 'expect: continue' handshake
+ this.client.getParams().setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, true);
+
+ HttpRequestExecutionHandler requestExecutionHandler = new HttpRequestExecutionHandler() {
+
+ public void initalizeContext(final HttpContext context, final Object attachment) {
+ context.setAttribute("LIST", (ResponseSequence) attachment);
+ context.setAttribute("REQ-COUNT", new Integer(0));
+ context.setAttribute("RES-COUNT", new Integer(0));
+ }
+
+ public void finalizeContext(final HttpContext context) {
+ }
+
+ public HttpRequest submitRequest(final HttpContext context) {
+ int i = ((Integer) context.getAttribute("REQ-COUNT")).intValue();
+ BasicHttpEntityEnclosingRequest post = null;
+ if (i < reqNo) {
+ post = new BasicHttpEntityEnclosingRequest("POST", "/");
+ post.addHeader("Secret", Integer.toString(i));
+ NByteArrayEntity outgoing = new NByteArrayEntity(
+ EncodingUtils.getAsciiBytes("No content"));
+ post.setEntity(outgoing);
+
+ context.setAttribute("REQ-COUNT", new Integer(i + 1));
+ }
+ return post;
+ }
+
+ public void handleResponse(final HttpResponse response, final HttpContext context) {
+ NHttpConnection conn = (NHttpConnection) context.getAttribute(
+ ExecutionContext.HTTP_CONNECTION);
+
+ ResponseSequence list = (ResponseSequence) context.getAttribute("LIST");
+ int i = ((Integer) context.getAttribute("RES-COUNT")).intValue();
+ i++;
+ context.setAttribute("RES-COUNT", new Integer(i));
+
+ HttpEntity entity = response.getEntity();
+ if (entity != null) {
+ try {
+ entity.consumeContent();
+ } catch (IOException ex) {
+ requestCount.abort();
+ return;
+ }
+ }
+
+ list.addResponse(response);
+ requestCount.decrement();
+
+ if (i < reqNo) {
+ conn.requestInput();
+ }
+ }
+
+ };
+
+ NHttpServiceHandler serviceHandler = createHttpServiceHandler(
+ requestHandler,
+ expectationVerifier,
+ this.execService);
+
+ NHttpClientHandler clientHandler = createHttpClientHandler(
+ requestExecutionHandler,
+ this.execService);
+
+ this.server.setRequestCount(requestCount);
+ this.client.setRequestCount(requestCount);
+
+ this.server.start(serviceHandler);
+ this.client.start(clientHandler);
+
+ ListenerEndpoint endpoint = this.server.getListenerEndpoint();
+ endpoint.waitFor();
+ InetSocketAddress serverAddress = (InetSocketAddress) endpoint.getAddress();
+
+ this.client.openConnection(
+ new InetSocketAddress("localhost", serverAddress.getPort()),
+ responses);
+
+ requestCount.await(10000);
+
+ this.client.shutdown();
+ this.server.shutdown();
+
+ assertEquals(reqNo, responses.size());
+ HttpResponse response = responses.getResponse(0);
+ assertEquals(HttpStatus.SC_EXPECTATION_FAILED, response.getStatusLine().getStatusCode());
+ response = responses.getResponse(1);
+ assertEquals(HttpStatus.SC_EXPECTATION_FAILED, response.getStatusLine().getStatusCode());
+ response = responses.getResponse(2);
+ assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
+ }
+
+ /**
+ * This test case executes a series of simple (non-pipelined) HEAD requests
+ * over multiple connections.
+ */
+ public void testSimpleHttpHeads() throws Exception {
+
+ final int connNo = 3;
+ final int reqNo = 20;
+ final RequestCount requestCount = new RequestCount(connNo * reqNo * 2);
+
+ final ByteSequence requestData = new ByteSequence();
+ requestData.rnd(reqNo);
+
+ List<ResponseSequence> responseData1 = new ArrayList<ResponseSequence>(connNo);
+ for (int i = 0; i < connNo; i++) {
+ responseData1.add(new ResponseSequence());
+ }
+ List<ResponseSequence> responseData2 = new ArrayList<ResponseSequence>(connNo);
+ for (int i = 0; i < connNo; i++) {
+ responseData2.add(new ResponseSequence());
+ }
+
+ final String[] method = new String[1];
+
+ HttpRequestHandler requestHandler = new HttpRequestHandler() {
+
+ public void handle(
+ final HttpRequest request,
+ final HttpResponse response,
+ final HttpContext context) throws HttpException, IOException {
+
+ String s = request.getRequestLine().getUri();
+ URI uri;
+ try {
+ uri = new URI(s);
+ } catch (URISyntaxException ex) {
+ throw new HttpException("Invalid request URI: " + s);
+ }
+ int index = Integer.parseInt(uri.getQuery());
+
+ byte[] data = requestData.getBytes(index);
+ NByteArrayEntity entity = new NByteArrayEntity(data);
+ response.setEntity(entity);
+ }
+
+ };
+
+ HttpRequestExecutionHandler requestExecutionHandler = new HttpRequestExecutionHandler() {
+
+ public void initalizeContext(final HttpContext context, final Object attachment) {
+ context.setAttribute("LIST", (ResponseSequence) attachment);
+ context.setAttribute("REQ-COUNT", new Integer(0));
+ context.setAttribute("RES-COUNT", new Integer(0));
+ }
+
+ public void finalizeContext(final HttpContext context) {
+ }
+
+ public HttpRequest submitRequest(final HttpContext context) {
+ int i = ((Integer) context.getAttribute("REQ-COUNT")).intValue();
+ BasicHttpRequest request = null;
+ if (i < reqNo) {
+ request = new BasicHttpRequest(method[0], "/?" + i);
+ context.setAttribute("REQ-COUNT", new Integer(i + 1));
+ }
+ return request;
+ }
+
+ public void handleResponse(final HttpResponse response, final HttpContext context) {
+ NHttpConnection conn = (NHttpConnection) context.getAttribute(
+ ExecutionContext.HTTP_CONNECTION);
+
+ ResponseSequence list = (ResponseSequence) context.getAttribute("LIST");
+ int i = ((Integer) context.getAttribute("RES-COUNT")).intValue();
+ i++;
+ context.setAttribute("RES-COUNT", new Integer(i));
+
+ list.addResponse(response);
+ requestCount.decrement();
+
+ if (i < reqNo) {
+ conn.requestInput();
+ }
+ }
+
+ };
+
+ NHttpServiceHandler serviceHandler = createHttpServiceHandler(
+ requestHandler,
+ null,
+ this.execService);
+
+ NHttpClientHandler clientHandler = createHttpClientHandler(
+ requestExecutionHandler,
+ this.execService);
+
+ this.server.setRequestCount(requestCount);
+ this.client.setRequestCount(requestCount);
+
+ this.server.start(serviceHandler);
+ this.client.start(clientHandler);
+
+ ListenerEndpoint endpoint = this.server.getListenerEndpoint();
+ endpoint.waitFor();
+ InetSocketAddress serverAddress = (InetSocketAddress) endpoint.getAddress();
+
+ method[0] = "GET";
+
+ for (int i = 0; i < responseData1.size(); i++) {
+ this.client.openConnection(
+ new InetSocketAddress("localhost", serverAddress.getPort()),
+ responseData1.get(i));
+ }
+
+ requestCount.await(connNo * reqNo, 10000);
+ assertEquals(connNo * reqNo, requestCount.getValue());
+
+ method[0] = "HEAD";
+
+ for (int i = 0; i < responseData2.size(); i++) {
+ this.client.openConnection(
+ new InetSocketAddress("localhost", serverAddress.getPort()),
+ responseData2.get(i));
+ }
+
+
+ requestCount.await(10000);
+ assertEquals(0, requestCount.getValue());
+
+ this.client.shutdown();
+ this.server.shutdown();
+
+ for (int c = 0; c < connNo; c++) {
+ ResponseSequence getResponses = responseData1.get(c);
+ ResponseSequence headResponses = responseData2.get(c);
+ ByteSequence expectedPackets = requestData;
+ assertEquals(expectedPackets.size(), headResponses.size());
+ assertEquals(expectedPackets.size(), getResponses.size());
+ for (int p = 0; p < requestData.size(); p++) {
+ HttpResponse getResponse = getResponses.getResponse(p);
+ HttpResponse headResponse = headResponses.getResponse(p);
+ assertEquals(null, headResponse.getEntity());
+
+ Header[] getHeaders = getResponse.getAllHeaders();
+ Header[] headHeaders = headResponse.getAllHeaders();
+ assertEquals(getHeaders.length, headHeaders.length);
+ for (int j = 0; j < getHeaders.length; j++) {
+ if ("Date".equals(getHeaders[j].getName())) {
+ continue;
+ }
+ assertEquals(getHeaders[j].toString(), headHeaders[j].toString());
+ }
+ }
+ }
+ }
+
}