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 2011/09/15 17:21:52 UTC

svn commit: r1171131 [1/2] - in /httpcomponents/httpcore/trunk/httpcore-nio/src: main/java/org/apache/http/nio/protocol/ test/java/org/apache/http/nio/protocol/

Author: olegk
Date: Thu Sep 15 15:21:52 2011
New Revision: 1171131

URL: http://svn.apache.org/viewvc?rev=1171131&view=rev
Log:
Unit tests for HttpAsyncServiceHandler and HttpAsyncRequestExecutor; fixed several bugs in HttpAsyncClientExchangeHandlerImpl

Added:
    httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestHttpAsyncRequestExecutor.java   (with props)
    httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestHttpAsyncServiceHandler.java   (with props)
Modified:
    httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncClientExchangeHandlerImpl.java
    httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncClientProtocolHandler.java
    httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequestExecutor.java
    httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequestHandler.java
    httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncServiceHandler.java
    httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestHttpAsyncClientProtocolHandler.java

Modified: httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncClientExchangeHandlerImpl.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncClientExchangeHandlerImpl.java?rev=1171131&r1=1171130&r2=1171131&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncClientExchangeHandlerImpl.java (original)
+++ httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncClientExchangeHandlerImpl.java Thu Sep 15 15:21:52 2011
@@ -181,7 +181,10 @@ class HttpAsyncClientExchangeHandlerImpl
 
     public boolean cancel() {
         try {
-            return this.responseConsumer.cancel();
+            boolean cancelled = this.responseConsumer.cancel();
+            this.future.cancel();
+            releaseResources();
+            return cancelled;
         } catch (RuntimeException ex) {
             failed(ex);
             throw ex;
@@ -198,6 +201,7 @@ class HttpAsyncClientExchangeHandlerImpl
             } else {
                 this.future.failed(ex);
             }
+            releaseResources();
         } catch (RuntimeException ex) {
             failed(ex);
             throw ex;

Modified: httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncClientProtocolHandler.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncClientProtocolHandler.java?rev=1171131&r1=1171130&r2=1171131&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncClientProtocolHandler.java (original)
+++ httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncClientProtocolHandler.java Thu Sep 15 15:21:52 2011
@@ -61,7 +61,7 @@ public class HttpAsyncClientProtocolHand
     public void connected(final NHttpClientConnection conn, final Object attachment) {
         HttpExchange httpexchange = new HttpExchange();
         HttpContext context = conn.getContext();
-        context.setAttribute(HTTP_EXCHNAGE, httpexchange);
+        context.setAttribute(HTTP_EXCHANGE, httpexchange);
         requestReady(conn);
     }
 
@@ -292,7 +292,7 @@ public class HttpAsyncClientProtocolHand
     }
 
     private HttpExchange getHttpExchange(final NHttpConnection conn) {
-        return (HttpExchange) conn.getContext().getAttribute(HTTP_EXCHNAGE);
+        return (HttpExchange) conn.getContext().getAttribute(HTTP_EXCHANGE);
     }
 
     private HttpExchange ensureNotNull(final HttpExchange httpExchange) {
@@ -349,7 +349,7 @@ public class HttpAsyncClientProtocolHand
             && status != HttpStatus.SC_RESET_CONTENT;
     }
 
