@Test
    void testReleaseConnection() throws Exception {
        configureServer(bootstrap -> bootstrap
                .register("/random/*", new RandomHandler()));
        final HttpHost target = startServer();

        final TestClient client = client();
        final PoolingHttpClientConnectionManager connManager = client.getConnectionManager();
        connManager.setMaxTotal(1);

        final HttpRoute route = new HttpRoute(target, null, false);
        final int rsplen = 8;
        final String uri = "/random/" + rsplen;

        final ClassicHttpRequest request = new BasicClassicHttpRequest("GET", target, uri);
        final HttpClientContext context = HttpClientContext.create();

        final LeaseRequest leaseRequest1 = connManager.lease("id1", route, null);
        final ConnectionEndpoint endpoint1 = leaseRequest1.get(Timeout.ZERO_MILLISECONDS);

        connManager.connect(endpoint1, null, context);

        try (final ClassicHttpResponse response1 = endpoint1.execute("id1", request, exec, context)) {
            Assertions.assertEquals(HttpStatus.SC_OK, response1.getCode());
        }

        // check that there is no auto-release by default
        // this should fail quickly, connection has not been released
        final LeaseRequest leaseRequest2 = connManager.lease("id2", route, null);
        Assertions.assertThrows(TimeoutException.class, () -> leaseRequest2.get(Timeout.ofMilliseconds(10)));

        endpoint1.close();
        connManager.release(endpoint1, null, TimeValue.NEG_ONE_MILLISECOND);
        final LeaseRequest leaseRequest3 = connManager.lease("id2", route, null);
        final ConnectionEndpoint endpoint2 = leaseRequest3.get(Timeout.ZERO_MILLISECONDS);
        Assertions.assertFalse(endpoint2.isConnected());

        connManager.connect(endpoint2, null, context);

        try (final ClassicHttpResponse response2 = endpoint2.execute("id2", request, exec, context)) {
            Assertions.assertEquals(HttpStatus.SC_OK, response2.getCode());
        }

        // release connection after marking it for re-use
        // expect the next connection obtained to be open
        connManager.release(endpoint2, null, TimeValue.NEG_ONE_MILLISECOND);

        final LeaseRequest leaseRequest4 = connManager.lease("id3", route, null);
        final ConnectionEndpoint endpoint3 = leaseRequest4.get(Timeout.ZERO_MILLISECONDS);
        Assertions.assertTrue(endpoint3.isConnected());

        // repeat the communication, no need to prepare the request again
        try (final ClassicHttpResponse response3 = endpoint3.execute("id3", request, exec, context)) {
            Assertions.assertEquals(HttpStatus.SC_OK, response3.getCode());
        }

        connManager.release(endpoint3, null, TimeValue.NEG_ONE_MILLISECOND);
        connManager.close();
    }
Tests releasing and re-using a connection after a response is read.
httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestConnectionManagement.java