public void testReleaseConnectionWithTimeLimits() throws Exception {
HttpParams mgrpar = defaultParams.copy();
ConnManagerParams.setMaxTotalConnections(mgrpar, 1);
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;
HttpRequest request =
new BasicHttpRequest("GET", uri, HttpVersion.HTTP_1_1);
ManagedClientConnection conn = getConnection(mgr, route);
conn.open(route, httpContext, defaultParams);
// a new context is created for each testcase, no need to reset
HttpResponse response = Helper.execute(
request, conn, target,
httpExecutor, httpProcessor, defaultParams, httpContext);
assertEquals("wrong status in first response",
HttpStatus.SC_OK,
response.getStatusLine().getStatusCode());
byte[] data = EntityUtils.toByteArray(response.getEntity());
assertEquals("wrong length of first response entity",
rsplen, data.length);
// ignore data, but it must be read
// check that there is no auto-release by default
try {
// this should fail quickly, connection has not been released
getConnection(mgr, route, 10L, TimeUnit.MILLISECONDS);
fail("ConnectionPoolTimeoutException should have been thrown");
} catch (ConnectionPoolTimeoutException e) {
// expected
}
// release connection without marking for re-use
// expect the next connection obtained to be closed
mgr.releaseConnection(conn, 100, TimeUnit.MILLISECONDS);
conn = getConnection(mgr, route);
assertFalse("connection should have been closed", conn.isOpen());
// repeat the communication, no need to prepare the request again
conn.open(route, httpContext, defaultParams);
httpContext.setAttribute(ExecutionContext.HTTP_CONNECTION, conn);
response = httpExecutor.execute(request, conn, httpContext);
httpExecutor.postProcess(response, httpProcessor, httpContext);
assertEquals("wrong status in second response",
HttpStatus.SC_OK,
response.getStatusLine().getStatusCode());
data = EntityUtils.toByteArray(response.getEntity());
assertEquals("wrong length of second response entity",
rsplen, data.length);
// ignore data, but it must be read
// release connection after marking it for re-use
// expect the next connection obtained to be open
conn.markReusable();
mgr.releaseConnection(conn, 100, TimeUnit.MILLISECONDS);
conn = getConnection(mgr, route);
assertTrue("connection should have been open", conn.isOpen());
// repeat the communication, no need to prepare the request again
httpContext.setAttribute(ExecutionContext.HTTP_CONNECTION, conn);
response = httpExecutor.execute(request, conn, httpContext);
httpExecutor.postProcess(response, httpProcessor, httpContext);
assertEquals("wrong status in third response",
HttpStatus.SC_OK,
response.getStatusLine().getStatusCode());
data = EntityUtils.toByteArray(response.getEntity());
assertEquals("wrong length of third response entity",
rsplen, data.length);
// ignore data, but it must be read
conn.markReusable();
mgr.releaseConnection(conn, 100, TimeUnit.MILLISECONDS);
Thread.sleep(150);
conn = getConnection(mgr, route);
assertTrue("connection should have been closed", !conn.isOpen());
// repeat the communication, no need to prepare the request again
conn.open(route, httpContext, defaultParams);
httpContext.setAttribute(ExecutionContext.HTTP_CONNECTION, conn);
response = httpExecutor.execute(request, conn, httpContext);
httpExecutor.postProcess(response, httpProcessor, httpContext);
assertEquals("wrong status in third response",
HttpStatus.SC_OK,
response.getStatusLine().getStatusCode());
data = EntityUtils.toByteArray(response.getEntity());
assertEquals("wrong length of fourth response entity",
rsplen, data.length);
// ignore data, but it must be read
mgr.shutdown();
}