-    static final String HTTP_EXCHNAGE = "http.nio.exchange";
+    static final String HTTP_EXCHANGE = "http.nio.exchange";
 
     class HttpExchange {
 

Modified: httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequestExecutor.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequestExecutor.java?rev=1171131&r1=1171130&r2=1171131&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequestExecutor.java (original)
+++ httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequestExecutor.java Thu Sep 15 15:21:52 2011
@@ -68,6 +68,12 @@ public class HttpAsyncRequestExecutor {
             final NHttpClientConnection conn,
             final HttpContext context,
             final FutureCallback<T> callback) {
+        if (requestProducer == null) {
+            throw new IllegalArgumentException("HTTP request producer may not be null");
+        }
+        if (responseConsumer == null) {
+            throw new IllegalArgumentException("HTTP response consumer may not be null");
+        }
         if (conn == null) {
             throw new IllegalArgumentException("HTTP connection may not be null");
         }
@@ -88,7 +94,7 @@ public class HttpAsyncRequestExecutor {
             final HttpAsyncResponseConsumer<T> responseConsumer,
             final NHttpClientConnection conn,
             final HttpContext context) {
-        return execute(requestProducer, responseConsumer, conn, context);
+        return execute(requestProducer, responseConsumer, conn, context, null);
     }
 
     public <T> Future<T> execute(
@@ -104,6 +110,12 @@ public class HttpAsyncRequestExecutor {
             final ConnPool<HttpHost, E> connPool,
             final HttpContext context,
             final FutureCallback<T> callback) {
+        if (requestProducer == null) {
+            throw new IllegalArgumentException("HTTP request producer may not be null");
+        }
+        if (responseConsumer == null) {
+            throw new IllegalArgumentException("HTTP response consumer may not be null");
+        }
         if (connPool == null) {
             throw new IllegalArgumentException("HTTP connection pool may not be null");
         }

Modified: httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequestHandler.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequestHandler.java?rev=1171131&r1=1171130&r2=1171131&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequestHandler.java (original)
+++ httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncRequestHandler.java Thu Sep 15 15:21:52 2011
@@ -41,7 +41,7 @@ public interface HttpAsyncRequestHandler
 
     HttpAsyncRequestConsumer<T> processRequest(
             HttpRequest request,
-            HttpContext context);
+            HttpContext context) throws HttpException, IOException;
 
     Cancellable handle(
             T data,

Modified: httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncServiceHandler.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncServiceHandler.java?rev=1171131&r1=1171130&r2=1171131&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncServiceHandler.java (original)
+++ httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncServiceHandler.java Thu Sep 15 15:21:52 2011
@@ -64,7 +64,7 @@ import org.apache.http.protocol.HttpProc
 @Immutable // provided injected dependencies are immutable
 public class HttpAsyncServiceHandler implements NHttpServiceHandler {
 
-    private static final String HTTP_EXCHANGE = "http.nio.http-exchange";
+    static final String HTTP_EXCHANGE = "http.nio.http-exchange";
 
     private final HttpAsyncRequestHandlerResolver handlerResolver;
     private final HttpAsyncExpectationVerifier expectationVerifier;
@@ -112,7 +112,7 @@ public class HttpAsyncServiceHandler imp
     }
 
     public void closed(final NHttpServerConnection conn) {
-        HttpExchange httpExchange = (HttpExchange) conn.getContext().getAttribute(HTTP_EXCHANGE);
+        HttpExchange httpExchange = ensureNotNull(getHttpExchange(conn));
         Cancellable asyncProcess = httpExchange.getAsyncProcess();
         httpExchange.clear();
         if (asyncProcess != null) {
@@ -120,8 +120,36 @@ public class HttpAsyncServiceHandler imp
         }
     }
 
+    public void exception(final NHttpServerConnection conn, final HttpException httpex) {
+        if (conn.isResponseSubmitted()) {
+            // There is not much that we can do if a response head
+            // has already been submitted
+            closeConnection(conn);
+            onException(httpex);
+            return;
+        }
+
+        HttpExchange httpExchange = ensureNotNull(getHttpExchange(conn));
+        try {
+            HttpAsyncResponseProducer responseProducer = handleException(httpex);
+            httpExchange.setResponseProducer(responseProducer);
+            commitResponse(conn, httpExchange);
+        } catch (RuntimeException ex) {
+            shutdownConnection(conn);
+            throw ex;
+        } catch (Exception ex) {
+            shutdownConnection(conn);
+            onException(ex);
+        }
+    }
+
+    public void exception(final NHttpServerConnection conn, final IOException ex) {
+        shutdownConnection(conn);
+        onException(ex);
+    }
+
     public void requestReceived(final NHttpServerConnection conn) {
-        HttpExchange httpExchange = (HttpExchange) conn.getContext().getAttribute(HTTP_EXCHANGE);
+        HttpExchange httpExchange = ensureNotNull(getHttpExchange(conn));
         try {
             HttpRequest request = conn.getHttpRequest();
             HttpContext context = httpExchange.getContext();
@@ -131,18 +159,16 @@ public class HttpAsyncServiceHandler imp
             context.setAttribute(ExecutionContext.HTTP_CONNECTION, conn);
             this.httpProcessor.process(request, context);
 
+            httpExchange.setRequest(request);
             HttpAsyncRequestHandler<Object> requestHandler = getRequestHandler(request);
-            HttpAsyncRequestConsumer<Object> consumer = requestHandler.processRequest(request, context);
-
             httpExchange.setRequestHandler(requestHandler);
+            HttpAsyncRequestConsumer<Object> consumer = requestHandler.processRequest(request, context);
             httpExchange.setRequestConsumer(consumer);
-            httpExchange.setRequest(request);
 
             consumer.requestReceived(request);
 
             if (request instanceof HttpEntityEnclosingRequest) {
-                HttpEntityEnclosingRequest entityRequest = (HttpEntityEnclosingRequest) request;
-                if (entityRequest.expectContinue()) {
+                if (((HttpEntityEnclosingRequest) request).expectContinue()) {
                     httpExchange.setRequestState(MessageState.ACK_EXPECTED);
                     if (this.expectationVerifier != null) {
                         conn.suspendInput();
@@ -172,55 +198,10 @@ public class HttpAsyncServiceHandler imp
         }
     }
 
-    public void exception(final NHttpServerConnection conn, final HttpException httpex) {
-        if (conn.isResponseSubmitted()) {
-            // There is not much that we can do if a response head
-            // has already been submitted
-            closeConnection(conn);
-            onException(httpex);
-            return;
-        }
-
-        HttpExchange httpExchange = (HttpExchange) conn.getContext().getAttribute(HTTP_EXCHANGE);
-        try {
-            HttpAsyncResponseProducer responseProducer = handleException(httpex);
-            httpExchange.setResponseProducer(responseProducer);
-            commitResponse(conn, httpExchange);
-        } catch (RuntimeException ex) {
-            shutdownConnection(conn);
-            throw ex;
-        } catch (Exception ex) {
-            shutdownConnection(conn);
-            onException(ex);
-        }
-    }
-
-    public void exception(final NHttpServerConnection conn, final IOException ex) {
-        shutdownConnection(conn);
-        onException(ex);
-    }
-
-    public void timeout(final NHttpServerConnection conn) {
-        try {
-            if (conn.getStatus() == NHttpConnection.ACTIVE) {
-                conn.close();
-                if (conn.getStatus() == NHttpConnection.CLOSING) {
-                    // Give the connection some grace time to
-                    // close itself nicely
-                    conn.setSocketTimeout(250);
-                }
-            } else {
-                conn.shutdown();
-            }
-        } catch (IOException ex) {
-            onException(ex);
-        }
-    }
-
     public void inputReady(final NHttpServerConnection conn, final ContentDecoder decoder) {
-        HttpExchange httpExchange = (HttpExchange) conn.getContext().getAttribute(HTTP_EXCHANGE);
+        HttpExchange httpExchange = ensureNotNull(getHttpExchange(conn));
         try {
-            HttpAsyncRequestConsumer<?> consumer = httpExchange.getRequestConsumer();
+            HttpAsyncRequestConsumer<?> consumer = ensureNotNull(httpExchange.getRequestConsumer());
             consumer.consumeContent(decoder, conn);
             httpExchange.setRequestState(MessageState.BODY_STREAM);
             if (decoder.isCompleted()) {
@@ -237,11 +218,11 @@ public class HttpAsyncServiceHandler imp
     }
 
     public void responseReady(final NHttpServerConnection conn) {
-        HttpExchange httpExchange = (HttpExchange) conn.getContext().getAttribute(HTTP_EXCHANGE);
+        HttpExchange httpExchange = ensureNotNull(getHttpExchange(conn));
         try {
             if (httpExchange.getRequestState() == MessageState.ACK) {
                 conn.requestInput();
-                httpExchange.setRequestState(MessageState.COMPLETED);
+                httpExchange.setRequestState(MessageState.BODY_STREAM);
                 HttpRequest request = httpExchange.getRequest();
                 HttpResponse response = create100Continue(request);
                 conn.submitResponse(response);
@@ -250,7 +231,6 @@ public class HttpAsyncServiceHandler imp
                     conn.resetInput();
                     httpExchange.setRequestState(MessageState.COMPLETED);
                 }
-                conn.resetInput();
                 commitResponse(conn, httpExchange);
             }
         } catch (RuntimeException ex) {
@@ -263,7 +243,7 @@ public class HttpAsyncServiceHandler imp
     }
 
     public void outputReady(final NHttpServerConnection conn, final ContentEncoder encoder) {
-        HttpExchange httpExchange = (HttpExchange) conn.getContext().getAttribute(HTTP_EXCHANGE);
+        HttpExchange httpExchange = ensureNotNull(getHttpExchange(conn));
         try {
             HttpAsyncResponseProducer responseProducer = httpExchange.getResponseProducer();
             HttpContext context = httpExchange.getContext();
@@ -289,6 +269,41 @@ public class HttpAsyncServiceHandler imp
         }
     }
 
+    public void timeout(final NHttpServerConnection conn) {
+        try {
+            if (conn.getStatus() == NHttpConnection.ACTIVE) {
+                conn.close();
+                if (conn.getStatus() == NHttpConnection.CLOSING) {
+                    // Give the connection some grace time to
+                    // close itself nicely
+                    conn.setSocketTimeout(250);
+                }
+            } else {
+                conn.shutdown();
+            }
+        } catch (IOException ex) {
+            onException(ex);
+        }
+    }
+
+    private HttpExchange getHttpExchange(final NHttpConnection conn) {
+        return (HttpExchange) conn.getContext().getAttribute(HTTP_EXCHANGE);
+    }
+
+    private HttpExchange ensureNotNull(final HttpExchange httpExchange) {
+        if (httpExchange == null) {
+            throw new IllegalStateException("HTTP exchange is null");
+        }
+        return httpExchange;
+    }
+
+    private HttpAsyncRequestConsumer<Object> ensureNotNull(final HttpAsyncRequestConsumer<Object> requestConsumer) {
+        if (requestConsumer == null) {
+            throw new IllegalStateException("Request consumer is null");
+        }
+        return requestConsumer;
+    }
+
     protected void onException(final Exception ex) {
     }
 
@@ -296,11 +311,7 @@ public class HttpAsyncServiceHandler imp
         try {
             conn.close();
         } catch (IOException ex) {
-            try {
-                conn.shutdown();
-            } catch (IOException ex2) {
-                onException(ex2);
-            }
+            onException(ex);
         }
     }
 
@@ -372,10 +383,6 @@ public class HttpAsyncServiceHandler imp
                 HttpAsyncResponseProducer responseProducer = handleException(ex);
                 httpExchange.setResponseProducer(responseProducer);
                 conn.requestOutput();
-            } catch (IOException ex) {
-                HttpAsyncResponseProducer responseProducer = handleException(ex);
-                httpExchange.setResponseProducer(responseProducer);
-                conn.requestOutput();
             }
         }
     }
@@ -412,7 +419,7 @@ public class HttpAsyncServiceHandler imp
             }
             httpExchange.clear();
         } else {
-            httpExchange.setRequestState(MessageState.BODY_STREAM);
+            httpExchange.setResponseState(MessageState.BODY_STREAM);
         }
     }
 
@@ -444,6 +451,8 @@ public class HttpAsyncServiceHandler imp
         HttpExchange() {
             super();
             this.context = new BasicHttpContext();
+            this.requestState = MessageState.READY;
+            this.responseState = MessageState.READY;
         }
 
         public HttpContext getContext() {

Modified: httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestHttpAsyncClientProtocolHandler.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestHttpAsyncClientProtocolHandler.java?rev=1171131&r1=1171130&r2=1171131&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestHttpAsyncClientProtocolHandler.java (original)
+++ httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestHttpAsyncClientProtocolHandler.java Thu Sep 15 15:21:52 2011
@@ -93,7 +93,7 @@ public class TestHttpAsyncClientProtocol
         this.protocolHandler.connected(this.conn, null);
 
         HttpExchange httpExchange = (HttpExchange) this.connContext.getAttribute(
-                HttpAsyncClientProtocolHandler.HTTP_EXCHNAGE);
+                HttpAsyncClientProtocolHandler.HTTP_EXCHANGE);
         Assert.assertNotNull(httpExchange);
         Assert.assertSame(this.exchangeHandler, httpExchange.getHandler());
         Mockito.verify(this.exchangeHandler).generateRequest();
@@ -111,7 +111,7 @@ public class TestHttpAsyncClientProtocol
         httpExchange.setRequestState(MessageState.COMPLETED);
         httpExchange.setResponseState(MessageState.COMPLETED);
         httpExchange.setHandler(this.exchangeHandler);
-        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHNAGE, httpExchange);
+        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHANGE, httpExchange);
 
         this.protocolHandler.closed(this.conn);
 
@@ -122,12 +122,12 @@ public class TestHttpAsyncClientProtocol
     }
 
     @Test
