/**
   * Tests fake exceptions, connection should be shutdown if the scheduler was marked as going down.
   * Mostly for code coverage.
   *
   * @throws SQLException
   * @throws InterruptedException
   */
  @Test
  public void testInterruptedException() throws SQLException, InterruptedException {
    ArrayBlockingQueue<ConnectionHandle> fakeFreeConnections =
        new ArrayBlockingQueue<ConnectionHandle>(1);
    fakeFreeConnections.add(mockConnection);

    config.setIdleConnectionTestPeriod(1);
    expect(mockPool.getConfig()).andReturn(config).anyTimes();
    expect(mockConnectionPartition.getFreeConnections()).andReturn(fakeFreeConnections).anyTimes();
    expect(mockConnectionPartition.getMinConnections()).andReturn(10).once();
    expect(mockConnection.isPossiblyBroken()).andReturn(false);
    expect(mockConnection.getConnectionLastUsed()).andReturn(0L);
    expect(mockPool.isConnectionHandleAlive((ConnectionHandle) anyObject()))
        .andReturn(true)
        .anyTimes();
    expect(mockExecutor.isShutdown()).andReturn(true);
    mockPool.releaseInAnyFreePartition(
        (ConnectionHandle) anyObject(), (ConnectionPartition) anyObject());
    expectLastCall().andThrow(new InterruptedException());
    // connection should be closed
    mockConnection.internalClose();
    mockPool.postDestroyConnection(mockConnection);
    expectLastCall().once();

    replay(mockPool, mockConnection, mockConnectionPartition, mockExecutor);
    this.testClass = new ConnectionTesterThread(mockConnectionPartition, mockExecutor, mockPool);
    this.testClass.run();
    verify(mockPool, mockConnectionPartition, mockExecutor, mockConnection);
  }
  /**
   * Tests fake exceptions, connection should be shutdown if the scheduler was marked as going down.
   * Same test except just used to check for a spurious interrupted exception (should be logged).
   *
   * @throws SQLException
   * @throws InterruptedException
   * @throws NoSuchFieldException
   * @throws SecurityException
   * @throws IllegalAccessException
   * @throws IllegalArgumentException
   */
  @Test
  public void testExceptionOnCloseConnection()
      throws SQLException, InterruptedException, SecurityException, NoSuchFieldException,
          IllegalArgumentException, IllegalAccessException {
    ArrayBlockingQueue<ConnectionHandle> fakeFreeConnections =
        new ArrayBlockingQueue<ConnectionHandle>(1);
    fakeFreeConnections.add(mockConnection);

    config.setIdleConnectionTestPeriod(1);
    expect(mockPool.getConfig()).andReturn(config).anyTimes();
    expect(mockConnectionPartition.getFreeConnections()).andReturn(fakeFreeConnections).anyTimes();
    expect(mockConnectionPartition.getMinConnections()).andReturn(10).once();
    expect(mockConnection.isPossiblyBroken()).andReturn(false);
    expect(mockConnection.getConnectionLastUsed()).andReturn(0L);
    expect(mockPool.isConnectionHandleAlive((ConnectionHandle) anyObject()))
        .andReturn(false)
        .anyTimes();

    // connection should be closed
    mockConnection.internalClose();
    expectLastCall().andThrow(new SQLException());

    replay(mockPool, mockConnection, mockConnectionPartition, mockExecutor, mockLogger);
    this.testClass = new ConnectionTesterThread(mockConnectionPartition, mockExecutor, mockPool);
    Field loggerField = this.testClass.getClass().getDeclaredField("logger");
    loggerField.setAccessible(true);
    loggerField.set(this.testClass, mockLogger);
    this.testClass.run();
    verify(mockPool, mockConnectionPartition, mockExecutor, mockConnection, mockLogger);
  }
  /**
   * Closing a connection handle should release that connection back in the pool and mark it as
   * closed.
   *
   * @throws SecurityException
   * @throws NoSuchFieldException
   * @throws IllegalArgumentException
   * @throws IllegalAccessException
   * @throws InvocationTargetException
   * @throws NoSuchMethodException
   * @throws SQLException
   */
  @SuppressWarnings("unchecked")
  @Test
  public void testInternalClose()
      throws SecurityException, NoSuchFieldException, IllegalArgumentException,
          IllegalAccessException, InvocationTargetException, NoSuchMethodException, SQLException {
    ConcurrentLinkedQueue<Statement> mockStatementHandles =
        createNiceMock(ConcurrentLinkedQueue.class);
    StatementHandle mockStatement = createNiceMock(StatementHandle.class);

    mockConnection.close();
    expectLastCall().once().andThrow(new SQLException()).once();

    Map<Connection, Reference<ConnectionHandle>> refs =
        new HashMap<Connection, Reference<ConnectionHandle>>();
    expect(mockPool.getFinalizableRefs()).andReturn(refs).anyTimes();
    FinalizableReferenceQueue finalizableRefQueue = new FinalizableReferenceQueue();

    expect(mockPool.getFinalizableRefQueue()).andReturn(finalizableRefQueue).anyTimes();
    expect(mockConnection.getPool()).andReturn(mockPool).anyTimes();

    replay(mockStatement, mockConnection, mockStatementHandles, mockPool);
    testClass.internalClose();
    try {
      testClass.internalClose(); // 2nd time should throw exception
      fail("Should have thrown an exception");
    } catch (Throwable t) {
      // do nothing.
    }

    verify(mockStatement, mockConnection, mockStatementHandles);
  }
  /**
   * Test case method for calling different get signatures.
   *
   * @throws SQLException
   * @throws SecurityException
   * @throws NoSuchFieldException
   * @throws IllegalArgumentException
   * @throws IllegalAccessException
   */
  @Test
  public void testStatementCacheDifferentGetSignatures()
      throws SQLException, SecurityException, NoSuchFieldException, IllegalArgumentException,
          IllegalAccessException {
    CommonTestUtils.logTestInfo("Tests statement get() signatures.");

    CommonTestUtils.logTestInfo("Tests statement close (put in cache).");
    String sql = CommonTestUtils.TEST_QUERY;
    BoneCP dsb = null;
    config.setMinConnectionsPerPartition(1);
    config.setMaxConnectionsPerPartition(5);
    config.setAcquireIncrement(1);
    config.setPartitionCount(1);
    config.setStatementsCacheSize(5);
    config.setStatementReleaseHelperThreads(0);
    dsb = new BoneCP(config);
    Connection conn = dsb.getConnection();
    Statement statement = conn.prepareStatement(sql);
    statement.close();

    StatementCache cache = new StatementCache(5, false, null);
    cache.putIfAbsent("test1", (StatementHandle) statement);
    assertNotNull(cache.get("test1"));

    assertNull(cache.get("test1", 1));
    assertNull(cache.get("test1", new int[] {1}));
    assertNull(cache.get("test1", new String[] {"1"}));
    assertNull(cache.get("test1", 1, 1));
    assertNull(cache.get("test1", 1, 1, 1));

    CommonTestUtils.logPass();
  }
