diff --git a/pom.xml b/pom.xml index 616b956853..874b4a0f80 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.alibaba druid - 0.1.4 + 0.1.5-SNAPSHOT druid diff --git a/src/main/java/com/alibaba/druid/mock/MockConnection.java b/src/main/java/com/alibaba/druid/mock/MockConnection.java index 386945d8dd..a9411163a7 100644 --- a/src/main/java/com/alibaba/druid/mock/MockConnection.java +++ b/src/main/java/com/alibaba/druid/mock/MockConnection.java @@ -33,19 +33,24 @@ import java.sql.Struct; import java.util.Map; import java.util.Properties; +import com.alibaba.druid.logging.Log; +import com.alibaba.druid.logging.LogFactory; + public class MockConnection implements Connection { - private boolean autoCommit = false; - private boolean closed = false; - private boolean readOnly = false; - private String catalog = null; - private int transactionIsolation; - private SQLWarning warning; - private int holdability; + private final static Log LOG = LogFactory.getLog(MockConnection.class); - private MockDriver driver; + private boolean autoCommit = false; + private boolean closed = false; + private boolean readOnly = false; + private String catalog = null; + private int transactionIsolation; + private SQLWarning warning; + private int holdability; - private Properties connectProperties; + private MockDriver driver; + + private Properties connectProperties; public MockConnection(){ this(null); @@ -139,6 +144,10 @@ public class MockConnection implements Connection { @Override public boolean isClosed() throws SQLException { + if (LOG.isDebugEnabled()) { + LOG.debug("check close " + closed); + } + return closed; } diff --git a/src/main/java/com/alibaba/druid/mock/MockDriver.java b/src/main/java/com/alibaba/druid/mock/MockDriver.java index 41f60439d7..ac89a537cd 100644 --- a/src/main/java/com/alibaba/druid/mock/MockDriver.java +++ b/src/main/java/com/alibaba/druid/mock/MockDriver.java @@ -25,7 +25,9 @@ import java.sql.NClob; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.SQLXML; +import java.util.List; import java.util.Properties; +import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.atomic.AtomicLong; import com.alibaba.druid.logging.Log; @@ -34,7 +36,8 @@ import com.alibaba.druid.mock.handler.MockExecuteHandler; import com.alibaba.druid.mock.handler.MySqlMockExecuteHandlerImpl; public class MockDriver implements Driver { - private final static Log LOG = LogFactory.getLog(MockDriver.class); + + private final static Log LOG = LogFactory.getLog(MockDriver.class); public final static MockExecuteHandler DEFAULT_HANDLER = new MySqlMockExecuteHandlerImpl(); @@ -43,15 +46,21 @@ public class MockDriver implements Driver { private MockExecuteHandler executeHandler = DEFAULT_HANDLER; - private final static MockDriver instance = new MockDriver(); + public final static MockDriver instance = new MockDriver(); private final AtomicLong connectCount = new AtomicLong(); private final AtomicLong connectionCloseCount = new AtomicLong(); + private final List connections = new CopyOnWriteArrayList(); + static { registerDriver(instance); } + public List getConnections() { + return connections; + } + protected void incrementConnectionCloseCount() { connectionCloseCount.incrementAndGet(); } @@ -62,6 +71,12 @@ public class MockDriver implements Driver { protected void afterConnectionClose(MockConnection conn) { connectionCloseCount.incrementAndGet(); + + connections.remove(conn); + + if (LOG.isDebugEnabled()) { + LOG.debug("close"); + } } public static boolean registerDriver(Driver driver) { @@ -90,6 +105,10 @@ public class MockDriver implements Driver { return null; } + if (LOG.isDebugEnabled()) { + LOG.debug("connect, url " + url); + } + if (info != null) { Object val = info.get("connectSleep"); if (val != null) { @@ -106,6 +125,7 @@ public class MockDriver implements Driver { if (url == null) { connectCount.incrementAndGet(); + connections.add(conn); return conn; } @@ -114,6 +134,7 @@ public class MockDriver implements Driver { conn.setCatalog(catalog); connectCount.incrementAndGet(); + connections.add(conn); return conn; } @@ -122,6 +143,7 @@ public class MockDriver implements Driver { conn.setCatalog(catalog); connectCount.incrementAndGet(); + connections.add(conn); return conn; } @@ -158,6 +180,10 @@ public class MockDriver implements Driver { } protected ResultSet executeQuery(MockStatement stmt, String sql) throws SQLException { + if (LOG.isDebugEnabled()) { + LOG.debug("executeQuery " + sql); + } + MockConnection conn = stmt.getMockConnection(); if (conn != null) { diff --git a/src/test/java/com/alibaba/druid/bvt/pool/TestIdle.java b/src/test/java/com/alibaba/druid/bvt/pool/TestIdle.java new file mode 100644 index 0000000000..fcccda62fb --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/pool/TestIdle.java @@ -0,0 +1,72 @@ +package com.alibaba.druid.bvt.pool; + +import java.sql.Connection; + +import junit.framework.Assert; +import junit.framework.TestCase; + +import com.alibaba.druid.mock.MockConnection; +import com.alibaba.druid.mock.MockDriver; +import com.alibaba.druid.pool.DruidDataSource; + +public class TestIdle extends TestCase { + + public void test_idle() throws Exception { + MockDriver driver = new MockDriver(); + + DruidDataSource dataSource = new DruidDataSource(); + dataSource.setUrl("jdbc:mock:xxx"); + dataSource.setDriver(driver); + dataSource.setInitialSize(2); + dataSource.setMaxActive(4); + dataSource.setMaxIdle(4); + dataSource.setMinIdle(1); + dataSource.setMinEvictableIdleTimeMillis(50 * 1); + dataSource.setTimeBetweenEvictionRunsMillis(10); + dataSource.setTestWhileIdle(true); + dataSource.setTestOnBorrow(false); + dataSource.setValidationQuery("SELECT 1"); + + { + Connection conn = dataSource.getConnection(); + + Assert.assertEquals(dataSource.getInitialSize(), driver.getConnections().size()); + + conn.close(); + Assert.assertEquals(dataSource.getInitialSize(), driver.getConnections().size()); + } + + { + int count = 4; + Connection[] connections = new Connection[4]; + for (int i = 0; i < count; ++i) { + connections[i] = dataSource.getConnection(); + } + Assert.assertEquals(4, driver.getConnections().size()); + for (int i = 0; i < count; ++i) { + connections[i].close(); + } + Assert.assertEquals(4, driver.getConnections().size()); + + Thread.sleep(dataSource.getMinEvictableIdleTimeMillis() * 2); + Assert.assertEquals(dataSource.getMinIdle(), driver.getConnections().size()); + } + + System.out.println("----------raw close all connection"); + for (MockConnection rawConn : driver.getConnections()) { + rawConn.close(); + } + + Thread.sleep(dataSource.getMinEvictableIdleTimeMillis() * 2); + Assert.assertEquals(0, driver.getConnections().size()); + Assert.assertEquals(0, dataSource.getPoolingCount()); + { + Connection conn = dataSource.getConnection(); + Assert.assertEquals(dataSource.getMinIdle(), driver.getConnections().size()); + conn.close(); + Assert.assertEquals(dataSource.getMinIdle(), driver.getConnections().size()); + } + + dataSource.close(); + } +} diff --git a/src/test/java/com/alibaba/druid/pool/dbcp/Test0.java b/src/test/java/com/alibaba/druid/pool/dbcp/Test0.java new file mode 100644 index 0000000000..4b6192dcd8 --- /dev/null +++ b/src/test/java/com/alibaba/druid/pool/dbcp/Test0.java @@ -0,0 +1,54 @@ +package com.alibaba.druid.pool.dbcp; + +import java.sql.Connection; + +import junit.framework.Assert; +import junit.framework.TestCase; + +import org.apache.commons.dbcp.BasicDataSource; + +import com.alibaba.druid.mock.MockConnection; +import com.alibaba.druid.mock.MockDriver; + +public class Test0 extends TestCase { + + public void test_idle() throws Exception { + MockDriver driver = MockDriver.instance; + + BasicDataSource dataSource = new BasicDataSource(); + dataSource.setUrl("jdbc:mock:xxx"); + dataSource.setDriverClassName("com.alibaba.druid.mock.MockDriver"); + dataSource.setInitialSize(0); + dataSource.setMaxActive(4); + dataSource.setMaxIdle(4); + dataSource.setMinIdle(1); + dataSource.setMinEvictableIdleTimeMillis(5000 * 1); + dataSource.setTimeBetweenEvictionRunsMillis(10); + dataSource.setTestWhileIdle(false); + dataSource.setTestOnBorrow(false); + dataSource.setValidationQuery("SELECT 1"); + + { + Connection conn = dataSource.getConnection(); + + // Assert.assertEquals(dataSource.getInitialSize(), driver.getConnections().size()); + System.out.println("raw size : " + driver.getConnections().size()); + + conn.close(); + System.out.println("raw size : " + driver.getConnections().size()); + } + + { + Connection conn = dataSource.getConnection(); + + // Assert.assertEquals(dataSource.getInitialSize(), driver.getConnections().size()); + System.out.println("raw size : " + driver.getConnections().size()); + + conn.close(); + System.out.println("raw size : " + driver.getConnections().size()); + } + + + dataSource.close(); + } +} diff --git a/src/test/java/com/alibaba/druid/pool/dbcp/TestIdle.java b/src/test/java/com/alibaba/druid/pool/dbcp/TestIdle.java new file mode 100644 index 0000000000..a387c784d2 --- /dev/null +++ b/src/test/java/com/alibaba/druid/pool/dbcp/TestIdle.java @@ -0,0 +1,84 @@ +package com.alibaba.druid.pool.dbcp; + +import java.sql.Connection; + +import junit.framework.Assert; +import junit.framework.TestCase; + +import org.apache.commons.dbcp.BasicDataSource; + +import com.alibaba.druid.mock.MockConnection; +import com.alibaba.druid.mock.MockDriver; + +public class TestIdle extends TestCase { + + public void test_idle() throws Exception { + MockDriver driver = MockDriver.instance; + + BasicDataSource dataSource = new BasicDataSource(); + dataSource.setUrl("jdbc:mock:xxx"); + dataSource.setDriverClassName("com.alibaba.druid.mock.MockDriver"); + dataSource.setInitialSize(0); + dataSource.setMaxActive(4); + dataSource.setMaxIdle(4); + dataSource.setMinIdle(1); + dataSource.setMinEvictableIdleTimeMillis(50 * 1); + dataSource.setTimeBetweenEvictionRunsMillis(10); + dataSource.setTestWhileIdle(false); + dataSource.setTestOnBorrow(false); + dataSource.setValidationQuery("SELECT 1"); + + { + Connection conn = dataSource.getConnection(); + + // Assert.assertEquals(dataSource.getInitialSize(), driver.getConnections().size()); + System.out.println("raw size : " + driver.getConnections().size()); + + conn.close(); + System.out.println("raw size : " + driver.getConnections().size()); + } + + { + Connection conn = dataSource.getConnection(); + + // Assert.assertEquals(dataSource.getInitialSize(), driver.getConnections().size()); + System.out.println("raw size : " + driver.getConnections().size()); + + conn.close(); + System.out.println("raw size : " + driver.getConnections().size()); + } + + { + int count = 4; + Connection[] connections = new Connection[4]; + for (int i = 0; i < count; ++i) { + connections[i] = dataSource.getConnection(); + } + System.out.println("raw size : " + driver.getConnections().size()); + for (int i = 0; i < count; ++i) { + connections[i].close(); + } + System.out.println("raw size : " + driver.getConnections().size()); + + System.out.println("----------sleep for evict"); + Thread.sleep(dataSource.getMinEvictableIdleTimeMillis() * 2); + System.out.println("raw size : " + driver.getConnections().size()); + } + + System.out.println("----------raw close all connection"); + for (MockConnection rawConn : driver.getConnections()) { + rawConn.close(); + } + + Thread.sleep(dataSource.getMinEvictableIdleTimeMillis() * 2); + System.out.println("raw size : " + driver.getConnections().size()); + { + Connection conn = dataSource.getConnection(); + System.out.println("raw size : " + driver.getConnections().size()); + conn.close(); + System.out.println("raw size : " + driver.getConnections().size()); + } + + dataSource.close(); + } +}