-    public void testHttpException() throws Exception {
+    public void testHttpExceptionHandling() throws Exception {
         HttpExchange httpExchange = this.protocolHandler.new HttpExchange();
         httpExchange.setRequestState(MessageState.COMPLETED);
         httpExchange.setResponseState(MessageState.COMPLETED);
         httpExchange.setHandler(this.exchangeHandler);
-        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHNAGE, httpExchange);
+        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHANGE, httpExchange);
 
         HttpException httpex = new HttpException();
         this.protocolHandler.exception(this.conn, httpex);
@@ -138,12 +138,12 @@ public class TestHttpAsyncClientProtocol
     }
 
     @Test
-    public void testIOException() throws Exception {
+    public void testIOExceptionHandling() throws Exception {
         HttpExchange httpExchange = this.protocolHandler.new HttpExchange();
         httpExchange.setRequestState(MessageState.COMPLETED);
         httpExchange.setResponseState(MessageState.COMPLETED);
         httpExchange.setHandler(this.exchangeHandler);
-        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHNAGE, httpExchange);
+        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHANGE, httpExchange);
 
         IOException ioex = new IOException();
         this.protocolHandler.exception(this.conn, ioex);
@@ -154,10 +154,10 @@ public class TestHttpAsyncClientProtocol
     }
 
     @Test
-    public void testSimpleRequest() throws Exception {
+    public void testBasicRequest() throws Exception {
         HttpExchange httpExchange = this.protocolHandler.new HttpExchange();
         httpExchange.setHandler(this.exchangeHandler);
-        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHNAGE, httpExchange);
+        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHANGE, httpExchange);
         HttpRequest request = new BasicHttpRequest("GET", "/");
         Mockito.when(this.exchangeHandler.generateRequest()).thenReturn(request);
 
