From ec91bff3311351ac50f9dbda2a70e07e59074d80 Mon Sep 17 00:00:00 2001 From: Brett Wooldridge Date: Tue, 14 Oct 2014 10:36:50 +0900 Subject: [PATCH] More code coverage tests. --- .../com/zaxxer/hikari/TestConcurrentBag.java | 96 +++ .../test/java/com/zaxxer/hikari/TestElf.java | 4 +- .../test/java/com/zaxxer/hikari/TestJNDI.java | 31 + .../java/com/zaxxer/hikari/TestProxies.java | 226 +++++ .../com/zaxxer/hikari/TestValidation.java | 15 + .../hikari/mocks/StubBaseConnection.java | 32 +- .../zaxxer/hikari/mocks/StubConnection.java | 808 ++++++++++-------- .../test/java/com/zaxxer/hikari/MiscTest.java | 75 +- .../com/zaxxer/hikari/TestConcurrentBag.java | 96 +++ .../test/java/com/zaxxer/hikari/TestElf.java | 4 +- .../test/java/com/zaxxer/hikari/TestJNDI.java | 16 + .../java/com/zaxxer/hikari/TestProxies.java | 226 +++++ .../com/zaxxer/hikari/TestValidation.java | 15 + .../hikari/mocks/StubBaseConnection.java | 32 +- .../zaxxer/hikari/mocks/StubConnection.java | 808 ++++++++++-------- 15 files changed, 1635 insertions(+), 849 deletions(-) create mode 100644 hikaricp-java6/src/test/java/com/zaxxer/hikari/TestConcurrentBag.java create mode 100644 hikaricp/src/test/java/com/zaxxer/hikari/TestConcurrentBag.java diff --git a/hikaricp-java6/src/test/java/com/zaxxer/hikari/TestConcurrentBag.java b/hikaricp-java6/src/test/java/com/zaxxer/hikari/TestConcurrentBag.java new file mode 100644 index 00000000..a2f3aa1a --- /dev/null +++ b/hikaricp-java6/src/test/java/com/zaxxer/hikari/TestConcurrentBag.java @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2013 Brett Wooldridge + * + * 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.zaxxer.hikari; + +import java.util.concurrent.TimeUnit; + +import org.junit.Assert; +import org.junit.Test; + +import com.zaxxer.hikari.pool.PoolBagEntry; +import com.zaxxer.hikari.util.ConcurrentBag; + +/** + * + * @author Brett Wooldridge + */ +public class TestConcurrentBag +{ + @Test + public void testConcurrentBag() throws InterruptedException + { + ConcurrentBag bag = new ConcurrentBag(null); + Assert.assertEquals(0, bag.values(8).size()); + + PoolBagEntry reserved = new PoolBagEntry(null, 0); + bag.add(reserved); + bag.reserve(reserved); // reserved + + PoolBagEntry inuse = new PoolBagEntry(null, 0); + bag.add(inuse); + bag.borrow(2L, TimeUnit.SECONDS); // in use + + PoolBagEntry notinuse = new PoolBagEntry(null, 0); + bag.add(notinuse); // not in use + + bag.dumpState(); + + try { + bag.requite(reserved); + Assert.fail(); + } + catch (IllegalStateException e) { + // pass + } + + try { + bag.remove(notinuse); + Assert.fail(); + } + catch (IllegalStateException e) { + // pass + } + + try { + bag.unreserve(notinuse); + Assert.fail(); + } + catch (IllegalStateException e) { + // pass + } + + try { + bag.remove(inuse); + bag.remove(inuse); + Assert.fail(); + } + catch (IllegalStateException e) { + // pass + } + + bag.close(); + try { + bag.add(new PoolBagEntry(null, 0)); + Assert.fail(); + } + catch (IllegalStateException e) { + // pass + } + + Assert.assertNotNull(notinuse.toString()); + } +} diff --git a/hikaricp-java6/src/test/java/com/zaxxer/hikari/TestElf.java b/hikaricp-java6/src/test/java/com/zaxxer/hikari/TestElf.java index 110e4387..9be1c32c 100644 --- a/hikaricp-java6/src/test/java/com/zaxxer/hikari/TestElf.java +++ b/hikaricp-java6/src/test/java/com/zaxxer/hikari/TestElf.java @@ -61,12 +61,12 @@ public final class TestElf } } - public static void setConfigUnitTest() + public static void setConfigUnitTest(boolean unitTest) { try { Field field = HikariConfig.class.getDeclaredField("unitTest"); field.setAccessible(true); - field.setBoolean(null, true); + field.setBoolean(null, unitTest); } catch (Exception e) { throw new RuntimeException(e); diff --git a/hikaricp-java6/src/test/java/com/zaxxer/hikari/TestJNDI.java b/hikaricp-java6/src/test/java/com/zaxxer/hikari/TestJNDI.java index 903e1433..6985ceac 100644 --- a/hikaricp-java6/src/test/java/com/zaxxer/hikari/TestJNDI.java +++ b/hikaricp-java6/src/test/java/com/zaxxer/hikari/TestJNDI.java @@ -1,3 +1,18 @@ +/* + * Copyright (C) 2014 Brett Wooldridge + * + * 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.zaxxer.hikari; import javax.naming.Context; @@ -53,6 +68,22 @@ public class TestJNDI Assert.assertEquals("foo", ds.getUsername()); } + @Test + public void testJndiLookup3() throws Exception + { + HikariJNDIFactory jndi = new HikariJNDIFactory(); + + Reference ref = new Reference("javax.sql.DataSource"); + ref.add(new BogusRef("dataSourceJNDI", "java:comp/env/HikariDS")); + try { + jndi.getObjectInstance(ref, null, null, null); + Assert.fail(); + } + catch (RuntimeException e) { + Assert.assertTrue(e.getMessage().contains("JNDI context is null")); + } + } + private class BogusContext extends AbstractContext { @Override diff --git a/hikaricp-java6/src/test/java/com/zaxxer/hikari/TestProxies.java b/hikaricp-java6/src/test/java/com/zaxxer/hikari/TestProxies.java index cd083dab..19685429 100644 --- a/hikaricp-java6/src/test/java/com/zaxxer/hikari/TestProxies.java +++ b/hikaricp-java6/src/test/java/com/zaxxer/hikari/TestProxies.java @@ -4,12 +4,14 @@ import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; +import java.util.concurrent.TimeUnit; import org.junit.Assert; import org.junit.Test; import com.zaxxer.hikari.mocks.StubConnection; import com.zaxxer.hikari.mocks.StubStatement; +import com.zaxxer.hikari.util.PoolUtilities; public class TestProxies { @@ -88,4 +90,228 @@ public class TestProxies ds.close(); } } + + @Test + public void testStatementExceptions() throws SQLException + { + HikariConfig config = new HikariConfig(); + config.setMinimumIdle(0); + config.setMaximumPoolSize(1); + config.setConnectionTimeout(TimeUnit.SECONDS.toMillis(1)); + config.setConnectionTestQuery("VALUES 1"); + config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource"); + + HikariDataSource ds = new HikariDataSource(config); + try { + Connection conn = ds.getConnection(); + StubConnection stubConnection = conn.unwrap(StubConnection.class); + stubConnection.throwException = true; + + try { + conn.createStatement(); + Assert.fail(); + } + catch (SQLException e) { + // pass + } + + try { + conn.createStatement(0, 0); + Assert.fail(); + } + catch (SQLException e) { + // pass + } + + try { + conn.createStatement(0, 0, 0); + Assert.fail(); + } + catch (SQLException e) { + // pass + } + + try { + conn.prepareCall(""); + Assert.fail(); + } + catch (SQLException e) { + // pass + } + + try { + conn.prepareCall("", 0, 0); + Assert.fail(); + } + catch (SQLException e) { + // pass + } + + try { + conn.prepareCall("", 0, 0, 0); + Assert.fail(); + } + catch (SQLException e) { + // pass + } + + try { + conn.prepareStatement(""); + Assert.fail(); + } + catch (SQLException e) { + // pass + } + + try { + conn.prepareStatement("", 0); + Assert.fail(); + } + catch (SQLException e) { + // pass + } + + try { + conn.prepareStatement("", new int[0]); + Assert.fail(); + } + catch (SQLException e) { + // pass + } + + try { + conn.prepareStatement("", new String[0]); + Assert.fail(); + } + catch (SQLException e) { + // pass + } + + try { + conn.prepareStatement("", 0, 0); + Assert.fail(); + } + catch (SQLException e) { + // pass + } + + try { + conn.prepareStatement("", 0, 0, 0); + Assert.fail(); + } + catch (SQLException e) { + // pass + } + } + finally { + ds.close(); + } + } + + @Test + public void testOtherExceptions() throws SQLException + { + HikariConfig config = new HikariConfig(); + config.setMinimumIdle(0); + config.setMaximumPoolSize(1); + config.setConnectionTestQuery("VALUES 1"); + config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource"); + + HikariDataSource ds = new HikariDataSource(config); + try { + Connection conn = ds.getConnection(); + StubConnection stubConnection = conn.unwrap(StubConnection.class); + stubConnection.throwException = true; + + try { + conn.setTransactionIsolation(Connection.TRANSACTION_NONE); + Assert.fail(); + } + catch (SQLException e) { + // pass + } + + try { + conn.isReadOnly(); + Assert.fail(); + } + catch (SQLException e) { + // pass + } + + try { + conn.setReadOnly(false); + Assert.fail(); + } + catch (SQLException e) { + // pass + } + + try { + conn.setCatalog(""); + Assert.fail(); + } + catch (SQLException e) { + // pass + } + + try { + conn.setAutoCommit(false); + Assert.fail(); + } + catch (SQLException e) { + // pass + } + + try { + conn.clearWarnings(); + Assert.fail(); + } + catch (SQLException e) { + // pass + } + + try { + conn.isValid(0); + Assert.fail(); + } + catch (SQLException e) { + // pass + } + + try { + conn.isWrapperFor(getClass()); + Assert.fail(); + } + catch (SQLException e) { + // pass + } + + try { + conn.unwrap(getClass()); + Assert.fail(); + } + catch (SQLException e) { + // pass + } + + try { + conn.close(); + Assert.fail(); + } + catch (SQLException e) { + // pass + } + + try { + Assert.assertFalse(conn.isValid(0)); + } + catch (SQLException e) { + Assert.fail(); + } +} + finally { + ds.close(); + } + } } diff --git a/hikaricp-java6/src/test/java/com/zaxxer/hikari/TestValidation.java b/hikaricp-java6/src/test/java/com/zaxxer/hikari/TestValidation.java index 2ee2df38..5cebc5d7 100644 --- a/hikaricp-java6/src/test/java/com/zaxxer/hikari/TestValidation.java +++ b/hikaricp-java6/src/test/java/com/zaxxer/hikari/TestValidation.java @@ -267,6 +267,21 @@ public class TestValidation } } + @Test + public void validateInvalidLeakDetection() + { + try { + HikariConfig config = new HikariConfig(); + config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource"); + config.setLeakDetectionThreshold(1000L); + config.validate(); + Assert.assertEquals(0, config.getLeakDetectionThreshold()); + } + catch (IllegalArgumentException ise) { + // pass + } + } + @Test public void validateZeroConnectionTimeout() { diff --git a/hikaricp-java6/src/test/java/com/zaxxer/hikari/mocks/StubBaseConnection.java b/hikaricp-java6/src/test/java/com/zaxxer/hikari/mocks/StubBaseConnection.java index ee1d64eb..af784cc3 100644 --- a/hikaricp-java6/src/test/java/com/zaxxer/hikari/mocks/StubBaseConnection.java +++ b/hikaricp-java6/src/test/java/com/zaxxer/hikari/mocks/StubBaseConnection.java @@ -7,17 +7,25 @@ import java.sql.Statement; public abstract class StubBaseConnection implements Connection { - /** {@inheritDoc} */ - @Override - public Statement createStatement() throws SQLException - { - return new StubStatement(this); - } + public volatile boolean throwException; - /** {@inheritDoc} */ - @Override - public PreparedStatement prepareStatement(String sql) throws SQLException - { - return new StubPreparedStatement(this); - } + /** {@inheritDoc} */ + @Override + public Statement createStatement() throws SQLException + { + if (throwException) { + throw new SQLException(); + } + return new StubStatement(this); + } + + /** {@inheritDoc} */ + @Override + public PreparedStatement prepareStatement(String sql) throws SQLException + { + if (throwException) { + throw new SQLException(); + } + return new StubPreparedStatement(this); + } } diff --git a/hikaricp-java6/src/test/java/com/zaxxer/hikari/mocks/StubConnection.java b/hikaricp-java6/src/test/java/com/zaxxer/hikari/mocks/StubConnection.java index 2434eef2..3bbd3f25 100644 --- a/hikaricp-java6/src/test/java/com/zaxxer/hikari/mocks/StubConnection.java +++ b/hikaricp-java6/src/test/java/com/zaxxer/hikari/mocks/StubConnection.java @@ -45,380 +45,438 @@ import com.zaxxer.hikari.util.PoolUtilities; */ public class StubConnection extends StubBaseConnection implements Connection { - public static final AtomicInteger count = new AtomicInteger(); - public static volatile boolean slowCreate; - - private static long foo; - private boolean autoCommit; - private int isolation; - private String catalog; - - static - { - foo = System.currentTimeMillis(); - } - - public StubConnection() - { - count.incrementAndGet(); - if (slowCreate) - { - PoolUtilities.quietlySleep(TimeUnit.SECONDS.toMillis(1)); - } - } - - /** {@inheritDoc} */ - @SuppressWarnings("unchecked") - @Override - public T unwrap(Class iface) throws SQLException - { - if (iface.isInstance(this)) { - return (T) this; - } - - throw new SQLException("Wrapped connection is not an instance of " + iface); - } - - /** {@inheritDoc} */ - @Override - public boolean isWrapperFor(Class iface) throws SQLException - { - return false; - } - - /** {@inheritDoc} */ - @Override - public CallableStatement prepareCall(String sql) throws SQLException - { - return null; - } - - /** {@inheritDoc} */ - @Override - public String nativeSQL(String sql) throws SQLException - { - return null; - } - - /** {@inheritDoc} */ - @Override - public void setAutoCommit(boolean autoCommit) throws SQLException - { - this.autoCommit = autoCommit; - } - - /** {@inheritDoc} */ - @Override - public boolean getAutoCommit() throws SQLException - { - return autoCommit; - } - - /** {@inheritDoc} */ - @Override - public void commit() throws SQLException - { - - } - - /** {@inheritDoc} */ - @Override - public void rollback() throws SQLException - { - - } - - /** {@inheritDoc} */ - @Override - public void close() throws SQLException - { - - } - - /** {@inheritDoc} */ - @Override - public boolean isClosed() throws SQLException - { - return false; - } - - /** {@inheritDoc} */ - @Override - public DatabaseMetaData getMetaData() throws SQLException - { - return null; - } - - /** {@inheritDoc} */ - @Override - public void setReadOnly(boolean readOnly) throws SQLException - { - } - - /** {@inheritDoc} */ - @Override - public boolean isReadOnly() throws SQLException - { - return false; - } - - /** {@inheritDoc} */ - @Override - public void setCatalog(String catalog) throws SQLException - { - this.catalog = catalog; - } - - /** {@inheritDoc} */ - @Override - public String getCatalog() throws SQLException - { - return catalog; - } - - /** {@inheritDoc} */ - @Override - public void setTransactionIsolation(int level) throws SQLException - { - this.isolation = level; - } - - /** {@inheritDoc} */ - @Override - public int getTransactionIsolation() throws SQLException - { - return isolation; - } - - /** {@inheritDoc} */ - @Override - public SQLWarning getWarnings() throws SQLException - { - return null; - } - - /** {@inheritDoc} */ - @Override - public void clearWarnings() throws SQLException - { - } - - /** {@inheritDoc} */ - @Override - public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException - { - return null; - } - - /** {@inheritDoc} */ - @Override - public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException - { - return new StubPreparedStatement(this); - } - - /** {@inheritDoc} */ - @Override - public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException - { - return null; - } - - /** {@inheritDoc} */ - @Override - public Map> getTypeMap() throws SQLException - { - return null; - } - - /** {@inheritDoc} */ - @Override - public void setTypeMap(Map> map) throws SQLException - { - } - - /** {@inheritDoc} */ - @Override - public void setHoldability(int holdability) throws SQLException - { - } - - /** {@inheritDoc} */ - @Override - public int getHoldability() throws SQLException - { - return (int) foo; - } - - /** {@inheritDoc} */ - @Override - public Savepoint setSavepoint() throws SQLException - { - return null; - } - - /** {@inheritDoc} */ - @Override - public Savepoint setSavepoint(String name) throws SQLException - { - return null; - } - - /** {@inheritDoc} */ - @Override - public void rollback(Savepoint savepoint) throws SQLException - { - } - - /** {@inheritDoc} */ - @Override - public void releaseSavepoint(Savepoint savepoint) throws SQLException - { - } - - /** {@inheritDoc} */ - @Override - public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException - { - return null; - } - - /** {@inheritDoc} */ - @Override - public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException - { - return new StubPreparedStatement(this); - } - - /** {@inheritDoc} */ - @Override - public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException - { - return null; - } - - /** {@inheritDoc} */ - @Override - public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException - { - return new StubPreparedStatement(this); - } - - /** {@inheritDoc} */ - @Override - public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException - { - return new StubPreparedStatement(this); - } - - /** {@inheritDoc} */ - @Override - public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException - { - return new StubPreparedStatement(this); - } - - /** {@inheritDoc} */ - @Override - public Clob createClob() throws SQLException - { - return null; - } - - /** {@inheritDoc} */ - @Override - public Blob createBlob() throws SQLException - { - return null; - } - - /** {@inheritDoc} */ - @Override - public NClob createNClob() throws SQLException - { - return null; - } - - /** {@inheritDoc} */ - @Override - public SQLXML createSQLXML() throws SQLException - { - return null; - } - - /** {@inheritDoc} */ - @Override - public boolean isValid(int timeout) throws SQLException - { - return true; - } - - /** {@inheritDoc} */ - @Override - public void setClientInfo(String name, String value) throws SQLClientInfoException - { - } - - /** {@inheritDoc} */ - @Override - public void setClientInfo(Properties properties) throws SQLClientInfoException - { - } - - /** {@inheritDoc} */ - @Override - public String getClientInfo(String name) throws SQLException - { - return null; - } - - /** {@inheritDoc} */ - @Override - public Properties getClientInfo() throws SQLException - { - return null; - } - - /** {@inheritDoc} */ - @Override - public Array createArrayOf(String typeName, Object[] elements) throws SQLException - { - return null; - } - - /** {@inheritDoc} */ - @Override - public Struct createStruct(String typeName, Object[] attributes) throws SQLException - { - return null; - } - - /** {@inheritDoc} */ - public void setSchema(String schema) throws SQLException - { - } - - /** {@inheritDoc} */ - public String getSchema() throws SQLException - { - return null; - } - - /** {@inheritDoc} */ - public void abort(Executor executor) throws SQLException - { - throw new SQLException("Intentianal exception during abort"); - } - - /** {@inheritDoc} */ - public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException - { - } - - /** {@inheritDoc} */ - public int getNetworkTimeout() throws SQLException - { - return 0; - } + public static final AtomicInteger count = new AtomicInteger(); + public static volatile boolean slowCreate; + + private static long foo; + private boolean autoCommit; + private int isolation; + private String catalog; + + static { + foo = System.currentTimeMillis(); + } + + public StubConnection() { + count.incrementAndGet(); + if (slowCreate) { + PoolUtilities.quietlySleep(TimeUnit.SECONDS.toMillis(1)); + } + } + + /** {@inheritDoc} */ + @SuppressWarnings("unchecked") + @Override + public T unwrap(Class iface) throws SQLException + { + if (throwException) { + throw new SQLException(); + } + + if (iface.isInstance(this)) { + return (T) this; + } + + throw new SQLException("Wrapped connection is not an instance of " + iface); + } + + /** {@inheritDoc} */ + @Override + public boolean isWrapperFor(Class iface) throws SQLException + { + if (throwException) { + throw new SQLException(); + } + return false; + } + + /** {@inheritDoc} */ + @Override + public CallableStatement prepareCall(String sql) throws SQLException + { + if (throwException) { + throw new SQLException(); + } + return null; + } + + /** {@inheritDoc} */ + @Override + public String nativeSQL(String sql) throws SQLException + { + return null; + } + + /** {@inheritDoc} */ + @Override + public void setAutoCommit(boolean autoCommit) throws SQLException + { + if (throwException) { + throw new SQLException(); + } + this.autoCommit = autoCommit; + } + + /** {@inheritDoc} */ + @Override + public boolean getAutoCommit() throws SQLException + { + return autoCommit; + } + + /** {@inheritDoc} */ + @Override + public void commit() throws SQLException + { + + } + + /** {@inheritDoc} */ + @Override + public void rollback() throws SQLException + { + + } + + /** {@inheritDoc} */ + @Override + public void close() throws SQLException + { + + } + + /** {@inheritDoc} */ + @Override + public boolean isClosed() throws SQLException + { + if (throwException) { + throw new SQLException(); + } + return false; + } + + /** {@inheritDoc} */ + @Override + public DatabaseMetaData getMetaData() throws SQLException + { + return null; + } + + /** {@inheritDoc} */ + @Override + public void setReadOnly(boolean readOnly) throws SQLException + { + if (throwException) { + throw new SQLException(); + } + } + + /** {@inheritDoc} */ + @Override + public boolean isReadOnly() throws SQLException + { + if (throwException) { + throw new SQLException(); + } + return false; + } + + /** {@inheritDoc} */ + @Override + public void setCatalog(String catalog) throws SQLException + { + if (throwException) { + throw new SQLException(); + } + this.catalog = catalog; + } + + /** {@inheritDoc} */ + @Override + public String getCatalog() throws SQLException + { + return catalog; + } + + /** {@inheritDoc} */ + @Override + public void setTransactionIsolation(int level) throws SQLException + { + if (throwException) { + throw new SQLException(); + } + this.isolation = level; + } + + /** {@inheritDoc} */ + @Override + public int getTransactionIsolation() throws SQLException + { + return isolation; + } + + /** {@inheritDoc} */ + @Override + public SQLWarning getWarnings() throws SQLException + { + return null; + } + + /** {@inheritDoc} */ + @Override + public void clearWarnings() throws SQLException + { + if (throwException) { + throw new SQLException(); + } + } + + /** {@inheritDoc} */ + @Override + public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException + { + if (throwException) { + throw new SQLException(); + } + return null; + } + + /** {@inheritDoc} */ + @Override + public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException + { + if (throwException) { + throw new SQLException(); + } + return new StubPreparedStatement(this); + } + + /** {@inheritDoc} */ + @Override + public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException + { + if (throwException) { + throw new SQLException(); + } + return null; + } + + /** {@inheritDoc} */ + @Override + public Map> getTypeMap() throws SQLException + { + return null; + } + + /** {@inheritDoc} */ + @Override + public void setTypeMap(Map> map) throws SQLException + { + } + + /** {@inheritDoc} */ + @Override + public void setHoldability(int holdability) throws SQLException + { + } + + /** {@inheritDoc} */ + @Override + public int getHoldability() throws SQLException + { + return (int) foo; + } + + /** {@inheritDoc} */ + @Override + public Savepoint setSavepoint() throws SQLException + { + return null; + } + + /** {@inheritDoc} */ + @Override + public Savepoint setSavepoint(String name) throws SQLException + { + return null; + } + + /** {@inheritDoc} */ + @Override + public void rollback(Savepoint savepoint) throws SQLException + { + } + + /** {@inheritDoc} */ + @Override + public void releaseSavepoint(Savepoint savepoint) throws SQLException + { + } + + /** {@inheritDoc} */ + @Override + public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException + { + if (throwException) { + throw new SQLException(); + } + return null; + } + + /** {@inheritDoc} */ + @Override + public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException + { + if (throwException) { + throw new SQLException(); + } + return new StubPreparedStatement(this); + } + + /** {@inheritDoc} */ + @Override + public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException + { + if (throwException) { + throw new SQLException(); + } + return null; + } + + /** {@inheritDoc} */ + @Override + public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException + { + if (throwException) { + throw new SQLException(); + } + return new StubPreparedStatement(this); + } + + /** {@inheritDoc} */ + @Override + public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException + { + if (throwException) { + throw new SQLException(); + } + return new StubPreparedStatement(this); + } + + /** {@inheritDoc} */ + @Override + public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException + { + if (throwException) { + throw new SQLException(); + } + return new StubPreparedStatement(this); + } + + /** {@inheritDoc} */ + @Override + public Clob createClob() throws SQLException + { + return null; + } + + /** {@inheritDoc} */ + @Override + public Blob createBlob() throws SQLException + { + return null; + } + + /** {@inheritDoc} */ + @Override + public NClob createNClob() throws SQLException + { + return null; + } + + /** {@inheritDoc} */ + @Override + public SQLXML createSQLXML() throws SQLException + { + return null; + } + + /** {@inheritDoc} */ + @Override + public boolean isValid(int timeout) throws SQLException + { + if (throwException) { + throw new SQLException(); + } + return true; + } + + /** {@inheritDoc} */ + @Override + public void setClientInfo(String name, String value) throws SQLClientInfoException + { + } + + /** {@inheritDoc} */ + @Override + public void setClientInfo(Properties properties) throws SQLClientInfoException + { + } + + /** {@inheritDoc} */ + @Override + public String getClientInfo(String name) throws SQLException + { + return null; + } + + /** {@inheritDoc} */ + @Override + public Properties getClientInfo() throws SQLException + { + return null; + } + + /** {@inheritDoc} */ + @Override + public Array createArrayOf(String typeName, Object[] elements) throws SQLException + { + return null; + } + + /** {@inheritDoc} */ + @Override + public Struct createStruct(String typeName, Object[] attributes) throws SQLException + { + return null; + } + + /** {@inheritDoc} */ + public void setSchema(String schema) throws SQLException + { + } + + /** {@inheritDoc} */ + public String getSchema() throws SQLException + { + return null; + } + + /** {@inheritDoc} */ + public void abort(Executor executor) throws SQLException + { + throw new SQLException("Intentianal exception during abort"); + } + + /** {@inheritDoc} */ + public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException + { + } + + /** {@inheritDoc} */ + public int getNetworkTimeout() throws SQLException + { + return 0; + } } diff --git a/hikaricp/src/test/java/com/zaxxer/hikari/MiscTest.java b/hikaricp/src/test/java/com/zaxxer/hikari/MiscTest.java index 6d259d53..a4639366 100644 --- a/hikaricp/src/test/java/com/zaxxer/hikari/MiscTest.java +++ b/hikaricp/src/test/java/com/zaxxer/hikari/MiscTest.java @@ -25,14 +25,9 @@ import java.util.concurrent.TimeUnit; import org.junit.Assert; import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.slf4j.impl.SimpleLogger; import org.slf4j.spi.LocationAwareLogger; import com.zaxxer.hikari.pool.HikariPool; -import com.zaxxer.hikari.pool.PoolBagEntry; -import com.zaxxer.hikari.util.ConcurrentBag; import com.zaxxer.hikari.util.LeakTask; import com.zaxxer.hikari.util.PoolUtilities; @@ -49,7 +44,7 @@ public class MiscTest config.setMaximumPoolSize(4); config.setPoolName("test"); config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource"); - TestElf.setConfigUnitTest(); + TestElf.setConfigUnitTest(true); final HikariDataSource ds = new HikariDataSource(config); try { @@ -60,6 +55,7 @@ public class MiscTest } finally { + TestElf.setConfigUnitTest(false); ds.close(); } } @@ -88,70 +84,6 @@ public class MiscTest } } - @Test - public void testConcurrentBag() throws InterruptedException - { - ConcurrentBag bag = new ConcurrentBag(null); - Assert.assertEquals(0, bag.values(8).size()); - - PoolBagEntry reserved = new PoolBagEntry(null, 0); - bag.add(reserved); - bag.reserve(reserved); // reserved - - PoolBagEntry inuse = new PoolBagEntry(null, 0); - bag.add(inuse); - bag.borrow(2L, TimeUnit.SECONDS); // in use - - PoolBagEntry notinuse = new PoolBagEntry(null, 0); - bag.add(notinuse); // not in use - - bag.dumpState(); - - try { - bag.requite(reserved); - Assert.fail(); - } - catch (IllegalStateException e) { - // pass - } - - try { - bag.remove(notinuse); - Assert.fail(); - } - catch (IllegalStateException e) { - // pass - } - - try { - bag.unreserve(notinuse); - Assert.fail(); - } - catch (IllegalStateException e) { - // pass - } - - try { - bag.remove(inuse); - bag.remove(inuse); - Assert.fail(); - } - catch (IllegalStateException e) { - // pass - } - - bag.close(); - try { - bag.add(new PoolBagEntry(null, 0)); - Assert.fail(); - } - catch (IllegalStateException e) { - // pass - } - - Assert.assertNotNull(notinuse.toString()); - } - @Test public void testLeakDetection() throws SQLException { @@ -165,7 +97,7 @@ public class MiscTest config.setPoolName("test"); config.setLeakDetectionThreshold(TimeUnit.SECONDS.toMillis(1)); config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource"); - TestElf.setConfigUnitTest(); + TestElf.setConfigUnitTest(true); final HikariDataSource ds = new HikariDataSource(config); try { @@ -183,6 +115,7 @@ public class MiscTest } finally { + TestElf.setConfigUnitTest(false); ds.close(); } } diff --git a/hikaricp/src/test/java/com/zaxxer/hikari/TestConcurrentBag.java b/hikaricp/src/test/java/com/zaxxer/hikari/TestConcurrentBag.java new file mode 100644 index 00000000..a2f3aa1a --- /dev/null +++ b/hikaricp/src/test/java/com/zaxxer/hikari/TestConcurrentBag.java @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2013 Brett Wooldridge + * + * 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.zaxxer.hikari; + +import java.util.concurrent.TimeUnit; + +import org.junit.Assert; +import org.junit.Test; + +import com.zaxxer.hikari.pool.PoolBagEntry; +import com.zaxxer.hikari.util.ConcurrentBag; + +/** + * + * @author Brett Wooldridge + */ +public class TestConcurrentBag +{ + @Test + public void testConcurrentBag() throws InterruptedException + { + ConcurrentBag bag = new ConcurrentBag(null); + Assert.assertEquals(0, bag.values(8).size()); + + PoolBagEntry reserved = new PoolBagEntry(null, 0); + bag.add(reserved); + bag.reserve(reserved); // reserved + + PoolBagEntry inuse = new PoolBagEntry(null, 0); + bag.add(inuse); + bag.borrow(2L, TimeUnit.SECONDS); // in use + + PoolBagEntry notinuse = new PoolBagEntry(null, 0); + bag.add(notinuse); // not in use + + bag.dumpState(); + + try { + bag.requite(reserved); + Assert.fail(); + } + catch (IllegalStateException e) { + // pass + } + + try { + bag.remove(notinuse); + Assert.fail(); + } + catch (IllegalStateException e) { + // pass + } + + try { + bag.unreserve(notinuse); + Assert.fail(); + } + catch (IllegalStateException e) { + // pass + } + + try { + bag.remove(inuse); + bag.remove(inuse); + Assert.fail(); + } + catch (IllegalStateException e) { + // pass + } + + bag.close(); + try { + bag.add(new PoolBagEntry(null, 0)); + Assert.fail(); + } + catch (IllegalStateException e) { + // pass + } + + Assert.assertNotNull(notinuse.toString()); + } +} diff --git a/hikaricp/src/test/java/com/zaxxer/hikari/TestElf.java b/hikaricp/src/test/java/com/zaxxer/hikari/TestElf.java index 110e4387..9be1c32c 100644 --- a/hikaricp/src/test/java/com/zaxxer/hikari/TestElf.java +++ b/hikaricp/src/test/java/com/zaxxer/hikari/TestElf.java @@ -61,12 +61,12 @@ public final class TestElf } } - public static void setConfigUnitTest() + public static void setConfigUnitTest(boolean unitTest) { try { Field field = HikariConfig.class.getDeclaredField("unitTest"); field.setAccessible(true); - field.setBoolean(null, true); + field.setBoolean(null, unitTest); } catch (Exception e) { throw new RuntimeException(e); diff --git a/hikaricp/src/test/java/com/zaxxer/hikari/TestJNDI.java b/hikaricp/src/test/java/com/zaxxer/hikari/TestJNDI.java index b984e5ed..6985ceac 100644 --- a/hikaricp/src/test/java/com/zaxxer/hikari/TestJNDI.java +++ b/hikaricp/src/test/java/com/zaxxer/hikari/TestJNDI.java @@ -68,6 +68,22 @@ public class TestJNDI Assert.assertEquals("foo", ds.getUsername()); } + @Test + public void testJndiLookup3() throws Exception + { + HikariJNDIFactory jndi = new HikariJNDIFactory(); + + Reference ref = new Reference("javax.sql.DataSource"); + ref.add(new BogusRef("dataSourceJNDI", "java:comp/env/HikariDS")); + try { + jndi.getObjectInstance(ref, null, null, null); + Assert.fail(); + } + catch (RuntimeException e) { + Assert.assertTrue(e.getMessage().contains("JNDI context is null")); + } + } + private class BogusContext extends AbstractContext { @Override diff --git a/hikaricp/src/test/java/com/zaxxer/hikari/TestProxies.java b/hikaricp/src/test/java/com/zaxxer/hikari/TestProxies.java index cd083dab..19685429 100644 --- a/hikaricp/src/test/java/com/zaxxer/hikari/TestProxies.java +++ b/hikaricp/src/test/java/com/zaxxer/hikari/TestProxies.java @@ -4,12 +4,14 @@ import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; +import java.util.concurrent.TimeUnit; import org.junit.Assert; import org.junit.Test; import com.zaxxer.hikari.mocks.StubConnection; import com.zaxxer.hikari.mocks.StubStatement; +import com.zaxxer.hikari.util.PoolUtilities; public class TestProxies { @@ -88,4 +90,228 @@ public class TestProxies ds.close(); } } + + @Test + public void testStatementExceptions() throws SQLException + { + HikariConfig config = new HikariConfig(); + config.setMinimumIdle(0); + config.setMaximumPoolSize(1); + config.setConnectionTimeout(TimeUnit.SECONDS.toMillis(1)); + config.setConnectionTestQuery("VALUES 1"); + config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource"); + + HikariDataSource ds = new HikariDataSource(config); + try { + Connection conn = ds.getConnection(); + StubConnection stubConnection = conn.unwrap(StubConnection.class); + stubConnection.throwException = true; + + try { + conn.createStatement(); + Assert.fail(); + } + catch (SQLException e) { + // pass + } + + try { + conn.createStatement(0, 0); + Assert.fail(); + } + catch (SQLException e) { + // pass + } + + try { + conn.createStatement(0, 0, 0); + Assert.fail(); + } + catch (SQLException e) { + // pass + } + + try { + conn.prepareCall(""); + Assert.fail(); + } + catch (SQLException e) { + // pass + } + + try { + conn.prepareCall("", 0, 0); + Assert.fail(); + } + catch (SQLException e) { + // pass + } + + try { + conn.prepareCall("", 0, 0, 0); + Assert.fail(); + } + catch (SQLException e) { + // pass + } + + try { + conn.prepareStatement(""); + Assert.fail(); + } + catch (SQLException e) { + // pass + } + + try { + conn.prepareStatement("", 0); + Assert.fail(); + } + catch (SQLException e) { + // pass + } + + try { + conn.prepareStatement("", new int[0]); + Assert.fail(); + } + catch (SQLException e) { + // pass + } + + try { + conn.prepareStatement("", new String[0]); + Assert.fail(); + } + catch (SQLException e) { + // pass + } + + try { + conn.prepareStatement("", 0, 0); + Assert.fail(); + } + catch (SQLException e) { + // pass + } + + try { + conn.prepareStatement("", 0, 0, 0); + Assert.fail(); + } + catch (SQLException e) { + // pass + } + } + finally { + ds.close(); + } + } + + @Test + public void testOtherExceptions() throws SQLException + { + HikariConfig config = new HikariConfig(); + config.setMinimumIdle(0); + config.setMaximumPoolSize(1); + config.setConnectionTestQuery("VALUES 1"); + config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource"); + + HikariDataSource ds = new HikariDataSource(config); + try { + Connection conn = ds.getConnection(); + StubConnection stubConnection = conn.unwrap(StubConnection.class); + stubConnection.throwException = true; + + try { + conn.setTransactionIsolation(Connection.TRANSACTION_NONE); + Assert.fail(); + } + catch (SQLException e) { + // pass + } + + try { + conn.isReadOnly(); + Assert.fail(); + } + catch (SQLException e) { + // pass + } + + try { + conn.setReadOnly(false); + Assert.fail(); + } + catch (SQLException e) { + // pass + } + + try { + conn.setCatalog(""); + Assert.fail(); + } + catch (SQLException e) { + // pass + } + + try { + conn.setAutoCommit(false); + Assert.fail(); + } + catch (SQLException e) { + // pass + } + + try { + conn.clearWarnings(); + Assert.fail(); + } + catch (SQLException e) { + // pass + } + + try { + conn.isValid(0); + Assert.fail(); + } + catch (SQLException e) { + // pass + } + + try { + conn.isWrapperFor(getClass()); + Assert.fail(); + } + catch (SQLException e) { + // pass + } + + try { + conn.unwrap(getClass()); + Assert.fail(); + } + catch (SQLException e) { + // pass + } + + try { + conn.close(); + Assert.fail(); + } + catch (SQLException e) { + // pass + } + + try { + Assert.assertFalse(conn.isValid(0)); + } + catch (SQLException e) { + Assert.fail(); + } +} + finally { + ds.close(); + } + } } diff --git a/hikaricp/src/test/java/com/zaxxer/hikari/TestValidation.java b/hikaricp/src/test/java/com/zaxxer/hikari/TestValidation.java index 2ee2df38..5cebc5d7 100644 --- a/hikaricp/src/test/java/com/zaxxer/hikari/TestValidation.java +++ b/hikaricp/src/test/java/com/zaxxer/hikari/TestValidation.java @@ -267,6 +267,21 @@ public class TestValidation } } + @Test + public void validateInvalidLeakDetection() + { + try { + HikariConfig config = new HikariConfig(); + config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource"); + config.setLeakDetectionThreshold(1000L); + config.validate(); + Assert.assertEquals(0, config.getLeakDetectionThreshold()); + } + catch (IllegalArgumentException ise) { + // pass + } + } + @Test public void validateZeroConnectionTimeout() { diff --git a/hikaricp/src/test/java/com/zaxxer/hikari/mocks/StubBaseConnection.java b/hikaricp/src/test/java/com/zaxxer/hikari/mocks/StubBaseConnection.java index ee1d64eb..af784cc3 100644 --- a/hikaricp/src/test/java/com/zaxxer/hikari/mocks/StubBaseConnection.java +++ b/hikaricp/src/test/java/com/zaxxer/hikari/mocks/StubBaseConnection.java @@ -7,17 +7,25 @@ import java.sql.Statement; public abstract class StubBaseConnection implements Connection { - /** {@inheritDoc} */ - @Override - public Statement createStatement() throws SQLException - { - return new StubStatement(this); - } + public volatile boolean throwException; - /** {@inheritDoc} */ - @Override - public PreparedStatement prepareStatement(String sql) throws SQLException - { - return new StubPreparedStatement(this); - } + /** {@inheritDoc} */ + @Override + public Statement createStatement() throws SQLException + { + if (throwException) { + throw new SQLException(); + } + return new StubStatement(this); + } + + /** {@inheritDoc} */ + @Override + public PreparedStatement prepareStatement(String sql) throws SQLException + { + if (throwException) { + throw new SQLException(); + } + return new StubPreparedStatement(this); + } } diff --git a/hikaricp/src/test/java/com/zaxxer/hikari/mocks/StubConnection.java b/hikaricp/src/test/java/com/zaxxer/hikari/mocks/StubConnection.java index 2434eef2..3bbd3f25 100644 --- a/hikaricp/src/test/java/com/zaxxer/hikari/mocks/StubConnection.java +++ b/hikaricp/src/test/java/com/zaxxer/hikari/mocks/StubConnection.java @@ -45,380 +45,438 @@ import com.zaxxer.hikari.util.PoolUtilities; */ public class StubConnection extends StubBaseConnection implements Connection { - public static final AtomicInteger count = new AtomicInteger(); - public static volatile boolean slowCreate; - - private static long foo; - private boolean autoCommit; - private int isolation; - private String catalog; - - static - { - foo = System.currentTimeMillis(); - } - - public StubConnection() - { - count.incrementAndGet(); - if (slowCreate) - { - PoolUtilities.quietlySleep(TimeUnit.SECONDS.toMillis(1)); - } - } - - /** {@inheritDoc} */ - @SuppressWarnings("unchecked") - @Override - public T unwrap(Class iface) throws SQLException - { - if (iface.isInstance(this)) { - return (T) this; - } - - throw new SQLException("Wrapped connection is not an instance of " + iface); - } - - /** {@inheritDoc} */ - @Override - public boolean isWrapperFor(Class iface) throws SQLException - { - return false; - } - - /** {@inheritDoc} */ - @Override - public CallableStatement prepareCall(String sql) throws SQLException - { - return null; - } - - /** {@inheritDoc} */ - @Override - public String nativeSQL(String sql) throws SQLException - { - return null; - } - - /** {@inheritDoc} */ - @Override - public void setAutoCommit(boolean autoCommit) throws SQLException - { - this.autoCommit = autoCommit; - } - - /** {@inheritDoc} */ - @Override - public boolean getAutoCommit() throws SQLException - { - return autoCommit; - } - - /** {@inheritDoc} */ - @Override - public void commit() throws SQLException - { - - } - - /** {@inheritDoc} */ - @Override - public void rollback() throws SQLException - { - - } - - /** {@inheritDoc} */ - @Override - public void close() throws SQLException - { - - } - - /** {@inheritDoc} */ - @Override - public boolean isClosed() throws SQLException - { - return false; - } - - /** {@inheritDoc} */ - @Override - public DatabaseMetaData getMetaData() throws SQLException - { - return null; - } - - /** {@inheritDoc} */ - @Override - public void setReadOnly(boolean readOnly) throws SQLException - { - } - - /** {@inheritDoc} */ - @Override - public boolean isReadOnly() throws SQLException - { - return false; - } - - /** {@inheritDoc} */ - @Override - public void setCatalog(String catalog) throws SQLException - { - this.catalog = catalog; - } - - /** {@inheritDoc} */ - @Override - public String getCatalog() throws SQLException - { - return catalog; - } - - /** {@inheritDoc} */ - @Override - public void setTransactionIsolation(int level) throws SQLException - { - this.isolation = level; - } - - /** {@inheritDoc} */ - @Override - public int getTransactionIsolation() throws SQLException - { - return isolation; - } - - /** {@inheritDoc} */ - @Override - public SQLWarning getWarnings() throws SQLException - { - return null; - } - - /** {@inheritDoc} */ - @Override - public void clearWarnings() throws SQLException - { - } - - /** {@inheritDoc} */ - @Override - public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException - { - return null; - } - - /** {@inheritDoc} */ - @Override - public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException - { - return new StubPreparedStatement(this); - } - - /** {@inheritDoc} */ - @Override - public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException - { - return null; - } - - /** {@inheritDoc} */ - @Override - public Map> getTypeMap() throws SQLException - { - return null; - } - - /** {@inheritDoc} */ - @Override - public void setTypeMap(Map> map) throws SQLException - { - } - - /** {@inheritDoc} */ - @Override - public void setHoldability(int holdability) throws SQLException - { - } - - /** {@inheritDoc} */ - @Override - public int getHoldability() throws SQLException - { - return (int) foo; - } - - /** {@inheritDoc} */ - @Override - public Savepoint setSavepoint() throws SQLException - { - return null; - } - - /** {@inheritDoc} */ - @Override - public Savepoint setSavepoint(String name) throws SQLException - { - return null; - } - - /** {@inheritDoc} */ - @Override - public void rollback(Savepoint savepoint) throws SQLException - { - } - - /** {@inheritDoc} */ - @Override - public void releaseSavepoint(Savepoint savepoint) throws SQLException - { - } - - /** {@inheritDoc} */ - @Override - public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException - { - return null; - } - - /** {@inheritDoc} */ - @Override - public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException - { - return new StubPreparedStatement(this); - } - - /** {@inheritDoc} */ - @Override - public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException - { - return null; - } - - /** {@inheritDoc} */ - @Override - public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException - { - return new StubPreparedStatement(this); - } - - /** {@inheritDoc} */ - @Override - public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException - { - return new StubPreparedStatement(this); - } - - /** {@inheritDoc} */ - @Override - public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException - { - return new StubPreparedStatement(this); - } - - /** {@inheritDoc} */ - @Override - public Clob createClob() throws SQLException - { - return null; - } - - /** {@inheritDoc} */ - @Override - public Blob createBlob() throws SQLException - { - return null; - } - - /** {@inheritDoc} */ - @Override - public NClob createNClob() throws SQLException - { - return null; - } - - /** {@inheritDoc} */ - @Override - public SQLXML createSQLXML() throws SQLException - { - return null; - } - - /** {@inheritDoc} */ - @Override - public boolean isValid(int timeout) throws SQLException - { - return true; - } - - /** {@inheritDoc} */ - @Override - public void setClientInfo(String name, String value) throws SQLClientInfoException - { - } - - /** {@inheritDoc} */ - @Override - public void setClientInfo(Properties properties) throws SQLClientInfoException - { - } - - /** {@inheritDoc} */ - @Override - public String getClientInfo(String name) throws SQLException - { - return null; - } - - /** {@inheritDoc} */ - @Override - public Properties getClientInfo() throws SQLException - { - return null; - } - - /** {@inheritDoc} */ - @Override - public Array createArrayOf(String typeName, Object[] elements) throws SQLException - { - return null; - } - - /** {@inheritDoc} */ - @Override - public Struct createStruct(String typeName, Object[] attributes) throws SQLException - { - return null; - } - - /** {@inheritDoc} */ - public void setSchema(String schema) throws SQLException - { - } - - /** {@inheritDoc} */ - public String getSchema() throws SQLException - { - return null; - } - - /** {@inheritDoc} */ - public void abort(Executor executor) throws SQLException - { - throw new SQLException("Intentianal exception during abort"); - } - - /** {@inheritDoc} */ - public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException - { - } - - /** {@inheritDoc} */ - public int getNetworkTimeout() throws SQLException - { - return 0; - } + public static final AtomicInteger count = new AtomicInteger(); + public static volatile boolean slowCreate; + + private static long foo; + private boolean autoCommit; + private int isolation; + private String catalog; + + static { + foo = System.currentTimeMillis(); + } + + public StubConnection() { + count.incrementAndGet(); + if (slowCreate) { + PoolUtilities.quietlySleep(TimeUnit.SECONDS.toMillis(1)); + } + } + + /** {@inheritDoc} */ + @SuppressWarnings("unchecked") + @Override + public T unwrap(Class iface) throws SQLException + { + if (throwException) { + throw new SQLException(); + } + + if (iface.isInstance(this)) { + return (T) this; + } + + throw new SQLException("Wrapped connection is not an instance of " + iface); + } + + /** {@inheritDoc} */ + @Override + public boolean isWrapperFor(Class iface) throws SQLException + { + if (throwException) { + throw new SQLException(); + } + return false; + } + + /** {@inheritDoc} */ + @Override + public CallableStatement prepareCall(String sql) throws SQLException + { + if (throwException) { + throw new SQLException(); + } + return null; + } + + /** {@inheritDoc} */ + @Override + public String nativeSQL(String sql) throws SQLException + { + return null; + } + + /** {@inheritDoc} */ + @Override + public void setAutoCommit(boolean autoCommit) throws SQLException + { + if (throwException) { + throw new SQLException(); + } + this.autoCommit = autoCommit; + } + + /** {@inheritDoc} */ + @Override + public boolean getAutoCommit() throws SQLException + { + return autoCommit; + } + + /** {@inheritDoc} */ + @Override + public void commit() throws SQLException + { + + } + + /** {@inheritDoc} */ + @Override + public void rollback() throws SQLException + { + + } + + /** {@inheritDoc} */ + @Override + public void close() throws SQLException + { + + } + + /** {@inheritDoc} */ + @Override + public boolean isClosed() throws SQLException + { + if (throwException) { + throw new SQLException(); + } + return false; + } + + /** {@inheritDoc} */ + @Override + public DatabaseMetaData getMetaData() throws SQLException + { + return null; + } + + /** {@inheritDoc} */ + @Override + public void setReadOnly(boolean readOnly) throws SQLException + { + if (throwException) { + throw new SQLException(); + } + } + + /** {@inheritDoc} */ + @Override + public boolean isReadOnly() throws SQLException + { + if (throwException) { + throw new SQLException(); + } + return false; + } + + /** {@inheritDoc} */ + @Override + public void setCatalog(String catalog) throws SQLException + { + if (throwException) { + throw new SQLException(); + } + this.catalog = catalog; + } + + /** {@inheritDoc} */ + @Override + public String getCatalog() throws SQLException + { + return catalog; + } + + /** {@inheritDoc} */ + @Override + public void setTransactionIsolation(int level) throws SQLException + { + if (throwException) { + throw new SQLException(); + } + this.isolation = level; + } + + /** {@inheritDoc} */ + @Override + public int getTransactionIsolation() throws SQLException + { + return isolation; + } + + /** {@inheritDoc} */ + @Override + public SQLWarning getWarnings() throws SQLException + { + return null; + } + + /** {@inheritDoc} */ + @Override + public void clearWarnings() throws SQLException + { + if (throwException) { + throw new SQLException(); + } + } + + /** {@inheritDoc} */ + @Override + public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException + { + if (throwException) { + throw new SQLException(); + } + return null; + } + + /** {@inheritDoc} */ + @Override + public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException + { + if (throwException) { + throw new SQLException(); + } + return new StubPreparedStatement(this); + } + + /** {@inheritDoc} */ + @Override + public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException + { + if (throwException) { + throw new SQLException(); + } + return null; + } + + /** {@inheritDoc} */ + @Override + public Map> getTypeMap() throws SQLException + { + return null; + } + + /** {@inheritDoc} */ + @Override + public void setTypeMap(Map> map) throws SQLException + { + } + + /** {@inheritDoc} */ + @Override + public void setHoldability(int holdability) throws SQLException + { + } + + /** {@inheritDoc} */ + @Override + public int getHoldability() throws SQLException + { + return (int) foo; + } + + /** {@inheritDoc} */ + @Override + public Savepoint setSavepoint() throws SQLException + { + return null; + } + + /** {@inheritDoc} */ + @Override + public Savepoint setSavepoint(String name) throws SQLException + { + return null; + } + + /** {@inheritDoc} */ + @Override + public void rollback(Savepoint savepoint) throws SQLException + { + } + + /** {@inheritDoc} */ + @Override + public void releaseSavepoint(Savepoint savepoint) throws SQLException + { + } + + /** {@inheritDoc} */ + @Override + public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException + { + if (throwException) { + throw new SQLException(); + } + return null; + } + + /** {@inheritDoc} */ + @Override + public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException + { + if (throwException) { + throw new SQLException(); + } + return new StubPreparedStatement(this); + } + + /** {@inheritDoc} */ + @Override + public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException + { + if (throwException) { + throw new SQLException(); + } + return null; + } + + /** {@inheritDoc} */ + @Override + public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException + { + if (throwException) { + throw new SQLException(); + } + return new StubPreparedStatement(this); + } + + /** {@inheritDoc} */ + @Override + public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException + { + if (throwException) { + throw new SQLException(); + } + return new StubPreparedStatement(this); + } + + /** {@inheritDoc} */ + @Override + public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException + { + if (throwException) { + throw new SQLException(); + } + return new StubPreparedStatement(this); + } + + /** {@inheritDoc} */ + @Override + public Clob createClob() throws SQLException + { + return null; + } + + /** {@inheritDoc} */ + @Override + public Blob createBlob() throws SQLException + { + return null; + } + + /** {@inheritDoc} */ + @Override + public NClob createNClob() throws SQLException + { + return null; + } + + /** {@inheritDoc} */ + @Override + public SQLXML createSQLXML() throws SQLException + { + return null; + } + + /** {@inheritDoc} */ + @Override + public boolean isValid(int timeout) throws SQLException + { + if (throwException) { + throw new SQLException(); + } + return true; + } + + /** {@inheritDoc} */ + @Override + public void setClientInfo(String name, String value) throws SQLClientInfoException + { + } + + /** {@inheritDoc} */ + @Override + public void setClientInfo(Properties properties) throws SQLClientInfoException + { + } + + /** {@inheritDoc} */ + @Override + public String getClientInfo(String name) throws SQLException + { + return null; + } + + /** {@inheritDoc} */ + @Override + public Properties getClientInfo() throws SQLException + { + return null; + } + + /** {@inheritDoc} */ + @Override + public Array createArrayOf(String typeName, Object[] elements) throws SQLException + { + return null; + } + + /** {@inheritDoc} */ + @Override + public Struct createStruct(String typeName, Object[] attributes) throws SQLException + { + return null; + } + + /** {@inheritDoc} */ + public void setSchema(String schema) throws SQLException + { + } + + /** {@inheritDoc} */ + public String getSchema() throws SQLException + { + return null; + } + + /** {@inheritDoc} */ + public void abort(Executor executor) throws SQLException + { + throw new SQLException("Intentianal exception during abort"); + } + + /** {@inheritDoc} */ + public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException + { + } + + /** {@inheritDoc} */ + public int getNetworkTimeout() throws SQLException + { + return 0; + } }