/**
   * Tests the MultiThreadedHttpConnectionManager's ability to restrict the maximum number of
   * connections.
   */
  public void testMaxConnections() {

    MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();
    connectionManager.getParams().setDefaultMaxConnectionsPerHost(1);
    connectionManager.getParams().setMaxTotalConnections(2);

    HostConfiguration host1 = new HostConfiguration();
    host1.setHost("host1", -1, "http");

    HostConfiguration host2 = new HostConfiguration();
    host2.setHost("host2", -1, "http");

    HttpConnection connection1 = connectionManager.getConnection(host1);
    HttpConnection connection2 = connectionManager.getConnection(host2);

    try {
      // this should fail quickly since the connection has not been released
      connectionManager.getConnectionWithTimeout(host2, 100);
      fail("ConnectionPoolTimeoutException should not be available");
    } catch (ConnectionPoolTimeoutException e) {
      // this should throw an exception
    }

    // release one of the connections
    connection2.releaseConnection();
    connection2 = null;

    try {
      // there should be a connection available now
      connection2 = connectionManager.getConnectionWithTimeout(host2, 100);
    } catch (ConnectionPoolTimeoutException e) {
      e.printStackTrace();
      fail("a httpConnection should have been available: " + e);
    }
  }
  /** Tests the MultiThreadedHttpConnectionManager's ability to reclaim unused connections. */
  public void testConnectionReclaiming() {

    MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();
    connectionManager.getParams().setDefaultMaxConnectionsPerHost(1);
    connectionManager.getParams().setMaxTotalConnections(1);

    HostConfiguration host1 = new HostConfiguration();
    host1.setHost("host1", -1, "http");

    HostConfiguration host2 = new HostConfiguration();
    host2.setHost("host2", -1, "http");

    HttpConnection connection = connectionManager.getConnection(host1);
    // now release this connection
    connection.releaseConnection();
    connection = null;

    try {
      // the connection from host1 should be reclaimed
      connection = connectionManager.getConnectionWithTimeout(host2, 100);
    } catch (ConnectTimeoutException e) {
      e.printStackTrace();
      fail("a httpConnection should have been available: " + e);
    }
  }
  public void testHostReusePreference() {

    final MultiThreadedHttpConnectionManager connectionManager =
        new MultiThreadedHttpConnectionManager();
    connectionManager.getParams().setDefaultMaxConnectionsPerHost(1);
    connectionManager.getParams().setMaxTotalConnections(1);

    final HostConfiguration host1 = new HostConfiguration();
    host1.setHost("host1", -1, "http");

    final HostConfiguration host2 = new HostConfiguration();
    host2.setHost("host2", -1, "http");

    HttpConnection connection = connectionManager.getConnection(host1);

    GetConnectionThread getHost1 = new GetConnectionThread(host1, connectionManager, 200);
    GetConnectionThread getHost2 = new GetConnectionThread(host2, connectionManager, 200);

    getHost2.start();
    getHost1.start();

    // give the threads some time to startup
    try {
      Thread.sleep(100);
    } catch (InterruptedException e1) {
      e1.printStackTrace();
    }

    // after the connection to host1 is released it should be given to getHost1
    connection.releaseConnection();
    connection = null;

    try {
      getHost1.join();
      getHost2.join();
    } catch (InterruptedException e) {
      e.printStackTrace();
    }

    assertNotSame(
        "Connection should have been given to someone",
        getHost1.getConnection(),
        getHost2.getConnection());
    assertNotNull("Connection should have been given to host1", getHost1.getConnection());
    assertNull("Connection should NOT have been given to host2", getHost2.getConnection());
  }
  /**
   * Tests that {@link MultiThreadedHttpConnectionManager#shutdown()} closes all resources and makes
   * the connection manger unusable.
   */
  public void testShutdown() {

    MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();
    connectionManager.getParams().setDefaultMaxConnectionsPerHost(1);
    connectionManager.getParams().setMaxTotalConnections(1);

    HostConfiguration host1 = new HostConfiguration();
    host1.setHost("host1", -1, "http");

    // hold on to the only connection
    HttpConnection connection = connectionManager.getConnection(host1);

    // wait for a connection on another thread
    GetConnectionThread getConn = new GetConnectionThread(host1, connectionManager, 0);
    getConn.start();

    connectionManager.shutdown();

    // now release this connection, this should close the connection, but have no other effect
    connection.releaseConnection();
    connection = null;

    try {
      getConn.join();
    } catch (InterruptedException e) {
      e.printStackTrace();
    }

    // this thread should have caught an exception without getting a connection
    assertNull("Not connection should have been checked out", getConn.getConnection());
    assertNotNull("There should have been an exception", getConn.getException());

    try {
      connectionManager.getConnection(host1);
      fail("An exception should have occurred");
    } catch (Exception e) {
      // this is expected
    }
  }
  public void testDeleteClosedConnections() {

    MultiThreadedHttpConnectionManager manager = new MultiThreadedHttpConnectionManager();

    HttpConnection conn = manager.getConnection(client.getHostConfiguration());

    assertEquals("connectionsInPool", manager.getConnectionsInPool(), 1);
    assertEquals(
        "connectionsInPool(host)", manager.getConnectionsInPool(client.getHostConfiguration()), 1);

    conn.close();
    conn.releaseConnection();

    assertEquals("connectionsInPool", manager.getConnectionsInPool(), 1);
    assertEquals(
        "connectionsInPool(host)", manager.getConnectionsInPool(client.getHostConfiguration()), 1);

    manager.deleteClosedConnections();

    assertEquals("connectionsInPool", manager.getConnectionsInPool(), 0);
    assertEquals(
        "connectionsInPool(host)", manager.getConnectionsInPool(client.getHostConfiguration()), 0);
  }