@@ -174,7 +174,7 @@ public class TestHttpAsyncClientProtocol
     public void testEntityEnclosingRequestWithoutExpectContinue() throws Exception {
         HttpExchange httpExchange = this.protocolHandler.new HttpExchange();
         httpExchange.setHandler(this.exchangeHandler);
-        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHNAGE, httpExchange);
+        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHANGE, httpExchange);
         BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
         request.setEntity(NStringEntity.create("stuff"));
         Mockito.when(this.exchangeHandler.generateRequest()).thenReturn(request);
@@ -192,7 +192,7 @@ public class TestHttpAsyncClientProtocol
     public void testEntityEnclosingRequestWithExpectContinue() throws Exception {
         HttpExchange httpExchange = this.protocolHandler.new HttpExchange();
         httpExchange.setHandler(this.exchangeHandler);
-        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHNAGE, httpExchange);
+        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHANGE, httpExchange);
         BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
         request.setHeader(HTTP.EXPECT_DIRECTIVE, HTTP.EXPECT_CONTINUE);
         Mockito.when(this.exchangeHandler.generateRequest()).thenReturn(request);
@@ -214,7 +214,7 @@ public class TestHttpAsyncClientProtocol
         RuntimeException runtimeEx = new RuntimeException();
         HttpExchange httpExchange = this.protocolHandler.new HttpExchange();
         httpExchange.setHandler(this.exchangeHandler);
-        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHNAGE, httpExchange);
+        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHANGE, httpExchange);
         Mockito.when(this.exchangeHandler.generateRequest()).thenThrow(runtimeEx);
         try {
             this.protocolHandler.requestReady(this.conn);
@@ -230,7 +230,7 @@ public class TestHttpAsyncClientProtocol
         HttpException httpex = new HttpException();
         HttpExchange httpExchange = this.protocolHandler.new HttpExchange();
         httpExchange.setHandler(this.exchangeHandler);
-        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHNAGE, httpExchange);
+        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHANGE, httpExchange);
         Mockito.when(this.exchangeHandler.generateRequest()).thenThrow(httpex);
 
         this.protocolHandler.requestReady(this.conn);
@@ -243,7 +243,7 @@ public class TestHttpAsyncClientProtocol
     public void testRequestContentOutput() throws Exception {
         HttpExchange httpExchange = this.protocolHandler.new HttpExchange();
         httpExchange.setHandler(this.exchangeHandler);
-        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHNAGE, httpExchange);
+        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHANGE, httpExchange);
         Mockito.when(this.encoder.isCompleted()).thenReturn(false);
 
         this.protocolHandler.outputReady(this.conn, this.encoder);
@@ -256,7 +256,7 @@ public class TestHttpAsyncClientProtocol
     public void testRequestContentOutputCompleted() throws Exception {
         HttpExchange httpExchange = this.protocolHandler.new HttpExchange();
         httpExchange.setHandler(this.exchangeHandler);
-        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHNAGE, httpExchange);
+        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHANGE, httpExchange);
         Mockito.when(this.encoder.isCompleted()).thenReturn(true);
 
         this.protocolHandler.outputReady(this.conn, this.encoder);
@@ -271,7 +271,7 @@ public class TestHttpAsyncClientProtocol
         HttpExchange httpExchange = this.protocolHandler.new HttpExchange();
         httpExchange.setRequestState(MessageState.ACK_EXPECTED);
         httpExchange.setHandler(this.exchangeHandler);
-        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHNAGE, httpExchange);
+        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHANGE, httpExchange);
 
         this.protocolHandler.outputReady(this.conn, this.encoder);
 
@@ -285,7 +285,7 @@ public class TestHttpAsyncClientProtocol
         RuntimeException runtimeEx = new RuntimeException();
         HttpExchange httpExchange = this.protocolHandler.new HttpExchange();
         httpExchange.setHandler(this.exchangeHandler);
-        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHNAGE, httpExchange);
+        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHANGE, httpExchange);
         Mockito.doThrow(runtimeEx).when(this.exchangeHandler).produceContent(this.encoder, this.conn);
 
         try {
@@ -302,7 +302,7 @@ public class TestHttpAsyncClientProtocol
         IOException ioex = new IOException();
         HttpExchange httpExchange = this.protocolHandler.new HttpExchange();
         httpExchange.setHandler(this.exchangeHandler);
-        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHNAGE, httpExchange);
+        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHANGE, httpExchange);
         Mockito.doThrow(ioex).when(this.exchangeHandler).produceContent(this.encoder, this.conn);
 
         this.protocolHandler.outputReady(this.conn, this.encoder);
@@ -312,12 +312,12 @@ public class TestHttpAsyncClientProtocol
     }
 
     @Test
-    public void testNormalResponse() throws Exception {
+    public void testBasicResponse() throws Exception {
         HttpExchange httpExchange = this.protocolHandler.new HttpExchange();
         HttpRequest request = new BasicHttpRequest("GET", "/");
         httpExchange.setRequest(request);
         httpExchange.setHandler(this.exchangeHandler);
-        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHNAGE, httpExchange);
+        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHANGE, httpExchange);
         BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
         Mockito.when(this.conn.getHttpResponse()).thenReturn(response);
 
@@ -328,7 +328,7 @@ public class TestHttpAsyncClientProtocol
     }
 
     @Test
-    public void testResponse100() throws Exception {
+    public void testResponseContinue() throws Exception {
         HttpExchange httpExchange = this.protocolHandler.new HttpExchange();
         httpExchange.setRequestState(MessageState.ACK_EXPECTED);
         httpExchange.setTimeout(1000);
@@ -336,7 +336,7 @@ public class TestHttpAsyncClientProtocol
         request.setEntity(NStringEntity.create("stuff"));
         httpExchange.setRequest(request);
         httpExchange.setHandler(this.exchangeHandler);
-        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHNAGE, httpExchange);
+        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHANGE, httpExchange);
         BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 100, "Continue");
         Mockito.when(this.conn.getHttpResponse()).thenReturn(response);
 
@@ -350,14 +350,14 @@ public class TestHttpAsyncClientProtocol
     }
 
     @Test
