diff --git a/pom.xml b/pom.xml
index b3adc37460..699a9060d6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -17,6 +17,8 @@
4.11
true
+ true
+
UTF-8
1.6
@@ -131,7 +133,7 @@
- true
+ ${javadoc.skip}
public
UTF-8
UTF-8
diff --git a/src/main/java/com/alibaba/druid/VERSION.java b/src/main/java/com/alibaba/druid/VERSION.java
index 32ce68f05a..f9dfab2ea6 100644
--- a/src/main/java/com/alibaba/druid/VERSION.java
+++ b/src/main/java/com/alibaba/druid/VERSION.java
@@ -19,7 +19,7 @@ public final class VERSION {
public final static int MajorVersion = 0;
public final static int MinorVersion = 2;
- public final static int RevisionVersion = 17;
+ public final static int RevisionVersion = 18;
public static String getVersionNumber() {
return VERSION.MajorVersion + "." + VERSION.MinorVersion + "." + VERSION.RevisionVersion;
diff --git a/src/main/java/com/alibaba/druid/pool/DruidAbstractDataSource.java b/src/main/java/com/alibaba/druid/pool/DruidAbstractDataSource.java
index 8e424e790b..6fc3528c78 100644
--- a/src/main/java/com/alibaba/druid/pool/DruidAbstractDataSource.java
+++ b/src/main/java/com/alibaba/druid/pool/DruidAbstractDataSource.java
@@ -248,8 +248,6 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements
this.useLocalSessionState = useLocalSessionState;
}
-
-
public boolean isOracle() {
return isOracle;
}
diff --git a/src/main/java/com/alibaba/druid/pool/DruidDataSource.java b/src/main/java/com/alibaba/druid/pool/DruidDataSource.java
index 7949c51e0c..e50294ec67 100644
--- a/src/main/java/com/alibaba/druid/pool/DruidDataSource.java
+++ b/src/main/java/com/alibaba/druid/pool/DruidDataSource.java
@@ -33,6 +33,7 @@ import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
import javax.management.JMException;
import javax.management.ObjectName;
@@ -45,6 +46,8 @@ import javax.sql.ConnectionEventListener;
import javax.sql.ConnectionPoolDataSource;
import javax.sql.PooledConnection;
+import org.h2.util.StringUtils;
+
import com.alibaba.druid.TransactionTimeoutException;
import com.alibaba.druid.VERSION;
import com.alibaba.druid.filter.AutoLoad;
@@ -91,6 +94,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
private static final long serialVersionUID = 1L;
// stats
+ private final AtomicLong recycleErrorCount = new AtomicLong();
private long connectCount = 0L;
private long closeCount = 0L;
private final AtomicLong connectErrorCount = new AtomicLong();
@@ -265,6 +269,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
preparedStatementCount.set(0);
transactionHistogram.reset();
cachedPreparedStatementDeleteCount.set(0);
+ recycleErrorCount.set(0);
}
public boolean isEnable() {
@@ -379,6 +384,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
return;
}
+ final ReentrantLock lock = this.lock;
try {
lock.lockInterruptibly();
} catch (InterruptedException e) {
@@ -469,18 +475,15 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
initExceptionSorter();
initValidConnectionChecker();
- if (driver.getClass().getName().equals("com.mysql.jdbc.Driver")) {
- if (this.isPoolPreparedStatements()) {
- LOG.error("mysql should not use 'PoolPreparedStatements'");
- }
- }
-
- if (useGloalDataSourceStat) {
+ if (isUseGloalDataSourceStat()) {
dataSourceStat = JdbcDataSourceStat.getGlobal();
if (dataSourceStat == null) {
dataSourceStat = new JdbcDataSourceStat("Global", "Global", this.dbType);
JdbcDataSourceStat.setGlobal(dataSourceStat);
}
+ if (dataSourceStat.getDbType() == null) {
+ dataSourceStat.setDbType(this.getDbType());
+ }
} else {
dataSourceStat = new JdbcDataSourceStat(this.name, this.jdbcUrl, this.dbType);
}
@@ -1042,8 +1045,13 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
}
LOG.error("recyle error", e);
+ recycleErrorCount.incrementAndGet();
}
}
+
+ public long getRecycleErrorCount() {
+ return recycleErrorCount.get();
+ }
public void clearStatementCache() throws SQLException {
lock.lock();
@@ -1228,7 +1236,15 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
@Override
public Connection getConnection(String username, String password) throws SQLException {
- throw new UnsupportedOperationException("Not supported by DruidDataSource");
+ if (!StringUtils.equals(username, this.username)) {
+ throw new UnsupportedOperationException("Not supported by DruidDataSource");
+ }
+
+ if (!StringUtils.equals(password, this.password)) {
+ throw new UnsupportedOperationException("Not supported by DruidDataSource");
+ }
+
+ return getConnection();
}
public long getCreateCount() {
diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlParameterizedOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlParameterizedOutputVisitor.java
index cd7316d2e0..1b2bbafcde 100644
--- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlParameterizedOutputVisitor.java
+++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlParameterizedOutputVisitor.java
@@ -61,6 +61,23 @@ public class MySqlParameterizedOutputVisitor extends MySqlOutputVisitor {
return false;
}
}
+
+ int numberCount = 0;
+ for (int i = name.length() - 1; i >= 0; --i) {
+ char ch = name.charAt(i);
+ if (ch < '0' || ch > '9') {
+ break;
+ } else {
+ numberCount++;
+ }
+ }
+
+ if (numberCount > 1) {
+ int numPos = name.length() - numberCount;
+ String realName = name.substring(0, numPos);
+ print(realName);
+ return false;
+ }
}
print(name);
return false;
diff --git a/src/main/java/com/alibaba/druid/stat/JdbcDataSourceStat.java b/src/main/java/com/alibaba/druid/stat/JdbcDataSourceStat.java
index 2b0f07d348..661b06dea1 100644
--- a/src/main/java/com/alibaba/druid/stat/JdbcDataSourceStat.java
+++ b/src/main/java/com/alibaba/druid/stat/JdbcDataSourceStat.java
@@ -70,9 +70,18 @@ public class JdbcDataSourceStat implements JdbcDataSourceStatMBean {
private final AtomicLong blobOpenCount = new AtomicLong();
- private static JdbcDataSourceStat global = new JdbcDataSourceStat(
- "global",
- "global");
+ private static JdbcDataSourceStat global;
+
+ static {
+ String dbType = null;
+ {
+ String property = System.getProperty("druid.globalDbType");
+ if (property != null && property.length() > 0) {
+ dbType = property;
+ }
+ }
+ global = new JdbcDataSourceStat("Global", "Global", dbType);
+ }
public static JdbcDataSourceStat getGlobal() {
return global;
@@ -114,6 +123,14 @@ public class JdbcDataSourceStat implements JdbcDataSourceStatMBean {
sqlStatMap = new LRUCache(maxSize, 16, 0.75f, false);
}
+ public String getDbType() {
+ return dbType;
+ }
+
+ public void setDbType(String dbType) {
+ this.dbType = dbType;
+ }
+
public void reset() {
blobOpenCount.set(0);
clobOpenCount.set(0);
@@ -266,6 +283,7 @@ public class JdbcDataSourceStat implements JdbcDataSourceStatMBean {
if (sqlStat == null) {
sqlStat = new JdbcSqlStat(sql);
sqlStat.setDbType(this.dbType);
+ sqlStat.setName(this.name);
sqlStatMap.put(sql, sqlStat);
}
diff --git a/src/main/java/com/alibaba/druid/support/http/WebStatFilter.java b/src/main/java/com/alibaba/druid/support/http/WebStatFilter.java
index cca00180c0..4dea2225da 100644
--- a/src/main/java/com/alibaba/druid/support/http/WebStatFilter.java
+++ b/src/main/java/com/alibaba/druid/support/http/WebStatFilter.java
@@ -191,9 +191,11 @@ public class WebStatFilter implements Filter {
if (isProfileEnable()) {
Profiler.release(nanos);
-
+
Map requestStatsMap = Profiler.getStatsMap();
- uriStat.getProfiletat().record(requestStatsMap);
+ if (uriStat != null) {
+ uriStat.getProfiletat().record(requestStatsMap);
+ }
Profiler.removeLocal();
}
}
@@ -380,8 +382,9 @@ public class WebStatFilter implements Filter {
StatFilterContext.getInstance().addContextListener(statFilterContextListener);
this.contextPath = DruidWebUtils.getContextPath(config.getServletContext());
- webAppStat = new WebAppStat(contextPath, this.sessionStatMaxCount);
-
+ if (webAppStat == null) {
+ webAppStat = new WebAppStat(contextPath, this.sessionStatMaxCount);
+ }
WebAppStatManager.getInstance().addWebAppStatSet(webAppStat);
}
@@ -410,6 +413,10 @@ public class WebStatFilter implements Filter {
this.profileEnable = profileEnable;
}
+ public void setWebAppStat(WebAppStat webAppStat) {
+ this.webAppStat = webAppStat;
+ }
+
public WebAppStat getWebAppStat() {
return webAppStat;
}
diff --git a/src/main/java/com/alibaba/druid/wall/spi/MySqlWallVisitor.java b/src/main/java/com/alibaba/druid/wall/spi/MySqlWallVisitor.java
index 1aa506e897..4fb1db7d76 100644
--- a/src/main/java/com/alibaba/druid/wall/spi/MySqlWallVisitor.java
+++ b/src/main/java/com/alibaba/druid/wall/spi/MySqlWallVisitor.java
@@ -63,7 +63,6 @@ import com.alibaba.druid.wall.WallContext;
import com.alibaba.druid.wall.WallProvider;
import com.alibaba.druid.wall.WallSqlTableStat;
import com.alibaba.druid.wall.WallVisitor;
-import com.alibaba.druid.wall.spi.WallVisitorUtils.WallConditionContext;
import com.alibaba.druid.wall.violation.ErrorCode;
import com.alibaba.druid.wall.violation.IllegalSQLObjectViolation;
@@ -178,13 +177,13 @@ public class MySqlWallVisitor extends MySqlASTVisitorAdapter implements WallVisi
public boolean visit(Limit x) {
if (x.getRowCount() instanceof SQLNumericLiteralExpr) {
WallContext context = WallContext.current();
-
+
int rowCount = ((SQLNumericLiteralExpr) x.getRowCount()).getNumber().intValue();
if (rowCount == 0) {
if (context != null) {
context.incrementWarnnings();
}
-
+
if (!provider.getConfig().isLimitZeroAllow()) {
this.getViolations().add(new IllegalSQLObjectViolation(ErrorCode.LIMIT_ZERO, "limit row 0",
this.toSQL(x)));
@@ -209,8 +208,21 @@ public class MySqlWallVisitor extends MySqlASTVisitorAdapter implements WallVisi
if (!checkVar(x.getParent(), x.getName())) {
boolean isTop = WallVisitorUtils.isTopNoneFromSelect(this, x);
if (!isTop) {
- violations.add(new IllegalSQLObjectViolation(ErrorCode.VARIANT_DENY, "variable not allow : "
- + x.getName(), toSQL(x)));
+ boolean allow = true;
+ if (isDeny(varName)) {
+ allow = false;
+ }
+
+ if (allow) {
+ if (WallVisitorUtils.isWhereOrHaving(x)) {
+ allow = false;
+ }
+ }
+
+ if (!allow) {
+ violations.add(new IllegalSQLObjectViolation(ErrorCode.VARIANT_DENY, "variable not allow : "
+ + x.getName(), toSQL(x)));
+ }
}
}
return false;
@@ -248,6 +260,14 @@ public class MySqlWallVisitor extends MySqlASTVisitorAdapter implements WallVisi
return false;
}
+
+ public boolean isDeny(String varName) {
+ if (varName.startsWith("@@")) {
+ varName = varName.substring(2);
+ }
+
+ return config.getDenyVariants().contains(varName);
+ }
public boolean visit(SQLVariantRefExpr x) {
String varName = x.getName();
@@ -256,10 +276,23 @@ public class MySqlWallVisitor extends MySqlASTVisitorAdapter implements WallVisi
}
if (varName.startsWith("@@") && !checkVar(x.getParent(), x.getName())) {
- boolean noneCondition = WallVisitorUtils.getWallConditionContext() == null;
- if (!noneCondition) {
- violations.add(new IllegalSQLObjectViolation(ErrorCode.VARIANT_DENY, "variable not allow : "
- + x.getName(), toSQL(x)));
+ boolean isTop = WallVisitorUtils.isTopNoneFromSelect(this, x);
+ if (!isTop) {
+ boolean allow = true;
+ if (isDeny(varName)) {
+ allow = false;
+ }
+
+ if (allow) {
+ if (WallVisitorUtils.isWhereOrHaving(x)) {
+ allow = false;
+ }
+ }
+
+ if (!allow) {
+ violations.add(new IllegalSQLObjectViolation(ErrorCode.VARIANT_DENY, "variable not allow : "
+ + x.getName(), toSQL(x)));
+ }
}
}
diff --git a/src/main/java/com/alibaba/druid/wall/spi/WallVisitorUtils.java b/src/main/java/com/alibaba/druid/wall/spi/WallVisitorUtils.java
index 6ae42251d6..8a0d28374e 100644
--- a/src/main/java/com/alibaba/druid/wall/spi/WallVisitorUtils.java
+++ b/src/main/java/com/alibaba/druid/wall/spi/WallVisitorUtils.java
@@ -60,6 +60,7 @@ import com.alibaba.druid.sql.ast.statement.SQLInsertStatement;
import com.alibaba.druid.sql.ast.statement.SQLJoinTableSource;
import com.alibaba.druid.sql.ast.statement.SQLRollbackStatement;
import com.alibaba.druid.sql.ast.statement.SQLSelect;
+import com.alibaba.druid.sql.ast.statement.SQLSelectGroupByClause;
import com.alibaba.druid.sql.ast.statement.SQLSelectItem;
import com.alibaba.druid.sql.ast.statement.SQLSelectQuery;
import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
@@ -622,6 +623,40 @@ public class WallVisitorUtils {
return false;
}
+ public static boolean isWhereOrHaving(SQLObject x) {
+ if (x == null) {
+ return false;
+ }
+
+ for (;;) {
+ SQLObject parent = x.getParent();
+
+ if (parent == null) {
+ return false;
+ }
+
+ if (parent instanceof SQLSelectQueryBlock) {
+ SQLSelectQueryBlock query = (SQLSelectQueryBlock) parent;
+ if (query.getWhere() == x) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ if (parent instanceof SQLSelectGroupByClause) {
+ SQLSelectGroupByClause groupBy = (SQLSelectGroupByClause) parent;
+ if (x == groupBy.getHaving()) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ x = parent;
+ }
+ }
+
public static class WallConditionContext {
private boolean partAlwayrue;
diff --git a/src/main/resources/META-INF/druid/wall/mysql/deny-variant.txt b/src/main/resources/META-INF/druid/wall/mysql/deny-variant.txt
new file mode 100644
index 0000000000..9c0c1da30a
--- /dev/null
+++ b/src/main/resources/META-INF/druid/wall/mysql/deny-variant.txt
@@ -0,0 +1,3 @@
+basedir
+version_compile_os
+version
\ No newline at end of file
diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallPermitVariantTest.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallPermitVariantTest.java
index 358506609e..bd48b1b3bf 100644
--- a/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallPermitVariantTest.java
+++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallPermitVariantTest.java
@@ -21,6 +21,7 @@ import org.junit.Assert;
import com.alibaba.druid.wall.WallConfig;
import com.alibaba.druid.wall.WallUtils;
+import com.alibaba.druid.wall.spi.MySqlWallProvider;
/**
* 这个场景测试访问Oracle系统对象
@@ -30,16 +31,16 @@ import com.alibaba.druid.wall.WallUtils;
public class MySqlWallPermitVariantTest extends TestCase {
public void test_allow() throws Exception {
- WallConfig config = new WallConfig();
- config.setVariantCheck(false);
+ MySqlWallProvider provider = new MySqlWallProvider();
+ provider.getConfig().setVariantCheck(false);
- Assert.assertTrue(WallUtils.isValidateMySql("select @@version_compile_os FROM X", config));
+ Assert.assertTrue(provider.checkValid("select @@version_compile_os FROM X"));
}
public void test_not_allow() throws Exception {
- WallConfig config = new WallConfig();
- config.setVariantCheck(true);
+ MySqlWallProvider provider = new MySqlWallProvider();
+ provider.getConfig().setVariantCheck(true);
- Assert.assertFalse(WallUtils.isValidateMySql("select @@version_compile_os FROM X", config));
+ Assert.assertFalse(provider.checkValid("select @@version_compile_os FROM X"));
}
}
diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest72.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest72.java
index c2ec53d1e1..943edca932 100644
--- a/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest72.java
+++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/MySqlWallTest72.java
@@ -37,7 +37,7 @@ public class MySqlWallTest72 extends TestCase {
provider.getConfig().setCommentAllow(true);
Assert.assertFalse(provider.checkValid(//
- "select * from t /**/ where 1=1"));
+ "select * from t /**/ where fid = 123 AND 1=1"));
Assert.assertEquals(1, provider.getTableStats().size());
}
diff --git a/src/test/java/com/alibaba/druid/bvt/pool/ConfigErrorTest3.java b/src/test/java/com/alibaba/druid/bvt/pool/ConfigErrorTest3.java
index c96d1e9464..5d839684ba 100644
--- a/src/test/java/com/alibaba/druid/bvt/pool/ConfigErrorTest3.java
+++ b/src/test/java/com/alibaba/druid/bvt/pool/ConfigErrorTest3.java
@@ -17,9 +17,10 @@ package com.alibaba.druid.bvt.pool;
import java.lang.reflect.Field;
-import junit.framework.Assert;
import junit.framework.TestCase;
+import org.junit.Assert;
+
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.logging.Log;
@@ -50,6 +51,6 @@ public class ConfigErrorTest3 extends TestCase {
Assert.assertEquals(0, LOG.getErrorCount());
dataSource.init();
- Assert.assertEquals(1, LOG.getErrorCount());
+ Assert.assertEquals(0, LOG.getErrorCount());
}
}
diff --git a/src/test/java/com/alibaba/druid/bvt/pool/DruidDataSourceC3P0AdapterTest.java b/src/test/java/com/alibaba/druid/bvt/pool/DruidDataSourceC3P0AdapterTest.java
index 8e9ca5c1b7..7fe99182f1 100644
--- a/src/test/java/com/alibaba/druid/bvt/pool/DruidDataSourceC3P0AdapterTest.java
+++ b/src/test/java/com/alibaba/druid/bvt/pool/DruidDataSourceC3P0AdapterTest.java
@@ -24,30 +24,25 @@ public class DruidDataSourceC3P0AdapterTest extends TestCase {
dataSource.close();
}
- public void test_conn_err() throws Exception {
- Exception error = null;
- try {
- dataSource.getConnection(null, null);
- } catch (UnsupportedOperationException e) {
- error = e;
- }
- Assert.assertNotNull(error);
+ public void test_conn_1() throws Exception {
+ Connection conn = dataSource.getConnection(null, null);
+ conn.close();
}
-
+
public void test_getDriverClass() throws Exception {
Assert.assertNull(dataSource.getDriverClass());
-
+
Connection conn = dataSource.getConnection();
conn.close();
-
+
Assert.assertEquals(MockDriver.class.getName(), dataSource.getDriverClass());
Assert.assertEquals(MockDriver.instance, dataSource.getDriver());
}
-
+
public void test_getJdbcUrl() throws Exception {
Assert.assertEquals("jdbc:mock:xxx", dataSource.getJdbcUrl());
}
-
+
public void test_getParentLogger_err() throws Exception {
Exception error = null;
try {
@@ -57,72 +52,72 @@ public class DruidDataSourceC3P0AdapterTest extends TestCase {
}
Assert.assertNotNull(error);
}
-
+
public void test_propertyCycle() throws Exception {
dataSource.setPropertyCycle(3);
Assert.assertEquals(3, dataSource.getPropertyCycle());
}
-
+
public void test_acquireIncrement() throws Exception {
dataSource.setAcquireIncrement(4);
Assert.assertEquals(4, dataSource.getAcquireIncrement());
}
-
+
public void test_overrideDefaultPassword() throws Exception {
dataSource.setOverrideDefaultPassword("x2");
Assert.assertEquals("x2", dataSource.getOverrideDefaultPassword());
}
-
+
public void test_overrideDefaultUser() throws Exception {
dataSource.setOverrideDefaultUser("x1");
Assert.assertEquals("x1", dataSource.getOverrideDefaultUser());
}
-
+
public void test_factoryClassLocation() throws Exception {
dataSource.setFactoryClassLocation("x3");
Assert.assertEquals("x3", dataSource.getFactoryClassLocation());
}
-
+
public void test_maxConnectionAge() throws Exception {
dataSource.setMaxConnectionAge(123);
Assert.assertEquals(123, dataSource.getMaxConnectionAge());
}
-
+
public void test_connectionCustomizerClassName() throws Exception {
dataSource.setConnectionCustomizerClassName("x4");
Assert.assertEquals("x4", dataSource.getConnectionCustomizerClassName());
}
-
+
public void test_maxIdleTimeExcessConnections() throws Exception {
dataSource.setMaxIdleTimeExcessConnections(101);
Assert.assertEquals(101, dataSource.getMaxIdleTimeExcessConnections());
}
-
+
public void test_maxAdministrativeTaskTime() throws Exception {
dataSource.setMaxAdministrativeTaskTime(102);
Assert.assertEquals(102, dataSource.getMaxAdministrativeTaskTime());
}
-
+
public void test_userOverridesAsString() throws Exception {
dataSource.setUserOverridesAsString("x5");
Assert.assertEquals("x5", dataSource.getUserOverridesAsString());
}
-
+
public void test_usesTraditionalReflectiveProxies() throws Exception {
dataSource.setUsesTraditionalReflectiveProxies(true);
Assert.assertEquals(true, dataSource.isUsesTraditionalReflectiveProxies());
}
-
+
public void test_forceIgnoreUnresolvedTransactions() throws Exception {
dataSource.setForceIgnoreUnresolvedTransactions(true);
Assert.assertEquals(true, dataSource.isForceIgnoreUnresolvedTransactions());
}
-
+
public void test_automaticTestTable() throws Exception {
dataSource.setAutomaticTestTable("x6");
Assert.assertEquals("x6", dataSource.getAutomaticTestTable());
}
-
+
public void test_connectionTesterClassName() throws Exception {
dataSource.setConnectionTesterClassName("x6");
Assert.assertEquals("x6", dataSource.getConnectionTesterClassName());
diff --git a/src/test/java/com/alibaba/druid/bvt/pool/DruidDataSourceTest_getConnection.java b/src/test/java/com/alibaba/druid/bvt/pool/DruidDataSourceTest_getConnection.java
index e081ee69b6..5681773450 100644
--- a/src/test/java/com/alibaba/druid/bvt/pool/DruidDataSourceTest_getConnection.java
+++ b/src/test/java/com/alibaba/druid/bvt/pool/DruidDataSourceTest_getConnection.java
@@ -1,5 +1,7 @@
package com.alibaba.druid.bvt.pool;
+import java.sql.Connection;
+
import junit.framework.TestCase;
import org.junit.Assert;
@@ -26,10 +28,25 @@ public class DruidDataSourceTest_getConnection extends TestCase {
dataSource.close();
}
- public void test_conn_error() throws Exception {
+ public void test_conn_ok() throws Exception {
+ Connection conn = dataSource.getConnection(null, null);
+ conn.close();
+ }
+
+ public void test_conn_user_error() throws Exception {
Exception error = null;
try {
- dataSource.getConnection(null, null);
+ dataSource.getConnection("a", null);
+ } catch (UnsupportedOperationException e) {
+ error = e;
+ }
+ Assert.assertNotNull(error);
+ }
+
+ public void test_conn_password_error() throws Exception {
+ Exception error = null;
+ try {
+ dataSource.getConnection(null, "a");
} catch (UnsupportedOperationException e) {
error = e;
}
diff --git a/src/test/java/com/alibaba/druid/bvt/pool/exception/OracleExceptionSorterTest_concurrent.java b/src/test/java/com/alibaba/druid/bvt/pool/exception/OracleExceptionSorterTest_concurrent.java
new file mode 100644
index 0000000000..884e8ea066
--- /dev/null
+++ b/src/test/java/com/alibaba/druid/bvt/pool/exception/OracleExceptionSorterTest_concurrent.java
@@ -0,0 +1,105 @@
+package com.alibaba.druid.bvt.pool.exception;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.concurrent.CountDownLatch;
+
+import junit.framework.TestCase;
+
+import org.junit.Assert;
+
+import com.alibaba.druid.mock.MockConnection;
+import com.alibaba.druid.pool.DruidDataSource;
+import com.alibaba.druid.pool.vendor.OracleExceptionSorter;
+import com.alibaba.druid.stat.DruidDataSourceStatManager;
+import com.alibaba.druid.stat.JdbcStatManager;
+import com.alibaba.druid.test.util.OracleMockDriver;
+import com.alibaba.druid.util.JdbcUtils;
+
+public class OracleExceptionSorterTest_concurrent extends TestCase {
+
+ private DruidDataSource dataSource;
+
+ protected void setUp() throws Exception {
+ Assert.assertEquals(0, JdbcStatManager.getInstance().getSqlList().size());
+
+ dataSource = new DruidDataSource();
+
+ dataSource.setExceptionSorter(new OracleExceptionSorter());
+
+ dataSource.setDriver(new OracleMockDriver());
+ dataSource.setUrl("jdbc:mock:xxx");
+ dataSource.setPoolPreparedStatements(true);
+ dataSource.setMaxOpenPreparedStatements(100);
+ dataSource.setMaxActive(1);
+ dataSource.setMaxWait(1000 * 100);
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ JdbcUtils.close(dataSource);
+ Assert.assertEquals(0, DruidDataSourceStatManager.getInstance().getDataSourceList().size());
+ }
+
+ public void test_connect() throws Exception {
+ final CountDownLatch latch_0 = new CountDownLatch(1);
+
+ Thread errorThread = new Thread() {
+
+ public void run() {
+ try {
+ Connection conn = dataSource.getConnection();
+
+ latch_0.countDown();
+
+ MockConnection mockConn = conn.unwrap(MockConnection.class);
+ Assert.assertNotNull(mockConn);
+
+ SQLException exception = new SQLException("xx", "xxx", 28);
+ mockConn.setError(exception);
+
+ try {
+ conn.createStatement();
+ } catch (SQLException ex) {
+ // ex.printStackTrace();
+ }
+ conn.close();
+ } catch (Exception error) {
+ error.printStackTrace();
+ }
+ }
+ };
+ errorThread.start();
+
+ final CountDownLatch workLatch = new CountDownLatch(2);
+ final CountDownLatch workCompleteLatch = new CountDownLatch(2);
+ for (int i = 0; i < 2; ++i) {
+ Thread thread = new Thread() {
+
+ public void run() {
+ try {
+ for (int i = 0; i < 1000; ++i) {
+ workLatch.countDown();
+ Connection conn = dataSource.getConnection();
+ conn.close();
+ }
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ } finally {
+ workCompleteLatch.countDown();
+ }
+ }
+ };
+ thread.start();
+ }
+ workLatch.await();
+
+ latch_0.countDown();
+
+ workCompleteLatch.await();
+
+ Assert.assertEquals(2001, dataSource.getConnectCount());
+ }
+
+}
diff --git a/src/test/java/com/alibaba/druid/bvt/proxy/filter/GlobalStatTest0.java b/src/test/java/com/alibaba/druid/bvt/proxy/filter/GlobalStatTest0.java
index 4ec5a7a824..d0a24ba237 100644
--- a/src/test/java/com/alibaba/druid/bvt/proxy/filter/GlobalStatTest0.java
+++ b/src/test/java/com/alibaba/druid/bvt/proxy/filter/GlobalStatTest0.java
@@ -3,14 +3,18 @@ package com.alibaba.druid.bvt.proxy.filter;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
-
-import org.junit.Assert;
+import java.util.List;
+import java.util.Map;
import junit.framework.TestCase;
+import org.junit.Assert;
+
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.stat.JdbcDataSourceStat;
import com.alibaba.druid.stat.JdbcStatManager;
+import com.alibaba.druid.support.json.JSONUtils;
+import com.alibaba.druid.util.JdbcConstants;
import com.alibaba.druid.util.JdbcUtils;
public class GlobalStatTest0 extends TestCase {
@@ -41,6 +45,7 @@ public class GlobalStatTest0 extends TestCase {
Assert.assertEquals(0, JdbcStatManager.getInstance().getSqlList().size());
}
+ @SuppressWarnings("unchecked")
public void test_execute() throws Exception {
{
Connection conn = dataSourceA.getConnection();
@@ -69,6 +74,13 @@ public class GlobalStatTest0 extends TestCase {
Assert.assertSame(JdbcDataSourceStat.getGlobal(), dataSourceB.getDataSourceStat());
Assert.assertEquals(1, JdbcStatManager.getInstance().getSqlList().size());
+ String json = JSONUtils.toJSONString(JdbcStatManager.getInstance().getSqlList());
+ List