Beispiel #5
0
  /** Tests that new connections are created on the fly. */
  @Test
  public void testConnectionCreate() throws InterruptedException, SQLException {
    CommonTestUtils.logTestInfo("Tests that new connections are created on the fly");
    config.setMinConnectionsPerPartition(10);
    config.setMaxConnectionsPerPartition(20);
    config.setAcquireIncrement(5);
    config.setPartitionCount(1);
    config.setReleaseHelperThreads(0);

    BoneCP dsb = new BoneCP(config);

    assertEquals(10, dsb.getTotalCreatedConnections());
    assertEquals(0, dsb.getTotalLeased());

    for (int i = 0; i < 10; i++) {
      dsb.getConnection();
    }
    assertEquals(10, dsb.getTotalLeased());

    for (int i = 0; i < 60; i++) {
      Thread.yield();
      Thread.sleep(2000); // give time for pool watch thread to fire up
      if (dsb.getTotalCreatedConnections() == 15) {
        break;
      }
    }
    assertEquals(15, dsb.getTotalCreatedConnections());
    assertEquals(10, dsb.getTotalLeased());
    assertEquals(5, dsb.getTotalFree());

    dsb.shutdown();
    CommonTestUtils.logPass();
  }
  /**
   * Closing a connection handle should release that connection back in the pool and mark it as
   * closed.
   *
   * @throws SecurityException
   * @throws NoSuchFieldException
   * @throws IllegalArgumentException
   * @throws IllegalAccessException
   * @throws InvocationTargetException
   * @throws NoSuchMethodException
   * @throws SQLException
   */
  @Test
  public void testClose()
      throws SecurityException, NoSuchFieldException, IllegalArgumentException,
          IllegalAccessException, InvocationTargetException, NoSuchMethodException, SQLException {

    Field field = testClass.getClass().getDeclaredField("doubleCloseCheck");
    field.setAccessible(true);
    field.set(testClass, true);

    testClass.renewConnection();
    mockPool.releaseConnection((Connection) anyObject());
    expectLastCall().once().andThrow(new SQLException()).once();
    replay(mockPool);

    testClass.close();

    // logically mark the connection as closed
    field = testClass.getClass().getDeclaredField("logicallyClosed");

    field.setAccessible(true);
    Assert.assertTrue(field.getBoolean(testClass));
    assertTrue(testClass.isClosed());

    testClass.renewConnection();
    try {
      testClass.close(); // 2nd time should throw an exception
      fail("Should have thrown an exception");
    } catch (Throwable t) {
      // do nothing.
    }

    verify(mockPool);
  }
  /**
   * 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);
  }
Beispiel #8
0
  /**
   * Test that requesting connections from a partition that is empty will fetch it from other
   * partitions that still have connections.
   */
  @Test
  public void testPartitionDrain() throws InterruptedException, SQLException {
    CommonTestUtils.logTestInfo("Test connections obtained from alternate partition");

    config.setAcquireIncrement(1);
    config.setMinConnectionsPerPartition(10);
    config.setMaxConnectionsPerPartition(10);
    config.setPartitionCount(2);
    BoneCP dsb = new BoneCP(config);
    for (int i = 0; i < 20; i++) {
      dsb.getConnection();
    }
    assertEquals(20, dsb.getTotalLeased());
    assertEquals(0, dsb.getTotalFree());
    dsb.close();
    CommonTestUtils.logPass();
  }
 /** Simple test. */
 @Test
 public void testIsConnectionHandleAlive() {
   // just make sure this is bounced off to the right place
   reset(mockPool);
   expect(mockPool.isConnectionHandleAlive(testClass)).andReturn(true).once();
   replay(mockPool);
   testClass.isConnectionAlive();
   verify(mockPool);
 }
  /**
   * Tests that a connection that is marked broken is closed internally and that the partition is
   * marked as being able to create new connections.
   *
   * @throws SQLException
   */
  @Test
  public void testConnectionMarkedBroken() throws SQLException {
    ArrayBlockingQueue<ConnectionHandle> fakeFreeConnections =
        new ArrayBlockingQueue<ConnectionHandle>(1);
    fakeFreeConnections.add(mockConnection);

    expect(mockPool.getConfig()).andReturn(config).anyTimes();
    expect(mockConnectionPartition.getFreeConnections()).andReturn(fakeFreeConnections).anyTimes();
    expect(mockConnection.isPossiblyBroken()).andReturn(true);

    // connection should be closed
    mockConnection.internalClose();
    mockPool.postDestroyConnection(mockConnection);
    expectLastCall().once();
    replay(mockPool, mockConnection, mockConnectionPartition, mockExecutor);
    this.testClass = new ConnectionTesterThread(mockConnectionPartition, mockExecutor, mockPool);
    this.testClass.run();
    verify(mockPool, mockConnectionPartition, mockExecutor, mockConnection);
  }
