From e43c11f7caf5df1c0dc4564ce8d1ad492637600b Mon Sep 17 00:00:00 2001 From: Brett Wooldridge Date: Sat, 11 Oct 2014 00:10:06 +0900 Subject: [PATCH] More test coverage. --- .../zaxxer/hikari/ConnectionStateTest.java | 30 +++++++ .../test/java/com/zaxxer/hikari/MiscTest.java | 37 +++++++- .../hikari/TestConnectionCloseBlocking.java | 74 ++++++++++++++++ .../com/zaxxer/hikari/TestConnections.java | 31 +++++++ .../test/java/com/zaxxer/hikari/TestElf.java | 45 ++++++---- .../java/com/zaxxer/hikari/TestFastList.java | 32 +++++++ .../java/com/zaxxer/hikari/TestProxies.java | 84 +++++++++++++++++++ .../zaxxer/hikari/mocks/StubConnection.java | 7 +- .../zaxxer/hikari/mocks/StubStatement.java | 2 +- .../test/java/com/zaxxer/hikari/MiscTest.java | 84 +++++++++++++++++++ .../com/zaxxer/hikari/TestConnections.java | 2 + .../java/com/zaxxer/hikari/TestProxies.java | 84 +++++++++++++++++++ .../zaxxer/hikari/mocks/StubConnection.java | 7 +- .../zaxxer/hikari/mocks/StubStatement.java | 2 +- 14 files changed, 499 insertions(+), 22 deletions(-) rename hikaricp/src/test/java/com/zaxxer/hikari/MiscTests.java => hikaricp-java6/src/test/java/com/zaxxer/hikari/MiscTest.java (60%) create mode 100644 hikaricp-java6/src/test/java/com/zaxxer/hikari/TestConnectionCloseBlocking.java create mode 100644 hikaricp-java6/src/test/java/com/zaxxer/hikari/TestProxies.java create mode 100644 hikaricp/src/test/java/com/zaxxer/hikari/MiscTest.java create mode 100644 hikaricp/src/test/java/com/zaxxer/hikari/TestProxies.java diff --git a/hikaricp-java6/src/test/java/com/zaxxer/hikari/ConnectionStateTest.java b/hikaricp-java6/src/test/java/com/zaxxer/hikari/ConnectionStateTest.java index fbe261a6..60e6921b 100644 --- a/hikaricp-java6/src/test/java/com/zaxxer/hikari/ConnectionStateTest.java +++ b/hikaricp-java6/src/test/java/com/zaxxer/hikari/ConnectionStateTest.java @@ -17,6 +17,7 @@ public class ConnectionStateTest ds.setAutoCommit(true); ds.setMinimumIdle(1); ds.setMaximumPoolSize(1); + ds.setJdbc4ConnectionTest(false); ds.setConnectionTestQuery("VALUES 1"); ds.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource"); ds.addDataSourceProperty("user", "bar"); @@ -30,6 +31,8 @@ public class ConnectionStateTest connection.setAutoCommit(false); connection.close(); + PoolUtilities.quietlySleep(1100L); + Connection connection2 = ds.getConnection(); Assert.assertSame(connection.unwrap(Connection.class), connection2.unwrap(Connection.class)); Assert.assertTrue(connection2.getAutoCommit()); @@ -80,6 +83,33 @@ public class ConnectionStateTest Assert.assertSame(Connection.TRANSACTION_REPEATABLE_READ, transactionIsolation); } + @Test + public void testReadOnly() throws Exception + { + HikariDataSource ds = new HikariDataSource(); + ds.setCatalog("test"); + ds.setMinimumIdle(1); + ds.setMaximumPoolSize(1); + ds.setConnectionTestQuery("VALUES 1"); + ds.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource"); + + try + { + Connection connection = ds.getConnection(); + connection.setReadOnly(true); + connection.close(); + + Connection connection2 = ds.getConnection(); + Assert.assertSame(connection.unwrap(Connection.class), connection2.unwrap(Connection.class)); + Assert.assertFalse(connection2.isReadOnly()); + connection2.close(); + } + finally + { + ds.close(); + } + } + @Test public void testCatalog() throws SQLException { diff --git a/hikaricp/src/test/java/com/zaxxer/hikari/MiscTests.java b/hikaricp-java6/src/test/java/com/zaxxer/hikari/MiscTest.java similarity index 60% rename from hikaricp/src/test/java/com/zaxxer/hikari/MiscTests.java rename to hikaricp-java6/src/test/java/com/zaxxer/hikari/MiscTest.java index f2539c85..dcd11942 100644 --- a/hikaricp/src/test/java/com/zaxxer/hikari/MiscTests.java +++ b/hikaricp-java6/src/test/java/com/zaxxer/hikari/MiscTest.java @@ -22,10 +22,14 @@ import java.sql.SQLException; import org.junit.Assert; import org.junit.Test; +import com.zaxxer.hikari.util.ConcurrentBag; +import com.zaxxer.hikari.util.ConcurrentBag.BagEntry; +import com.zaxxer.hikari.util.PoolUtilities; + /** * @author Brett Wooldridge */ -public class MiscTests +public class MiscTest { @Test public void testLogWriter() throws SQLException @@ -46,4 +50,35 @@ public class MiscTests ds.close(); } } + + @Test + public void testInvalidIsolation() + { + try { + PoolUtilities.getTransactionIsolation("INVALID"); + Assert.fail(); + } + catch (Exception e) { + Assert.assertTrue(e instanceof IllegalArgumentException); + } + } + + @Test + public void testCreateInstance() + { + try { + PoolUtilities.createInstance("invalid", null); + Assert.fail(); + } + catch (RuntimeException e) { + Assert.assertTrue(e.getCause() instanceof ClassNotFoundException); + } + } + + @Test + public void testBagDump() + { + ConcurrentBag bag = new ConcurrentBag(null); + bag.dumpState(); + } } diff --git a/hikaricp-java6/src/test/java/com/zaxxer/hikari/TestConnectionCloseBlocking.java b/hikaricp-java6/src/test/java/com/zaxxer/hikari/TestConnectionCloseBlocking.java new file mode 100644 index 00000000..0e38c028 --- /dev/null +++ b/hikaricp-java6/src/test/java/com/zaxxer/hikari/TestConnectionCloseBlocking.java @@ -0,0 +1,74 @@ +/** + * + */ +package com.zaxxer.hikari; + +import static org.mockito.Matchers.anyInt; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.when; + +import java.sql.Connection; +import java.sql.SQLException; +import java.util.concurrent.TimeUnit; + +import org.junit.Assert; +import org.junit.Test; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; + +import com.zaxxer.hikari.mocks.MockDataSource; +import com.zaxxer.hikari.util.PoolUtilities; + +/** + * Test for cases when db network connectivity goes down and close is called on existing connections. By default Hikari + * blocks longer than getMaximumTimeout (it can hang for a lot of time depending on driver timeout settings). Closing + * async the connections fixes this issue. + * + */ +public class TestConnectionCloseBlocking { + @Test + public void testConnectionCloseBlocking() throws SQLException { + HikariConfig config = new HikariConfig(); + config.setMinimumIdle(0); + config.setMaximumPoolSize(1); + config.setConnectionTimeout(1500); + config.setDataSource(new CustomMockDataSource()); + + HikariDataSource ds = new HikariDataSource(config); + + long start = System.currentTimeMillis(); + try { + Connection connection = ds.getConnection(); + connection.close(); + // Hikari only checks for validity for connections with lastAccess > 1000 ms so we sleep for 1001 ms to force + // Hikari to do a connection validation which will fail and will trigger the connection to be closed + PoolUtilities.quietlySleep(1001); + start = System.currentTimeMillis(); + connection = ds.getConnection(); // on physical connection close we sleep 2 seconds + Assert.assertTrue("Waited longer than timeout", + (PoolUtilities.elapsedTimeMs(start) < config.getConnectionTimeout())); + } catch (SQLException e) { + Assert.assertTrue("getConnection failed because close connection took longer than timeout", + (PoolUtilities.elapsedTimeMs(start) < config.getConnectionTimeout())); + } finally { + ds.close(); + } + } + + private static class CustomMockDataSource extends MockDataSource { + @Override + public Connection getConnection() throws SQLException { + Connection mockConnection = super.getConnection(); + when(mockConnection.isValid(anyInt())).thenReturn(false); + doAnswer(new Answer() { + @Override + public Void answer(InvocationOnMock invocation) throws Throwable { + TimeUnit.SECONDS.sleep(2); + return null; + } + }).when(mockConnection).close(); + return mockConnection; + } + } + +} diff --git a/hikaricp-java6/src/test/java/com/zaxxer/hikari/TestConnections.java b/hikaricp-java6/src/test/java/com/zaxxer/hikari/TestConnections.java index 5c8255c2..9f55ed97 100644 --- a/hikaricp-java6/src/test/java/com/zaxxer/hikari/TestConnections.java +++ b/hikaricp-java6/src/test/java/com/zaxxer/hikari/TestConnections.java @@ -20,12 +20,14 @@ import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; +import java.util.HashMap; import java.util.concurrent.TimeUnit; import org.junit.Assert; import org.junit.Test; import com.zaxxer.hikari.mocks.StubConnection; +import com.zaxxer.hikari.pool.HikariPool; /** * System property testProxy can be one of: @@ -45,6 +47,8 @@ public class TestConnections config.setMaximumPoolSize(1); config.setInitializationFailFast(true); config.setConnectionTestQuery("VALUES 1"); + config.setConnectionInitSql("SELECT 1"); + config.setRecordMetrics(true); config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource"); HikariDataSource ds = new HikariDataSource(config); @@ -322,4 +326,31 @@ public class TestConnections ds.close(); } } + + @Test + public void testGetWithUsername() throws Exception + { + HikariConfig config = new HikariConfig(); + config.setMinimumIdle(1); + config.setMaximumPoolSize(4); + config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource"); + + final HikariDataSource ds = new HikariDataSource(config); + try { + Connection connection1 = ds.getConnection("foo", "bar"); + connection1.close(); + + Connection connection2 = ds.getConnection("faz", "baf"); + connection2.close(); + + HashMap multiPool = TestElf.getMultiPool(ds); + Assert.assertTrue(multiPool.size() > 1); + + Object[] array = multiPool.keySet().toArray(); + Assert.assertNotEquals(array[0], array[1]); + } + finally { + ds.close(); + } + } } 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 1b2357c1..7ecf5a5e 100644 --- a/hikaricp-java6/src/test/java/com/zaxxer/hikari/TestElf.java +++ b/hikaricp-java6/src/test/java/com/zaxxer/hikari/TestElf.java @@ -17,6 +17,7 @@ package com.zaxxer.hikari; import java.lang.reflect.Field; +import java.util.HashMap; import com.zaxxer.hikari.pool.HikariPool; @@ -27,22 +28,32 @@ import com.zaxxer.hikari.pool.HikariPool; */ public final class TestElf { - private TestElf() - { - // default constructor - } + private TestElf() { + // default constructor + } - public static HikariPool getPool(HikariDataSource ds) - { - try - { - Field field = ds.getClass().getDeclaredField("pool"); - field.setAccessible(true); - return (HikariPool) field.get(ds); - } - catch (Exception e) - { - throw new RuntimeException(e); - } - } + public static HikariPool getPool(HikariDataSource ds) + { + try { + Field field = ds.getClass().getDeclaredField("pool"); + field.setAccessible(true); + return (HikariPool) field.get(ds); + } + catch (Exception e) { + throw new RuntimeException(e); + } + } + + @SuppressWarnings("unchecked") + public static HashMap getMultiPool(HikariDataSource ds) + { + try { + Field field = ds.getClass().getDeclaredField("multiPool"); + field.setAccessible(true); + return (HashMap) field.get(ds); + } + catch (Exception e) { + throw new RuntimeException(e); + } + } } diff --git a/hikaricp-java6/src/test/java/com/zaxxer/hikari/TestFastList.java b/hikaricp-java6/src/test/java/com/zaxxer/hikari/TestFastList.java index 4d7deae3..722df674 100644 --- a/hikaricp-java6/src/test/java/com/zaxxer/hikari/TestFastList.java +++ b/hikaricp-java6/src/test/java/com/zaxxer/hikari/TestFastList.java @@ -75,6 +75,38 @@ public class TestFastList } } + @Test + public void testClear() + { + FastList list = new FastList(Statement.class); + for (int i = 0; i < 100; i++) + { + StubStatement statement = new StubStatement(null); + list.add(statement); + } + + Assert.assertNotEquals(0, list.size()); + list.clear(); + Assert.assertEquals(0, list.size()); + } + + @Test + public void testRemoveLast() + { + FastList list = new FastList(Statement.class); + + Statement last = null; + for (int i = 0; i < 100; i++) + { + StubStatement statement = new StubStatement(null); + list.add(statement); + last = statement; + } + + Assert.assertEquals(last, list.removeLast()); + Assert.assertEquals(99, list.size()); + } + @Test public void testPolyMorphism1() { diff --git a/hikaricp-java6/src/test/java/com/zaxxer/hikari/TestProxies.java b/hikaricp-java6/src/test/java/com/zaxxer/hikari/TestProxies.java new file mode 100644 index 00000000..460cf0d3 --- /dev/null +++ b/hikaricp-java6/src/test/java/com/zaxxer/hikari/TestProxies.java @@ -0,0 +1,84 @@ +package com.zaxxer.hikari; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; + +import org.junit.Assert; +import org.junit.Test; + +import com.zaxxer.hikari.mocks.StubConnection; +import com.zaxxer.hikari.mocks.StubStatement; + +public class TestProxies +{ + @Test + public void testProxyCreation() 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(); + + Assert.assertNotNull(conn.createStatement(ResultSet.FETCH_FORWARD, ResultSet.TYPE_SCROLL_INSENSITIVE)); + Assert.assertNotNull(conn.createStatement(ResultSet.FETCH_FORWARD, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.HOLD_CURSORS_OVER_COMMIT)); + Assert.assertNotNull(conn.prepareCall("some sql")); + Assert.assertNotNull(conn.prepareCall("some sql", ResultSet.FETCH_FORWARD, ResultSet.TYPE_SCROLL_INSENSITIVE)); + Assert.assertNotNull(conn.prepareCall("some sql", ResultSet.FETCH_FORWARD, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.HOLD_CURSORS_OVER_COMMIT)); + Assert.assertNotNull(conn.prepareStatement("some sql", PreparedStatement.NO_GENERATED_KEYS)); + Assert.assertNotNull(conn.prepareStatement("some sql", new int[3])); + Assert.assertNotNull(conn.prepareStatement("some sql", new String[3])); + Assert.assertNotNull(conn.prepareStatement("some sql", ResultSet.FETCH_FORWARD, ResultSet.TYPE_SCROLL_INSENSITIVE)); + Assert.assertNotNull(conn.prepareStatement("some sql", ResultSet.FETCH_FORWARD, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.HOLD_CURSORS_OVER_COMMIT)); + Assert.assertNotNull(conn.toString()); + + Assert.assertTrue(conn.isWrapperFor(Connection.class)); + Assert.assertTrue(conn.isValid(10)); + Assert.assertFalse(conn.isClosed()); + Assert.assertTrue(conn.unwrap(StubConnection.class) instanceof StubConnection); + try { + conn.unwrap(TestProxies.class); + Assert.fail(); + } + catch (SQLException e) { + // pass + } + } + finally { + ds.close(); + } + } + + @Test + public void testStatementProxy() 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(); + + PreparedStatement stmt = conn.prepareStatement("some sql"); + stmt.executeQuery(); + stmt.executeQuery("some sql"); + Assert.assertFalse(stmt.isClosed()); + Assert.assertNotNull(stmt.getGeneratedKeys()); + Assert.assertNotNull(stmt.getResultSet()); + Assert.assertNotNull(stmt.getConnection()); + Assert.assertTrue(stmt.unwrap(StubStatement.class) instanceof StubStatement); + } + finally { + ds.close(); + } + } +} 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 070b8bcb..2434eef2 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 @@ -68,10 +68,15 @@ public class StubConnection extends StubBaseConnection implements Connection } /** {@inheritDoc} */ + @SuppressWarnings("unchecked") @Override public T unwrap(Class iface) throws SQLException { - return null; + if (iface.isInstance(this)) { + return (T) this; + } + + throw new SQLException("Wrapped connection is not an instance of " + iface); } /** {@inheritDoc} */ diff --git a/hikaricp-java6/src/test/java/com/zaxxer/hikari/mocks/StubStatement.java b/hikaricp-java6/src/test/java/com/zaxxer/hikari/mocks/StubStatement.java index 335bb366..38475c93 100644 --- a/hikaricp-java6/src/test/java/com/zaxxer/hikari/mocks/StubStatement.java +++ b/hikaricp-java6/src/test/java/com/zaxxer/hikari/mocks/StubStatement.java @@ -41,7 +41,7 @@ public class StubStatement implements Statement public T unwrap(Class iface) throws SQLException { checkClosed(); - return null; + return (T) this; } /** {@inheritDoc} */ diff --git a/hikaricp/src/test/java/com/zaxxer/hikari/MiscTest.java b/hikaricp/src/test/java/com/zaxxer/hikari/MiscTest.java new file mode 100644 index 00000000..dcd11942 --- /dev/null +++ b/hikaricp/src/test/java/com/zaxxer/hikari/MiscTest.java @@ -0,0 +1,84 @@ +/* + * 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.io.PrintWriter; +import java.sql.SQLException; + +import org.junit.Assert; +import org.junit.Test; + +import com.zaxxer.hikari.util.ConcurrentBag; +import com.zaxxer.hikari.util.ConcurrentBag.BagEntry; +import com.zaxxer.hikari.util.PoolUtilities; + +/** + * @author Brett Wooldridge + */ +public class MiscTest +{ + @Test + public void testLogWriter() throws SQLException + { + HikariConfig config = new HikariConfig(); + config.setMinimumIdle(1); + config.setMaximumPoolSize(4); + config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource"); + + final HikariDataSource ds = new HikariDataSource(config); + try { + PrintWriter writer = new PrintWriter(System.out); + ds.setLogWriter(writer); + Assert.assertSame(writer, ds.getLogWriter()); + } + finally + { + ds.close(); + } + } + + @Test + public void testInvalidIsolation() + { + try { + PoolUtilities.getTransactionIsolation("INVALID"); + Assert.fail(); + } + catch (Exception e) { + Assert.assertTrue(e instanceof IllegalArgumentException); + } + } + + @Test + public void testCreateInstance() + { + try { + PoolUtilities.createInstance("invalid", null); + Assert.fail(); + } + catch (RuntimeException e) { + Assert.assertTrue(e.getCause() instanceof ClassNotFoundException); + } + } + + @Test + public void testBagDump() + { + ConcurrentBag bag = new ConcurrentBag(null); + bag.dumpState(); + } +} diff --git a/hikaricp/src/test/java/com/zaxxer/hikari/TestConnections.java b/hikaricp/src/test/java/com/zaxxer/hikari/TestConnections.java index 2a3a7d4e..9f55ed97 100644 --- a/hikaricp/src/test/java/com/zaxxer/hikari/TestConnections.java +++ b/hikaricp/src/test/java/com/zaxxer/hikari/TestConnections.java @@ -47,6 +47,8 @@ public class TestConnections config.setMaximumPoolSize(1); config.setInitializationFailFast(true); config.setConnectionTestQuery("VALUES 1"); + config.setConnectionInitSql("SELECT 1"); + config.setRecordMetrics(true); config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource"); HikariDataSource ds = new HikariDataSource(config); diff --git a/hikaricp/src/test/java/com/zaxxer/hikari/TestProxies.java b/hikaricp/src/test/java/com/zaxxer/hikari/TestProxies.java new file mode 100644 index 00000000..460cf0d3 --- /dev/null +++ b/hikaricp/src/test/java/com/zaxxer/hikari/TestProxies.java @@ -0,0 +1,84 @@ +package com.zaxxer.hikari; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; + +import org.junit.Assert; +import org.junit.Test; + +import com.zaxxer.hikari.mocks.StubConnection; +import com.zaxxer.hikari.mocks.StubStatement; + +public class TestProxies +{ + @Test + public void testProxyCreation() 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(); + + Assert.assertNotNull(conn.createStatement(ResultSet.FETCH_FORWARD, ResultSet.TYPE_SCROLL_INSENSITIVE)); + Assert.assertNotNull(conn.createStatement(ResultSet.FETCH_FORWARD, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.HOLD_CURSORS_OVER_COMMIT)); + Assert.assertNotNull(conn.prepareCall("some sql")); + Assert.assertNotNull(conn.prepareCall("some sql", ResultSet.FETCH_FORWARD, ResultSet.TYPE_SCROLL_INSENSITIVE)); + Assert.assertNotNull(conn.prepareCall("some sql", ResultSet.FETCH_FORWARD, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.HOLD_CURSORS_OVER_COMMIT)); + Assert.assertNotNull(conn.prepareStatement("some sql", PreparedStatement.NO_GENERATED_KEYS)); + Assert.assertNotNull(conn.prepareStatement("some sql", new int[3])); + Assert.assertNotNull(conn.prepareStatement("some sql", new String[3])); + Assert.assertNotNull(conn.prepareStatement("some sql", ResultSet.FETCH_FORWARD, ResultSet.TYPE_SCROLL_INSENSITIVE)); + Assert.assertNotNull(conn.prepareStatement("some sql", ResultSet.FETCH_FORWARD, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.HOLD_CURSORS_OVER_COMMIT)); + Assert.assertNotNull(conn.toString()); + + Assert.assertTrue(conn.isWrapperFor(Connection.class)); + Assert.assertTrue(conn.isValid(10)); + Assert.assertFalse(conn.isClosed()); + Assert.assertTrue(conn.unwrap(StubConnection.class) instanceof StubConnection); + try { + conn.unwrap(TestProxies.class); + Assert.fail(); + } + catch (SQLException e) { + // pass + } + } + finally { + ds.close(); + } + } + + @Test + public void testStatementProxy() 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(); + + PreparedStatement stmt = conn.prepareStatement("some sql"); + stmt.executeQuery(); + stmt.executeQuery("some sql"); + Assert.assertFalse(stmt.isClosed()); + Assert.assertNotNull(stmt.getGeneratedKeys()); + Assert.assertNotNull(stmt.getResultSet()); + Assert.assertNotNull(stmt.getConnection()); + Assert.assertTrue(stmt.unwrap(StubStatement.class) instanceof StubStatement); + } + finally { + ds.close(); + } + } +} 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 070b8bcb..2434eef2 100644 --- a/hikaricp/src/test/java/com/zaxxer/hikari/mocks/StubConnection.java +++ b/hikaricp/src/test/java/com/zaxxer/hikari/mocks/StubConnection.java @@ -68,10 +68,15 @@ public class StubConnection extends StubBaseConnection implements Connection } /** {@inheritDoc} */ + @SuppressWarnings("unchecked") @Override public T unwrap(Class iface) throws SQLException { - return null; + if (iface.isInstance(this)) { + return (T) this; + } + + throw new SQLException("Wrapped connection is not an instance of " + iface); } /** {@inheritDoc} */ diff --git a/hikaricp/src/test/java/com/zaxxer/hikari/mocks/StubStatement.java b/hikaricp/src/test/java/com/zaxxer/hikari/mocks/StubStatement.java index 335bb366..38475c93 100644 --- a/hikaricp/src/test/java/com/zaxxer/hikari/mocks/StubStatement.java +++ b/hikaricp/src/test/java/com/zaxxer/hikari/mocks/StubStatement.java @@ -41,7 +41,7 @@ public class StubStatement implements Statement public T unwrap(Class iface) throws SQLException { checkClosed(); - return null; + return (T) this; } /** {@inheritDoc} */