-    public void testResponse100OutOfSequence() throws Exception {
+    public void testResponseContinueOutOfSequence() throws Exception {
         HttpExchange httpExchange = this.protocolHandler.new HttpExchange();
         httpExchange.setRequestState(MessageState.COMPLETED);
         BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
         request.setEntity(NStringEntity.create("stuff"));
         httpExchange.setRequest(request);
         httpExchange.setHandler(this.exchangeHandler);
-        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHNAGE, httpExchange);
+        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHANGE, httpExchange);
         BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 100, "Continue");
         Mockito.when(this.conn.getHttpResponse()).thenReturn(response);
 
@@ -369,7 +369,7 @@ public class TestHttpAsyncClientProtocol
     }
 
     @Test
-    public void testResponse111() throws Exception {
+    public void testResponseUnsupported1xx() throws Exception {
         HttpExchange httpExchange = this.protocolHandler.new HttpExchange();
         httpExchange.setRequestState(MessageState.ACK_EXPECTED);
         httpExchange.setTimeout(1000);
@@ -377,7 +377,7 @@ public class TestHttpAsyncClientProtocol
         request.setEntity(NStringEntity.create("stuff"));
         httpExchange.setRequest(request);
         httpExchange.setHandler(this.exchangeHandler);
-        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHNAGE, httpExchange);
+        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHANGE, httpExchange);
         BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 111, "WTF?");
         Mockito.when(this.conn.getHttpResponse()).thenReturn(response);
 
@@ -398,7 +398,7 @@ public class TestHttpAsyncClientProtocol
         request.setEntity(NStringEntity.create("stuff"));
         httpExchange.setRequest(request);
         httpExchange.setHandler(this.exchangeHandler);
-        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHNAGE, httpExchange);
+        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHANGE, httpExchange);
         BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 403, "Unauthorized");
         Mockito.when(this.conn.getHttpResponse()).thenReturn(response);
 
@@ -420,7 +420,7 @@ public class TestHttpAsyncClientProtocol
         request.setEntity(NStringEntity.create("stuff"));
         httpExchange.setRequest(request);
         httpExchange.setHandler(this.exchangeHandler);
-        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHNAGE, httpExchange);
+        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHANGE, httpExchange);
         BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 403, "Unauthorized");
         Mockito.when(this.conn.getHttpResponse()).thenReturn(response);
 
@@ -440,7 +440,7 @@ public class TestHttpAsyncClientProtocol
         HttpRequest request = new BasicHttpRequest("HEAD", "/");
         httpExchange.setRequest(request);
         httpExchange.setHandler(this.exchangeHandler);
-        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHNAGE, httpExchange);
+        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHANGE, httpExchange);
         BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
         Mockito.when(this.conn.getHttpResponse()).thenReturn(response);
         Mockito.when(this.reuseStrategy.keepAlive(response, this.exchangeContext)).thenReturn(true);
@@ -463,7 +463,7 @@ public class TestHttpAsyncClientProtocol
         HttpRequest request = new BasicHttpRequest("Connect", "/");
         httpExchange.setRequest(request);
         httpExchange.setHandler(this.exchangeHandler);
-        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHNAGE, httpExchange);
+        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHANGE, httpExchange);
         BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
         Mockito.when(this.conn.getHttpResponse()).thenReturn(response);
         Mockito.when(this.reuseStrategy.keepAlive(response, this.exchangeContext)).thenReturn(true);
@@ -486,7 +486,7 @@ public class TestHttpAsyncClientProtocol
         HttpRequest request = new BasicHttpRequest("Connect", "/");
         httpExchange.setRequest(request);
         httpExchange.setHandler(this.exchangeHandler);
-        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHNAGE, httpExchange);
+        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHANGE, httpExchange);
         BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1,
                 HttpStatus.SC_NOT_MODIFIED, "Not modified");
         Mockito.when(this.conn.getHttpResponse()).thenReturn(response);
@@ -511,7 +511,7 @@ public class TestHttpAsyncClientProtocol
         HttpRequest request = new BasicHttpRequest("GET", "/");
         httpExchange.setRequest(request);
         httpExchange.setHandler(this.exchangeHandler);
-        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHNAGE, httpExchange);
+        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHANGE, httpExchange);
         BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
         Mockito.when(this.conn.getHttpResponse()).thenReturn(response);
         Mockito.doThrow(runtimeEx).when(this.exchangeHandler).responseReceived(response);
@@ -531,7 +531,7 @@ public class TestHttpAsyncClientProtocol
         HttpRequest request = new BasicHttpRequest("GET", "/");
         httpExchange.setRequest(request);
         httpExchange.setHandler(this.exchangeHandler);
-        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHNAGE, httpExchange);
+        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHANGE, httpExchange);
         BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
         Mockito.when(this.conn.getHttpResponse()).thenReturn(response);
         Mockito.doThrow(httpex).when(this.exchangeHandler).responseReceived(response);
@@ -546,7 +546,7 @@ public class TestHttpAsyncClientProtocol
     public void testResponseContentInput() throws Exception {
         HttpExchange httpExchange = this.protocolHandler.new HttpExchange();
         httpExchange.setHandler(this.exchangeHandler);
-        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHNAGE, httpExchange);
+        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHANGE, httpExchange);
         Mockito.when(this.decoder.isCompleted()).thenReturn(false);
 
         this.protocolHandler.inputReady(this.conn, this.decoder);
@@ -563,7 +563,7 @@ public class TestHttpAsyncClientProtocol
         BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
         httpExchange.setResponse(response);
         httpExchange.setHandler(this.exchangeHandler);
-        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHNAGE, httpExchange);
+        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHANGE, httpExchange);
         Mockito.when(this.reuseStrategy.keepAlive(response, this.exchangeContext)).thenReturn(true);
         Mockito.when(this.exchangeHandler.getConnectionReuseStrategy()).thenReturn(this.reuseStrategy);
         Mockito.when(this.decoder.isCompleted()).thenReturn(true);
@@ -586,7 +586,7 @@ public class TestHttpAsyncClientProtocol
         httpExchange.setResponse(response);
         httpExchange.invalidate();
         httpExchange.setHandler(this.exchangeHandler);
-        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHNAGE, httpExchange);
+        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHANGE, httpExchange);
         Mockito.when(this.decoder.isCompleted()).thenReturn(true);
 
         this.protocolHandler.inputReady(this.conn, this.decoder);