Beispiel #11
0
  /**
   * Test case for cache put.
   *
   * @throws SQLException
   * @throws SecurityException
   * @throws NoSuchFieldException
   * @throws IllegalArgumentException
   * @throws IllegalAccessException
   */
  @Test
  public void testStatementCachePut()
      throws SQLException, SecurityException, NoSuchFieldException, IllegalArgumentException,
          IllegalAccessException {
    CommonTestUtils.logTestInfo("Tests statement close (put in cache).");
    String sql = CommonTestUtils.TEST_QUERY;
    BoneCP dsb = null;
    config.setMinConnectionsPerPartition(1);
    config.setMaxConnectionsPerPartition(5);
    config.setAcquireIncrement(1);
    config.setPartitionCount(1);
    config.setStatementsCacheSize(5);
    config.setStatementReleaseHelperThreads(0);
    config.setStatisticsEnabled(true);
    dsb = new BoneCP(config);
    Connection conn = dsb.getConnection();
    Statement statement = conn.prepareStatement(sql);
    statement.close();
    Field statementCache = conn.getClass().getDeclaredField("preparedStatementCache");
    statementCache.setAccessible(true);
    IStatementCache cache = (IStatementCache) statementCache.get(conn);

    statement = cache.get(sql);
    assertNotNull(statement);
    // Calling again should not provide the same object
    assertNull(cache.get(sql));

    // now pretend we have 1 connection being asked for the same statement
    // twice
    statement = conn.prepareStatement(sql);
    Statement statement2 = conn.prepareStatement(sql);

    statement.close(); // release it again
    statement2.close(); // release the other one

    statement2.close();
    statement.close();
    conn.close();
    dsb.shutdown();

    CommonTestUtils.logPass();
  }
  /**
   * Callable statement tests.
   *
   * @throws SecurityException
   * @throws IllegalArgumentException
   * @throws NoSuchFieldException
   * @throws IllegalAccessException
   * @throws NoSuchMethodException
   * @throws InvocationTargetException
   */
  @Test
  public void testCallableStatement()
      throws SecurityException, IllegalArgumentException, NoSuchFieldException,
          IllegalAccessException, NoSuchMethodException, InvocationTargetException {
    expect(mockPool.captureStackTrace((String) anyObject())).andReturn("").anyTimes();
    replay(mockPool);

    callableStatementTest(String.class);
    callableStatementTest(String.class, int.class, int.class);
    callableStatementTest(String.class, int.class, int.class, int.class);
  }
