001: /*
002:
003: Derby - Class org.apache.derbyTesting.functionTests.tests.jdbc4.StatementEventsTest
004:
005: Licensed to the Apache Software Foundation (ASF) under one or more
006: contributor license agreements. See the NOTICE file distributed with
007: this work for additional information regarding copyright ownership.
008: The ASF licenses this file to you under the Apache License, Version 2.0
009: (the "License"); you may not use this file except in compliance with
010: the License. You may obtain a copy of the License at
011:
012: http://www.apache.org/licenses/LICENSE-2.0
013:
014: Unless required by applicable law or agreed to in writing, software
015: distributed under the License is distributed on an "AS IS" BASIS,
016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: See the License for the specific language governing permissions and
018: limitations under the License.
019:
020: */
021:
022: package org.apache.derbyTesting.functionTests.tests.jdbc4;
023:
024: import java.sql.*;
025: import javax.sql.*;
026: import junit.framework.*;
027:
028: import org.apache.derbyTesting.functionTests.util.TestDataSourceFactory;
029: import org.apache.derbyTesting.junit.BaseJDBCTestCase;
030:
031: import java.util.Enumeration;
032:
033: /*
034: This class is used to test the JDBC4 statement event
035: support
036: */
037: public class StatementEventsTest extends BaseJDBCTestCase {
038:
039: /**
040: * Type of data source to use. If <code>true</code>, use
041: * <code>XADataSource</code>; otherwise, use
042: * <code>ConnectionPoolDataSource</code>.
043: */
044: private boolean xa;
045: /**
046: * Type of statement to use. If <code>true</code>, use
047: * <code>CallableStatement</code>; otherwise, use
048: * <code>PreparedStatement</code>.
049: */
050: private boolean callable;
051:
052: /** The statement that caused the last statementClosed event. */
053: private Statement closedStatement;
054: /** Number of times statementClosed events have been raised. */
055: private int closedCount;
056: /** The statement that caused the last statementError event. */
057: private Statement errorStatement;
058: /** Number of times statementError events have been raised. */
059: private int errorCount;
060:
061: /**
062: * The pooled connection to use in the test (could also be an XA
063: * connection).
064: */
065: private PooledConnection pooledConnection;
066: /** The connection object to use in the test. */
067: private Connection connection;
068:
069: /**
070: * Create a test with the given name.
071: *
072: * @param name name of the test.
073: */
074: public StatementEventsTest(String name) {
075: super (name);
076: }
077:
078: /**
079: * Set whether the test should use <code>XADataSource</code> or
080: * <code>ConnectionPoolDataSource</code>.
081: *
082: * @param xa if <code>true</code>, use XA
083: */
084: private void setXA(boolean xa) {
085: this .xa = xa;
086: }
087:
088: /**
089: * Set whether the test should use <code>CallableStatement</code> or
090: * <code>PreparedStatement</code>.
091: *
092: * @param callable if <code>true</code>, use callable statement; otherwise,
093: * use prepared statement
094: */
095: private void setCallable(boolean callable) {
096: this .callable = callable;
097: }
098:
099: /**
100: * Return the name of the test.
101: *
102: * @return name of the test
103: */
104: public String getName() {
105: return super .getName() + (xa ? "_xa" : "_pooled")
106: + (callable ? "_callable" : "_prepared");
107: }
108:
109: // TEST SETUP
110:
111: /**
112: * Set up the connection to the database and register a statement event
113: * listener.
114: *
115: * @exception SQLException if a database error occurs
116: */
117: public void setUp() throws SQLException {
118: if (xa) {
119: XADataSource ds = TestDataSourceFactory.getXADataSource();
120: pooledConnection = ds.getXAConnection();
121: } else {
122: ConnectionPoolDataSource ds = TestDataSourceFactory
123: .getConnectionPoolDataSource();
124: pooledConnection = ds.getPooledConnection();
125: }
126: StatementEventListener listener = new StatementEventListener() {
127: public void statementClosed(StatementEvent event) {
128: closedStatement = event.getStatement();
129: closedCount++;
130: }
131:
132: public void statementErrorOccurred(StatementEvent event) {
133: errorStatement = event.getStatement();
134: errorCount++;
135: }
136: };
137: pooledConnection.addStatementEventListener(listener);
138: connection = pooledConnection.getConnection();
139: }
140:
141: /**
142: * Free resources used in the test.
143: *
144: * @exception SQLException if a database error occurs
145: */
146: public void tearDown() throws SQLException {
147: connection.close();
148: pooledConnection.close();
149: }
150:
151: /**
152: * Return suite with all tests of the class for all combinations of
153: * pooled/xa connection and prepared/callable statement.
154: *
155: * @return a test suite
156: */
157: public static Test suite() {
158: TestSuite suites = new TestSuite();
159: boolean[] truefalse = new boolean[] { true, false };
160: for (boolean xa : truefalse) {
161: for (boolean callable : truefalse) {
162: suites.addTest(new Suite(xa, callable));
163: }
164: }
165: return suites;
166: }
167:
168: /**
169: * Test suite class which contains all test cases in
170: * <code>StatementEventsTest</code> for a given configuration.
171: */
172: private static class Suite extends TestSuite {
173: private Suite(boolean xa, boolean callable) {
174: super (StatementEventsTest.class);
175: for (Enumeration e = tests(); e.hasMoreElements();) {
176: StatementEventsTest test = (StatementEventsTest) e
177: .nextElement();
178: test.setXA(xa);
179: test.setCallable(callable);
180: }
181: }
182: }
183:
184: // UTILITIES
185:
186: /**
187: * Prepare a statement.
188: *
189: * @param sql SQL text
190: * @return a <code>PreparedStatement</code> or
191: * <code>CallableStatement</code> object
192: * @exception SQLException if a database error occurs
193: */
194: private PreparedStatement prepare(String sql) throws SQLException {
195: if (callable) {
196: return connection.prepareCall(sql);
197: }
198: return connection.prepareStatement(sql);
199: }
200:
201: // TEST CASES
202:
203: /**
204: * Test that a close event is raised when a statement is closed.
205: *
206: * @exception SQLException if a database error occurs
207: */
208: public void testCloseEvent() throws SQLException {
209: PreparedStatement ps = prepare("VALUES (1)");
210: ps.close();
211: assertSame("Close event raised on wrong statement.", ps,
212: closedStatement);
213: assertEquals("Incorrect close count.", 1, closedCount);
214: }
215:
216: /**
217: * Test whether a close event is raised when a connection is
218: * closed. (Client should raise a close event since the connection calls
219: * <code>close()</code> on its statements. Embedded should not raise a
220: * close event since the connection does not call <code>close()</code> on
221: * its statements.)
222: *
223: * @exception SQLException if a database error occurs
224: */
225: public void testCloseEventOnClosedConnection() throws SQLException {
226: PreparedStatement ps = prepare("VALUES (1)");
227: connection.close();
228: if (usingDerbyNetClient()) {
229: assertSame("Close event raised on wrong statement.", ps,
230: closedStatement);
231: assertEquals("Incorrect close count.", 1, closedCount);
232: } else if (usingEmbedded()) {
233: assertNull("Didn't expect close event.", closedStatement);
234: assertEquals("Incorrect close count.", 0, closedCount);
235: } else {
236: fail("Unknown framework.");
237: }
238: }
239:
240: /**
241: * Test that an error event is raised when <code>execute()</code> fails
242: * because the connection is closed.
243: *
244: * @exception SQLException if a database error occurs
245: */
246: public void testErrorEventOnClosedConnection() throws SQLException {
247: PreparedStatement ps = prepare("VALUES (1)");
248: connection.close();
249: try {
250: ps.execute();
251: fail("No exception thrown.");
252: } catch (SQLException e) {
253: assertSQLState("Unexpected SQL state.", "08003", e);
254: assertSame("Error event raised on wrong statement.", ps,
255: errorStatement);
256: assertEquals("Incorrect error count.", 1, errorCount);
257: }
258: }
259: }
|