You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ro...@apache.org on 2007/05/20 16:21:29 UTC

svn commit: r539880 - in /jakarta/httpcomponents/httpclient/trunk/src/test/org/apache/http/impl/conn: ExecReqThread.java TestTSCCMWithServer.java

Author: rolandw
Date: Sun May 20 07:21:28 2007
New Revision: 539880

URL: http://svn.apache.org/viewvc?view=rev&rev=539880
Log:
server-based multithreaded test of TSCCM

Added:
    jakarta/httpcomponents/httpclient/trunk/src/test/org/apache/http/impl/conn/ExecReqThread.java   (with props)
Modified:
    jakarta/httpcomponents/httpclient/trunk/src/test/org/apache/http/impl/conn/TestTSCCMWithServer.java

Added: jakarta/httpcomponents/httpclient/trunk/src/test/org/apache/http/impl/conn/ExecReqThread.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpclient/trunk/src/test/org/apache/http/impl/conn/ExecReqThread.java?view=auto&rev=539880
==============================================================================
--- jakarta/httpcomponents/httpclient/trunk/src/test/org/apache/http/impl/conn/ExecReqThread.java (added)
+++ jakarta/httpcomponents/httpclient/trunk/src/test/org/apache/http/impl/conn/ExecReqThread.java Sun May 20 07:21:28 2007
@@ -0,0 +1,157 @@
+/*
+ * $HeadURL$
+ * $Revision$
+ * $Date$
+ * ====================================================================
+ * 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.impl.conn;
+
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpResponse;
+import org.apache.http.params.HttpParams;
+import org.apache.http.protocol.HttpContext;
+import org.apache.http.protocol.HttpProcessor;
+import org.apache.http.protocol.HttpRequestExecutor;
+import org.apache.http.protocol.HttpExecutionContext;
+import org.apache.http.util.EntityUtils;
+
+import org.apache.http.conn.HttpRoute;
+import org.apache.http.conn.ManagedClientConnection;
+import org.apache.http.conn.ClientConnectionManager;
+
+
+/**
+ * Executes a request from a new thread.
+ * 
+ * @author Michael Becke
+ * @author Roland Weber (rolandw at apache.org)
+ */
+public class ExecReqThread extends GetConnThread {
+
+    protected RequestSpec  request_spec;
+    protected HttpResponse response;
+    protected byte[]       response_data;
+
+
+    /**
+     * Executes a request.
+     * This involves the following steps:
+     * <ol>
+     * <li>obtain a connection (see base class)</li>
+     * <li>open the connection</li>
+     * <li>prepare context and request</li>
+     * <li>execute request to obtain the response</li>
+     * <li>consume the response entity (if there is one)</li>
+     * <li>release the connection</li>
+     * </ol>
+     */    
+    public ExecReqThread(ClientConnectionManager mgr,
+                         HttpRoute route, long timeout,
+                         RequestSpec reqspec) {
+        super(mgr, route, timeout);
+
+        request_spec = reqspec;
+    }
+
+    
+    public HttpResponse getResponse() {
+        return response;
+    }
+
+    public byte[] getResponseData() {
+        return response_data;
+    }
+
+
+    /**
+     * This method is invoked when the thread is started.
+     * It invokes the base class implementation.
+     */
+    public void run() {
+        super.run();    // obtain connection
+        if (connection == null)
+            return;     // problem obtaining connection
+
+        try {
+            request_spec.context.setAttribute
+                (HttpExecutionContext.HTTP_CONNECTION, connection);
+
+            doOpenConnection();
+
+            HttpRequest request = (HttpRequest) request_spec.context.
+                getAttribute(HttpExecutionContext.HTTP_REQUEST);
+            request_spec.executor.preProcess
+                (request, request_spec.processor, request_spec.context);
+
+            response = request_spec.executor.execute
+                (request, connection, request_spec.context);
+
+            request_spec.executor.postProcess
+                (response, request_spec.processor, request_spec.context);
+
+            doConsumeResponse();
+
+        } catch (Throwable dart) {
+            dart.printStackTrace(System.out);
+            if (exception != null)
+                exception = dart;
+
+        } finally {
+            conn_manager.releaseConnection(connection);
+        }
+    }
+
+
+    /**
+     * Opens the connection after it has been obtained.
+     */
+    protected void doOpenConnection() throws Exception {
+        connection.open
+            (conn_route, request_spec.context, request_spec.params);
+    }
+
+    /**
+     * Reads the response entity, if there is one.
+     */
+    protected void doConsumeResponse() throws Exception {
+        if (response.getEntity() != null)
+            response_data = EntityUtils.toByteArray(response.getEntity());
+    }
+
+
+    /**
+     * Helper class collecting request data.
+     * The request and target are expected in the context.
+     */
+    public static class RequestSpec {
+        public HttpRequestExecutor executor;
+        public HttpProcessor processor;
+        public HttpContext context;
+        public HttpParams params;
+    }
+
+}

Propchange: jakarta/httpcomponents/httpclient/trunk/src/test/org/apache/http/impl/conn/ExecReqThread.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jakarta/httpcomponents/httpclient/trunk/src/test/org/apache/http/impl/conn/ExecReqThread.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: jakarta/httpcomponents/httpclient/trunk/src/test/org/apache/http/impl/conn/ExecReqThread.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: jakarta/httpcomponents/httpclient/trunk/src/test/org/apache/http/impl/conn/TestTSCCMWithServer.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpclient/trunk/src/test/org/apache/http/impl/conn/TestTSCCMWithServer.java?view=diff&rev=539880&r1=539879&r2=539880
==============================================================================
--- jakarta/httpcomponents/httpclient/trunk/src/test/org/apache/http/impl/conn/TestTSCCMWithServer.java (original)
+++ jakarta/httpcomponents/httpclient/trunk/src/test/org/apache/http/impl/conn/TestTSCCMWithServer.java Sun May 20 07:21:28 2007
@@ -61,6 +61,20 @@
  */
 public class TestTSCCMWithServer extends ServerTestBase {
 
+    // Server-based tests not ported from 3.x TestHttpConnectionManager
+    //
+    // testWriteRequestReleaseConnection
+    //      This tests auto-release in case of an I/O error while writing.
+    //      It's a test of the execution framework, not of the manager.
+    // testConnectMethodFailureRelease
+    //      This tests method.fakeResponse() and auto-release. It's a
+    //      test of a 3.x specific hack and the execution framework.
+    // testResponseAutoRelease
+    //      Auto-release is not part of the connection manager anymore.
+    // testMaxConnectionsPerServer
+    //      Connection limits are already tested without a server.
+
+
     public TestTSCCMWithServer(String testName) {
         super(testName);
     }
@@ -96,6 +110,70 @@
     }
 
 
+
+    /**
+     * Tests executing several requests in parallel.
+     */
+    public void testParallelRequests() throws Exception {
+        // 3.x: TestHttpConnectionManager.testGetFromMultipleThreads
+
+        final int COUNT = 8; // adjust to execute more requests
+
+        HttpParams mgrpar = defaultParams.copy();
+        HttpConnectionManagerParams.setMaxTotalConnections
+            (mgrpar, COUNT/2);
+        HttpConnectionManagerParams.setDefaultMaxConnectionsPerHost
+            (mgrpar, COUNT/2);
+        ThreadSafeClientConnManager mgr = createTSCCM(mgrpar, null);
+
+        final HttpHost target = getServerHttp();
+        final HttpRoute route = new HttpRoute(target, null, false);
+        final int      rsplen = 8;
+        final String      uri = "/random/" + rsplen;
+
+        ExecReqThread[] threads = new ExecReqThread [COUNT];
+        for (int i=0; i<COUNT; i++) {
+
+            HttpRequest request = new BasicHttpRequest
+                ("GET", uri, HttpVersion.HTTP_1_1);
+
+            ExecReqThread.RequestSpec ertrs = new ExecReqThread.RequestSpec();
+            ertrs.executor = httpExecutor;
+            ertrs.processor = httpProcessor;
+            ertrs.context = new HttpExecutionContext(null);
+            ertrs.params = defaultParams;
+
+            ertrs.context.setAttribute
+                (HttpExecutionContext.HTTP_TARGET_HOST, target);
+            ertrs.context.setAttribute
+                (HttpExecutionContext.HTTP_REQUEST, request);
+
+            threads[i] = new ExecReqThread(mgr, route, 5000L, ertrs);
+        }
+
+        for (int i=0; i<threads.length; i++) {
+            threads[i].start();
+        }
+
+        for (int i=0; i<threads.length; i++) {
+            threads[i].join(10000);
+            assertNull("exception in thread " + i,
+                       threads[i].getException());
+            assertNotNull("no response in thread " + i,
+                          threads[i].getResponse());
+            assertEquals("wrong status code in thread " + i, 200,
+                         threads[i].getResponse()
+                         .getStatusLine().getStatusCode());
+            assertNotNull("no response data in thread " + i,
+                          threads[i].getResponseData());
+            assertEquals("wrong length of data in thread" + i, rsplen,
+                         threads[i].getResponseData().length);
+        }
+
+        mgr.shutdown();
+    }
+
+
     /**
      * Tests releasing and re-using a connection after a response is read.
      */
@@ -293,28 +371,6 @@
 
         assertNull("TSCCM not garbage collected", wref.get());
     }
-
-
-    // List of server-based tests in 3.x TestHttpConnectionManager
-    //
-    // + testReleaseConnection
-    // + testDroppedThread
-    // + testReclaimUnusedConnection
-    // testGetFromMultipleThreads, depends on extra threads
-
-
-    // Server-based tests not ported from 3.x TestHttpConnectionManager
-    //
-    // testWriteRequestReleaseConnection
-    //      This tests auto-release in case of an I/O error while writing.
-    //      It's a test of the execution framework, not of the manager.
-    // testConnectMethodFailureRelease
-    //      This tests method.fakeResponse() and auto-release. It's a
-    //      test of a 3.x specific hack and the execution framework.
-    // testResponseAutoRelease
-    //      Auto-release is not part of the connection manager.
-    // testMaxConnectionsPerServer
-    //      Connection limits are already tested without a server.
 
 
 } // class TestTSCCMWithServer