Beispiel #13
0
  @Test
  public void testGetReleaseSingleThread() throws InterruptedException, SQLException {
    CommonTestUtils.logTestInfo("Test simple get/release connection from 1 partition");

    config.setMinConnectionsPerPartition(30);
    config.setMaxConnectionsPerPartition(100);
    config.setAcquireIncrement(5);
    config.setPartitionCount(1);
    BoneCP dsb = new BoneCP(config);

    for (int i = 0; i < 60; i++) {
      Connection conn = dsb.getConnection();
      conn.close();
    }
    assertEquals(0, dsb.getTotalLeased());
    assertEquals(30, dsb.getTotalFree());

    dsb.shutdown();
    CommonTestUtils.logPass();
  }
Beispiel #14
0
  /**
   * Test limits.
   *
   * @throws SQLException
   * @throws SecurityException
   * @throws NoSuchFieldException
   * @throws IllegalArgumentException
   * @throws IllegalAccessException
   */
  @Test
  public void testStatementCacheLimits()
      throws SQLException, SecurityException, NoSuchFieldException, IllegalArgumentException,
          IllegalAccessException {
    CommonTestUtils.logTestInfo("Tests statement caching module.");
    String sql = CommonTestUtils.TEST_QUERY;
    BoneCP dsb = null;
    config.setMinConnectionsPerPartition(2);
    config.setMaxConnectionsPerPartition(5);
    config.setAcquireIncrement(1);
    config.setPartitionCount(1);
    config.setStatementsCacheSize(5);
    dsb = new BoneCP(config);
    Connection conn = dsb.getConnection();
    StatementHandle statement = (StatementHandle) conn.prepareStatement(sql);

    StatementCache cache = new StatementCache(5, true, new Statistics(dsb));
    cache.putIfAbsent("test1", statement);
    cache.putIfAbsent("test2", statement);
    cache.putIfAbsent("test3", statement);
    cache.putIfAbsent("test4", statement);
    cache.putIfAbsent("test5", statement);

    conn.close();

    for (int i = 0; i < 5000000; i++) {
      cache.putIfAbsent("test" + i, statement);
      if ((i % 10000) == 0) {
        System.gc();
      }
      if (cache.size() != i) {
        break;
      }
    }
    // some elements should have been dropped in the cache
    assertFalse(cache.size() == 5000000);

    dsb.shutdown();
    CommonTestUtils.logPass();
  }
Beispiel #15
0
  /**
   * Prepared statement tests.
   *
   * @throws SQLException
   * @throws SecurityException
   * @throws NoSuchFieldException
   * @throws IllegalArgumentException
   * @throws IllegalAccessException
   */
  @Test
  public void testPreparedStatement()
      throws SQLException, SecurityException, NoSuchFieldException, IllegalArgumentException,
          IllegalAccessException {
    BoneCP dsb = null;
    CommonTestUtils.logTestInfo("Tests that prepared statements are obtained from cache when set.");
    config.setMinConnectionsPerPartition(10);
    config.setMaxConnectionsPerPartition(20);
    config.setAcquireIncrement(5);
    config.setPartitionCount(1);
    config.setStatementsCacheSize(1);
    config.setLogStatementsEnabled(true);
    config.setStatementReleaseHelperThreads(0);
    dsb = new BoneCP(config);

    ConnectionHandle con = (ConnectionHandle) dsb.getConnection();
    Field preparedStatement = con.getClass().getDeclaredField("preparedStatementCache");
    preparedStatement.setAccessible(true);
    // switch to our mock
    preparedStatement.set(con, mockCache);
    expect(mockCache.get(isA(String.class))).andReturn(null);
    //		mockCache.put(isA(String.class), isA(PreparedStatement.class));

    replay(mockCache);
    Statement statement = con.prepareStatement(CommonTestUtils.TEST_QUERY);
    statement.close();
    verify(mockCache);

    reset(mockCache);
    expect(mockCache.get(isA(String.class))).andReturn(null);
    replay(mockCache);

    con.prepareStatement(CommonTestUtils.TEST_QUERY);
    statement.close();
    verify(mockCache);
    dsb.shutdown();
    statement.close();
    con.close();
    CommonTestUtils.logPass();
  }
  /** @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);
  }
Beispiel #17
0
  /** Tests that new connections are created on the fly. */
  @Test
  public void testConnectionCreate() throws InterruptedException, SQLException {
    CommonTestUtils.logTestInfo("Tests that new connections are created on the fly");
    config.setMinConnectionsPerPartition(10);
    config.setMaxConnectionsPerPartition(20);
    config.setAcquireIncrement(5);
    config.setPartitionCount(1);
    config.setReleaseHelperThreads(0);
    config.setPoolAvailabilityThreshold(0);

    BoneCP dsb = new BoneCP(config);

    assertEquals(10, dsb.getTotalCreatedConnections());
    assertEquals(0, dsb.getTotalLeased());

    Connection[] con = new Connection[10];
    for (int i = 0; i < 10; i++) {
      con[i] = dsb.getConnection(); // keep track of it to avoid finalizer
    }
    assertEquals(10, dsb.getTotalLeased());

    for (int i = 0; i < 10; i++) {
      Thread.yield();
      Thread.sleep(500); // give time for pool watch thread to fire up
      if (dsb.getTotalCreatedConnections() == 15) {
        break;
      }
    }
    assertEquals(15, dsb.getTotalCreatedConnections());
    assertEquals(10, dsb.getTotalLeased());
    assertEquals(5, dsb.getTotalFree());

    for (Connection c : con) {
      c.close();
    }

    dsb.shutdown();
    CommonTestUtils.logPass();
  }
