/** 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(); }
/** * 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(); }
@Test public void testGetObjectInstance() throws Exception { config.setAcquireIncrement(5); config.setMinConnectionsPerPartition(30); config.setMaxConnectionsPerPartition(100); config.setPartitionCount(1); Reference mockRef = createNiceMock(Reference.class); Enumeration<RefAddr> mockEnum = createNiceMock(Enumeration.class); RefAddr mockRefAddr = createNiceMock(RefAddr.class); expect(mockRef.getAll()).andReturn(mockEnum).anyTimes(); expect(mockEnum.hasMoreElements()).andReturn(true).times(2); expect(mockEnum.nextElement()).andReturn(mockRefAddr).anyTimes(); expect(mockRefAddr.getType()) .andReturn("driverClassName") .once() .andReturn("password") .times(2); expect(mockRefAddr.getContent()) .andReturn("com.jolbox.bonecp.MockJDBCDriver") .once() .andReturn("abcdefgh") .once(); replay(mockRef, mockEnum, mockRefAddr); BoneCPDataSource dsb = new BoneCPDataSource(); BoneCPDataSource result = (BoneCPDataSource) dsb.getObjectInstance(mockRef, null, null, null); assertEquals("abcdefgh", result.getPassword()); verify(mockRef, mockEnum, mockRefAddr); }
@Test public void testMultithreadMultiPartition() throws InterruptedException, SQLException { CommonTestUtils.logTestInfo("Test multiple threads hitting a multiple partitions concurrently"); config.setAcquireIncrement(5); config.setMinConnectionsPerPartition(10); config.setMaxConnectionsPerPartition(25); config.setPartitionCount(5); config.setReleaseHelperThreads(0); BoneCPDataSource dsb = new BoneCPDataSource(config); dsb.setDriverClass("com.jolbox.bonecp.MockJDBCDriver"); CommonTestUtils.startThreadTest(100, 1000, dsb, 0, false); assertEquals(0, dsb.getTotalLeased()); dsb.close(); CommonTestUtils.logPass(); }
@Test public void testMultithreadSinglePartition() throws InterruptedException, SQLException { CommonTestUtils.logTestInfo("Test multiple threads hitting a single partition concurrently"); config.setAcquireIncrement(5); config.setMinConnectionsPerPartition(30); config.setMaxConnectionsPerPartition(100); config.setPartitionCount(1); BoneCPDataSource dsb = new BoneCPDataSource(config); dsb.setDriverClass("org.hsqldb.jdbcDriver"); CommonTestUtils.startThreadTest(100, 100, dsb, 0, false); assertEquals(0, dsb.getTotalLeased()); dsb.close(); CommonTestUtils.logPass(); }
/** * 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(); }
@Test public void testMultithreadMultiPartitionWithConstantWorkDelay() throws InterruptedException, SQLException { CommonTestUtils.logTestInfo( "Test multiple threads hitting a partition and doing some work on each connection"); config.setAcquireIncrement(1); config.setMinConnectionsPerPartition(10); config.setMaxConnectionsPerPartition(10); config.setPartitionCount(1); BoneCPDataSource dsb = new BoneCPDataSource(config); dsb.setDriverClass("org.hsqldb.jdbcDriver"); CommonTestUtils.startThreadTest(15, 10, dsb, 50, false); assertEquals(0, dsb.getTotalLeased()); dsb.close(); CommonTestUtils.logPass(); }
/** * Tests general methods. * * @throws CloneNotSupportedException */ @Test public void testCloneEqualsHashCode() throws CloneNotSupportedException { config.setAcquireIncrement(5); config.setMinConnectionsPerPartition(30); config.setMaxConnectionsPerPartition(100); config.setPartitionCount(1); BoneCPDataSource dsb = new BoneCPDataSource(config); BoneCPDataSource clone = (BoneCPDataSource) dsb.clone(); assertTrue(clone.hasSameConfiguration(dsb)); assertFalse(clone.hasSameConfiguration(null)); assertTrue(clone.hasSameConfiguration(dsb)); clone.setJdbcUrl("something else"); assertFalse(clone.hasSameConfiguration(dsb)); }
@Test public void testMultithreadMultiPartitionWithRandomWorkDelay() throws InterruptedException, SQLException { CommonTestUtils.logTestInfo( "Test multiple threads hitting a partition and doing some work of random duration on each connection"); config.setAcquireIncrement(5); config.setMinConnectionsPerPartition(10); config.setMaxConnectionsPerPartition(25); config.setPartitionCount(5); BoneCPDataSource dsb = new BoneCPDataSource(config); dsb.setDriverClass("com.jolbox.bonecp.MockJDBCDriver"); CommonTestUtils.startThreadTest(100, 10, dsb, -50, false); assertEquals(0, dsb.getTotalLeased()); dsb.close(); CommonTestUtils.logPass(); }
/** * 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(); }
@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(); }
/** * 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(); }
/** * 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(); }
/** 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(); }
@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(); }
@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(); } }
/** * Mostly for code coverage. * * @throws IOException * @throws NoSuchMethodException * @throws SecurityException * @throws InvocationTargetException * @throws IllegalAccessException * @throws IllegalArgumentException * @throws ClassNotFoundException */ @Test public void testDataSource() throws SQLException, IOException, SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException, ClassNotFoundException { config.setAcquireIncrement(5); config.setMinConnectionsPerPartition(30); config.setMaxConnectionsPerPartition(100); config.setPartitionCount(1); BoneCPDataSource dsb = new BoneCPDataSource(config); dsb.setPartitionCount(1); dsb.setAcquireRetryDelay(-1); dsb.setAcquireRetryAttempts(0); dsb.setMaxConnectionsPerPartition(100); dsb.setMinConnectionsPerPartition(30); dsb.setTransactionRecoveryEnabled(true); dsb.setConnectionHook(new CoverageHook()); dsb.setLazyInit(false); dsb.setStatementsCachedPerConnection(30); dsb.setStatementsCacheSize(30); dsb.setReleaseHelperThreads(0); dsb.setDriverClass("com.jolbox.bonecp.MockJDBCDriver"); dsb.isWrapperFor(String.class); dsb.setIdleMaxAge(0L); dsb.setAcquireIncrement(5); dsb.setIdleConnectionTestPeriod(0L); dsb.setConnectionTestStatement("test"); dsb.setInitSQL(CommonTestUtils.TEST_QUERY); dsb.setCloseConnectionWatch(true); dsb.setLogStatementsEnabled(false); dsb.getConnection().close(); assertNotNull(dsb.getConfig()); assertNotNull(dsb.toString()); dsb.setConnectionHookClassName("bad class name"); assertEquals("bad class name", dsb.getConnectionHookClassName()); assertNull(dsb.getConnectionHook()); dsb.setConnectionHookClassName("com.jolbox.bonecp.hooks.CustomHook"); assertTrue(dsb.getConnectionHook() instanceof CustomHook); File tmp = File.createTempFile("bonecp", ""); dsb.setLogWriter(new PrintWriter(tmp)); assertNotNull(dsb.getLogWriter()); try { dsb.setLoginTimeout(0); fail("Should throw exception"); } catch (UnsupportedOperationException e) { // do nothing } try { dsb.getLoginTimeout(); fail("Should throw exception"); } catch (UnsupportedOperationException e) { // do nothing } Connection c = dsb.getConnection("test", "test"); assertNotNull(c); BoneCPDataSource dsb2 = new BoneCPDataSource(); // empty constructor test dsb2.setDriverClass("inexistent"); try { dsb2.getConnection(); fail("Should fail"); } catch (SQLException e) { // do nothing } assertNull(dsb.unwrap(String.class)); assertEquals("com.jolbox.bonecp.MockJDBCDriver", dsb.getDriverClass()); dsb.setClassLoader(getClass().getClassLoader()); dsb.loadClass("java.lang.String"); assertEquals(getClass().getClassLoader(), dsb.getClassLoader()); }