@@ -606,7 +606,7 @@ public class TestHttpAsyncClientProtocol
         BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
         httpExchange.setResponse(response);
         httpExchange.setHandler(this.exchangeHandler);
-        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHNAGE, httpExchange);
+        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHANGE, httpExchange);
         Mockito.when(this.reuseStrategy.keepAlive(response, this.exchangeContext)).thenReturn(false);
         Mockito.when(this.exchangeHandler.getConnectionReuseStrategy()).thenReturn(this.reuseStrategy);
         Mockito.when(this.decoder.isCompleted()).thenReturn(true);
@@ -625,7 +625,7 @@ public class TestHttpAsyncClientProtocol
         RuntimeException runtimeEx = new RuntimeException();
         HttpExchange httpExchange = this.protocolHandler.new HttpExchange();
         httpExchange.setHandler(this.exchangeHandler);
-        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHNAGE, httpExchange);
+        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHANGE, httpExchange);
         Mockito.doThrow(runtimeEx).when(this.exchangeHandler).consumeContent(this.decoder, this.conn);
 
         try {
@@ -642,7 +642,7 @@ public class TestHttpAsyncClientProtocol
         IOException ioex = new IOException();
         HttpExchange httpExchange = this.protocolHandler.new HttpExchange();
         httpExchange.setHandler(this.exchangeHandler);
-        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHNAGE, httpExchange);
+        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHANGE, httpExchange);
         Mockito.doThrow(ioex).when(this.exchangeHandler).consumeContent(this.decoder, this.conn);
 
         this.protocolHandler.inputReady(this.conn, this.decoder);
@@ -654,7 +654,7 @@ public class TestHttpAsyncClientProtocol
     @Test
     public void testTimeoutNoHandler() throws Exception {
         HttpExchange httpExchange = this.protocolHandler.new HttpExchange();
-        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHNAGE, httpExchange);
+        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHANGE, httpExchange);
 
         this.protocolHandler.timeout(this.conn);
 
@@ -667,7 +667,7 @@ public class TestHttpAsyncClientProtocol
         httpExchange.setRequestState(MessageState.ACK_EXPECTED);
         httpExchange.setTimeout(1000);
         httpExchange.setHandler(this.exchangeHandler);
-        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHNAGE, httpExchange);
+        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHANGE, httpExchange);
 
         this.protocolHandler.timeout(this.conn);
 
@@ -681,7 +681,7 @@ public class TestHttpAsyncClientProtocol
         HttpExchange httpExchange = this.protocolHandler.new HttpExchange();
         httpExchange.setRequestState(MessageState.BODY_STREAM);
         httpExchange.setHandler(this.exchangeHandler);
-        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHNAGE, httpExchange);
+        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHANGE, httpExchange);
         Mockito.when(this.conn.getStatus()).thenReturn(NHttpConnection.ACTIVE, NHttpConnection.CLOSED);
 
         this.protocolHandler.timeout(this.conn);
@@ -697,7 +697,7 @@ public class TestHttpAsyncClientProtocol
         HttpExchange httpExchange = this.protocolHandler.new HttpExchange();
         httpExchange.setRequestState(MessageState.BODY_STREAM);
         httpExchange.setHandler(this.exchangeHandler);
-        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHNAGE, httpExchange);
+        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHANGE, httpExchange);
         Mockito.when(this.conn.getStatus()).thenReturn(NHttpConnection.ACTIVE, NHttpConnection.CLOSING);
 
         this.protocolHandler.timeout(this.conn);
@@ -713,7 +713,7 @@ public class TestHttpAsyncClientProtocol
         HttpExchange httpExchange = this.protocolHandler.new HttpExchange();
         httpExchange.setRequestState(MessageState.BODY_STREAM);
         httpExchange.setHandler(this.exchangeHandler);
-        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHNAGE, httpExchange);
+        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHANGE, httpExchange);
         Mockito.when(this.conn.getStatus()).thenReturn(NHttpConnection.CLOSING, NHttpConnection.CLOSED);
 
         this.protocolHandler.timeout(this.conn);
@@ -728,7 +728,7 @@ public class TestHttpAsyncClientProtocol
         RuntimeException runtimeEx = new RuntimeException();
         HttpExchange httpExchange = this.protocolHandler.new HttpExchange();
         httpExchange.setHandler(this.exchangeHandler);
