diff --git a/src/test/org/apache/http/impl/conn/GetConnThread.java b/src/test/org/apache/http/impl/conn/GetConnThread.java
new file mode 100644
index 000000000..bc5769688
--- /dev/null
+++ b/src/test/org/apache/http/impl/conn/GetConnThread.java
@@ -0,0 +1,86 @@
+/*
+ * $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
+ * .
+ *
+ */
+
+package org.apache.http.impl.conn;
+
+import org.apache.http.conn.HttpRoute;
+import org.apache.http.conn.ManagedClientConnection;
+import org.apache.http.conn.ClientConnectionManager;
+
+
+/**
+ * Thread to get a connection from a connection manager.
+ * Used by connection manager tests.
+ * Code based on HttpClient 3.x class TestHttpConnectionManager
.
+ */
+public class GetConnThread extends Thread {
+
+ protected ClientConnectionManager conn_manager;
+ protected HttpRoute conn_route;
+ protected long conn_timeout;
+
+ protected ManagedClientConnection connection;
+ protected Throwable exception;
+
+ /**
+ * Creates a new thread.
+ * When this thread is started, it will try to obtain a connection.
+ */
+ public GetConnThread(ClientConnectionManager mgr,
+ HttpRoute route, long timeout) {
+
+ conn_manager = mgr;
+ conn_route = route;
+ conn_timeout = timeout;
+ }
+
+
+ /**
+ * This method is executed when the thread is started.
+ */
+ public void run() {
+ try {
+ connection = conn_manager.getConnection(conn_route, conn_timeout);
+ } catch (Throwable dart) {
+ exception = dart;
+ }
+ // terminate
+ }
+
+
+ public Throwable getException() {
+ return exception;
+ }
+
+ public ManagedClientConnection getConnection() {
+ return connection;
+ }
+
+}
diff --git a/src/test/org/apache/http/impl/conn/TestTSCCMNoServer.java b/src/test/org/apache/http/impl/conn/TestTSCCMNoServer.java
index 5044e988a..29bce71de 100644
--- a/src/test/org/apache/http/impl/conn/TestTSCCMNoServer.java
+++ b/src/test/org/apache/http/impl/conn/TestTSCCMNoServer.java
@@ -368,7 +368,7 @@ public void testReleaseConnection() throws Exception {
public void testDeleteClosedConnections() {
ThreadSafeClientConnManager mgr = createTSCCM(null, null);
-
+
HttpHost target = new HttpHost("www.test.invalid", 80, "http");
HttpRoute route = new HttpRoute(target, null, false);
HostConfiguration hcfg = route.toHostConfig(); //@@@ deprecated
@@ -396,9 +396,142 @@ public void testDeleteClosedConnections() {
mgr.shutdown();
}
- // testShutdownAll, depends on parameterization and extra threads
- // testShutdown, depends on parameterization and extra threads
- // testHostReusePreference, depends on parameterization and extra threads
- // testWaitingThreadInterrupted - depends on extra thread
+
+ public void testShutdown() throws Exception {
+ // 3.x: TestHttpConnectionManager.testShutdown
+
+ HttpParams params = createDefaultParams();
+ HttpConnectionManagerParams.setDefaultMaxConnectionsPerHost(params, 1);
+ HttpConnectionManagerParams.setMaxTotalConnections(params, 1);
+
+ ThreadSafeClientConnManager mgr = createTSCCM(params, null);
+
+ HttpHost target = new HttpHost("www.test.invalid", 80, "http");
+ HttpRoute route = new HttpRoute(target, null, false);
+
+ // get the only connection, then start an extra thread
+ // on shutdown, the extra thread should get an exception
+
+ ManagedClientConnection conn = mgr.getConnection(route, 1L);
+ GetConnThread gct = new GetConnThread(mgr, route, 0L); // no timeout
+ gct.start();
+ Thread.sleep(100); // give extra thread time to block
+
+
+ mgr.shutdown();
+
+ // First release the connection. If the manager keeps working
+ // despite the shutdown, this will deblock the extra thread.
+ // The release itself should turn into a no-op, without exception.
+ mgr.releaseConnection(conn);
+
+
+ gct.join(10000);
+ assertNull("thread should not have obtained connection",
+ gct.getConnection());
+ assertNotNull("thread should have gotten an exception",
+ gct.getException());
+ assertSame("thread got wrong exception",
+ IllegalStateException.class, gct.getException().getClass());
+
+ // the manager is down, we should not be able to get a connection
+ try {
+ conn = mgr.getConnection(route, 1L);
+ fail("shut-down manager does not raise exception");
+ } catch (IllegalStateException isx) {
+ // expected
+ }
+ }
+
+
+ public void testInterruptThread() throws Exception {
+ // 3.x: TestHttpConnectionManager.testWaitingThreadInterrupted
+
+ HttpParams params = createDefaultParams();
+ HttpConnectionManagerParams.setMaxTotalConnections(params, 1);
+
+ ThreadSafeClientConnManager mgr = createTSCCM(params, null);
+
+ HttpHost target = new HttpHost("www.test.invalid", 80, "http");
+ HttpRoute route = new HttpRoute(target, null, false);
+
+ // get the only connection, then start an extra thread
+ ManagedClientConnection conn = mgr.getConnection(route, 1L);
+ GetConnThread gct = new GetConnThread(mgr, route, 0L); // no timeout
+ gct.start();
+ Thread.sleep(100); // give extra thread time to block
+
+
+ // interrupt the thread, it should cancel waiting with an exception
+ gct.interrupt();
+
+
+ gct.join(10000);
+ assertNotNull("thread should have gotten an exception",
+ gct.getException());
+ assertSame("thread got wrong exception",
+ IllegalThreadStateException.class,
+ gct.getException().getClass());
+
+ // make sure the manager is still working
+ try {
+ mgr.getConnection(route, 10L);
+ fail("should have gotten a timeout");
+ } catch (ConnectionPoolTimeoutException e) {
+ // expected
+ }
+
+ mgr.releaseConnection(conn);
+ conn = mgr.getConnection(route, 10L); // this time, no exception
+ assertNotNull("should have gotten a connection", conn);
+
+ mgr.shutdown();
+ }
+
+
+
+ public void testReusePreference() throws Exception {
+ // 3.x: TestHttpConnectionManager.testHostReusePreference
+
+ HttpParams params = createDefaultParams();
+ HttpConnectionManagerParams.setMaxTotalConnections(params, 1);
+
+ ThreadSafeClientConnManager mgr = createTSCCM(params, null);
+
+ HttpHost target1 = new HttpHost("www.test1.invalid", 80, "http");
+ HttpRoute route1 = new HttpRoute(target1, null, false);
+ HttpHost target2 = new HttpHost("www.test2.invalid", 80, "http");
+ HttpRoute route2 = new HttpRoute(target2, null, false);
+
+ // get the only connection, then start two extra threads
+ ManagedClientConnection conn = mgr.getConnection(route1, 1L);
+ GetConnThread gct1 = new GetConnThread(mgr, route1, 1000L);
+ GetConnThread gct2 = new GetConnThread(mgr, route2, 1000L);
+
+ // the second thread is started first, to distinguish the
+ // route-based reuse preference from first-come, first-served
+ gct2.start();
+ Thread.sleep(100); // give the thread time to block
+ gct1.start();
+ Thread.sleep(100); // give the thread time to block
+
+
+ // releasing the connection for route1 should deblock thread1
+ // the other thread gets a timeout
+ mgr.releaseConnection(conn);
+
+ gct1.join(10000);
+ gct2.join(10000);
+
+ assertNotNull("thread 1 should have gotten a connection",
+ gct1.getConnection());
+ assertNull ("thread 2 should NOT have gotten a connection",
+ gct2.getConnection());
+
+ mgr.shutdown();
+ }
+
+ // 3.x TestHttpConnectionManager.testShutdownAll is not ported
+ // the shutdownAll() method is scheduled for removal
} // class TestTSCCMNoServer
diff --git a/src/test/org/apache/http/impl/conn/TestTSCCMWithServer.java b/src/test/org/apache/http/impl/conn/TestTSCCMWithServer.java
index 6076cf73e..626afa053 100644
--- a/src/test/org/apache/http/impl/conn/TestTSCCMWithServer.java
+++ b/src/test/org/apache/http/impl/conn/TestTSCCMWithServer.java
@@ -296,13 +296,11 @@ public void testConnectionManagerGC() throws Exception {
// List of server-based tests in 3.x TestHttpConnectionManager
- // The execution framework (HttpClient) used by some of them
- // can probably be replaced by hand-coded request execution
//
// + testReleaseConnection
// + testDroppedThread
// + testReclaimUnusedConnection
- // testGetFromMultipleThreads, depends on execution framework
+ // testGetFromMultipleThreads, depends on extra threads
// Server-based tests not ported from 3.x TestHttpConnectionManager