/**
   * Tests that a partition with expired connections should those connections killed off.
   *
   * @throws SQLException
   */
  @Test
  @SuppressWarnings({"unchecked", "rawtypes"})
  public void testConnectionExpired() throws SQLException {

    TransferQueue<ConnectionHandle> mockQueue = createNiceMock(TransferQueue.class);
    expect(mockConnectionPartition.getAvailableConnections()).andReturn(1);
    expect(mockConnectionPartition.getFreeConnections()).andReturn(mockQueue).anyTimes();
    ConnectionHandle mockConnectionExpired = createNiceMock(ConnectionHandle.class);
    ConnectionHandle mockConnection = createNiceMock(ConnectionHandle.class);
    expect(mockQueue.poll()).andReturn(mockConnectionExpired).once();

    expect(mockConnectionExpired.isExpired(anyLong())).andReturn(true).once();

    expect(mockExecutor.isShutdown()).andReturn(false).once();

    mockConnectionExpired.internalClose();
    expectLastCall().once();

    mockPool.postDestroyConnection(mockConnectionExpired);
    expectLastCall().once();

    expect(mockExecutor.schedule((Callable) anyObject(), anyLong(), (TimeUnit) anyObject()))
        .andReturn(null)
        .once();
    replay(
        mockQueue,
        mockExecutor,
        mockConnectionPartition,
        mockConnection,
        mockPool,
        mockConnectionExpired);
    testClass.run();
    verify(mockConnectionExpired);
  }
  /**
   * Tests that a partition with expired connections should those connections killed off.
   *
   * @throws SQLException
   */
  @Test
  @SuppressWarnings("unchecked")
  public void testConnectionNotExpiredLifoMode() throws SQLException {

    LIFOQueue<ConnectionHandle> mockQueue = createNiceMock(LIFOQueue.class);
    expect(mockConnectionPartition.getAvailableConnections()).andReturn(1);
    expect(mockConnectionPartition.getFreeConnections()).andReturn(mockQueue).anyTimes();
    ConnectionHandle mockConnection = createNiceMock(ConnectionHandle.class);
    expect(mockQueue.poll()).andReturn(mockConnection).once();

    expect(mockConnection.isExpired(anyLong())).andReturn(false).once();

    expect(mockExecutor.isShutdown()).andReturn(false).once();

    expect(mockConnection.getOriginatingPartition()).andReturn(mockConnectionPartition).anyTimes();
    expect(mockQueue.offerLast(mockConnection)).andReturn(false).anyTimes();
    mockConnection.internalClose();

    replay(mockQueue, mockExecutor, mockConnectionPartition, mockConnection, mockPool);
    ConnectionMaxAgeThread testClass2 =
        new ConnectionMaxAgeThread(mockConnectionPartition, mockExecutor, mockPool, 5000, true);
    testClass2.run();

    verify(mockConnection, mockPool);
  }
  /** @throws SQLException */
  @Test
  public void testCloseConnectionWithException() throws SQLException {
    ConnectionHandle mockConnection = createNiceMock(ConnectionHandle.class);
    mockPool.postDestroyConnection(mockConnection);
    expectLastCall().once();

    mockConnection.internalClose();
    expectLastCall().andThrow(new SQLException());

    replay(mockConnection, mockPool);
    testClass.closeConnection(mockConnection);
    verify(mockConnection, mockPool);
  }
  /** @throws SQLException */
  @Test
  public void testCloseConnectionWithExceptionCoverage() throws SQLException {
    ConnectionHandle mockConnection = createNiceMock(ConnectionHandle.class);
    mockPool.postDestroyConnection(mockConnection);
    expectLastCall().once();
    ConnectionMaxAgeThread.logger = null; // make it break.
    mockConnection.internalClose();
    expectLastCall().andThrow(new SQLException());

    replay(mockConnection, mockPool);
    try {
      testClass.closeConnection(mockConnection);
    } catch (Exception e) {
      // do nothing
    }
    verify(mockConnection, mockPool);
  }
  /** @throws SQLException */
  @Test
  @SuppressWarnings({"unchecked"})
  public void testExceptionsCase() throws SQLException {

    TransferQueue<ConnectionHandle> mockQueue = createNiceMock(TransferQueue.class);
    expect(mockConnectionPartition.getAvailableConnections()).andReturn(2);
    expect(mockConnectionPartition.getFreeConnections()).andReturn(mockQueue).anyTimes();
    ConnectionHandle mockConnectionException = createNiceMock(ConnectionHandle.class);
    expect(mockQueue.poll()).andReturn(mockConnectionException).times(2);
    expect(mockConnectionException.isExpired(anyLong()))
        .andThrow(new RuntimeException())
        .anyTimes();
    expect(mockExecutor.isShutdown()).andReturn(false).once().andReturn(true).once();

    replay(mockQueue, mockConnectionException, mockExecutor, mockConnectionPartition, mockPool);
    testClass.run();
    verify(mockExecutor, mockConnectionException);
  }
  /** @throws SQLException */
  @Test
  @SuppressWarnings("unchecked")
  public void testExceptionsCaseWherePutInPartitionFails() throws SQLException {

    TransferQueue<ConnectionHandle> mockQueue = createNiceMock(TransferQueue.class);
    expect(mockConnectionPartition.getAvailableConnections()).andReturn(1);
    expect(mockConnectionPartition.getFreeConnections()).andReturn(mockQueue).anyTimes();
    ConnectionHandle mockConnectionException = createNiceMock(ConnectionHandle.class);
    expect(mockQueue.poll()).andReturn(mockConnectionException).times(1);
    expect(mockConnectionException.isExpired(anyLong())).andReturn(false).anyTimes();
    expect(mockExecutor.isShutdown()).andReturn(false).anyTimes();
    mockPool.putConnectionBackInPartition(mockConnectionException);
    expectLastCall().andThrow(new SQLException()).once();

    // we should be able to reschedule
    expect(mockExecutor.schedule((Runnable) anyObject(), anyLong(), (TimeUnit) anyObject()))
        .andReturn(null)
        .once();

    replay(mockQueue, mockConnectionException, mockExecutor, mockConnectionPartition, mockPool);
    testClass.run();
    verify(mockExecutor, mockConnectionException);
  }