connectLatch, WaitPolicy.AFTER_CONNECT, PlainSocketFactory.getSocketFactory());
final Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", stallingSocketFactory)
.build();
final PoolingHttpClientConnectionManager mgr = new PoolingHttpClientConnectionManager(registry);
mgr.setMaxTotal(1);
final HttpHost target = getServerHttp();
final HttpRoute route = new HttpRoute(target, null, false);
final HttpContext context = new BasicHttpContext();
final HttpClientConnection conn = getConnection(mgr, route);
final AtomicReference<Throwable> throwRef = new AtomicReference<Throwable>();
final Thread abortingThread = new Thread(new Runnable() {
public void run() {
try {
stallingSocketFactory.waitForState();
conn.shutdown();
mgr.releaseConnection(conn, null, -1, null);
connectLatch.countDown();
} catch (final Throwable e) {
throwRef.set(e);
}
}
});
abortingThread.start();
try {
mgr.connect(conn, route.getTargetHost(), route.getLocalAddress(), 0, context);
Assert.fail("IOException expected");
} catch(final IOException expected) {
}
abortingThread.join(5000);
if(throwRef.get() != null) {
throw new RuntimeException(throwRef.get());
}
Assert.assertFalse(conn.isOpen());
// Give the server a bit of time to accept the connection, but
// ensure that it can accept it.
for(int i = 0; i < 10; i++) {
if(localServer.getAcceptedConnectionCount() == 1) {
break;
}
Thread.sleep(100);
}
Assert.assertEquals(1, localServer.getAcceptedConnectionCount());
// the connection is expected to be released back to the manager
final HttpClientConnection conn2 = getConnection(mgr, route, 5L, TimeUnit.SECONDS);
Assert.assertFalse("connection should have been closed", conn2.isOpen());
mgr.releaseConnection(conn2, null, -1, null);
mgr.shutdown();
}