blob: 4ea627c8988b5c6754491fdc7fcdc91cfdb0f1da [file] [log] [blame]
/*
* 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;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import org.apache.commons.pool2.impl.GenericKeyedObjectPool;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
/**
*/
public class TestDelegatingConnection {
/**
* Delegate that doesn't support read-only or auto-commit.
* It will merely take the input value of setReadOnly and
* setAutoCommit and discard it, to keep false.
*/
static class NoReadOnlyOrAutoCommitConnection extends TesterConnection {
private final boolean readOnly = false;
private final boolean autoCommit = false;
public NoReadOnlyOrAutoCommitConnection() {
super("","");
}
@Override
public boolean getAutoCommit() {
return autoCommit;
}
@Override
public boolean isReadOnly() throws SQLException {
return readOnly;
}
@Override
public void setAutoCommit(final boolean autoCommit) {
// Do nothing
}
@Override
public void setReadOnly(final boolean readOnly) {
// Do nothing
}
}
/**
* Delegate that will throw RTE on toString
* Used to validate fix for DBCP-241
*/
static class RTEGeneratingConnection extends TesterConnection {
public RTEGeneratingConnection() {
super("","");
}
@Override
public String toString() {
throw new RuntimeException("bang!");
}
}
private DelegatingConnection<? extends Connection> delegatingConnection;
private Connection connection;
private Connection connection2;
private TesterStatement testerStatement;
private TesterResultSet testerResultSet;
@BeforeEach
public void setUp() throws Exception {
connection = new TesterConnection("test", "test");
connection2 = new TesterConnection("test", "test");
delegatingConnection = new DelegatingConnection<>(connection);
testerStatement = new TesterStatement(delegatingConnection);
testerResultSet = new TesterResultSet(testerStatement);
}
@Test
public void testAutoCommitCaching() throws SQLException {
final Connection con = new NoReadOnlyOrAutoCommitConnection();
final DelegatingConnection<Connection> delCon = new DelegatingConnection<>(con);
delCon.setAutoCommit(true);
assertFalse(con.getAutoCommit());
assertFalse(delCon.getAutoCommit());
}
@Test
public void testCheckOpen() throws Exception {
delegatingConnection.checkOpen();
delegatingConnection.close();
try {
delegatingConnection.checkOpen();
fail("Expecting SQLException");
} catch (final SQLException ex) {
// expected
}
}
/**
* Verify fix for DBCP-241
*/
@Test
public void testCheckOpenNull() throws Exception {
try {
delegatingConnection.close();
delegatingConnection.checkOpen();
fail("Expecting SQLException");
} catch (final SQLException ex) {
assertTrue(ex.getMessage().endsWith("is closed."));
}
try {
delegatingConnection = new DelegatingConnection<>(null);
delegatingConnection.setClosedInternal(true);
delegatingConnection.checkOpen();
fail("Expecting SQLException");
} catch (final SQLException ex) {
assertTrue(ex.getMessage().endsWith("is null."));
}
try {
final PoolingConnection pc = new PoolingConnection(connection2);
pc.setStatementPool(new GenericKeyedObjectPool<>(pc));
delegatingConnection = new DelegatingConnection<>(pc);
pc.close();
delegatingConnection.close();
try (PreparedStatement ps = delegatingConnection.prepareStatement("")){}
fail("Expecting SQLException");
} catch (final SQLException ex) {
assertTrue(ex.getMessage().endsWith("is closed."));
}
try {
delegatingConnection = new DelegatingConnection<>(new RTEGeneratingConnection());
delegatingConnection.close();
delegatingConnection.checkOpen();
fail("Expecting SQLException");
} catch (final SQLException ex) {
assertTrue(ex.getMessage().endsWith("is closed."));
}
}
@Test
public void testConnectionToString() throws Exception {
final String s = delegatingConnection.toString();
assertNotNull(s);
assertFalse(s.isEmpty());
}
@Test
public void testGetDelegate() throws Exception {
assertEquals(connection,delegatingConnection.getDelegate());
}
@Test
public void testIsClosed() throws Exception {
delegatingConnection.checkOpen();
assertFalse(delegatingConnection.isClosed());
delegatingConnection.close();
assertTrue(delegatingConnection.isClosed());
}
@Test
public void testIsClosedNullDelegate() throws Exception {
delegatingConnection.checkOpen();
assertFalse(delegatingConnection.isClosed());
delegatingConnection.setDelegate(null);
assertTrue(delegatingConnection.isClosed());
}
@Test
public void testPassivateWithResultSetCloseException() {
try {
testerResultSet.setSqlExceptionOnClose(true);
delegatingConnection.addTrace(testerResultSet);
delegatingConnection.passivate();
Assertions.fail("Expected SQLExceptionList");
} catch (final SQLException e) {
Assertions.assertTrue(e instanceof SQLExceptionList);
Assertions.assertEquals(1, ((SQLExceptionList) e).getCauseList().size());
} finally {
testerResultSet.setSqlExceptionOnClose(false);
}
}
@Test
public void testPassivateWithResultSetCloseExceptionAndStatementCloseException() {
try {
testerStatement.setSqlExceptionOnClose(true);
testerResultSet.setSqlExceptionOnClose(true);
delegatingConnection.addTrace(testerStatement);
delegatingConnection.addTrace(testerResultSet);
delegatingConnection.passivate();
Assertions.fail("Expected SQLExceptionList");
} catch (final SQLException e) {
Assertions.assertTrue(e instanceof SQLExceptionList);
Assertions.assertEquals(2, ((SQLExceptionList) e).getCauseList().size());
} finally {
testerStatement.setSqlExceptionOnClose(false);
testerResultSet.setSqlExceptionOnClose(false);
}
}
@Test
public void testPassivateWithStatementCloseException() {
try {
testerStatement.setSqlExceptionOnClose(true);
delegatingConnection.addTrace(testerStatement);
delegatingConnection.passivate();
Assertions.fail("Expected SQLExceptionList");
} catch (final SQLException e) {
Assertions.assertTrue(e instanceof SQLExceptionList);
Assertions.assertEquals(1, ((SQLExceptionList) e).getCauseList().size());
} finally {
testerStatement.setSqlExceptionOnClose(false);
}
}
@Test
public void testReadOnlyCaching() throws SQLException {
final Connection con = new NoReadOnlyOrAutoCommitConnection();
final DelegatingConnection<Connection> delCon = new DelegatingConnection<>(con);
delCon.setReadOnly(true);
assertFalse(con.isReadOnly());
assertFalse(delCon.isReadOnly());
}
}