diff --git a/src/main/java/com/alibaba/druid/mock/MockResultSet.java b/src/main/java/com/alibaba/druid/mock/MockResultSet.java index f2182faf77..f2ae9a8bfb 100644 --- a/src/main/java/com/alibaba/druid/mock/MockResultSet.java +++ b/src/main/java/com/alibaba/druid/mock/MockResultSet.java @@ -77,7 +77,7 @@ public class MockResultSet extends ResultSetBase implements ResultSet { throw new SQLException(); } - if (rowIndex > 0) { + if (rowIndex >= 0) { rowIndex--; return true; } diff --git a/src/main/java/com/alibaba/druid/pool/DruidDataSource.java b/src/main/java/com/alibaba/druid/pool/DruidDataSource.java index 01ae419fa9..3008cd6556 100644 --- a/src/main/java/com/alibaba/druid/pool/DruidDataSource.java +++ b/src/main/java/com/alibaba/druid/pool/DruidDataSource.java @@ -145,10 +145,15 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat public void restart() { lock.lock(); try { + if (LOG.isInfoEnabled()) { + LOG.info("{dataSource-" + this.getID() + "} restart"); + } + this.close(); this.resetStat(); this.inited = false; this.enable = true; + this.closed = false; } finally { lock.unlock(); } diff --git a/src/main/java/com/alibaba/druid/pool/DruidPooledResultSet.java b/src/main/java/com/alibaba/druid/pool/DruidPooledResultSet.java index 0243788926..6c80236c7f 100644 --- a/src/main/java/com/alibaba/druid/pool/DruidPooledResultSet.java +++ b/src/main/java/com/alibaba/druid/pool/DruidPooledResultSet.java @@ -93,6 +93,10 @@ public final class DruidPooledResultSet extends PoolableWrapper implements Resul throw checkException(t); } } + + public int getFetchRowCount() { + return fetchRowCount; + } @Override public boolean wasNull() throws SQLException { diff --git a/src/test/java/com/alibaba/druid/bvt/pool/DruidDataSourceTest.java b/src/test/java/com/alibaba/druid/bvt/pool/DruidDataSourceTest.java new file mode 100644 index 0000000000..e10b98c047 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/pool/DruidDataSourceTest.java @@ -0,0 +1,39 @@ +package com.alibaba.druid.bvt.pool; + +import java.sql.Connection; + +import junit.framework.Assert; +import junit.framework.TestCase; + +import com.alibaba.druid.pool.DruidDataSource; + +public class DruidDataSourceTest extends TestCase { + + private DruidDataSource dataSource; + + protected void setUp() throws Exception { + dataSource = new DruidDataSource(); + dataSource.setUrl("jdbc:mock:xxx"); + dataSource.setTestOnBorrow(false); + + dataSource.init(); + } + + protected void tearDown() throws Exception { + dataSource.close(); + } + + public void test_getInitStackTrace() { + String stackTrace = dataSource.getInitStackTrace(); + Assert.assertTrue(stackTrace.indexOf("com.alibaba.druid.bvt.pool.DruidDataSourceTest.setUp") != -1); + } + + public void test_restart() throws Exception { + Assert.assertEquals(true, dataSource.isInited()); + dataSource.restart(); + Assert.assertEquals(false, dataSource.isInited()); + + Connection conn = dataSource.getConnection(); + conn.close(); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/pool/DruidDataSourceTest2.java b/src/test/java/com/alibaba/druid/bvt/pool/DruidDataSourceTest2.java new file mode 100644 index 0000000000..4efca3947a --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/pool/DruidDataSourceTest2.java @@ -0,0 +1,40 @@ +package com.alibaba.druid.bvt.pool; + +import junit.framework.Assert; +import junit.framework.TestCase; + +import com.alibaba.druid.pool.DruidDataSource; + +/** + * 这个场景测试minIdle > maxActive + * + * @author wenshao + */ +public class DruidDataSourceTest2 extends TestCase { + + private DruidDataSource dataSource; + + protected void setUp() throws Exception { + dataSource = new DruidDataSource(); + dataSource.setUrl("jdbc:mock:xxx"); + dataSource.setTestOnBorrow(false); + dataSource.setFilters("stat"); + dataSource.setMinIdle(100); + dataSource.setMaxActive(1); + + } + + protected void tearDown() throws Exception { + dataSource.close(); + } + + public void test_error() throws Exception { + Exception error = null; + try { + dataSource.init(); + } catch (IllegalArgumentException e) { + error = e; + } + Assert.assertNotNull(error); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/pool/DruidDataSourceTest3.java b/src/test/java/com/alibaba/druid/bvt/pool/DruidDataSourceTest3.java new file mode 100644 index 0000000000..bbc5d033bf --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/pool/DruidDataSourceTest3.java @@ -0,0 +1,109 @@ +package com.alibaba.druid.bvt.pool; + +import java.sql.SQLException; +import java.util.Properties; +import java.util.concurrent.CountDownLatch; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.druid.filter.FilterAdapter; +import com.alibaba.druid.filter.FilterChain; +import com.alibaba.druid.pool.DruidDataSource; +import com.alibaba.druid.proxy.jdbc.ConnectionProxy; + +/** + * 这个场景测试并发初始化 + * @author wenshao + * + */ +public class DruidDataSourceTest3 extends TestCase { + + private DruidDataSource dataSource; + private volatile Exception error; + private volatile Exception errorB; + + protected void setUp() throws Exception { + dataSource = new DruidDataSource(); + dataSource.setUrl("jdbc:mock:xxx"); + dataSource.setTestOnBorrow(false); + dataSource.setInitialSize(1); + + dataSource.getProxyFilters().add(new FilterAdapter() { + + public ConnectionProxy connection_connect(FilterChain chain, Properties info) throws SQLException { + try { + Thread.sleep(Long.MAX_VALUE); + } catch (InterruptedException e) { + // skip + } + return null; + } + }); + + } + + protected void tearDown() throws Exception { + dataSource.close(); + } + + public void test_error() throws Exception { + final CountDownLatch startedLatch = new CountDownLatch(1); + final CountDownLatch endLatch = new CountDownLatch(1); + + Thread threadA = new Thread("A") { + + public void run() { + try { + startedLatch.countDown(); + dataSource.init(); + } catch (SQLException e) { + error = e; + } finally { + endLatch.countDown(); + } + } + }; + threadA.start(); + + startedLatch.await(); + + Thread.sleep(10); + + Assert.assertFalse(dataSource.isInited()); + + final CountDownLatch startedLatchB = new CountDownLatch(1); + final CountDownLatch endLatchB = new CountDownLatch(1); + Thread threadB = new Thread("B") { + + public void run() { + try { + startedLatchB.countDown(); + dataSource.init(); + } catch (SQLException e) { + errorB = e; + } finally { + endLatchB.countDown(); + } + } + }; + threadB.start(); + startedLatchB.await(); + + threadB.interrupt(); + endLatchB.await(); + + Assert.assertNotNull(errorB); + Assert.assertTrue(errorB.getCause() instanceof InterruptedException); + + threadA.interrupt(); + + endLatch.await(); + endLatchB.await(); + Assert.assertNotNull(error); + + Assert.assertEquals(1, dataSource.getCreateErrorCount()); + + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/pool/DruidDataSourceTest4.java b/src/test/java/com/alibaba/druid/bvt/pool/DruidDataSourceTest4.java new file mode 100644 index 0000000000..22d4732a49 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/pool/DruidDataSourceTest4.java @@ -0,0 +1,39 @@ +package com.alibaba.druid.bvt.pool; + +import junit.framework.Assert; +import junit.framework.TestCase; + +import com.alibaba.druid.pool.DruidDataSource; + +/** + * 这个场景测试maxActive < 0 + * + * @author wenshao + */ +public class DruidDataSourceTest4 extends TestCase { + + private DruidDataSource dataSource; + + protected void setUp() throws Exception { + dataSource = new DruidDataSource(); + dataSource.setUrl("jdbc:mock:xxx"); + dataSource.setTestOnBorrow(false); + dataSource.setFilters("stat"); + dataSource.setMaxActive(-1); + + } + + protected void tearDown() throws Exception { + dataSource.close(); + } + + public void test_error() throws Exception { + Exception error = null; + try { + dataSource.init(); + } catch (IllegalArgumentException e) { + error = e; + } + Assert.assertNotNull(error); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/pool/DruidDataSourceTest5.java b/src/test/java/com/alibaba/druid/bvt/pool/DruidDataSourceTest5.java new file mode 100644 index 0000000000..2a2ef79335 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/pool/DruidDataSourceTest5.java @@ -0,0 +1,39 @@ +package com.alibaba.druid.bvt.pool; + +import junit.framework.Assert; +import junit.framework.TestCase; + +import com.alibaba.druid.pool.DruidDataSource; + +/** + * 这个场景测试initialSize > maxActive + * + * @author wenshao + */ +public class DruidDataSourceTest5 extends TestCase { + + private DruidDataSource dataSource; + + protected void setUp() throws Exception { + dataSource = new DruidDataSource(); + dataSource.setUrl("jdbc:mock:xxx"); + dataSource.setTestOnBorrow(false); + dataSource.setFilters("stat"); + dataSource.setInitialSize(100); + + } + + protected void tearDown() throws Exception { + dataSource.close(); + } + + public void test_error() throws Exception { + Exception error = null; + try { + dataSource.init(); + } catch (IllegalArgumentException e) { + error = e; + } + Assert.assertNotNull(error); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/pool/DruidDataSourceTest6.java b/src/test/java/com/alibaba/druid/bvt/pool/DruidDataSourceTest6.java new file mode 100644 index 0000000000..94442c24a9 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/pool/DruidDataSourceTest6.java @@ -0,0 +1,51 @@ +package com.alibaba.druid.bvt.pool; + +import java.sql.Connection; +import java.sql.SQLException; +import java.util.Properties; + +import org.junit.Assert; + +import junit.framework.TestCase; + +import com.alibaba.druid.filter.FilterAdapter; +import com.alibaba.druid.filter.FilterChain; +import com.alibaba.druid.pool.DruidDataSource; +import com.alibaba.druid.proxy.jdbc.ConnectionProxy; + +/** + * 这个场景测试defaultAutoCommit + * + * @author wenshao + */ +public class DruidDataSourceTest6 extends TestCase { + + private DruidDataSource dataSource; + + protected void setUp() throws Exception { + dataSource = new DruidDataSource(); + dataSource.setUrl("jdbc:mock:xxx"); + dataSource.setTestOnBorrow(false); + dataSource.setDefaultAutoCommit(true); + dataSource.getProxyFilters().add(new FilterAdapter() { + public ConnectionProxy connection_connect(FilterChain chain, Properties info) throws SQLException { + ConnectionProxy conn = chain.connection_connect(info); + conn.setAutoCommit(false); + return conn; + } + }); + + } + + protected void tearDown() throws Exception { + dataSource.close(); + } + + public void test_autoCommit() throws Exception { + Connection conn = dataSource.getConnection(); + + Assert.assertTrue(conn.getAutoCommit()); + + conn.close(); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/pool/DruidDataSourceTest_createError.java b/src/test/java/com/alibaba/druid/bvt/pool/DruidDataSourceTest_createError.java new file mode 100644 index 0000000000..306a0a14bf --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/pool/DruidDataSourceTest_createError.java @@ -0,0 +1,53 @@ +package com.alibaba.druid.bvt.pool; + +import java.sql.SQLException; +import java.util.Properties; + +import org.junit.Assert; + +import junit.framework.TestCase; + +import com.alibaba.druid.filter.FilterAdapter; +import com.alibaba.druid.filter.FilterChain; +import com.alibaba.druid.pool.DruidDataSource; +import com.alibaba.druid.proxy.jdbc.ConnectionProxy; + +/** + * 这个场景测试createError + * + * @author wenshao + */ +public class DruidDataSourceTest_createError extends TestCase { + + private DruidDataSource dataSource; + + protected void setUp() throws Exception { + dataSource = new DruidDataSource(); + dataSource.setUrl("jdbc:mock:xxx"); + dataSource.setTestOnBorrow(false); + dataSource.setDefaultAutoCommit(true); + dataSource.setInitialSize(1); + dataSource.getProxyFilters().add(new FilterAdapter() { + + public ConnectionProxy connection_connect(FilterChain chain, Properties info) throws SQLException { + throw new SQLException(); + } + }); + + } + + protected void tearDown() throws Exception { + dataSource.close(); + } + + public void test_error() throws Exception { + Exception error = null; + try { + dataSource.init(); + } catch (Exception e) { + error = e; + } + + Assert.assertNotNull(error); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/pool/DruidDataSourceTest_loadSysPropertyFilter.java b/src/test/java/com/alibaba/druid/bvt/pool/DruidDataSourceTest_loadSysPropertyFilter.java new file mode 100644 index 0000000000..0f3117059d --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/pool/DruidDataSourceTest_loadSysPropertyFilter.java @@ -0,0 +1,42 @@ +package com.alibaba.druid.bvt.pool; + +import java.sql.Connection; +import java.sql.SQLException; +import java.util.Properties; + +import org.junit.Assert; + +import junit.framework.TestCase; + +import com.alibaba.druid.filter.FilterAdapter; +import com.alibaba.druid.filter.FilterChain; +import com.alibaba.druid.pool.DruidDataSource; +import com.alibaba.druid.proxy.jdbc.ConnectionProxy; + +/** + * 这个场景测试defaultAutoCommit + * + * @author wenshao + */ +public class DruidDataSourceTest_loadSysPropertyFilter extends TestCase { + + private DruidDataSource dataSource; + + protected void setUp() throws Exception { + dataSource = new DruidDataSource(); + dataSource.setUrl("jdbc:wrap-jdbc:filters=stat,log4j:jdbc:mock:xxx"); + dataSource.setTestOnBorrow(false); + dataSource.setFilters("stat"); + } + + protected void tearDown() throws Exception { + dataSource.close(); + System.clearProperty("druid.filters"); + } + + public void test_autoCommit() throws Exception { + dataSource.init(); + + Assert.assertEquals(2, dataSource.getProxyFilters().size()); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/pool/DruidDataSourceTest_wrapDriverFilters.java b/src/test/java/com/alibaba/druid/bvt/pool/DruidDataSourceTest_wrapDriverFilters.java new file mode 100644 index 0000000000..fa53d1347c --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/pool/DruidDataSourceTest_wrapDriverFilters.java @@ -0,0 +1,44 @@ +package com.alibaba.druid.bvt.pool; + +import java.sql.Connection; +import java.sql.SQLException; +import java.util.Properties; + +import org.junit.Assert; + +import junit.framework.TestCase; + +import com.alibaba.druid.filter.FilterAdapter; +import com.alibaba.druid.filter.FilterChain; +import com.alibaba.druid.pool.DruidDataSource; +import com.alibaba.druid.proxy.jdbc.ConnectionProxy; + +/** + * 这个场景测试defaultAutoCommit + * + * @author wenshao + */ +public class DruidDataSourceTest_wrapDriverFilters extends TestCase { + + private DruidDataSource dataSource; + + protected void setUp() throws Exception { + System.setProperty("druid.filters", "stat,log4j"); + + dataSource = new DruidDataSource(); + dataSource.setUrl("jdbc:mock:xxx"); + dataSource.setTestOnBorrow(false); + dataSource.setFilters("stat"); + } + + protected void tearDown() throws Exception { + dataSource.close(); + System.clearProperty("druid.filters"); + } + + public void test_autoCommit() throws Exception { + dataSource.init(); + + Assert.assertEquals(2, dataSource.getProxyFilters().size()); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/pool/DruidPooledResultSetTest.java b/src/test/java/com/alibaba/druid/bvt/pool/DruidPooledResultSetTest.java index 9761164463..c852d376d0 100644 --- a/src/test/java/com/alibaba/druid/bvt/pool/DruidPooledResultSetTest.java +++ b/src/test/java/com/alibaba/druid/bvt/pool/DruidPooledResultSetTest.java @@ -100,4 +100,34 @@ public class DruidPooledResultSetTest extends TestCase { conn.close(); } + + public void test_rowCount() throws Exception { + String sql = "select ?"; + Connection conn = dataSource.getConnection(); + + PreparedStatement stmt = conn.prepareStatement(sql); + stmt.setString(1, "xxx"); + DruidPooledResultSet rs = (DruidPooledResultSet) stmt.executeQuery(); + + Assert.assertEquals(true, rs.next()); + Assert.assertEquals(false, rs.next()); + + Assert.assertEquals(1, rs.getFetchRowCount()); + + Assert.assertEquals(true, rs.previous()); + Assert.assertEquals(false, rs.previous()); + + Assert.assertEquals(1, rs.getFetchRowCount()); + + Assert.assertEquals(true, rs.next()); + Assert.assertEquals(false, rs.next()); + + Assert.assertEquals(1, rs.getFetchRowCount()); + + Assert.assertFalse(rs.rowUpdated()); + + rs.close(); + + conn.close(); + } } diff --git a/src/test/java/com/alibaba/druid/bvt/pool/DruidPooledResultSetTest2.java b/src/test/java/com/alibaba/druid/bvt/pool/DruidPooledResultSetTest2.java new file mode 100644 index 0000000000..3aa84c709a --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/pool/DruidPooledResultSetTest2.java @@ -0,0 +1,59 @@ +/* + * Copyright 1999-2011 Alibaba Group Holding Ltd. + * + * 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.alibaba.druid.bvt.pool; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; + +import junit.framework.Assert; +import junit.framework.TestCase; + +import com.alibaba.druid.mock.MockResultSet; +import com.alibaba.druid.pool.DruidDataSource; + +public class DruidPooledResultSetTest2 extends TestCase { + + private DruidDataSource dataSource; + + protected void setUp() throws Exception { + dataSource = new DruidDataSource(); + dataSource.setUrl("jdbc:mock:xxx"); + dataSource.setTestOnBorrow(false); + } + + protected void tearDown() throws Exception { + dataSource.close(); + } + + public void testWrap() throws Exception { + String sql = "select ?"; + Connection conn = dataSource.getConnection(); + + PreparedStatement stmt = conn.prepareStatement(sql); + stmt.setString(1, "xxx"); + ResultSet rs = stmt.executeQuery(); + + ResultSet raw = rs.unwrap(ResultSet.class); + + Assert.assertTrue(raw instanceof MockResultSet); + + rs.close(); + + conn.close(); + } + +} diff --git a/src/test/java/com/alibaba/druid/bvt/pool/DumpTest.java b/src/test/java/com/alibaba/druid/bvt/pool/DumpTest.java index c3d20d0be8..0316b1cb76 100644 --- a/src/test/java/com/alibaba/druid/bvt/pool/DumpTest.java +++ b/src/test/java/com/alibaba/druid/bvt/pool/DumpTest.java @@ -123,4 +123,7 @@ public class DumpTest extends TestCase { Assert.assertNotNull(dataSource.getSqlStat((int) sqlStat.getId())); } + public void test_getReference() throws Exception { + dataSource.getReference(); + } }