-        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHNAGE, httpExchange);
+        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHANGE, httpExchange);
         Mockito.doThrow(runtimeEx).when(this.exchangeHandler).failed(Mockito.any(SocketTimeoutException.class));
 
         try {
@@ -748,7 +748,7 @@ public class TestHttpAsyncClientProtocol
         BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
         httpExchange.setResponse(response);
         httpExchange.setHandler(this.exchangeHandler);
-        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHNAGE, httpExchange);
+        this.connContext.setAttribute(HttpAsyncClientProtocolHandler.HTTP_EXCHANGE, httpExchange);
         Mockito.when(this.exchangeHandler.isDone()).thenReturn(true);
 
         Assert.assertEquals("request state: READY; request: GET / HTTP/1.1; " +

Added: httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestHttpAsyncRequestExecutor.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestHttpAsyncRequestExecutor.java?rev=1171131&view=auto
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestHttpAsyncRequestExecutor.java (added)
+++ httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestHttpAsyncRequestExecutor.java Thu Sep 15 15:21:52 2011
@@ -0,0 +1,338 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.http.nio.protocol;
+
+import java.util.concurrent.Future;
+
+import junit.framework.Assert;
+
+import org.apache.http.ConnectionReuseStrategy;
+import org.apache.http.HttpHost;
+import org.apache.http.concurrent.FutureCallback;
+import org.apache.http.impl.nio.pool.BasicNIOPoolEntry;
+import org.apache.http.nio.NHttpClientConnection;
+import org.apache.http.nio.protocol.HttpAsyncRequestExecutor.ConnRequestCallback;
+import org.apache.http.params.BasicHttpParams;
+import org.apache.http.params.HttpParams;
+import org.apache.http.pool.ConnPool;
+import org.apache.http.pool.PoolEntry;
+import org.apache.http.protocol.BasicHttpContext;
+import org.apache.http.protocol.HttpContext;
+import org.apache.http.protocol.HttpProcessor;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mockito;
+
+public class TestHttpAsyncRequestExecutor {
+
+    private HttpProcessor httpProcessor;
+    private ConnectionReuseStrategy reuseStrategy;
+    private HttpParams params;
+    private HttpAsyncRequestExecutor requestExecutor;
+    private HttpContext exchangeContext;
+    private HttpContext connContext;
+    private HttpAsyncRequestProducer requestProducer;
+    private HttpAsyncResponseConsumer<Object> responseConsumer;
+    private NHttpClientConnection conn;
+    private FutureCallback<Object> callback;
+    private ConnPool<HttpHost, PoolEntry<HttpHost, NHttpClientConnection>> connPool;
+
+    @SuppressWarnings("unchecked")
+    @Before
+    public void setUp() throws Exception {
+        this.httpProcessor = Mockito.mock(HttpProcessor.class);
+        this.reuseStrategy = Mockito.mock(ConnectionReuseStrategy.class);
+        this.params = new BasicHttpParams();
+        this.requestExecutor = new HttpAsyncRequestExecutor(
+                this.httpProcessor, this.reuseStrategy, this.params);
+        this.exchangeContext = new BasicHttpContext();
+        this.requestProducer = Mockito.mock(HttpAsyncRequestProducer.class);
+        this.responseConsumer = Mockito.mock(HttpAsyncResponseConsumer.class);
+        this.conn = Mockito.mock(NHttpClientConnection.class);
+        this.callback = Mockito.mock(FutureCallback.class);
+        this.connContext = new BasicHttpContext();
+        this.connPool = Mockito.mock(ConnPool.class);
+
+        Mockito.when(this.conn.getContext()).thenReturn(this.connContext);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+    }
+
+    @Test
+    public void testInvalidExecution() throws Exception {
+        try {
+            this.requestExecutor.execute(
+                    null,
+                    this.responseConsumer,
+                    this.conn);
+            Assert.fail("IllegalArgumentException expected");
+        } catch (IllegalArgumentException ex) {
+        }
+        try {
+            this.requestExecutor.execute(
+                    this.requestProducer,
+                    null,
+                    this.conn);
+            Assert.fail("IllegalArgumentException expected");
+        } catch (IllegalArgumentException ex) {
+        }
+        try {
+            this.requestExecutor.execute(
+                    this.requestProducer,
+                    this.responseConsumer,
+                    (NHttpClientConnection) null);
+            Assert.fail("IllegalArgumentException expected");
+        } catch (IllegalArgumentException ex) {
+        }
+        try {
+            this.requestExecutor.execute(
+                    this.requestProducer,
+                    this.responseConsumer,
+                    this.conn,
+                    null);
+            Assert.fail("IllegalArgumentException expected");
+        } catch (IllegalArgumentException ex) {
+        }
+
+        try {
+            this.requestExecutor.execute(
+                    null,
+                    this.responseConsumer,
+                    this.connPool);
+            Assert.fail("IllegalArgumentException expected");
+        } catch (IllegalArgumentException ex) {
+        }
+        try {
+            this.requestExecutor.execute(
+                    this.requestProducer,
+                    null,
+                    this.connPool);
+            Assert.fail("IllegalArgumentException expected");
+        } catch (IllegalArgumentException ex) {
+        }
+        try {
+            this.requestExecutor.execute(
+                    this.requestProducer,
+                    this.responseConsumer,
+                    (ConnPool<HttpHost, PoolEntry<HttpHost, NHttpClientConnection>>) null);
+            Assert.fail("IllegalArgumentException expected");
+        } catch (IllegalArgumentException ex) {
+        }
+        try {
+            this.requestExecutor.execute(
+                    this.requestProducer,
+                    this.responseConsumer,
+                    this.connPool,
+                    null);
+            Assert.fail("IllegalArgumentException expected");
+        } catch (IllegalArgumentException ex) {
+        }
+    }
+
+    @Test
+    public void testSimpleExecute() throws Exception {
+        Future<Object> future = this.requestExecutor.execute(
+                this.requestProducer,
+                this.responseConsumer,
+                this.conn, this.exchangeContext, null);
+        Assert.assertNotNull(future);
+        Assert.assertNotNull(this.connContext.getAttribute(HttpAsyncClientProtocolHandler.HTTP_HANDLER));
+        Mockito.verify(this.conn).requestOutput();
+    }
+
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    @Test
+    public void testPooledConnectionRequestFailed() throws Exception {
+        HttpHost host = new HttpHost("somehost");
+        Mockito.when(this.requestProducer.getTarget()).thenReturn(host);
+
+        Future<Object> future = this.requestExecutor.execute(
+                this.requestProducer,
+                this.responseConsumer,
+                this.connPool, this.exchangeContext, this.callback);
+        Assert.assertNotNull(future);
+        ArgumentCaptor<FutureCallback> argCaptor = ArgumentCaptor.forClass(FutureCallback.class);
+        Mockito.verify(this.connPool).lease(
+                Mockito.eq(host), Mockito.isNull(), argCaptor.capture());
+        ConnRequestCallback connRequestCallback = (ConnRequestCallback) argCaptor.getValue();
+
+        Exception oppsie = new Exception();
+        connRequestCallback.failed(oppsie);
+        Mockito.verify(this.responseConsumer).failed(oppsie);
+        Mockito.verify(this.callback).failed(oppsie);
+        Mockito.verify(this.responseConsumer).close();
+        Mockito.verify(this.requestProducer).close();
+    }
+
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    @Test
+    public void testPooledConnectionRequestCancelled() throws Exception {
+        HttpHost host = new HttpHost("somehost");
+        Mockito.when(this.requestProducer.getTarget()).thenReturn(host);
+
+        Future<Object> future = this.requestExecutor.execute(
+                this.requestProducer,
+                this.responseConsumer,
+                this.connPool, this.exchangeContext, this.callback);
+        Assert.assertNotNull(future);
+        ArgumentCaptor<FutureCallback> argCaptor = ArgumentCaptor.forClass(FutureCallback.class);
+        Mockito.verify(this.connPool).lease(
+                Mockito.eq(host), Mockito.isNull(), argCaptor.capture());
+        ConnRequestCallback connRequestCallback = (ConnRequestCallback) argCaptor.getValue();
+
+        connRequestCallback.cancelled();
+        Mockito.verify(this.responseConsumer).cancel();
+        Mockito.verify(this.callback).cancelled();
+        Mockito.verify(this.responseConsumer).close();
+        Mockito.verify(this.requestProducer).close();
+    }
+
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    @Test
+    public void testPooledConnectionAutoReleaseOnRequestCancel() throws Exception {
+        HttpHost host = new HttpHost("somehost");
+        Mockito.when(this.requestProducer.getTarget()).thenReturn(host);
+
+        Future<Object> future = this.requestExecutor.execute(
+                this.requestProducer,
+                this.responseConsumer,
+                this.connPool, this.exchangeContext, this.callback);
+        Assert.assertNotNull(future);
+        ArgumentCaptor<FutureCallback> argCaptor = ArgumentCaptor.forClass(FutureCallback.class);
+        Mockito.verify(this.connPool).lease(
+                Mockito.eq(host), Mockito.isNull(), argCaptor.capture());
+        ConnRequestCallback connRequestCallback = (ConnRequestCallback) argCaptor.getValue();
+
+        future.cancel(true);
+        BasicNIOPoolEntry entry = new BasicNIOPoolEntry("id", host, this.conn);
+        connRequestCallback.completed(entry);
+        Mockito.verify(this.connPool).release(entry, true);
+        Mockito.verify(this.conn, Mockito.never()).requestOutput();
+    }
+
+
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    @Test
+    public void testPooledRequestExecutionSucceeded() throws Exception {
+        HttpHost host = new HttpHost("somehost");
+        Mockito.when(this.requestProducer.getTarget()).thenReturn(host);
+
+        Future<Object> future = this.requestExecutor.execute(
+                this.requestProducer,
+                this.responseConsumer,
+                this.connPool, this.exchangeContext, this.callback);
+        Assert.assertNotNull(future);
+        ArgumentCaptor<FutureCallback> argCaptor = ArgumentCaptor.forClass(FutureCallback.class);
+        Mockito.verify(this.connPool).lease(
+                Mockito.eq(host), Mockito.isNull(), argCaptor.capture());
+        ConnRequestCallback connRequestCallback = (ConnRequestCallback) argCaptor.getValue();
+
+        BasicNIOPoolEntry entry = new BasicNIOPoolEntry("id", host, this.conn);
+        connRequestCallback.completed(entry);
+        HttpAsyncClientExchangeHandlerImpl exchangeHandler = (HttpAsyncClientExchangeHandlerImpl) this.connContext.getAttribute(
+                HttpAsyncClientProtocolHandler.HTTP_HANDLER);
+        Assert.assertNotNull(exchangeHandler);
+        Mockito.verify(this.conn).requestOutput();
+
+        Object result = new Object();
+        Mockito.when(this.responseConsumer.getResult()).thenReturn(result);
+        exchangeHandler.responseCompleted(this.exchangeContext);
+        Mockito.verify(this.callback).completed(result);
+        Mockito.verify(this.responseConsumer).close();
+        Mockito.verify(this.requestProducer).close();
+        Mockito.verify(this.connPool).release(entry, true);
+    }
+
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    @Test
+    public void testPooledRequestExecutionFailed() throws Exception {
+        HttpHost host = new HttpHost("somehost");
+        Mockito.when(this.requestProducer.getTarget()).thenReturn(host);
+
+        Future<Object> future = this.requestExecutor.execute(
+                this.requestProducer,
+                this.responseConsumer,
+                this.connPool, this.exchangeContext, this.callback);
+        Assert.assertNotNull(future);
+        ArgumentCaptor<FutureCallback> argCaptor = ArgumentCaptor.forClass(FutureCallback.class);
+        Mockito.verify(this.connPool).lease(
+                Mockito.eq(host), Mockito.isNull(), argCaptor.capture());
+        ConnRequestCallback connRequestCallback = (ConnRequestCallback) argCaptor.getValue();
+
+        BasicNIOPoolEntry entry = new BasicNIOPoolEntry("id", host, this.conn);
+        connRequestCallback.completed(entry);
+        HttpAsyncClientExchangeHandlerImpl exchangeHandler = (HttpAsyncClientExchangeHandlerImpl) this.connContext.getAttribute(
+                HttpAsyncClientProtocolHandler.HTTP_HANDLER);
+        Assert.assertNotNull(exchangeHandler);
+        Mockito.verify(this.conn).requestOutput();
+
+        Exception oppsie = new Exception();
+        exchangeHandler.failed(oppsie);
+        Mockito.verify(this.responseConsumer).failed(oppsie);
+        Mockito.verify(this.callback).failed(oppsie);
+        Mockito.verify(this.responseConsumer).close();
+        Mockito.verify(this.requestProducer).close();
+        Mockito.verify(this.connPool).release(entry, false);
+    }
+
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    @Test
+    public void testPooledRequestExecutionCancelled() throws Exception {
+        HttpHost host = new HttpHost("somehost");
+        Mockito.when(this.requestProducer.getTarget()).thenReturn(host);
+
+        Future<Object> future = this.requestExecutor.execute(
+                this.requestProducer,
+                this.responseConsumer,
+                this.connPool, this.exchangeContext, this.callback);
+        Assert.assertNotNull(future);
+        ArgumentCaptor<FutureCallback> argCaptor = ArgumentCaptor.forClass(FutureCallback.class);
+        Mockito.verify(this.connPool).lease(
+                Mockito.eq(host), Mockito.isNull(), argCaptor.capture());
+        ConnRequestCallback connRequestCallback = (ConnRequestCallback) argCaptor.getValue();
+
+        BasicNIOPoolEntry entry = new BasicNIOPoolEntry("id", host, this.conn);
+        connRequestCallback.completed(entry);
+        HttpAsyncClientExchangeHandlerImpl exchangeHandler = (HttpAsyncClientExchangeHandlerImpl) this.connContext.getAttribute(
+                HttpAsyncClientProtocolHandler.HTTP_HANDLER);
+        Assert.assertNotNull(exchangeHandler);
+        Mockito.verify(this.conn).requestOutput();
+
+        exchangeHandler.cancel();
+        Mockito.verify(this.responseConsumer).cancel();
+        Mockito.verify(this.callback).cancelled();
+        Mockito.verify(this.responseConsumer).close();
+        Mockito.verify(this.requestProducer).close();
+        Mockito.verify(this.connPool).release(entry, false);
+    }
+
+}
\ No newline at end of file

Propchange: httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestHttpAsyncRequestExecutor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestHttpAsyncRequestExecutor.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/protocol/TestHttpAsyncRequestExecutor.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain