/** * Copyright 2010 Wallace Wadge * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.jolbox.bonecp; import static org.easymock.EasyMock.anyLong; import static org.easymock.EasyMock.anyObject; import static org.easymock.EasyMock.expect; import static org.easymock.EasyMock.expectLastCall; import static org.easymock.EasyMock.makeThreadSafe; import static org.easymock.EasyMock.replay; import static org.easymock.EasyMock.reset; import static org.easymock.EasyMock.verify; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.lang.Thread.State; import java.lang.reflect.Array; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement; import java.util.Map; import java.util.Properties; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.locks.Lock; import javax.management.InstanceAlreadyExistsException; import javax.management.InstanceNotFoundException; import javax.management.MBeanRegistrationException; import javax.management.MBeanServer; import javax.management.NotCompliantMBeanException; import javax.management.ObjectInstance; import javax.management.ObjectName; import javax.sql.DataSource; import junit.framework.Assert; import org.easymock.EasyMock; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.slf4j.Logger; import com.jolbox.bonecp.hooks.AcquireFailConfig; import com.jolbox.bonecp.hooks.ConnectionHook; import com.jolbox.bonecp.hooks.ConnectionState; import com.jolbox.bonecp.hooks.CustomHook; /** * @author wwadge * */ @SuppressWarnings("resource") public class TestBoneCP { /** Class under test. */ private BoneCP testClass; /** Mock handle. */ private BoneCPConfig mockConfig; /** Mock handle. */ private ConnectionPartition mockPartition; /** Mock handle. */ private ScheduledExecutorService mockKeepAliveScheduler; /** Mock handle. */ private ExecutorService mockConnectionsScheduler; /** Mock handle. */ private LinkedBlockingQueue<ConnectionHandle> mockConnectionHandles; /** Mock handle. */ private ConnectionHandle mockConnection; /** Mock handle. */ private Lock mockLock; /** Mock handle. */ private Logger mockLogger; /** Mock handle. */ private DatabaseMetaData mockDatabaseMetadata; /** Mock handle. */ private MockResultSet mockResultSet; /** Fake database driver. */ private MockJDBCDriver driver; private BoneCP mockPool; /** * Reset the mocks. * @throws IllegalAccessException * @throws IllegalArgumentException * @throws SQLException * @throws NoSuchFieldException * @throws SecurityException * @throws CloneNotSupportedException */ @Before @SuppressWarnings({ "unchecked", "deprecation" }) public void before() throws IllegalArgumentException, IllegalAccessException, SQLException, SecurityException, NoSuchFieldException, CloneNotSupportedException{ driver = new MockJDBCDriver(new MockJDBCAnswer() { public Connection answer() throws SQLException { return new MockConnection(); } }); mockConfig = EasyMock.createNiceMock(BoneCPConfig.class); expect(mockConfig.clone()).andReturn(mockConfig).anyTimes(); expect(mockConfig.getPartitionCount()).andReturn(2).anyTimes(); expect(mockConfig.getMaxConnectionsPerPartition()).andReturn(1).anyTimes(); expect(mockConfig.getMinConnectionsPerPartition()).andReturn(1).anyTimes(); expect(mockConfig.getIdleConnectionTestPeriodInMinutes()).andReturn(0L).anyTimes(); expect(mockConfig.getIdleMaxAgeInMinutes()).andReturn(1000L).anyTimes(); expect(mockConfig.getUsername()).andReturn(CommonTestUtils.username).anyTimes(); expect(mockConfig.getPassword()).andReturn(CommonTestUtils.password).anyTimes(); expect(mockConfig.getJdbcUrl()).andReturn(CommonTestUtils.url).anyTimes(); expect(mockConfig.getReleaseHelperThreads()).andReturn(1).once().andReturn(0).anyTimes(); expect(mockConfig.getStatementReleaseHelperThreads()).andReturn(1).once().andReturn(0).anyTimes(); expect(mockConfig.getInitSQL()).andReturn(CommonTestUtils.TEST_QUERY).anyTimes(); expect(mockConfig.isCloseConnectionWatch()).andReturn(true).anyTimes(); expect(mockConfig.isLogStatementsEnabled()).andReturn(true).anyTimes(); expect(mockConfig.getConnectionTimeoutInMs()).andReturn(Long.MAX_VALUE).anyTimes(); expect(mockConfig.getServiceOrder()).andReturn("LIFO").anyTimes(); mockConfig.sanitize(); expectLastCall().anyTimes(); expect(mockConfig.getAcquireRetryDelayInMs()).andReturn(1000L).anyTimes(); expect(mockConfig.getPoolName()).andReturn("poolName").anyTimes(); expect(mockConfig.getPoolAvailabilityThreshold()).andReturn(20).anyTimes(); replay(mockConfig); // once for no {statement, connection} release threads, once with release threads.... testClass = new BoneCP(mockConfig); testClass = new BoneCP(mockConfig); Field field = testClass.getClass().getDeclaredField("partitions"); field.setAccessible(true); ConnectionPartition[] partitions = (ConnectionPartition[]) field.get(testClass); // if all ok assertEquals(2, partitions.length); // switch to our mock version now mockPartition = EasyMock.createNiceMock(ConnectionPartition.class); Array.set(field.get(testClass), 0, mockPartition); Array.set(field.get(testClass), 1, mockPartition); mockKeepAliveScheduler = EasyMock.createNiceMock(ScheduledExecutorService.class); field = testClass.getClass().getDeclaredField("keepAliveScheduler"); field.setAccessible(true); field.set(testClass, mockKeepAliveScheduler); field = testClass.getClass().getDeclaredField("connectionsScheduler"); field.setAccessible(true); mockConnectionsScheduler = EasyMock.createNiceMock(ExecutorService.class); field.set(testClass, mockConnectionsScheduler); mockConnectionHandles = EasyMock.createNiceMock(LinkedBlockingQueue.class); mockConnection = EasyMock.createNiceMock(ConnectionHandle.class); mockLock = EasyMock.createNiceMock(Lock.class); mockLogger = TestUtils.mockLogger(testClass.getClass()); makeThreadSafe(mockLogger, true); mockDatabaseMetadata = EasyMock.createNiceMock(DatabaseMetaData.class); mockResultSet = EasyMock.createNiceMock(MockResultSet.class); mockLogger.error((String)anyObject(), anyObject()); expectLastCall().anyTimes(); mockPool = EasyMock.createNiceMock(BoneCP.class); reset(mockConfig, mockKeepAliveScheduler, mockConnectionsScheduler, mockPartition, mockConnectionHandles, mockConnection, mockLock); } /** * @throws SQLException */ @After public void teardown() throws SQLException{ driver.disable(); } /** * Test method for {@link com.jolbox.bonecp.BoneCP#shutdown()}. * @throws IllegalAccessException * @throws NoSuchFieldException * @throws IllegalArgumentException * @throws SecurityException */ @Test public void testShutdown() throws SecurityException, IllegalArgumentException, NoSuchFieldException, IllegalAccessException { testShutdownClose(true); } /** Tests obtaining internal connection. * @throws SQLException * @throws ClassNotFoundException * @throws InterruptedException */ @Test public void testObtainInternalConnection() throws SQLException, ClassNotFoundException, InterruptedException{ expect(this.mockPool.getConfig()).andReturn(mockConfig).anyTimes(); DataSource mockDataSourceBean = EasyMock.createNiceMock(DataSource.class); expect(this.mockConfig.getDatasourceBean()).andReturn(mockDataSourceBean).anyTimes(); expect(mockConfig.getJdbcUrl()).andReturn("jdbc:mock:driver").anyTimes(); mockConfig.setAcquireRetryDelayInMs(1); CustomHook testHook = new CustomHook(); expect(mockConfig.getConnectionHook()).andReturn(testHook).anyTimes(); // make it fail the first time and succeed the second time expect(this.mockPool.getDbIsDown()).andReturn(new AtomicBoolean()).anyTimes(); expect(mockDataSourceBean.getConnection()).andThrow(new SQLException()).once().andReturn(null).once(); // a call in obtainRaw expect(mockConnection.getInternalConnection()).andReturn(new MockConnection()).anyTimes(); // a call in obtainRaw replay(this.mockPool, mockConfig, mockDataSourceBean, mockConnection); this.testClass.obtainInternalConnection(mockConnection); // get counts on our hooks assertEquals(1, testHook.fail); assertEquals(1, testHook.acquire); // Test 2: Same thing but without the hooks reset(this.mockPool, mockDataSourceBean); expect(this.mockPool.getDbIsDown()).andReturn(new AtomicBoolean()).anyTimes(); expect(this.mockPool.getConfig()).andReturn(mockConfig).anyTimes(); expect(mockDataSourceBean.getConnection()).andThrow(new SQLException()).once().andReturn(this.mockConnection).once(); int count=1; mockConfig.setConnectionHook(null); replay(this.mockPool, mockDataSourceBean); assertEquals(this.mockConnection, this.testClass.obtainInternalConnection(mockConnection)); // Test 3: Keep failing reset(this.mockPool, mockDataSourceBean); expect(this.mockPool.getConfig()).andReturn(mockConfig).anyTimes(); expect(mockDataSourceBean.getConnection()).andThrow(new SQLException()).anyTimes(); replay(this.mockPool, mockDataSourceBean); count=99; mockConfig.setAcquireRetryAttempts(2); try{ this.testClass.obtainInternalConnection(mockConnection); fail("Should have thrown an exception"); } catch (SQLException e){ // expected behaviour } // Test 4: Get signalled to interrupt fail delay count=99; mockConfig.setAcquireRetryAttempts(2); mockConfig.setAcquireRetryDelayInMs(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(); this.testClass.obtainInternalConnection(mockConnection); fail("Should have thrown an exception"); } catch (SQLException e){ // expected behaviour } // Test: No acquire delay reset(this.mockPool, mockDataSourceBean, mockConfig); expect(this.mockPool.getConfig()).andReturn(mockConfig).anyTimes(); expect(mockDataSourceBean.getConnection()).andThrow(new SQLException()).anyTimes(); mockConfig.setAcquireRetryAttempts(0); replay(this.mockPool, mockDataSourceBean, mockConfig); count=99; try{ this.testClass.obtainInternalConnection(mockConnection); fail("Should have thrown an exception"); } catch (SQLException e){ // expected behaviour } mockConfig.setAcquireRetryDelayInMs(10); // Test: coverage /* PowerMock.mockStatic(Thread.class); Thread.sleep(anyLong()); expectLastCall().andThrow(new InterruptedException()).anyTimes(); PowerMock.replay(Thread.class); reset(this.mockPool, mockDataSourceBean); expect(this.mockPool.getConfig()).andReturn(mockConfig).anyTimes(); expect(mockDataSourceBean.getConnection()).andThrow(new SQLException()).anyTimes(); replay(this.mockPool, mockDataSourceBean); count=99; mockConfig.setAcquireRetryAttempts(2); try{ this.testClass.obtainInternalConnection(mockConnection); fail("Should have thrown an exception"); } catch (SQLException e){ // expected behaviour } */ } /** * @throws SQLException */ @Test public void testObtainInternalConnectionWithFailingInitSQL() throws SQLException { DataSource mockDataSourceBean = EasyMock.createNiceMock(DataSource.class); // Test: Fail in sending out init connection reset(mockConfig, mockDataSourceBean); reset(mockConnection); expect(mockConnection.getInternalConnection()).andReturn(new MockConnection()).anyTimes(); // a call in obtainRaw expect(this.mockConfig.getDatasourceBean()).andReturn(mockDataSourceBean).anyTimes(); expect(mockConfig.getJdbcUrl()).andReturn("jdbc:mock:driver").anyTimes(); expect(mockDataSourceBean.getConnection()).andReturn(mockConnection).once(); // a call in obtainRaw expect(mockConfig.getInitSQL()).andReturn("Foo").anyTimes(); Statement mockStatement = EasyMock.createNiceMock(Statement.class); expect(mockConnection.createStatement()).andReturn(mockStatement).anyTimes(); expect(mockStatement.execute((String)anyObject())).andThrow(new SQLException()); mockConnection.close(); expectLastCall().once(); // this is what we're testing replay(mockConfig, mockDataSourceBean, mockConnection, mockStatement); try { this.testClass.obtainInternalConnection(mockConnection); fail("Should have thrown an exception"); } catch (SQLException e) { //normal case verify(mockConnection); } } /** * Tests shutdown/close method. * @param doShutdown call shutdown or call close * @throws NoSuchFieldException * @throws SecurityException * @throws IllegalAccessException * @throws IllegalArgumentException */ private void testShutdownClose(boolean doShutdown) throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException { expect(mockConfig.isDeregisterDriverOnClose()).andReturn(false).anyTimes(); expect(mockConfig.isDisableJMX()).andReturn(false).anyTimes(); expect(mockConfig.getPoolName()).andReturn("foo").anyTimes(); expect(mockKeepAliveScheduler.shutdownNow()).andReturn(null).once(); expect(mockConnectionsScheduler.shutdownNow()).andReturn(null).once(); // expect(mockConnectionHandles.poll()).andReturn(null).once(); expect(mockPartition.getFreeConnections()).andReturn(mockConnectionHandles).anyTimes(); ExecutorService mockReleaseHelper = EasyMock.createNiceMock(ExecutorService.class); replay(mockConfig, mockConnectionsScheduler, mockKeepAliveScheduler, mockPartition, mockConnectionHandles, mockReleaseHelper); if (doShutdown){ testClass.shutdown(); } else { testClass.close(); } verify(mockConnectionsScheduler, mockKeepAliveScheduler, mockPartition, mockConnectionHandles); } /** * Tests shutdown/close method coverage. * @throws InterruptedException */ @Test public void testShutdownCoverageClose() throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException, InterruptedException { expect(mockConnectionsScheduler.awaitTermination(5, TimeUnit.SECONDS)).andThrow(new InterruptedException()).once(); replay(mockConnectionsScheduler); try{ testClass.shutdown(); } catch(Exception e){ // do nothing } } /** * Test method for {@link com.jolbox.bonecp.BoneCP#close()}. * @throws IllegalAccessException * @throws NoSuchFieldException * @throws IllegalArgumentException * @throws SecurityException */ @Test public void testClose() throws SecurityException, IllegalArgumentException, NoSuchFieldException, IllegalAccessException { testClass.poolShuttingDown=false; testShutdownClose(false); } // /** // * Test method. // * @throws SQLException // */ // @Test // public void testTerminateAllConnections() throws SQLException { // // expect(mockConnectionHandles.poll()).andReturn(mockConnection).times(2).andReturn(null).once(); // mockConnection.destroyConnection(); // expectLastCall().once().andThrow(new SQLException()).once(); // expect(mockPartition.getFreeConnections()).andReturn(mockConnectionHandles).anyTimes(); // expect(mockConnection.getOriginatingPartition()).andReturn(mockPartition).anyTimes(); // Connection mockRealConnection = EasyMock.createNiceMock(Connection.class); // expect(mockConnection.getInternalConnection()).andReturn(mockRealConnection).anyTimes(); // replay(mockRealConnection, mockConnectionsScheduler, mockKeepAliveScheduler, mockPartition, mockConnectionHandles, mockConnection); // // // test. // testClass.connectionStrategy.terminateAllConnections(); // verify(mockConnectionsScheduler, mockKeepAliveScheduler, mockPartition, mockConnectionHandles, mockConnection); // } /** * Test method for. * @throws SQLException */ @Test public void testTerminateAllConnections2() throws SQLException { Connection mockRealConnection = EasyMock.createNiceMock(Connection.class); // same test but to cover the finally section reset(mockRealConnection, mockConnectionsScheduler, mockKeepAliveScheduler, mockPartition, mockConnectionHandles, mockConnection); expect(mockPartition.getFreeConnections()).andThrow(new RuntimeException()).once(); expect(mockConnection.getOriginatingPartition()).andReturn(mockPartition).anyTimes(); replay(mockRealConnection, mockConnectionsScheduler, mockKeepAliveScheduler, mockPartition, mockConnectionHandles, mockConnection); // test. try{ testClass.connectionStrategy.terminateAllConnections(); fail("Should throw exception"); } catch (RuntimeException e){ // do nothing } verify(mockConnectionsScheduler, mockKeepAliveScheduler, mockPartition, mockConnectionHandles, mockConnection); } /** * Mostly for coverage. */ @Test public void testPostDestroyConnection(){ Connection mockRealConnection = EasyMock.createNiceMock(Connection.class); reset(mockConnection); expect(mockConnection.getOriginatingPartition()).andReturn(mockPartition).anyTimes(); mockPartition.updateCreatedConnections(-1); expectLastCall().once(); mockPartition.setUnableToCreateMoreTransactions(false); expectLastCall().once(); ConnectionHook mockConnectionHook = EasyMock.createNiceMock(ConnectionHook.class); expect(mockConnection.getConnectionHook()).andReturn(mockConnectionHook).anyTimes(); expect(mockConnection.getInternalConnection()).andReturn(mockRealConnection).anyTimes(); mockConnectionHook.onDestroy(mockConnection); expectLastCall().once(); replay(mockRealConnection, mockConnectionHook, mockConnection); testClass.postDestroyConnection(mockConnection); verify(mockConnectionHook, mockConnection); } /** * Test method for {@link com.jolbox.bonecp.BoneCP#getConnection()}. * @throws SQLException * @throws InterruptedException * @throws IllegalAccessException * @throws IllegalArgumentException * @throws NoSuchFieldException * @throws SecurityException */ @Test public void testGetConnection() throws SQLException, InterruptedException, IllegalArgumentException, IllegalAccessException, SecurityException, NoSuchFieldException { // Test 1: Get connection - normal state expect(mockPartition.isUnableToCreateMoreTransactions()).andReturn(true).once(); expect(mockPartition.getFreeConnections()).andReturn(mockConnectionHandles).anyTimes(); expect(mockPartition.getAvailableConnections()).andReturn(1).anyTimes(); expect(mockConnectionHandles.poll()).andReturn(mockConnection).once(); mockConnection.renewConnection(); expectLastCall().once(); replay(mockPartition, mockConnectionHandles, mockConnection); assertEquals(mockConnection, testClass.getConnection()); verify(mockPartition, mockConnectionHandles, mockConnection); } /** * Test method for {@link com.jolbox.bonecp.BoneCP#getConnection()}. * @throws SQLException * @throws InterruptedException * @throws IllegalAccessException * @throws IllegalArgumentException * @throws NoSuchFieldException * @throws SecurityException */ @Test public void testGetConnectionWithTimeout() throws SQLException, InterruptedException, IllegalArgumentException, IllegalAccessException, SecurityException, NoSuchFieldException { expect(mockPartition.isUnableToCreateMoreTransactions()).andReturn(true).once(); expect(mockPartition.getFreeConnections()).andReturn(mockConnectionHandles).anyTimes(); expect(mockConnectionHandles.poll()).andReturn(null).anyTimes(); replay(mockPartition, mockConnectionHandles, mockConnection); try{ testClass.getConnection(); fail("Should have thrown an exception"); } catch (SQLException e){ // do nothing } verify(mockPartition, mockConnectionHandles, mockConnection); } /** * Test method. * @throws SQLException * @throws InterruptedException * @throws IllegalAccessException * @throws IllegalArgumentException * @throws NoSuchFieldException * @throws SecurityException */ @Test public void testGetRawConnectionViaDataSourceBean() throws SQLException, InterruptedException, IllegalArgumentException, IllegalAccessException, SecurityException, NoSuchFieldException { DataSource mockDataSource = EasyMock.createNiceMock(DataSource.class); expect(mockDataSource.getConnection()).andReturn(mockConnection).once(); expect(mockConfig.getJdbcUrl()).andReturn("").once().andReturn("jdbc:mock:foo").times(2); expect(mockConfig.getUsername()).andReturn(null).anyTimes(); expect(mockConfig.getDatasourceBean()).andReturn(mockDataSource).once().andReturn(null).times(2); testClass.clientInfo = new Properties(); // coverage replay(mockConfig, mockDataSource); testClass.obtainRawInternalConnection(); // 2nd path testClass.jvmMajorVersion=5; testClass.obtainRawInternalConnection(); testClass.clientInfo = null; testClass.obtainRawInternalConnection(); // coverage verify(mockConfig, mockDataSource); } /** * Test method. * @throws SQLException * @throws InterruptedException * @throws IllegalAccessException * @throws IllegalArgumentException * @throws NoSuchFieldException * @throws SecurityException */ @Test public void testGetRawConnectionWithExternalAuth() throws SQLException, InterruptedException, IllegalArgumentException, IllegalAccessException, SecurityException, NoSuchFieldException { testClass.config = mockConfig; expect(mockConfig.isExternalAuth()).andReturn(true).once(); expect(mockConfig.getDatasourceBean()).andReturn(null).once(); expect(mockConfig.getJdbcUrl()).andReturn(CommonTestUtils.url).once(); replay(mockConfig); assertNotNull(testClass.obtainRawInternalConnection()); verify(mockConfig); // coverage reset(mockConfig); expect(mockConfig.isExternalAuth()).andReturn(false).once(); expect(mockConfig.getDriverProperties()).andReturn(new Properties()).once(); expect(mockConfig.getDatasourceBean()).andReturn(null).once(); expect(mockConfig.getJdbcUrl()).andReturn(CommonTestUtils.url).once(); replay(mockConfig); assertNotNull(testClass.obtainRawInternalConnection()); verify(mockConfig); } @Test public void testGetRawConnectionCoverage() throws SQLException, InterruptedException, IllegalArgumentException, IllegalAccessException, SecurityException, NoSuchFieldException { testClass.config = mockConfig; testClass.driverInitialized = false; // coverage reset(mockConfig); expect(mockConfig.isExternalAuth()).andReturn(false).once(); expect(mockConfig.getDriverProperties()).andReturn(new Properties()).once(); expect(mockConfig.getDatasourceBean()).andReturn(null).once(); expect(mockConfig.getJdbcUrl()).andReturn(CommonTestUtils.url).once(); replay(mockConfig); assertNotNull(testClass.obtainRawInternalConnection()); verify(mockConfig); // coverage of exception driver.setMockJDBCAnswer(new MockJDBCAnswer() { public Connection answer() throws SQLException { throw new SQLException(); } }); reset(mockConfig); expect(mockConfig.isExternalAuth()).andReturn(false).once(); expect(mockConfig.getDriverProperties()).andReturn(new Properties()).once(); expect(mockConfig.getDatasourceBean()).andReturn(null).once(); expect(mockConfig.getJdbcUrl()).andReturn(CommonTestUtils.url).once(); replay(mockConfig); try{ testClass.obtainRawInternalConnection(); } catch (SQLException e){ // nothing } driver.unregister(); } /** * Test method. * @throws SQLException * @throws InterruptedException * @throws IllegalAccessException * @throws IllegalArgumentException * @throws NoSuchFieldException * @throws SecurityException */ @Test public void testGetConnectionViaDriverProperties() throws SQLException, InterruptedException, IllegalArgumentException, IllegalAccessException, SecurityException, NoSuchFieldException { // DataSource mockDataSource = EasyMock.createNiceMock(DataSource.class); // expect(mockDataSource.getConnection()).andReturn(mockConnection).once(); expect(mockConfig.getDriverProperties()).andReturn(new Properties()).once().andReturn(null).once(); expect(mockConfig.getDatasourceBean()).andReturn(null).anyTimes(); expect(mockConfig.getJdbcUrl()).andReturn(CommonTestUtils.url).anyTimes(); expect(mockConfig.isExternalAuth()).andReturn(true).once().andReturn(false).once(); replay(mockConfig); testClass.obtainRawInternalConnection(); testClass.obtainRawInternalConnection(); // coverage verify(mockConfig); } /** * Test method. * @throws SQLException * @throws InterruptedException * @throws IllegalAccessException * @throws IllegalArgumentException * @throws NoSuchFieldException * @throws SecurityException */ @Test public void testGetConnectionViaDataSourceBeanWithPass() throws SQLException, InterruptedException, IllegalArgumentException, IllegalAccessException, SecurityException, NoSuchFieldException { DataSource mockDataSource = EasyMock.createNiceMock(DataSource.class); expect(mockDataSource.getConnection((String)anyObject(), (String)anyObject())).andReturn(mockConnection).once(); expect(mockConfig.getJdbcUrl()).andReturn("").once(); expect(mockConfig.getUsername()).andReturn("username").once(); expect(mockConfig.getPassword()).andReturn(null).once(); expect(mockConfig.getDatasourceBean()).andReturn(mockDataSource).once(); replay(mockConfig, mockDataSource); testClass.obtainRawInternalConnection(); verify(mockConfig, mockDataSource); } /** * Attempting to fetch a connection from a pool that is marked as being shut down should throw an exception */ @Test public void testGetConnectionOnShutdownPool() { // Test #8: testClass.poolShuttingDown = true; try{ testClass.getConnection(); fail("Should have thrown an exception"); } catch (SQLException e){ // do nothing } } /** Like test 6, except we fake an unchecked exception to make sure our locks are released. * @throws NoSuchFieldException * @throws IllegalAccessException */ @Test public void testGetConnectionUncheckedExceptionTriggeredWhileWaiting() throws NoSuchFieldException, IllegalAccessException { reset(mockPartition, mockConnectionHandles, mockConnection); expect(mockPartition.isUnableToCreateMoreTransactions()).andReturn(false).anyTimes(); expect(mockPartition.getFreeConnections()).andReturn(mockConnectionHandles).anyTimes(); expect(mockPartition.getMaxConnections()).andReturn(0).anyTimes(); // cause a division by zero error replay(mockPartition, mockConnectionHandles, mockConnection, mockLock); try{ testClass.getConnection(); fail("Should have thrown an exception"); } catch (Throwable t){ // do nothing } verify(mockPartition, mockConnectionHandles, mockConnection, mockLock); } /** If we hit our limit, we should signal for more connections to be created on the fly * @throws SQLException */ @Test public void testGetConnectionLimitsHit() throws SQLException { reset(mockPartition, mockConnectionHandles, mockConnection); expect(mockConfig.getPoolAvailabilityThreshold()).andReturn(0).anyTimes(); expect(mockPartition.isUnableToCreateMoreTransactions()).andReturn(false).anyTimes(); expect(mockPartition.getFreeConnections()).andReturn(mockConnectionHandles).anyTimes(); expect(mockPartition.getMaxConnections()).andReturn(10).anyTimes(); expect(mockPartition.getAvailableConnections()).andReturn(1).anyTimes(); BlockingQueue<Object> bq = new ArrayBlockingQueue<Object>(1); bq.add(new Object()); expect(mockPartition.getPoolWatchThreadSignalQueue()).andReturn(bq); // mockPartition.almostFullSignal(); // expectLastCall().once(); expect(mockConnectionHandles.poll()).andReturn(mockConnection).once(); mockConnection.renewConnection(); expectLastCall().once(); replay(mockPartition, mockConnectionHandles, mockConnection); testClass.getConnection(); verify(mockPartition, mockConnectionHandles, mockConnection); } /** Connection queues are starved of free connections. Should block and wait on one without spin-locking. * @throws NoSuchFieldException * @throws IllegalAccessException * @throws InterruptedException * @throws SQLException */ @Test public void testGetConnectionConnectionQueueStarved() throws NoSuchFieldException, IllegalAccessException, InterruptedException, SQLException { reset(mockPartition, mockConnectionHandles, mockConnection); expect(mockPartition.isUnableToCreateMoreTransactions()).andReturn(true).once(); expect(mockPartition.getFreeConnections()).andReturn(mockConnectionHandles).anyTimes(); expect(mockConnectionHandles.poll(Long.MAX_VALUE, TimeUnit.MILLISECONDS)).andReturn(mockConnection).once(); mockConnection.renewConnection(); expectLastCall().once(); replay(mockPartition, mockConnectionHandles, mockConnection); assertEquals(mockConnection, testClass.getConnection()); verify(mockPartition, mockConnectionHandles, mockConnection); } /** Simulate an interrupted exception elsewhere. * @throws NoSuchFieldException * @throws IllegalAccessException * @throws InterruptedException */ @Test public void testGetConnectionSimulateInterruptedException2() throws NoSuchFieldException, IllegalAccessException, InterruptedException { reset(mockPartition, mockConnectionHandles, mockConnection); expect(mockPartition.isUnableToCreateMoreTransactions()).andReturn(true).once(); expect(mockPartition.getFreeConnections()).andReturn(mockConnectionHandles).anyTimes(); expect(mockConnectionHandles.poll()).andReturn(null).once(); expect(mockConnectionHandles.poll(Long.MAX_VALUE, TimeUnit.MILLISECONDS)).andThrow(new InterruptedException()).once(); replay(mockPartition, mockConnectionHandles, mockConnection); try{ testClass.getConnection(); fail("Should have throw an SQL Exception"); } catch (SQLException e){ // do nothing } verify(mockPartition, mockConnectionHandles, mockConnection); } /** Simulate an interrupted exception elsewhere. * @throws NoSuchFieldException * @throws IllegalAccessException * @throws InterruptedException */ @Test public void testGetConnectionSimulateInterruptedExceptionWithNullReturn() throws NoSuchFieldException, IllegalAccessException, InterruptedException { reset(mockPartition, mockConnectionHandles, mockConnection); expect(mockPartition.isUnableToCreateMoreTransactions()).andReturn(true).once(); expect(mockPartition.getFreeConnections()).andReturn(mockConnectionHandles).anyTimes(); testClass.nullOnConnectionTimeout = true; expect(mockConnectionHandles.poll()).andReturn(null).once(); expect(mockConnectionHandles.poll(Long.MAX_VALUE, TimeUnit.MILLISECONDS)).andThrow(new InterruptedException()).once(); replay(mockPartition, mockConnectionHandles, mockConnection); try{ assertNull(testClass.getConnection()); } catch (SQLException e){ fail("Should not have throw an SQL Exception"); // do nothing } verify(mockPartition, mockConnectionHandles, mockConnection); } /** Test #3: Like test #2 but simulate an interrupted exception * @throws NoSuchFieldException * @throws IllegalAccessException * @throws InterruptedException */ @Test public void testGetConnectionSimulateInterruptedException() throws NoSuchFieldException, IllegalAccessException, InterruptedException { reset(mockPartition, mockConnectionHandles, mockConnection); expect(mockPartition.getMaxConnections()).andReturn(100).anyTimes(); expect(mockPartition.getFreeConnections()).andReturn(mockConnectionHandles).anyTimes(); expect(mockConnectionHandles.poll(Long.MAX_VALUE, TimeUnit.MILLISECONDS)).andThrow(new InterruptedException()).once(); BlockingQueue<Object> bq = new ArrayBlockingQueue<Object>(1); bq.add(new Object()); expect(mockPartition.getPoolWatchThreadSignalQueue()).andReturn(bq); replay(mockPartition, mockConnectionHandles, mockConnection); try{ testClass.getConnection(); fail("Should have throw an SQL Exception"); } catch (SQLException e){ // do nothing } verify(mockPartition, mockConnectionHandles, mockConnection); } /** Test #3: Like test #2 but simulate an interrupted exception * @throws NoSuchFieldException * @throws IllegalAccessException * @throws InterruptedException */ @Test public void testGetConnectionWithNullReturn() throws NoSuchFieldException, IllegalAccessException, InterruptedException { reset(mockPartition, mockConnectionHandles, mockConnection); expect(mockPartition.getMaxConnections()).andReturn(100).anyTimes(); expect(mockPartition.getFreeConnections()).andReturn(mockConnectionHandles).anyTimes(); expect(mockConnectionHandles.poll(Long.MAX_VALUE, TimeUnit.MILLISECONDS)).andReturn(null).once(); BlockingQueue<Object> bq = new ArrayBlockingQueue<Object>(1); bq.add(new Object()); testClass.nullOnConnectionTimeout = true; expect(mockPartition.getPoolWatchThreadSignalQueue()).andReturn(bq); replay(mockPartition, mockConnectionHandles, mockConnection); try{ assertNull(testClass.getConnection()); } catch (SQLException e){ fail("Should have throw an SQL Exception"); // do nothing } verify(mockPartition, mockConnectionHandles, mockConnection); } /** Get connection, not finding any available block to wait for one * @throws InterruptedException * @throws SQLException */ @Test public void testGetConnectionBlockOnUnavailable() throws InterruptedException, SQLException { reset(mockPartition, mockConnectionHandles, mockConnection); expect(mockPartition.isUnableToCreateMoreTransactions()).andReturn(true).once(); expect(mockPartition.getFreeConnections()).andReturn(mockConnectionHandles).anyTimes(); expect(mockPartition.getAvailableConnections()).andReturn(1).anyTimes(); expect(mockConnectionHandles.poll()).andReturn(null).once(); expect(mockConnectionHandles.poll(Long.MAX_VALUE, TimeUnit.MILLISECONDS)).andReturn(mockConnection).once(); mockConnection.renewConnection(); expectLastCall().once(); replay(mockPartition, mockConnectionHandles, mockConnection); assertEquals(mockConnection, testClass.getConnection()); verify(mockPartition, mockConnectionHandles, mockConnection); } /** Test obtaining a connection asynchronously. * @throws InterruptedException * @throws ExecutionException */ @Test public void testGetAsyncConnection() throws InterruptedException, ExecutionException{ expect(mockPartition.isUnableToCreateMoreTransactions()).andReturn(true).once(); expect(mockPartition.getFreeConnections()).andReturn(mockConnectionHandles).anyTimes(); expect(mockPartition.getAvailableConnections()).andReturn(1).anyTimes(); expect(mockConnectionHandles.poll()).andReturn(mockConnection).once(); mockConnection.renewConnection(); expectLastCall().once(); replay(mockPartition, mockConnectionHandles, mockConnection); assertEquals(mockConnection, testClass.getAsyncConnection().get()); verify(mockPartition, mockConnectionHandles, mockConnection); } /** * Test method for {@link com.jolbox.bonecp.BoneCP#releaseConnection(java.sql.Connection)}. * @throws SQLException * @throws IllegalAccessException * @throws IllegalArgumentException * @throws NoSuchFieldException * @throws SecurityException * @throws InterruptedException */ @Test public void testReleaseConnection() throws SQLException, IllegalArgumentException, IllegalAccessException, SecurityException, NoSuchFieldException, InterruptedException { // Test #1: Test releasing connections directly expect(mockConnection.isPossiblyBroken()).andReturn(false).once(); expect(mockConnection.getOriginatingPartition()).andReturn(mockPartition).anyTimes(); expect(mockPartition.getFreeConnections()).andReturn(mockConnectionHandles).anyTimes(); expect(mockPartition.getAvailableConnections()).andReturn(1).anyTimes(); // expect(mockConnectionHandles.offer(mockConnection)).andReturn(true).once(); // should reset last connection use mockConnection.setConnectionLastUsedInMs(anyLong()); expectLastCall().once(); Connection mockRealConnection = EasyMock.createNiceMock(Connection.class); expect(mockConnection.getInternalConnection()).andReturn(mockRealConnection).anyTimes(); replay(mockRealConnection, mockConnection, mockPartition, mockConnectionHandles); testClass.releaseConnection(mockConnection); verify(mockConnection, mockPartition, mockConnectionHandles); reset(mockConnection, mockPartition, mockConnectionHandles); } /** * Test method for {@link com.jolbox.bonecp.BoneCP#internalReleaseConnection(ConnectionHandle)}. * @throws InterruptedException * @throws SQLException */ @Test public void testInternalReleaseConnection() throws InterruptedException, SQLException { // Test #1: Test normal case where connection is considered to be not broken // should reset last connection use mockConnection.setConnectionLastUsedInMs(anyLong()); expectLastCall().once(); expect(mockConnection.getOriginatingPartition()).andReturn(mockPartition).anyTimes(); expect(mockPartition.getFreeConnections()).andReturn(mockConnectionHandles).anyTimes(); expect(mockPartition.getAvailableConnections()).andReturn(1).anyTimes(); Connection mockRealConnection = EasyMock.createNiceMock(Connection.class); expect(mockConnection.getInternalConnection()).andReturn(mockRealConnection).anyTimes(); // expect(mockConnectionHandles.offer(mockConnection)).andReturn(false).anyTimes(); expect(mockConnectionHandles.offer(mockConnection)).andReturn(true).once(); replay(mockRealConnection, mockConnection,mockPartition, mockConnectionHandles); testClass.internalReleaseConnection(mockConnection); verify(mockConnection,mockPartition, mockConnectionHandles); } /** * Test method for {@link com.jolbox.bonecp.BoneCP#internalReleaseConnection(ConnectionHandle)}. * @throws InterruptedException * @throws SQLException */ @Test public void testInternalReleaseConnectionWhereConnectionIsBroken() throws InterruptedException, SQLException { // Test case where connection is broken mockConnection.logicallyClosed = new AtomicBoolean(false); reset(mockConnection,mockPartition, mockConnectionHandles); expect(mockConnection.isPossiblyBroken()).andReturn(true).once(); expect(mockConfig.getConnectionTestStatement()).andReturn(null).once(); // make it fail to return false expect(mockConnection.getMetaData()).andThrow(new SQLException()).once(); expect(mockConnection.getOriginatingPartition()).andReturn(mockPartition).anyTimes(); // we're about to destroy this connection, so we can create new ones. mockPartition.setUnableToCreateMoreTransactions(false); expectLastCall().once(); // break out from the next method, we're not interested in it expect(mockPartition.isUnableToCreateMoreTransactions()).andReturn(true).once(); Connection mockRealConnection = EasyMock.createNiceMock(Connection.class); expect(mockConnection.getInternalConnection()).andReturn(mockRealConnection).anyTimes(); replay(mockPartition, mockConnection); testClass.internalReleaseConnection(mockConnection); verify(mockPartition, mockConnection); } /** * Test method for {@link com.jolbox.bonecp.BoneCP#internalReleaseConnection(ConnectionHandle)}. * @throws InterruptedException * @throws SQLException */ @Test public void testInternalReleaseConnectionWhereConnectionIsMarkedBrokenButConnectionTestSucceeds() throws InterruptedException, SQLException { // Test case where connection is broken mockConnection.logicallyClosed = new AtomicBoolean(false); reset(mockConnection,mockPartition, mockConnectionHandles); expect(mockConnection.isPossiblyBroken()).andReturn(true).once(); expect(mockConfig.getConnectionTestStatement()).andReturn(null).once(); expect(mockConnection.getMetaData()).andReturn(EasyMock.createNiceMock(DatabaseMetaData.class)).once(); expect(mockPartition.getFreeConnections()).andReturn(mockConnectionHandles).anyTimes(); expect(mockPartition.getAvailableConnections()).andReturn(1).anyTimes(); expect(mockConnection.getOriginatingPartition()).andReturn(mockPartition).anyTimes(); Connection mockRealConnection = EasyMock.createNiceMock(Connection.class); expect(mockConnection.getInternalConnection()).andReturn(mockRealConnection).anyTimes(); replay(mockPartition, mockConnection); testClass.internalReleaseConnection(mockConnection); verify(mockPartition, mockConnection); } /** * Test method for {@link com.jolbox.bonecp.BoneCP#internalReleaseConnection(ConnectionHandle)}. * @throws InterruptedException * @throws SQLException */ @Test public void testInternalReleaseConnectionWherePoolisShuttingDown() throws InterruptedException, SQLException { mockConnection.logicallyClosed = new AtomicBoolean(false); reset(mockConnection,mockPartition, mockConnectionHandles); expect(mockConnection.getOriginatingPartition()).andReturn(mockPartition).anyTimes(); Connection mockRealConnection = EasyMock.createNiceMock(Connection.class); expect(mockConnection.getInternalConnection()).andReturn(mockRealConnection).anyTimes(); mockConnection.internalClose(); expectLastCall().once(); replay(mockPartition, mockConnection); testClass.poolShuttingDown = true; testClass.internalReleaseConnection(mockConnection); testClass.poolShuttingDown = false; verify(mockPartition, mockConnection); } /** * Test method for {@link com.jolbox.bonecp.BoneCP#internalReleaseConnection(ConnectionHandle)}. * * @throws InterruptedException * @throws SQLException */ @Test public void testInternalReleaseConnectionWhereConnectionIsExpired() throws InterruptedException, SQLException { // Test case where connection is expired reset(mockConnection, mockPartition, mockConnectionHandles); Connection mockRealConnection = EasyMock.createNiceMock(Connection.class); expect(mockConnection.getInternalConnection()).andReturn(mockRealConnection).anyTimes(); // return a partition expect(mockConnection.getOriginatingPartition()).andReturn(mockPartition).anyTimes(); // break out from this method, we're not interested in it expect(mockPartition.isUnableToCreateMoreTransactions()).andReturn(true).once(); expect(mockConnection.isExpired()).andReturn(true).anyTimes(); mockConnection.internalClose(); expectLastCall(); replay(mockPartition, mockConnection, mockRealConnection); testClass.internalReleaseConnection(mockConnection); verify(mockPartition, mockConnection, mockRealConnection); } /** * Test method for {@link com.jolbox.bonecp.BoneCP#putConnectionBackInPartition(com.jolbox.bonecp.ConnectionHandle)}. * @throws InterruptedException * @throws SQLException */ @Test public void testPutConnectionBackInPartition() throws InterruptedException, SQLException { expect(mockPartition.getFreeConnections()).andReturn(mockConnectionHandles).anyTimes(); expect(mockPartition.getAvailableConnections()).andReturn(1).anyTimes(); Connection mockRealConnection = EasyMock.createNiceMock(Connection.class); expect(mockConnection.getInternalConnection()).andReturn(mockRealConnection).anyTimes(); expect(mockConnection.getOriginatingPartition()).andReturn(mockPartition).anyTimes(); expect(mockConnectionHandles.offer(mockConnection)).andReturn(true).once(); replay(mockRealConnection, mockPartition, mockConnectionHandles, mockConnection); testClass.putConnectionBackInPartition(mockConnection); // FIXME // assertEquals(2, ai.get()); verify(mockPartition, mockConnectionHandles); } /** * Test method for {@link com.jolbox.bonecp.BoneCP#putConnectionBackInPartition(com.jolbox.bonecp.ConnectionHandle)}. * @throws InterruptedException * @throws SQLException */ @Test public void testPutConnectionBackInPartitionWithResetConnectionOnClose() throws InterruptedException, SQLException { expect(mockPartition.getFreeConnections()).andReturn(mockConnectionHandles).anyTimes(); expect(mockPartition.getAvailableConnections()).andReturn(1).anyTimes(); expect(mockConnection.getOriginatingPartition()).andReturn(mockPartition).anyTimes(); expect(mockConnectionHandles.offer(mockConnection)).andReturn(true).once(); expect(mockConnection.isTxResolved()).andReturn(false).once(); Connection mockInternalConnection = EasyMock.createNiceMock(Connection.class); expect(mockInternalConnection.getAutoCommit()).andReturn(false).once(); expect(mockConnection.getInternalConnection()).andReturn(mockInternalConnection).anyTimes(); mockInternalConnection.rollback(); mockInternalConnection.setAutoCommit(true); replay(mockInternalConnection, mockPartition, mockConnectionHandles, mockConnection); testClass.resetConnectionOnClose = true; testClass.putConnectionBackInPartition(mockConnection); verify(mockPartition, mockConnectionHandles); } /** * Test method for com.jolbox.bonecp.BoneCP isConnectionHandleAlive. * @throws SQLException */ @Test public void testIsConnectionHandleAlive() throws SQLException { // Test 1: Normal case (+ without connection test statement) expect(mockConfig.getConnectionTestStatement()).andReturn(null).once(); mockConnection.logicallyClosed=new AtomicBoolean(); expect(mockConnection.getMetaData()).andReturn(mockDatabaseMetadata).once(); expect(mockDatabaseMetadata.getTables((String)anyObject(), (String)anyObject(), (String)anyObject(), (String[])anyObject())).andReturn(mockResultSet).once(); mockResultSet.close(); expectLastCall().once(); replay(mockConfig, mockConnection, mockDatabaseMetadata, mockResultSet); assertTrue(testClass.isConnectionHandleAlive(mockConnection)); verify(mockConfig, mockConnection, mockResultSet,mockDatabaseMetadata); } /** * Test method for com.jolbox.bonecp.BoneCP isConnectionHandleAlive. * @throws SQLException */ @Test public void testIsConnectionHandleAliveTriggerException() throws SQLException { // Test 2: Same test as testIsConnectionHandleAlive but triggers an exception reset(mockConfig, mockConnection, mockDatabaseMetadata, mockResultSet); expect(mockConfig.getConnectionTestStatement()).andReturn(null).once(); expect(mockConnection.getMetaData()).andThrow(new SQLException()).once(); mockConnection.logicallyClosed = new AtomicBoolean(false); replay(mockConfig, mockConnection, mockDatabaseMetadata, mockResultSet); assertFalse(testClass.isConnectionHandleAlive(mockConnection)); verify(mockConfig, mockConnection, mockResultSet,mockDatabaseMetadata); } /** * Test method for com.jolbox.bonecp.BoneCP isConnectionHandleAlive. * @throws SQLException */ @Test public void testIsConnectionHandleAliveNormalCaseWithConnectionTestStatement() throws SQLException { // Test 3: Normal case (+ with connection test statement) reset(mockConfig, mockConnection, mockDatabaseMetadata, mockResultSet); Statement mockStatement = EasyMock.createNiceMock(Statement.class); expect(mockConfig.getConnectionTestStatement()).andReturn("whatever").once(); expect(mockConnection.createStatement()).andReturn(mockStatement).once(); expect(mockStatement.execute((String)anyObject())).andReturn(true).once(); // mockResultSet.close(); // expectLastCall().once(); mockConnection.logicallyClosed = new AtomicBoolean(true); replay(mockConfig, mockConnection, mockDatabaseMetadata,mockStatement); assertTrue(testClass.isConnectionHandleAlive(mockConnection)); verify(mockConfig, mockConnection,mockDatabaseMetadata, mockStatement); } /** * Test method for com.jolbox.bonecp.BoneCP isConnectionHandleAlive. * @throws SQLException */ @Test public void testIsConnectionHandleAliveNormalCaseWithConnectionTestTriggerException() throws SQLException { Statement mockStatement = EasyMock.createNiceMock(Statement.class); // Test 4: Same like test testIsConnectionHandleAliveNormalCaseWithConnectionTestStatement but triggers exception reset(mockConfig, mockConnection, mockDatabaseMetadata, mockResultSet); expect(mockConfig.getConnectionTestStatement()).andReturn("whatever").once(); expect(mockConnection.createStatement()).andReturn(mockStatement).once(); expect(mockStatement.execute((String)anyObject())).andThrow(new RuntimeException()).once(); mockStatement.close(); expectLastCall().once(); replay(mockConfig, mockConnection, mockDatabaseMetadata,mockStatement, mockResultSet); // assertFalse(testClass.isConnectionHandleAlive(mockConnection)); try{ mockConnection.logicallyClosed = new AtomicBoolean(true);// (code coverage) testClass.isConnectionHandleAlive(mockConnection); fail("Should have thrown an exception"); } catch (RuntimeException e){ // do nothing } verify(mockConfig, mockConnection, mockResultSet,mockDatabaseMetadata, mockStatement); } /** * Test method for com.jolbox.bonecp.BoneCP isConnectionHandleAlive. * @throws SQLException */ @Test public void testIsConnectionHandleAliveNormalCaseWithConnectionTestTriggerExceptionInFinally() throws SQLException { Statement mockStatement = EasyMock.createNiceMock(Statement.class); // Test 5: Same like test testIsConnectionHandleAliveNormalCaseWithConnectionTestTriggerException // but triggers exception in finally block reset(mockConfig, mockConnection, mockDatabaseMetadata, mockResultSet); expect(mockConfig.getConnectionTestStatement()).andReturn("whatever").once(); expect(mockConnection.createStatement()).andReturn(mockStatement).once(); expect(mockStatement.execute((String)anyObject())).andThrow(new RuntimeException()).once(); mockStatement.close(); expectLastCall().andThrow(new SQLException()).once(); mockConnection.logicallyClosed = new AtomicBoolean(false); replay(mockConfig, mockConnection, mockDatabaseMetadata,mockStatement, mockResultSet); try{ testClass.isConnectionHandleAlive(mockConnection); fail("Should have thrown an exception"); } catch (RuntimeException e){ // do nothing } verify(mockConfig, mockConnection, mockResultSet,mockDatabaseMetadata, mockStatement); } /** * Test method for maybeSignalForMoreConnections(com.jolbox.bonecp.ConnectionPartition)}. * @throws SecurityException * @throws NoSuchMethodException * @throws IllegalArgumentException * @throws IllegalAccessException * @throws InvocationTargetException */ @Test public void testMaybeSignalForMoreConnections() throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException{ expect(mockPartition.isUnableToCreateMoreTransactions()).andReturn(false).once(); expect(mockPartition.getFreeConnections()).andReturn(mockConnectionHandles).anyTimes(); // expect(mockConnectionHandles.size()).andReturn(1).anyTimes(); expect(mockPartition.getAvailableConnections()).andReturn(1).anyTimes(); expect(mockPartition.getMaxConnections()).andReturn(10).anyTimes(); BlockingQueue<Object> bq = new ArrayBlockingQueue<Object>(1); expect(mockPartition.getPoolWatchThreadSignalQueue()).andReturn(bq).anyTimes(); // mockPartition.lockAlmostFullLock(); // expectLastCall().once(); // mockPartition.almostFullSignal(); // expectLastCall().once(); // mockPartition.unlockAlmostFullLock(); // expectLastCall().once(); replay(mockPartition, mockConnectionHandles); Method method = testClass.getClass().getDeclaredMethod("maybeSignalForMoreConnections", ConnectionPartition.class); method.setAccessible(true); method.invoke(testClass, new Object[]{mockPartition}); verify(mockPartition, mockConnectionHandles); } /** * Test method for maybeSignalForMoreConnections(com.jolbox.bonecp.ConnectionPartition)}. * @throws SecurityException * @throws NoSuchMethodException * @throws IllegalArgumentException * @throws IllegalAccessException * @throws InvocationTargetException */ @Test public void testMaybeSignalForMoreConnectionsWithException() throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException{ BlockingQueue<Object> bq = new ArrayBlockingQueue<Object>(1); Method method = testClass.getClass().getDeclaredMethod("maybeSignalForMoreConnections", ConnectionPartition.class); method.setAccessible(true); // Test 2, same test but fake an exception reset(mockPartition, mockConnectionHandles); expect(mockPartition.getPoolWatchThreadSignalQueue()).andReturn(bq).anyTimes(); expect(mockPartition.isUnableToCreateMoreTransactions()).andReturn(false).anyTimes(); expect(mockPartition.getFreeConnections()).andReturn(mockConnectionHandles).anyTimes(); expect(mockConnectionHandles.size()).andReturn(1).anyTimes(); expect(mockPartition.getMaxConnections()).andReturn(10).anyTimes(); // mockPartition.lockAlmostFullLock(); // expectLastCall().once(); // mockPartition.almostFullSignal(); // expectLastCall().andThrow(new RuntimeException()).once(); // mockPartition.unlockAlmostFullLock(); // expectLastCall().once(); replay(mockPartition, mockConnectionHandles); try{ method.invoke(testClass, new Object[]{mockPartition}); fail("Should have thrown an exception"); } catch (Throwable t){ // do nothing } verify(mockPartition, mockConnectionHandles); } /** * Test method for {@link com.jolbox.bonecp.BoneCP#getTotalLeased()}. */ @Test public void testGetTotalLeased() { expect(mockPartition.getCreatedConnections()).andReturn(5).anyTimes(); expect(mockPartition.getFreeConnections()).andReturn(mockConnectionHandles).anyTimes(); expect(mockPartition.getAvailableConnections()).andReturn(3).anyTimes(); replay(mockPartition, mockConnectionHandles); ConnectionPartition cp = testClass.partitions[1]; assertEquals(4, testClass.getTotalLeased()); testClass.partitions[1] = null; // test safety assertEquals(2, testClass.getTotalLeased()); verify(mockPartition, mockConnectionHandles); } /** * Test method for {@link com.jolbox.bonecp.BoneCP#getTotalFree()}. */ @Test public void testGetTotalFree() { expect(mockPartition.getFreeConnections()).andReturn(mockConnectionHandles).anyTimes(); expect(mockPartition.getAvailableConnections()).andReturn(3).anyTimes(); // expect(mockConnectionHandles.size()).andReturn(3).anyTimes(); replay(mockPartition, mockConnectionHandles); assertEquals(6, testClass.getTotalFree()); testClass.partitions[1] = null; // test safety assertEquals(3, testClass.getTotalFree()); verify(mockPartition, mockConnectionHandles); } /** * Test method for {@link com.jolbox.bonecp.BoneCP#getTotalCreatedConnections()}. */ @Test public void testGetTotalCreatedConnections() { expect(mockPartition.getCreatedConnections()).andReturn(5).anyTimes(); replay(mockPartition); assertEquals(10, testClass.getTotalCreatedConnections()); testClass.partitions[1] = null; // test safety assertEquals(5, testClass.getTotalCreatedConnections()); verify(mockPartition); } /** * Test method for {@link com.jolbox.bonecp.BoneCP#getConfig()}. */ @Test public void testGetConfig() { assertEquals(mockConfig, testClass.getConfig()); } /** * Coverage. * @throws SQLException * @throws CloneNotSupportedException * @throws ClassNotFoundException */ @SuppressWarnings("resource") @Test public void testCoverage() throws SQLException, CloneNotSupportedException, ClassNotFoundException{ BoneCPConfig config = EasyMock.createNiceMock(BoneCPConfig.class); expect(config.isLazyInit()).andReturn(true).anyTimes(); expect(config.isDisableJMX()).andReturn(true).anyTimes(); expect(config.getJdbcUrl()).andReturn(CommonTestUtils.url).anyTimes(); expect(config.getMinConnectionsPerPartition()).andReturn(2).anyTimes(); expect(config.getMaxConnectionsPerPartition()).andReturn(20).anyTimes(); expect(config.getPartitionCount()).andReturn(1).anyTimes(); expect(config.getServiceOrder()).andReturn("LIFO").anyTimes(); expect(config.getMaxConnectionAgeInSeconds()).andReturn(100000L).anyTimes(); expect(config.clone()).andThrow(new CloneNotSupportedException()).once().andReturn(config).once(); replay(config); try{ new BoneCP(config); fail("Should throw exception because clone throws a fake exception"); } catch(SQLException e){ // nothing } new BoneCP(config); } @Test public void testIdleThreadsStartCoverage() throws SQLException, CloneNotSupportedException, ClassNotFoundException{ BoneCPConfig config = EasyMock.createNiceMock(BoneCPConfig.class); expect(config.isLazyInit()).andReturn(true).anyTimes(); expect(config.isDisableJMX()).andReturn(true).anyTimes(); expect(config.getJdbcUrl()).andReturn(CommonTestUtils.url).anyTimes(); expect(config.getMinConnectionsPerPartition()).andReturn(2).anyTimes(); expect(config.getMaxConnectionsPerPartition()).andReturn(20).anyTimes(); expect(config.getPartitionCount()).andReturn(1).anyTimes(); expect(config.getServiceOrder()).andReturn("LIFO").anyTimes(); expect(config.getMaxConnectionAgeInSeconds()).andReturn(100000L).anyTimes(); expect(config.clone()).andReturn(config).anyTimes(); expect(config.getIdleConnectionTestPeriod((TimeUnit)anyObject())).andReturn(5L).times(2).andReturn(0L).times(2); expect(config.getIdleMaxAge(TimeUnit.SECONDS)).andReturn(0L).times(2).andReturn(4L).times(2); reset(mockKeepAliveScheduler); replay(config, mockKeepAliveScheduler); BoneCP pool = new BoneCP(config); // test idleConnectionTestPeriod > 0. max age = 0 // assertEquals(1, pool.keepAliveScheduler.shutdownNow().size()); pool = new BoneCP(config); // test idleConnectionTestPeriod = 0. max age > 0 // assertEquals(1, pool.keepAliveScheduler.shutdownNow().size()); verify(config, mockKeepAliveScheduler); } @Test public void testIdleThreadsStart2Coverage() throws SQLException, CloneNotSupportedException, ClassNotFoundException{ BoneCPConfig config = EasyMock.createNiceMock(BoneCPConfig.class); expect(config.isLazyInit()).andReturn(true).anyTimes(); expect(config.isDisableJMX()).andReturn(true).anyTimes(); expect(config.getJdbcUrl()).andReturn(CommonTestUtils.url).anyTimes(); expect(config.getMinConnectionsPerPartition()).andReturn(2).anyTimes(); expect(config.getMaxConnectionsPerPartition()).andReturn(20).anyTimes(); expect(config.getPartitionCount()).andReturn(1).anyTimes(); expect(config.getServiceOrder()).andReturn("LIFO").anyTimes(); expect(config.getMaxConnectionAgeInSeconds()).andReturn(100000L).anyTimes(); expect(config.clone()).andReturn(config).anyTimes(); expect(config.getIdleConnectionTestPeriod((TimeUnit)anyObject())).andReturn(5L).anyTimes(); expect(config.getIdleMaxAge(TimeUnit.SECONDS)).andReturn(4L).anyTimes(); reset(mockKeepAliveScheduler); replay(config, mockKeepAliveScheduler); BoneCP pool = new BoneCP(config); // test idleConnectionTestPeriod > 0. max age > 0 assertEquals(1, pool.keepAliveScheduler.shutdownNow().size()); verify(config, mockKeepAliveScheduler); } @Test public void testDetectJVMVersion() throws ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException, CloneNotSupportedException, SQLException{ // AtomicInteger ai = new AtomicInteger(); // final Connection connection = EasyMock.createNiceMock(Connection.class); expect(mockConfig.clone()).andReturn(mockConfig).anyTimes(); expect(mockConfig.getPartitionCount()).andReturn(2).anyTimes(); expect(mockConfig.getMaxConnectionsPerPartition()).andReturn(1).anyTimes(); expect(mockConfig.getMinConnectionsPerPartition()).andReturn(1).anyTimes(); expect(mockConfig.getIdleConnectionTestPeriodInMinutes()).andReturn(0L).anyTimes(); expect(mockConfig.getIdleMaxAgeInMinutes()).andReturn(1000L).anyTimes(); expect(mockConfig.getUsername()).andReturn(CommonTestUtils.username).anyTimes(); expect(mockConfig.getPassword()).andReturn(CommonTestUtils.password).anyTimes(); expect(mockConfig.getJdbcUrl()).andReturn(CommonTestUtils.url).anyTimes(); expect(mockConfig.getInitSQL()).andReturn(CommonTestUtils.TEST_QUERY).anyTimes(); expect(mockConfig.isCloseConnectionWatch()).andReturn(true).anyTimes(); expect(mockConfig.isLogStatementsEnabled()).andReturn(true).anyTimes(); expect(mockConfig.getConnectionTimeoutInMs()).andReturn(Long.MAX_VALUE).anyTimes(); expect(mockConfig.getServiceOrder()).andReturn("LIFO").anyTimes(); expect(mockConfig.getClassLoader()).andReturn(this.getClass().getClassLoader()).anyTimes(); mockConfig.sanitize(); expectLastCall().anyTimes(); expect(mockConfig.getAcquireRetryDelayInMs()).andReturn(1000L).anyTimes(); expect(mockConfig.getPoolName()).andReturn("poolName").anyTimes(); expect(mockConfig.getPoolAvailabilityThreshold()).andReturn(20).anyTimes(); replay(mockConfig); BoneCP.connectionClass = FakeTestClassJDK5.class.getCanonicalName(); BoneCP pool = new BoneCP(mockConfig); assertEquals(5, pool.jvmMajorVersion); BoneCP.connectionClass = FakeTestClassJDK6.class.getCanonicalName(); pool = new BoneCP(mockConfig); assertEquals(6, pool.jvmMajorVersion); BoneCP.connectionClass = FakeTestClassJDK7.class.getCanonicalName(); pool = new BoneCP(mockConfig); assertEquals(7, pool.jvmMajorVersion); } /** JMX setup test * @throws SecurityException * @throws NoSuchFieldException * @throws IllegalArgumentException * @throws IllegalAccessException * @throws InstanceAlreadyExistsException * @throws MBeanRegistrationException * @throws NotCompliantMBeanException * @throws InstanceNotFoundException */ @Test public void testJMXRegister() throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException, InstanceAlreadyExistsException, MBeanRegistrationException, NotCompliantMBeanException, InstanceNotFoundException{ MBeanServer mockMbs = EasyMock.createNiceMock(MBeanServer.class); Field field = testClass.getClass().getDeclaredField("mbs"); field.setAccessible(true); field.set(testClass, mockMbs); expect(mockConfig.getPoolName()).andReturn(null).anyTimes(); ObjectInstance mockInstance = EasyMock.createNiceMock(ObjectInstance.class); expect(mockMbs.isRegistered((ObjectName)anyObject())).andReturn(false).anyTimes(); expect(mockMbs.registerMBean(anyObject(), (ObjectName)anyObject())).andReturn(mockInstance).once().andThrow(new InstanceAlreadyExistsException()).once(); replay(mockMbs, mockInstance, mockConfig); testClass.registerUnregisterJMX(true); verify(mockMbs); } @Test public void testJMXUnregisterNoName() throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException, InstanceAlreadyExistsException, MBeanRegistrationException, NotCompliantMBeanException, InstanceNotFoundException{ MBeanServer mockMbs = EasyMock.createNiceMock(MBeanServer.class); Field field = testClass.getClass().getDeclaredField("mbs"); field.setAccessible(true); field.set(testClass, mockMbs); expect(mockConfig.getPoolName()).andReturn(null).anyTimes(); ObjectInstance mockInstance = EasyMock.createNiceMock(ObjectInstance.class); reset(mockMbs, mockInstance, mockConfig); expect(mockMbs.isRegistered((ObjectName)anyObject())).andReturn(true).anyTimes(); mockMbs.unregisterMBean((ObjectName)anyObject()); replay(mockMbs, mockInstance, mockConfig); testClass.registerUnregisterJMX(false); verify(mockMbs); } /** Test for different pool names. * @throws SecurityException * @throws NoSuchFieldException * @throws IllegalArgumentException * @throws IllegalAccessException * @throws InstanceAlreadyExistsException * @throws MBeanRegistrationException * @throws NotCompliantMBeanException */ @Test public void testJMXRegisterWithName() throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException, InstanceAlreadyExistsException, MBeanRegistrationException, NotCompliantMBeanException{ MBeanServer mockMbs = EasyMock.createNiceMock(MBeanServer.class); Field field = testClass.getClass().getDeclaredField("mbs"); field.setAccessible(true); field.set(testClass, mockMbs); expect(mockConfig.getPoolName()).andReturn("poolName").anyTimes(); ObjectInstance mockInstance = EasyMock.createNiceMock(ObjectInstance.class); expect(mockMbs.isRegistered((ObjectName)anyObject())).andReturn(false).anyTimes(); expect(mockMbs.registerMBean(anyObject(), (ObjectName)anyObject())).andReturn(mockInstance).once().andThrow(new InstanceAlreadyExistsException()).once(); replay(mockMbs, mockInstance, mockConfig); testClass.registerUnregisterJMX(true); verify(mockMbs); } /** Test for different pool names. * @throws SecurityException * @throws NoSuchFieldException * @throws IllegalArgumentException * @throws IllegalAccessException * @throws InstanceAlreadyExistsException * @throws MBeanRegistrationException * @throws NotCompliantMBeanException * @throws InstanceNotFoundException */ @Test public void testJMXUnRegisterWithName() throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException, InstanceAlreadyExistsException, MBeanRegistrationException, NotCompliantMBeanException, InstanceNotFoundException{ MBeanServer mockMbs = EasyMock.createNiceMock(MBeanServer.class); Field field = testClass.getClass().getDeclaredField("mbs"); field.setAccessible(true); field.set(testClass, mockMbs); field = testClass.getClass().getDeclaredField("config"); field.setAccessible(true); field.set(testClass, mockConfig); expect(mockConfig.getPoolName()).andReturn("poolName").anyTimes(); ObjectInstance mockInstance = EasyMock.createNiceMock(ObjectInstance.class); expect(mockMbs.isRegistered((ObjectName)anyObject())).andReturn(true).anyTimes(); mockMbs.unregisterMBean((ObjectName)anyObject()); expectLastCall().times(2).andThrow(new InstanceNotFoundException()).once(); replay(mockMbs, mockInstance, mockConfig); testClass.registerUnregisterJMX(false); testClass.registerUnregisterJMX(false); // should trigger an exception verify(mockMbs); } /** * @throws SecurityException * @throws NoSuchMethodException * @throws IllegalArgumentException * @throws IllegalAccessException * @throws InvocationTargetException */ @Test public void testCaptureException() throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException{ Method method = testClass.getClass().getDeclaredMethod("captureStackTrace", String.class); method.setAccessible(true); try{ method.invoke(testClass); fail("Should throw an exception"); } catch (Exception e){ // do nothing } } /** Tests for watch connection. * @throws SecurityException * @throws NoSuchMethodException * @throws IllegalArgumentException * @throws IllegalAccessException * @throws InvocationTargetException * @throws NoSuchFieldException */ @Test public void testWatchConnection() throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException, NoSuchFieldException{ Field field = testClass.getClass().getDeclaredField("closeConnectionExecutor"); field.setAccessible(true); ExecutorService mockExecutor = EasyMock.createNiceMock(ExecutorService.class); field.set(testClass, mockExecutor); Method method = testClass.getClass().getDeclaredMethod("watchConnection", ConnectionHandle.class); method.setAccessible(true); expect(mockExecutor.submit((CloseThreadMonitor) anyObject())).andReturn(null).once(); replay(mockExecutor); method.invoke(testClass, mockConnection); verify(mockExecutor); // Test #2: Code coverage method.invoke(testClass, new Object[]{null}); } /** * */ @Test public void testUnregisterDriver() { expect(mockConfig.isDeregisterDriverOnClose()).andReturn(true).anyTimes(); expect(mockConfig.getJdbcUrl()).andReturn("jdbc:mock").anyTimes(); replay(mockConfig); try { Assert.assertNotNull(DriverManager.getDriver("jdbc:mock")); } catch (SQLException e1) { fail("SQLException thrown"); } testClass.unregisterDriver(); testClass.unregisterDriver(); // should log a message (nothing to unregister) } }