Beispiel #18
0
 @Test
 public void testClosedConnection() throws InterruptedException, SQLException {
   BoneCP dsb = null;
   CommonTestUtils.logTestInfo(
       "Tests that closed connections trigger exceptions if use is attempted.");
   config.setMinConnectionsPerPartition(10);
   config.setMaxConnectionsPerPartition(20);
   config.setAcquireIncrement(5);
   config.setPartitionCount(1);
   try {
     dsb = new BoneCP(config);
     Connection conn = dsb.getConnection();
     conn.prepareCall(CommonTestUtils.TEST_QUERY);
     conn.close();
     try {
       conn.prepareCall(CommonTestUtils.TEST_QUERY);
       fail("Should have thrown an exception");
     } catch (SQLException e) {
       CommonTestUtils.logPass();
     }
   } finally {
     dsb.shutdown();
   }
 }
Beispiel #19
0
  @Test
  public void testConnectionGivenButDBLost() throws SQLException {
    config.setAcquireIncrement(5);
    config.setMinConnectionsPerPartition(30);
    config.setMaxConnectionsPerPartition(100);
    config.setPartitionCount(1);
    BoneCP dsb = new BoneCP(config);
    Connection con = dsb.getConnection();
    // kill off the db...
    String sql = "SHUTDOWN"; // hsqldb interprets this as a request to terminate
    Statement stmt = con.createStatement();
    stmt.executeUpdate(sql);
    stmt.close();

    stmt = con.createStatement();
    try {
      stmt.execute(CommonTestUtils.TEST_QUERY);
      fail("Connection should have been marked as broken");
    } catch (Exception e) {
      assertTrue(((ConnectionHandle) con).isPossiblyBroken());
    }

    con.close();
  }
  /**
   * Mock setup.
   *
   * @throws Exception
   */
  @BeforeClass
  public static void setUp() throws Exception {
    config = CommonTestUtils.getConfigClone();
    mockConnection = createNiceMock(ConnectionHandle.class);
    mockPreparedStatementCache = createNiceMock(IStatementCache.class);
    mockCallableStatementCache = createNiceMock(IStatementCache.class);

    mockLogger = createNiceMock(Logger.class);
    makeThreadSafe(mockLogger, true);
    mockPool = createNiceMock(BoneCP.class);
    mockPool.closeConnectionWatch = true;
    expect(mockPool.getConfig()).andReturn(config).anyTimes();
    config.setTransactionRecoveryEnabled(false);
    config.setStatementsCacheSize(1);
    replay(mockPool);
    testClass =
        new ConnectionHandle(
            mockConnection, mockPreparedStatementCache, mockCallableStatementCache, mockPool);
    testStatementCache = new StatementCache(100);
    Field field = testClass.getClass().getDeclaredField("logger");
    field.setAccessible(true);
    field.set(null, mockLogger);
    config.setReleaseHelperThreads(0);
  }
  /** @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);
  }
  /**
   * Test marking of possibly broken status.
   *
   * @throws SecurityException
   * @throws NoSuchFieldException
   * @throws IllegalArgumentException
   * @throws IllegalAccessException
   */
  @Test
  public void testMarkPossiblyBroken()
      throws SecurityException, NoSuchFieldException, IllegalArgumentException,
          IllegalAccessException {
    Field field = testClass.getClass().getDeclaredField("possiblyBroken");
    field.setAccessible(true);
    field.set(testClass, false);
    testClass.markPossiblyBroken(null);
    Assert.assertTrue(field.getBoolean(testClass));

    // Test that a db fatal error will lead to the pool being instructed to terminate all
    // connections (+ log)
    mockPool.terminateAllConnections();
    mockLogger.error((String) anyObject(), anyObject());
    replay(mockPool);
    testClass.markPossiblyBroken(new SQLException("test", "08001"));
    verify(mockPool);
  }
 /**
  * Tests that a thrown exception will call the onAcquireFail hook.
  *
  * @throws SQLException
  */
 @Test
 public void testConstructorFail() throws SQLException {
   BoneCPConfig mockConfig = createNiceMock(BoneCPConfig.class);
   ConnectionHook mockConnectionHook = createNiceMock(CoverageHook.class);
   expect(mockPool.getConfig()).andReturn(mockConfig).anyTimes();
   expect(mockConfig.getConnectionHook()).andReturn(mockConnectionHook).once();
   expect(
           mockConnectionHook.onAcquireFail(
               (Throwable) anyObject(), (AcquireFailConfig) anyObject()))
       .andReturn(false)
       .once();
   replay(mockPool, mockConfig, mockConnectionHook);
   try {
     new ConnectionHandle("", "", "", mockPool);
     fail("Should throw an exception");
   } catch (Throwable t) {
     // do nothing.
   }
   verify(mockPool, mockConfig, mockPool);
 }
  /**
   * Tests that a partition with expired connections should those connections killed off.
   *
   * @throws SQLException
   */
  @Test
  @SuppressWarnings("unchecked")
  public void testConnectionNotExpired() throws SQLException {

    TransferQueue<ConnectionHandle> mockQueue = createNiceMock(TransferQueue.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();

    mockPool.putConnectionBackInPartition(mockConnection);
    expectLastCall().once();

    replay(mockQueue, mockExecutor, mockConnectionPartition, mockConnection, mockPool);
    testClass.run();
    verify(mockConnection, mockPool);
  }
  /**
   * Tests sendInitialSQL method.
   *
   * @throws SecurityException
   * @throws NoSuchFieldException
   * @throws IllegalArgumentException
   * @throws IllegalAccessException
   * @throws SQLException
   */
  @Test
  public void testSendInitialSQL()
      throws SecurityException, NoSuchFieldException, IllegalArgumentException,
          IllegalAccessException, SQLException {

    BoneCPConfig mockConfig = createNiceMock(BoneCPConfig.class);
    expect(mockPool.getConfig()).andReturn(mockConfig).anyTimes();

    expect(mockConfig.getInitSQL()).andReturn("test").anyTimes();
    testClass.setInternalConnection(mockConnection);

    Statement mockStatement = createNiceMock(Statement.class);
    ResultSet mockResultSet = createNiceMock(ResultSet.class);
    expect(mockConnection.createStatement()).andReturn(mockStatement).once();
    expect(mockStatement.executeQuery("test")).andReturn(mockResultSet).once();
    mockResultSet.close();
    expectLastCall().once();

    replay(mockConfig, mockPool, mockConnection, mockStatement, mockResultSet);
    testClass.sendInitSQL();
    verify(mockConfig, mockPool, mockConnection, mockStatement, mockResultSet);
  }
  /** @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);
  }
  /** Test for clear statement caches. */
  @Test
  public void testClearStatementCaches() {

    testClass.statementCachingEnabled = true;
    mockPreparedStatementCache.clear();
    expectLastCall().once();
    mockCallableStatementCache.clear();
    expectLastCall().once();

    replay(mockPreparedStatementCache, mockCallableStatementCache);
    testClass.clearStatementCaches(true);
    verify(mockPreparedStatementCache, mockCallableStatementCache);
    reset(mockPreparedStatementCache, mockCallableStatementCache);

    mockPool.closeConnectionWatch = true;
    mockPreparedStatementCache.checkForProperClosure();
    expectLastCall().once();
    mockCallableStatementCache.checkForProperClosure();
    expectLastCall().once();

    replay(mockPreparedStatementCache, mockCallableStatementCache);
    testClass.clearStatementCaches(false);
    verify(mockPreparedStatementCache, mockCallableStatementCache);
  }
  /**
   * @throws SecurityException
   * @throws NoSuchFieldException
   * @throws IllegalArgumentException
   * @throws IllegalAccessException
   * @throws SQLException
   */
  @Test
  public void testDoubleClose()
      throws SecurityException, NoSuchFieldException, IllegalArgumentException,
          IllegalAccessException, SQLException {
    Field field = testClass.getClass().getDeclaredField("doubleCloseCheck");
    field.setAccessible(true);
    field.set(testClass, true);

    field = testClass.getClass().getDeclaredField("logicallyClosed");
    field.setAccessible(true);
    field.set(testClass, true);

    field = testClass.getClass().getDeclaredField("doubleCloseException");
    field.setAccessible(true);
    field.set(testClass, "fakeexception");
    mockLogger.error((String) anyObject(), anyObject());
    expectLastCall().once();

    mockPool.releaseConnection((Connection) anyObject());
    expectLastCall().once().andThrow(new SQLException()).once();
    replay(mockLogger, mockPool);

    testClass.close();
  }
  /**
   * Tests obtaining internal connection.
   *
   * @throws SQLException
   * @throws ClassNotFoundException
   */
  @Test
  public void testObtainInternalConnection() throws SQLException, ClassNotFoundException {
    expect(mockPool.getConfig()).andReturn(config).anyTimes();

    testClass.url = "jdbc:mock:driver";
    config.setAcquireRetryDelay(1);
    CustomHook testHook = new CustomHook();
    config.setConnectionHook(testHook);
    // make it fail the first time and succeed the second time
    expect(mockPool.obtainRawInternalConnection())
        .andThrow(new SQLException())
        .once()
        .andReturn(mockConnection)
        .once();
    replay(mockPool);
    testClass.obtainInternalConnection();
    // get counts on our hooks

    assertEquals(1, testHook.fail);
    assertEquals(1, testHook.acquire);

    // Test 2: Same thing but without the hooks
    reset(mockPool);
    expect(mockPool.getConfig()).andReturn(config).anyTimes();
    expect(mockPool.obtainRawInternalConnection())
        .andThrow(new SQLException())
        .once()
        .andReturn(mockConnection)
        .once();
    count = 1;
    config.setConnectionHook(null);
    replay(mockPool);
    assertEquals(mockConnection, testClass.obtainInternalConnection());

    // Test 3: Keep failing
    reset(mockPool);
    expect(mockPool.getConfig()).andReturn(config).anyTimes();
    expect(mockPool.obtainRawInternalConnection()).andThrow(new SQLException()).anyTimes();
    replay(mockPool);
    count = 99;
    config.setAcquireRetryAttempts(2);
    try {
      testClass.obtainInternalConnection();
      fail("Should have thrown an exception");
    } catch (SQLException e) {
      // expected behaviour
    }

    //	Test 4: Get signalled to interrupt fail delay
    count = 99;
    config.setAcquireRetryAttempts(2);
    config.setAcquireRetryDelay(7000);
    final Thread currentThread = Thread.currentThread();

    try {
      new Thread(
              new Runnable() {

                //				@Override
                public void run() {
                  while (!currentThread.getState().equals(State.TIMED_WAITING)) {
                    try {
                      Thread.sleep(50);
                    } catch (InterruptedException e) {
                      e.printStackTrace();
                    }
                  }
                  currentThread.interrupt();
                }
              })
          .start();
      testClass.obtainInternalConnection();
      fail("Should have thrown an exception");
    } catch (SQLException e) {
      // expected behaviour
    }
    config.setAcquireRetryDelay(10);
  }