/** * 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.provider; import static org.easymock.EasyMock.*; import static com.jolbox.bonecp.provider.BoneCPConnectionProvider.CONFIG_CONNECTION_DRIVER_CLASS; import static com.jolbox.bonecp.provider.BoneCPConnectionProvider.CONFIG_CONNECTION_PASSWORD; import static com.jolbox.bonecp.provider.BoneCPConnectionProvider.CONFIG_CONNECTION_URL; import static com.jolbox.bonecp.provider.BoneCPConnectionProvider.CONFIG_CONNECTION_USERNAME; import static org.easymock.EasyMock.anyObject; import static org.easymock.EasyMock.expectLastCall; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.fail; import java.lang.reflect.Field; import java.sql.Connection; import java.sql.SQLException; import java.util.Properties; import org.hibernate.HibernateException; import org.junit.After; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import com.jolbox.bonecp.BoneCP; import com.jolbox.bonecp.BoneCPConfig; import com.jolbox.bonecp.ConnectionHandle; import com.jolbox.bonecp.MockConnection; import com.jolbox.bonecp.MockJDBCAnswer; import com.jolbox.bonecp.MockJDBCDriver; /** Test case for the Hibernate boneCP connection provider. * @author wallacew * */ public class TestBoneCPConnectionProvider { /** Mock handle. */ private static BoneCP mockPool; /** Mock handle. */ private static ConnectionHandle mockConnection; /** Mock handle. */ private static Properties mockProperties; /** Class under test. */ private static BoneCPConnectionProvider testClass; /** hsqldb driver. */ private static String URL = "jdbc:mock"; /** hsqldb username. */ private static String USERNAME = "sa"; /** hsqldb password. */ private static String PASSWORD = ""; /** hsqldb driver. */ private static String DRIVER = "com.jolbox.bonecp.MockJDBCDriver"; /** A dummy query for HSQLDB. */ public static final String TEST_QUERY = "SELECT 1 FROM INFORMATION_SCHEMA.SYSTEM_USERS"; /** Mock driver handler. */ private MockJDBCDriver driver; /** Class setup. * @throws SecurityException * @throws NoSuchFieldException * @throws IllegalArgumentException * @throws IllegalAccessException * @throws ClassNotFoundException */ @BeforeClass public static void setup() throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException, ClassNotFoundException { mockPool = createNiceMock(BoneCP.class); mockConnection = createNiceMock(ConnectionHandle.class); mockProperties = createNiceMock(Properties.class); } /** * Mock reset. * @throws IllegalAccessException * @throws IllegalArgumentException * @throws NoSuchFieldException * @throws SecurityException * @throws SQLException */ @Before public void before() throws IllegalArgumentException, IllegalAccessException, SecurityException, NoSuchFieldException, SQLException{ testClass = new BoneCPConnectionProvider(); // wire in our mock Field field = testClass.getClass().getDeclaredField("pool"); field.setAccessible(true); field.set(testClass, mockPool); reset(mockPool, mockConnection, mockProperties); // load the driver. this.driver = new MockJDBCDriver(new MockJDBCAnswer() { public Connection answer() throws SQLException { return new MockConnection(); } }); } /** * Cleanup * @throws SQLException */ @After public void deregisterDriver() throws SQLException{ if (this.driver != null){ this.driver.unregister(); } } /** * Test method for {@link com.jolbox.bonecp.provider.BoneCPConnectionProvider#close()}. */ @Test public void testClose() { mockPool.shutdown(); expectLastCall().once(); replay(mockPool); testClass.close(); verify(mockPool); } /** * Test method for {@link com.jolbox.bonecp.provider.BoneCPConnectionProvider#closeConnection(java.sql.Connection)}. * @throws SQLException */ @Test public void testCloseConnection() throws SQLException { mockConnection.close(); expectLastCall().once(); replay(mockPool); testClass.closeConnection(mockConnection); verify(mockPool); } /** * Test method for {@link com.jolbox.bonecp.provider.BoneCPConnectionProvider#configure(java.util.Properties)}. * @throws NoSuchFieldException * @throws SecurityException * @throws IllegalAccessException * @throws IllegalArgumentException * @throws NoSuchMethodException * @throws ClassNotFoundException * @throws SQLException */ @Test @SuppressWarnings("deprecation") public void testConfigure() throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException, NoSuchMethodException, ClassNotFoundException, SQLException { Class.forName("com.jolbox.bonecp.MockJDBCDriver"); expect(mockProperties.getProperty("bonecp.statementsCacheSize")).andReturn("40").anyTimes(); expect(mockProperties.getProperty("bonecp.minConnectionsPerPartition")).andReturn("20").anyTimes(); expect(mockProperties.getProperty("bonecp.maxConnectionsPerPartition")).andReturn("50").anyTimes(); expect(mockProperties.getProperty("bonecp.acquireIncrement")).andReturn("5").anyTimes(); expect(mockProperties.getProperty("bonecp.partitionCount")).andReturn("5").anyTimes(); expect(mockProperties.getProperty("bonecp.releaseHelperThreads")).andReturn("3").anyTimes(); expect(mockProperties.getProperty("bonecp.idleConnectionTestPeriod")).andReturn("60").anyTimes(); expect(mockProperties.getProperty("bonecp.idleMaxAge")).andReturn("240").anyTimes(); expect(mockProperties.getProperty("javax.persistence.jdbc.url")).andReturn(URL).anyTimes(); expect(mockProperties.getProperty("javax.persistence.jdbc.user")).andReturn(USERNAME).anyTimes(); expect(mockProperties.getProperty("javax.persistence.jdbc.password")).andReturn(PASSWORD).anyTimes(); expect(mockProperties.getProperty("javax.persistence.jdbc.driver")).andReturn(DRIVER).anyTimes(); expect(mockProperties.getProperty("bonecp.connectionHookClassName")).andReturn("com.jolbox.bonecp.provider.CustomHook").anyTimes(); expect(mockProperties.getProperty("bonecp.connectionTestStatement")).andReturn(TEST_QUERY).anyTimes(); expect(mockProperties.getProperty("bonecp.initSQL")).andReturn(TEST_QUERY).anyTimes(); expect(mockProperties.getProperty("bonecp.logStatementsEnabled")).andReturn("true").anyTimes(); BoneCPConnectionProvider partialTestClass = createMockBuilder(BoneCPConnectionProvider.class).addMockedMethod( BoneCPConnectionProvider.class.getDeclaredMethod("createPool", BoneCPConfig.class)).createMock(); expect(partialTestClass.createPool((BoneCPConfig)anyObject())).andReturn(mockPool).once(); replay(mockProperties, partialTestClass); partialTestClass.configure(mockProperties); // fetch the configuration object and check that everything is as we passed BoneCPConfig config = partialTestClass.getConfig(); assertEquals(40, config.getStatementsCacheSize()); // assertEquals(30, config.getStatementsCachedPerConnection()); assertEquals(20, config.getMinConnectionsPerPartition()); assertEquals(50, config.getMaxConnectionsPerPartition()); assertEquals(5, config.getAcquireIncrement()); assertEquals(5, config.getPartitionCount()); assertEquals(3, config.getReleaseHelperThreads()); assertEquals(60, config.getIdleConnectionTestPeriodInMinutes()); assertEquals(240, config.getIdleMaxAgeInMinutes()); assertEquals(URL, config.getJdbcUrl()); assertEquals(USERNAME, config.getUsername()); assertEquals(PASSWORD, config.getPassword()); assertEquals(TEST_QUERY, config.getInitSQL()); assertEquals(true, config.isLogStatementsEnabled()); verify(mockProperties, partialTestClass); reset(mockProperties); expect(mockProperties.getProperty(CONFIG_CONNECTION_DRIVER_CLASS)).andReturn(null).anyTimes(); replay(mockProperties); try{ testClass.configure(mockProperties); fail("Should have failed with exception"); } catch (HibernateException e){ // do nothing } reset(mockProperties); expect(mockProperties.getProperty(CONFIG_CONNECTION_DRIVER_CLASS)).andReturn(DRIVER).anyTimes(); expect(mockProperties.getProperty(CONFIG_CONNECTION_URL, "JDBC URL NOT SET IN CONFIG")).andReturn("somethinginvalid").anyTimes(); expect(mockProperties.getProperty(CONFIG_CONNECTION_USERNAME, "username not set")).andReturn(USERNAME).anyTimes(); expect(mockProperties.getProperty(CONFIG_CONNECTION_PASSWORD, "password not set")).andReturn(PASSWORD).anyTimes(); replay(mockProperties); try{ testClass.configure(mockProperties); fail("Should have failed with exception"); } catch (HibernateException e){ // do nothing } verify(mockProperties); reset(mockProperties); expect(mockProperties.getProperty(CONFIG_CONNECTION_DRIVER_CLASS)).andReturn("somethingbad").anyTimes(); expect(mockProperties.getProperty(CONFIG_CONNECTION_URL, "JDBC URL NOT SET IN CONFIG")).andReturn("somethinginvalid").anyTimes(); expect(mockProperties.getProperty(CONFIG_CONNECTION_USERNAME, "username not set")).andReturn(USERNAME).anyTimes(); expect(mockProperties.getProperty(CONFIG_CONNECTION_PASSWORD, "password not set")).andReturn(PASSWORD).anyTimes(); replay(mockProperties); try{ testClass.configure(mockProperties); fail("Should have failed with exception"); } catch (HibernateException e){ // do nothing } testClass.setClassLoader(getClass().getClassLoader()); testClass.loadClass("java.lang.String"); testClass.setClassLoader(this.getClass().getClassLoader()); assertEquals(this.getClass().getClassLoader(), testClass.getClassLoader()); // coverage stuff reset(mockProperties); expect(mockProperties.getProperty("bonecp.partitionCount")).andReturn("something bad"); expect(mockProperties.getProperty("bonecp.logStatementsEnabled")).andReturn("something bad"); expect(mockProperties.getProperty("bonecp.idleMaxAge")).andReturn("something bad"); replay(mockProperties); try{ testClass.configure(mockProperties); fail("Should have failed with exception"); } catch (HibernateException e){ // do nothing } } /** * Test method for {@link com.jolbox.bonecp.provider.BoneCPConnectionProvider#createPool(BoneCPConfig)}. * @throws SQLException * @throws ClassNotFoundException * @throws CloneNotSupportedException */ @Test public void testCreatePool() throws SQLException, ClassNotFoundException, CloneNotSupportedException { BoneCPConfig mockConfig = createNiceMock(BoneCPConfig.class); expect(mockConfig.getPartitionCount()).andReturn(1).anyTimes(); expect(mockConfig.getMaxConnectionsPerPartition()).andReturn(1).anyTimes(); expect(mockConfig.getMinConnectionsPerPartition()).andReturn(1).anyTimes(); expect(mockConfig.getIdleConnectionTestPeriodInMinutes()).andReturn(100L).anyTimes(); expect(mockConfig.getUsername()).andReturn("somethingbad").anyTimes(); expect(mockConfig.getPassword()).andReturn("somethingbad").anyTimes(); expect(mockConfig.getJdbcUrl()).andReturn("invalid").anyTimes(); // expect(mockConfig.getReleaseHelperThreads()).andReturn(1).once().andReturn(0).anyTimes(); replay(mockConfig); try{ testClass.createPool(mockConfig); fail("Should throw an exception"); } catch (RuntimeException e){ // do nothing } verify(mockConfig); reset(mockConfig); Class.forName(DRIVER); mockConfig = createNiceMock(BoneCPConfig.class); expect(mockConfig.getPartitionCount()).andReturn(1).anyTimes(); expect(mockConfig.getMaxConnectionsPerPartition()).andReturn(1).anyTimes(); expect(mockConfig.getMinConnectionsPerPartition()).andReturn(1).anyTimes(); expect(mockConfig.getIdleConnectionTestPeriodInMinutes()).andReturn(100L).anyTimes(); expect(mockConfig.getUsername()).andReturn(USERNAME).anyTimes(); expect(mockConfig.getPassword()).andReturn(PASSWORD).anyTimes(); expect(mockConfig.getJdbcUrl()).andReturn(URL).anyTimes(); expect(mockConfig.isLazyInit()).andReturn(false).anyTimes(); expect(mockConfig.clone()).andReturn(mockConfig).anyTimes(); replay(mockConfig); try{ testClass.createPool(mockConfig); } catch (RuntimeException e){ fail("Should pass: "); } verify(mockConfig); } /** * Test method for {@link com.jolbox.bonecp.provider.BoneCPConnectionProvider#getConnection()}. * @throws SQLException * @throws NoSuchFieldException * @throws SecurityException * @throws IllegalAccessException * @throws IllegalArgumentException */ @Test public void testGetConnection() throws SQLException, SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException { Field field = testClass.getClass().getDeclaredField("autocommit"); field.setAccessible(true); field.set(testClass, true); field = testClass.getClass().getDeclaredField("isolation"); field.setAccessible(true); field.set(testClass, 8); expect(mockPool.getConnection()).andReturn(mockConnection).once(); expect(mockConnection.getAutoCommit()).andReturn(false).once(); expect(mockConnection.getTransactionIsolation()).andReturn(0).once(); mockConnection.setTransactionIsolation(8); expectLastCall().once(); replay(mockPool, mockConnection); testClass.getConnection(); verify(mockPool, mockConnection); } /** * Test method for {@link com.jolbox.bonecp.provider.BoneCPConnectionProvider#getConnection()}. * @throws SQLException * @throws NoSuchFieldException * @throws SecurityException * @throws IllegalAccessException * @throws IllegalArgumentException */ @Test public void testGetConnectionWithException() throws SQLException, SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException { Field field = testClass.getClass().getDeclaredField("isolation"); field.setAccessible(true); field.set(testClass, 8); expect(mockPool.getConnection()).andReturn(mockConnection).once(); expect(mockConnection.getTransactionIsolation()).andThrow(new SQLException()).once(); mockConnection.close(); expectLastCall().once(); replay(mockPool, mockConnection); try{ testClass.getConnection(); fail("Should throw an exception"); } catch(SQLException e){ // do nothing } verify(mockPool, mockConnection); } /** * Test method for {@link com.jolbox.bonecp.provider.BoneCPConnectionProvider#getConnection()}. * @throws SQLException * @throws NoSuchFieldException * @throws SecurityException * @throws IllegalAccessException * @throws IllegalArgumentException */ @Test public void testGetConnectionWithExceptionEvenInFinally() throws SQLException, SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException { Field field = testClass.getClass().getDeclaredField("isolation"); field.setAccessible(true); field.set(testClass, 8); expect(mockPool.getConnection()).andReturn(mockConnection).once(); expect(mockConnection.getTransactionIsolation()).andThrow(new SQLException()).once(); mockConnection.close(); expectLastCall().andThrow(new SQLException()).once(); replay(mockPool, mockConnection); try{ testClass.getConnection(); fail("Should throw an exception"); } catch(SQLException e){ // do nothing } verify(mockPool, mockConnection); } /** * Test method for {@link com.jolbox.bonecp.provider.BoneCPConnectionProvider#supportsAggressiveRelease()}. */ @Test public void testSupportsAggressiveRelease() { assertFalse(testClass.supportsAggressiveRelease()); } }