Repository: commons-dbcp
Updated Branches:
  refs/heads/master 629040340 -> 64a13ee39


http://git-wip-us.apache.org/repos/asf/commons-dbcp/blob/64a13ee3/src/test/java/org/apache/commons/dbcp2/managed/TestLocalXaResource.java
----------------------------------------------------------------------
diff --git 
a/src/test/java/org/apache/commons/dbcp2/managed/TestLocalXaResource.java 
b/src/test/java/org/apache/commons/dbcp2/managed/TestLocalXaResource.java
new file mode 100644
index 0000000..7efe5ca
--- /dev/null
+++ b/src/test/java/org/apache/commons/dbcp2/managed/TestLocalXaResource.java
@@ -0,0 +1,590 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.commons.dbcp2.managed;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.CallableStatement;
+import java.sql.Clob;
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.NClob;
+import java.sql.PreparedStatement;
+import java.sql.SQLClientInfoException;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.sql.SQLXML;
+import java.sql.Savepoint;
+import java.sql.Statement;
+import java.sql.Struct;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.Executor;
+
+import javax.transaction.xa.XAException;
+import javax.transaction.xa.XAResource;
+import javax.transaction.xa.Xid;
+
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests for LocalXAConnectionFactory$LocalXAResource
+ */
+public class TestLocalXaResource {
+
+    private Connection conn;
+    private LocalXAConnectionFactory.LocalXAResource resource;
+
+    @Before
+    public void setUp() {
+        conn = new TestConnection();
+        resource = new LocalXAConnectionFactory.LocalXAResource(conn);
+    }
+
+    @Test
+    public void testConstructor() {
+        assertEquals(0, resource.getTransactionTimeout());
+        assertNull(resource.getXid());
+        // the current implementation always return false, regardless of the 
input value
+        assertFalse(resource.setTransactionTimeout(100));
+        // the current implementation always return an empty/zero'd array, 
regardless of the input value
+        assertEquals(0, resource.recover(100).length);
+    }
+
+    @Test
+    public void testIsSame() {
+        assertTrue(resource.isSameRM(resource));
+        assertFalse(resource.isSameRM(new 
LocalXAConnectionFactory.LocalXAResource(conn)));
+    }
+
+    @Test(expected=XAException.class)
+    public void testStartInvalidFlag() throws XAException {
+        // currently, valid values are TMNOFLAGS and TMRESUME
+        resource.start(null, XAResource.TMENDRSCAN);
+    }
+
+    @Test(expected=XAException.class)
+    public void testStartNoFlagButAlreadyEnlisted() throws XAException {
+        resource.start(new TestXid(), XAResource.TMNOFLAGS);
+        resource.start(new TestXid(), XAResource.TMNOFLAGS);
+    }
+
+    @Test(expected=XAException.class)
+    public void testStartNoFlagResumeButDifferentXid() throws XAException {
+        resource.start(new TestXid(), XAResource.TMNOFLAGS);
+        resource.start(new TestXid(), XAResource.TMRESUME);
+    }
+
+    @Test
+    public void testStartNoFlagResume() throws XAException {
+        Xid xid = new TestXid();
+        resource.start(xid, XAResource.TMNOFLAGS);
+        resource.start(xid, XAResource.TMRESUME);
+        assertEquals(xid, resource.getXid());
+    }
+
+    @Test
+    public void testStartNoFlagResumeEnd() throws XAException {
+        Xid xid = new TestXid();
+        resource.start(xid, XAResource.TMNOFLAGS);
+        resource.start(xid, XAResource.TMRESUME);
+        // flag is never used in the end
+        resource.end(xid, 0);
+        assertEquals(xid, resource.getXid());
+    }
+
+    @Test(expected=NullPointerException.class)
+    public void testStartNoFlagResumeEndMissingXid() throws XAException {
+        Xid xid = new TestXid();
+        resource.start(xid, XAResource.TMNOFLAGS);
+        resource.start(xid, XAResource.TMRESUME);
+        // flag is never used in the end
+        resource.end(null, 0);
+    }
+
+    @Test(expected=XAException.class)
+    public void testStartNoFlagResumeEndDifferentXid() throws XAException {
+        Xid xid = new TestXid();
+        resource.start(xid, XAResource.TMNOFLAGS);
+        resource.start(xid, XAResource.TMRESUME);
+        // flag is never used in the end
+        resource.end(new TestXid(), 0);
+    }
+
+    @Test
+    public void testForgetDifferentXid() throws XAException {
+        Xid xid = new TestXid();
+        resource.start(xid, XAResource.TMNOFLAGS);
+        resource.forget(new TestXid());
+        assertEquals(xid, resource.getXid());
+    }
+
+    @Test
+    public void testForgetMissingXid() throws XAException {
+        Xid xid = new TestXid();
+        resource.start(xid, XAResource.TMNOFLAGS);
+        resource.forget(null);
+        assertEquals(xid, resource.getXid());
+    }
+
+    @Test
+    public void testForget() throws XAException {
+        Xid xid = new TestXid();
+        resource.start(xid, XAResource.TMNOFLAGS);
+        resource.forget(xid);
+        assertNull(resource.getXid());
+    }
+
+    @Test
+    public void testStartReadOnlyConnectionPrepare() throws XAException, 
SQLException {
+        Xid xid = new TestXid();
+        conn.setAutoCommit(false);
+        conn.setReadOnly(true);
+        resource.start(xid, XAResource.TMNOFLAGS);
+        resource.prepare(xid);
+        assertFalse(conn.getAutoCommit());
+    }
+
+    /**
+     * When an exception is thrown on the {@link Connection#getAutoCommit()}, 
then the
+     * value is set to {@code true} by default.
+     * @throws XAException when there are errors with the transaction
+     * @throws SQLException when there are errors with other SQL/DB parts
+     */
+    @Test
+    public void testStartExceptionOnGetAutoCommit() throws XAException, 
SQLException {
+        Xid xid = new TestXid();
+        ((TestConnection) conn).throwWhenGetAutoCommit = true;
+        conn.setAutoCommit(false);
+        conn.setReadOnly(true);
+        // the start method with no flag will call getAutoCommit, the 
exception will be thrown, and it will be set
+        // to true
+        resource.start(xid, XAResource.TMNOFLAGS);
+        // and prepare sets the value computed in start in the connection
+        resource.prepare(xid);
+        ((TestConnection) conn).throwWhenGetAutoCommit = false;
+        assertTrue(conn.getAutoCommit());
+    }
+
+    /**
+     * When an exception is thrown on the {@link Connection#getAutoCommit()}, 
then the
+     * value is set to {@code true} by default. However, if the connection is 
not read-only,
+     * then the value set by the user in the original connection will be kept.
+     * @throws XAException when there are errors with the transaction
+     * @throws SQLException when there are errors with other SQL/DB parts
+     */
+    @Test
+    public void testStartReadOnlyConnectionExceptionOnGetAutoCommit() throws 
XAException, SQLException {
+        Xid xid = new TestXid();
+        ((TestConnection) conn).throwWhenGetAutoCommit = true;
+        conn.setAutoCommit(false);
+        conn.setReadOnly(false);
+        // the start method with no flag will call getAutoCommit, the 
exception will be thrown, and it will be set
+        // to true
+        resource.start(xid, XAResource.TMNOFLAGS);
+        // and prepare sets the value computed in start in the connection
+        resource.prepare(xid);
+        ((TestConnection) conn).throwWhenGetAutoCommit = false;
+        assertFalse(conn.getAutoCommit());
+    }
+
+    @Test(expected=XAException.class)
+    public void testStartFailsWhenCannotSetAutoCommit() throws XAException, 
SQLException {
+        Xid xid = new TestXid();
+        ((TestConnection) conn).throwWhenSetAutoCommit = true;
+        resource.start(xid, XAResource.TMNOFLAGS);
+    }
+
+    @Test(expected=NullPointerException.class)
+    public void testCommitMissingXid() throws SQLException, XAException {
+        resource.commit(null, false);
+    }
+
+    @Test(expected=XAException.class)
+    public void testCommitNoTransaction() throws SQLException, XAException {
+        ((TestConnection) conn).closed = false;
+        conn.setReadOnly(false);
+        resource.commit(new TestXid(), false);
+    }
+
+    @Test(expected=XAException.class)
+    public void testCommitInvalidXid() throws SQLException, XAException {
+        Xid xid = new TestXid();
+        ((TestConnection) conn).closed = false;
+        conn.setReadOnly(false);
+        resource.start(xid, XAResource.TMNOFLAGS);
+        resource.commit(new TestXid(), false);
+    }
+
+    @Test(expected=XAException.class)
+    public void testCommitConnectionClosed() throws SQLException, XAException {
+        Xid xid = new TestXid();
+        ((TestConnection) conn).closed = true;
+        conn.setReadOnly(false);
+        resource.start(xid, XAResource.TMNOFLAGS);
+        resource.commit(xid, false);
+    }
+
+    @Test
+    public void testCommitConnectionNotReadOnly() throws SQLException, 
XAException {
+        Xid xid = new TestXid();
+        ((TestConnection) conn).closed = false;
+        conn.setReadOnly(true);
+        resource.start(xid, XAResource.TMNOFLAGS);
+        resource.commit(xid, false);
+        assertFalse(((TestConnection) conn).committed);
+    }
+
+    @Test
+    public void testCommit() throws SQLException, XAException {
+        Xid xid = new TestXid();
+        ((TestConnection) conn).closed = false;
+        conn.setReadOnly(false);
+        resource.start(xid, XAResource.TMNOFLAGS);
+        resource.commit(xid, false);
+        assertTrue(((TestConnection) conn).committed);
+    }
+
+    @Test(expected=NullPointerException.class)
+    public void testRollbackMissingXid() throws XAException {
+        resource.rollback(null);
+    }
+
+    @Test(expected=XAException.class)
+    public void testRollbackInvalidXid() throws SQLException, XAException {
+        Xid xid = new TestXid();
+        ((TestConnection) conn).closed = false;
+        conn.setReadOnly(false);
+        resource.start(xid, XAResource.TMNOFLAGS);
+        resource.rollback(new TestXid());
+    }
+
+    @Test
+    public void testRollback() throws SQLException, XAException {
+        Xid xid = new TestXid();
+        ((TestConnection) conn).closed = false;
+        conn.setReadOnly(false);
+        resource.start(xid, XAResource.TMNOFLAGS);
+        resource.rollback(xid);
+        assertTrue(((TestConnection) conn).rolledback);
+    }
+
+    private static class TestConnection implements Connection {
+
+        public boolean throwWhenGetAutoCommit = false;
+        public boolean throwWhenSetAutoCommit = false;
+        boolean autoCommit = false;
+        boolean readOnly = false;
+        public boolean committed = false;
+        public boolean rolledback = false;
+        public boolean closed = false;
+
+        @Override
+        public <T> T unwrap(Class<T> iface) throws SQLException {
+            return null;
+        }
+
+        @Override
+        public boolean isWrapperFor(Class<?> iface) throws SQLException {
+            return false;
+        }
+
+        @Override
+        public Statement createStatement() throws SQLException {
+            return null;
+        }
+
+        @Override
+        public PreparedStatement prepareStatement(String sql) throws 
SQLException {
+            return null;
+        }
+
+        @Override
+        public CallableStatement prepareCall(String sql) throws SQLException {
+            return null;
+        }
+
+        @Override
+        public String nativeSQL(String sql) throws SQLException {
+            return null;
+        }
+
+        @Override
+        public void setAutoCommit(boolean autoCommit) throws SQLException {
+            if (throwWhenSetAutoCommit) {
+                throw new SQLException();
+            }
+            this.autoCommit = autoCommit;
+        }
+
+        @Override
+        public boolean getAutoCommit() throws SQLException {
+            if (throwWhenGetAutoCommit) {
+                throw new SQLException();
+            }
+            return autoCommit;
+        }
+
+        @Override
+        public void commit() throws SQLException {
+            committed = true;
+        }
+
+        @Override
+        public void rollback() throws SQLException {
+            rolledback = true;
+        }
+
+        @Override
+        public void close() throws SQLException {
+            closed = true;
+        }
+
+        @Override
+        public boolean isClosed() throws SQLException {
+            return closed;
+        }
+
+        @Override
+        public DatabaseMetaData getMetaData() throws SQLException {
+            return null;
+        }
+
+        @Override
+        public void setReadOnly(boolean readOnly) throws SQLException {
+            this.readOnly = readOnly;
+        }
+
+        @Override
+        public boolean isReadOnly() throws SQLException {
+            return readOnly;
+        }
+
+        @Override
+        public void setCatalog(String catalog) throws SQLException {
+        }
+
+        @Override
+        public String getCatalog() throws SQLException {
+            return null;
+        }
+
+        @Override
+        public void setTransactionIsolation(int level) throws SQLException {
+        }
+
+        @Override
+        public int getTransactionIsolation() throws SQLException {
+            return 0;
+        }
+
+        @Override
+        public SQLWarning getWarnings() throws SQLException {
+            return null;
+        }
+
+        @Override
+        public void clearWarnings() throws SQLException {
+        }
+
+        @Override
+        public Statement createStatement(int resultSetType, int 
resultSetConcurrency) throws SQLException {
+            return null;
+        }
+
+        @Override
+        public PreparedStatement prepareStatement(String sql, int 
resultSetType, int resultSetConcurrency)
+                throws SQLException {
+            return null;
+        }
+
+        @Override
+        public CallableStatement prepareCall(String sql, int resultSetType, 
int resultSetConcurrency)
+                throws SQLException {
+            return null;
+        }
+
+        @Override
+        public Map<String, Class<?>> getTypeMap() throws SQLException {
+            return null;
+        }
+
+        @Override
+        public void setTypeMap(Map<String, Class<?>> map) throws SQLException {
+        }
+
+        @Override
+        public void setHoldability(int holdability) throws SQLException {
+        }
+
+        @Override
+        public int getHoldability() throws SQLException {
+            return 0;
+        }
+
+        @Override
+        public Savepoint setSavepoint() throws SQLException {
+            return null;
+        }
+
+        @Override
+        public Savepoint setSavepoint(String name) throws SQLException {
+            return null;
+        }
+
+        @Override
+        public void rollback(Savepoint savepoint) throws SQLException {
+        }
+
+        @Override
+        public void releaseSavepoint(Savepoint savepoint) throws SQLException {
+        }
+
+        @Override
+        public Statement createStatement(int resultSetType, int 
resultSetConcurrency, int resultSetHoldability)
+                throws SQLException {
+            return null;
+        }
+
+        @Override
+        public PreparedStatement prepareStatement(String sql, int 
resultSetType, int resultSetConcurrency,
+                int resultSetHoldability) throws SQLException {
+            return null;
+        }
+
+        @Override
+        public CallableStatement prepareCall(String sql, int resultSetType, 
int resultSetConcurrency,
+                int resultSetHoldability) throws SQLException {
+            return null;
+        }
+
+        @Override
+        public PreparedStatement prepareStatement(String sql, int 
autoGeneratedKeys) throws SQLException {
+            return null;
+        }
+
+        @Override
+        public PreparedStatement prepareStatement(String sql, int[] 
columnIndexes) throws SQLException {
+            return null;
+        }
+
+        @Override
+        public PreparedStatement prepareStatement(String sql, String[] 
columnNames) throws SQLException {
+            return null;
+        }
+
+        @Override
+        public Clob createClob() throws SQLException {
+            return null;
+        }
+
+        @Override
+        public Blob createBlob() throws SQLException {
+            return null;
+        }
+
+        @Override
+        public NClob createNClob() throws SQLException {
+            return null;
+        }
+
+        @Override
+        public SQLXML createSQLXML() throws SQLException {
+            return null;
+        }
+
+        @Override
+        public boolean isValid(int timeout) throws SQLException {
+            return false;
+        }
+
+        @Override
+        public void setClientInfo(String name, String value) throws 
SQLClientInfoException {
+        }
+
+        @Override
+        public void setClientInfo(Properties properties) throws 
SQLClientInfoException {
+        }
+
+        @Override
+        public String getClientInfo(String name) throws SQLException {
+            return null;
+        }
+
+        @Override
+        public Properties getClientInfo() throws SQLException {
+            return null;
+        }
+
+        @Override
+        public Array createArrayOf(String typeName, Object[] elements) throws 
SQLException {
+            return null;
+        }
+
+        @Override
+        public Struct createStruct(String typeName, Object[] attributes) 
throws SQLException {
+            return null;
+        }
+
+        @Override
+        public void setSchema(String schema) throws SQLException {
+        }
+
+        @Override
+        public String getSchema() throws SQLException {
+            return null;
+        }
+
+        @Override
+        public void abort(Executor executor) throws SQLException {
+        }
+
+        @Override
+        public void setNetworkTimeout(Executor executor, int milliseconds) 
throws SQLException {
+        }
+
+        @Override
+        public int getNetworkTimeout() throws SQLException {
+            return 0;
+        }
+    }
+
+    private static class TestXid implements Xid {
+
+        @Override
+        public byte[] getBranchQualifier() {
+            return null;
+        }
+
+        @Override
+        public int getFormatId() {
+            return 0;
+        }
+
+        @Override
+        public byte[] getGlobalTransactionId() {
+            return null;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/commons-dbcp/blob/64a13ee3/src/test/java/org/apache/commons/dbcp2/managed/TestManagedDataSource.java
----------------------------------------------------------------------
diff --git 
a/src/test/java/org/apache/commons/dbcp2/managed/TestManagedDataSource.java 
b/src/test/java/org/apache/commons/dbcp2/managed/TestManagedDataSource.java
index 320469f..5f31d7a 100644
--- a/src/test/java/org/apache/commons/dbcp2/managed/TestManagedDataSource.java
+++ b/src/test/java/org/apache/commons/dbcp2/managed/TestManagedDataSource.java
@@ -256,4 +256,31 @@ public class TestManagedDataSource extends 
TestConnectionPool {
         c1.close();
         c2.close();
     }
+
+    @Test(expected=IllegalStateException.class)
+    public void testTransactionRegistryNotInitialized() throws Exception {
+        try (ManagedDataSource<?> ds = new ManagedDataSource<>(pool, null)) {
+            ds.getConnection();
+        }
+    }
+
+    @Test(expected=IllegalStateException.class)
+    public void testSetTransactionRegistryAlreadySet() {
+        ManagedDataSource<?> managed = (ManagedDataSource<?>) ds;
+        managed.setTransactionRegistry(null);
+    }
+
+    @Test(expected=NullPointerException.class)
+    public void testSetNullTransactionRegistry() throws Exception {
+        try (ManagedDataSource<?> ds = new ManagedDataSource<>(pool, null)) {
+            ds.setTransactionRegistry(null);
+        }
+    }
+
+    @Test()
+    public void testSetTransactionRegistry() throws Exception {
+        try (ManagedDataSource<?> ds = new ManagedDataSource<>(pool, null)) {
+            ds.setTransactionRegistry(new 
TransactionRegistry(transactionManager));
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/commons-dbcp/blob/64a13ee3/src/test/java/org/apache/commons/dbcp2/managed/TestPoolableManagedConnection.java
----------------------------------------------------------------------
diff --git 
a/src/test/java/org/apache/commons/dbcp2/managed/TestPoolableManagedConnection.java
 
b/src/test/java/org/apache/commons/dbcp2/managed/TestPoolableManagedConnection.java
new file mode 100644
index 0000000..44da212
--- /dev/null
+++ 
b/src/test/java/org/apache/commons/dbcp2/managed/TestPoolableManagedConnection.java
@@ -0,0 +1,141 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.commons.dbcp2.managed;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Properties;
+
+import javax.transaction.TransactionManager;
+
+import org.apache.commons.dbcp2.ConnectionFactory;
+import org.apache.commons.dbcp2.DriverConnectionFactory;
+import org.apache.commons.dbcp2.PoolableConnection;
+import org.apache.commons.dbcp2.PoolableConnectionFactory;
+import org.apache.commons.dbcp2.TesterDriver;
+import org.apache.commons.pool2.impl.GenericObjectPool;
+import org.apache.geronimo.transaction.manager.TransactionManagerImpl;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests for PoolableManagedConnection.
+ */
+public class TestPoolableManagedConnection {
+
+    private TransactionManager transactionManager;
+    private TransactionRegistry transactionRegistry;
+    private GenericObjectPool<PoolableConnection> pool;
+    private Connection conn;
+    private PoolableManagedConnection poolableManagedConnection;
+
+    @Before
+    public void setUp() throws Exception {
+        // create a GeronimoTransactionManager for testing
+        transactionManager = new TransactionManagerImpl();
+
+        // create a driver connection factory
+        final Properties properties = new Properties();
+        properties.setProperty("user", "userName");
+        properties.setProperty("password", "password");
+        final ConnectionFactory connectionFactory = new 
DriverConnectionFactory(new TesterDriver(), "jdbc:apache:commons:testdriver", 
properties);
+
+        // wrap it with a LocalXAConnectionFactory
+        final XAConnectionFactory xaConnectionFactory = new 
LocalXAConnectionFactory(transactionManager, connectionFactory);
+
+        // create transaction registry
+        transactionRegistry = xaConnectionFactory.getTransactionRegistry();
+
+        // create the pool object factory
+        final PoolableConnectionFactory factory = new 
PoolableConnectionFactory(xaConnectionFactory, null);
+        factory.setValidationQuery("SELECT DUMMY FROM DUAL");
+        factory.setDefaultReadOnly(Boolean.TRUE);
+        factory.setDefaultAutoCommit(Boolean.TRUE);
+
+        // create the pool
+        pool = new GenericObjectPool<>(factory);
+        factory.setPool(pool);
+        pool.setMaxTotal(10);
+        pool.setMaxWaitMillis(100);
+    }
+
+    @After
+    public void tearDown() throws SQLException {
+        if (conn != null && !conn.isClosed())
+            conn.close();
+        if (pool != null && !pool.isClosed())
+            pool.close();
+    }
+
+    @Test
+    public void testManagedConnection() throws Exception {
+        assertEquals(0, pool.getNumActive());
+        // create a connection
+        conn = pool.borrowObject();
+        assertEquals(1, pool.getNumActive());
+        // create the poolable managed connection
+        poolableManagedConnection = new 
PoolableManagedConnection(transactionRegistry, conn, pool);
+        poolableManagedConnection.close();
+        // closing a poolable managed connection won't close it, but simply 
return to the pool
+        assertEquals(1, pool.getNumActive());
+        // but closing the underlying connection really closes it
+        conn.close();
+        assertEquals(0, pool.getNumActive());
+    }
+
+    @Test
+    public void testPoolableConnection() throws Exception {
+        // create a connection
+        // pool uses LocalXAConnectionFactory, which register the connection 
with the TransactionRegistry
+        conn = pool.borrowObject();
+        assertNotNull(transactionRegistry.getXAResource(conn));
+        // create the poolable managed connection
+        poolableManagedConnection = new 
PoolableManagedConnection(transactionRegistry, conn, pool);
+        poolableManagedConnection.close();
+        assertNotNull(transactionRegistry.getXAResource(conn));
+    }
+
+    @Test
+    public void testReallyClose() throws Exception {
+        assertEquals(0, pool.getNumActive());
+        // create a connection
+        // pool uses LocalXAConnectionFactory, which register the connection 
with the TransactionRegistry
+        conn = pool.borrowObject();
+        assertEquals(1, pool.getNumActive());
+        assertNotNull(transactionRegistry.getXAResource(conn));
+        // create the poolable managed connection
+        poolableManagedConnection = new 
PoolableManagedConnection(transactionRegistry, conn, pool);
+        poolableManagedConnection.close();
+        assertNotNull(transactionRegistry.getXAResource(conn));
+        assertEquals(1, pool.getNumActive());
+        // this must close the managed connection, removing it from the 
transaction registry
+        poolableManagedConnection.reallyClose();
+        try {
+            assertNull(transactionRegistry.getXAResource(conn));
+            fail("Transaction registry was supposed to be empty now");
+        } catch (SQLException e) {}
+        assertEquals(0, pool.getNumActive());
+    }
+}
\ No newline at end of file

Reply via email to