001: /*
002:
003: Derby - Class org.apache.derbyTesting.functionTests.tests.lang.closed
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.lang;
023:
024: import java.sql.Connection;
025: import java.sql.Statement;
026: import java.sql.PreparedStatement;
027: import java.sql.ResultSet;
028: import java.sql.ResultSetMetaData;
029: import java.sql.DatabaseMetaData;
030: import java.sql.SQLException;
031: import java.sql.SQLWarning;
032:
033: import org.apache.derby.tools.ij;
034: import org.apache.derby.tools.JDBCDisplayUtil;
035: import org.apache.derbyTesting.functionTests.util.TestUtil;
036:
037: /**
038: Test execution of closed JDBC objects. Executing or accessing a closed
039: object should report that it is closed.
040: <p>
041: Note that alot of this behavior is not very specifically specified in
042: the JDBC guide, so this test is local to our own handler. Running JBMS
043: under other handlers (such as weblogic) may produce different results due
044: to how they cache data and reuse client-side objects.
045:
046: @author ames
047: */
048: public class closed implements Runnable {
049:
050: private static boolean jsr169_test = false;
051:
052: public static void main(String[] args) {
053: System.out.println("Test closed starting");
054: boolean passed = true;
055:
056: try {
057: Connection conn;
058:
059: // use the ij utility to read the property file and
060: // make the initial connection.
061: ij.getPropertyArg(args);
062: conn = ij.startJBMS();
063:
064: passed = testDerby62(conn) && passed;
065:
066: // want all tests to run regardless of intermediate errors
067: passed = testStatement(conn) && passed;
068:
069: passed = testPreparedStatement(conn) && passed;
070:
071: passed = testResultSet(conn) && passed;
072:
073: // this test needs to be last, because the connection will
074: // be closed by it.
075: passed = testConnection(conn) && passed;
076:
077: if (!conn.isClosed()) {
078: passed = false;
079: System.out
080: .println("FAIL -- connection not closed by test");
081: conn.close();
082: }
083:
084: // shutdown the database
085: System.out.println("Test database shutdown ...");
086: passed = shutdownTest("wombat", "shutdown=true");
087:
088: // shutdown the system
089: System.out.println("Test system shutdown ...");
090: passed = shutdownTest("", "shutdown=true");
091:
092: } catch (Throwable e) {
093: passed = false;
094: System.out.println("FAIL -- unexpected exception:");
095: JDBCDisplayUtil.ShowException(System.out, e);
096: }
097:
098: if (passed)
099: System.out.println("PASS");
100: System.out.println("Test closed finished");
101: }
102:
103: static boolean shutdownTest(String databaseName,
104: String shutdownString) throws SQLException {
105: // static boolean shutdownTest(String databaseName, String shutdownString) throws SQLException, IllegalAccessException, ClassNotFoundException, InstantiationException {
106:
107: boolean passed = true;
108:
109: Connection c1 = TestUtil.getConnection("wombat", null);
110: Connection c2 = TestUtil.getConnection("wombat", null);
111: Connection c3a = TestUtil.getConnection("wombat", null);
112: Connection c3b = TestUtil.getConnection("wombat", null);
113:
114: try {
115: c3a.createStatement().execute("DROP TABLE CLOSED.LOCKME");
116: } catch (SQLException sqle) {
117: }
118: try {
119: c3a.createStatement().execute("DROP PROCEDURE SLEEP");
120: } catch (SQLException sqle) {
121: }
122:
123: c3a.createStatement().execute(
124: "CREATE TABLE CLOSED.LOCKME(i int)");
125:
126: c3a
127: .createStatement()
128: .execute(
129: "create procedure sleep(t INTEGER) dynamic result sets 0 language java external name 'java.lang.Thread.sleep' parameter style java");
130: c3a.setAutoCommit(false);
131: c3a.createStatement().execute(
132: "LOCK TABLE CLOSED.LOCKME IN SHARE MODE");
133:
134: closed r2 = new closed(c2, "CALL sleep(10000)");
135: closed r3 = new closed(c3b,
136: "LOCK TABLE CLOSED.LOCKME IN EXCLUSIVE MODE");
137:
138: Thread t2 = new Thread(r2);
139: t2.start();
140: Thread t3 = new Thread(r3);
141: t3.start();
142:
143: try {
144: Thread.currentThread().sleep(2000);
145: } catch (InterruptedException ie) {
146: System.out.println(ie);
147: }
148:
149: SQLException s = null;
150: try {
151: TestUtil.getConnection(databaseName, shutdownString);
152: } catch (SQLException sqle) {
153: s = sqle;
154: }
155:
156: try {
157: t2.join();
158: } catch (InterruptedException ie) {
159: System.out.println(ie);
160: }
161: try {
162: t3.join();
163: } catch (InterruptedException ie) {
164: System.out.println(ie);
165: }
166:
167: System.out.println(r2.result);
168: System.out.println(r3.result);
169:
170: if (s != null)
171: JDBCDisplayUtil.ShowException(System.out, s);
172:
173: if (!c1.isClosed()) {
174: passed = false;
175: System.out.println("FAIL -- connection not shutdown "
176: + databaseName + ";" + shutdownString);
177: c1.close();
178: }
179: if (!c2.isClosed()) {
180: passed = false;
181: System.out
182: .println("FAIL -- active connection not shutdown "
183: + databaseName + ";" + shutdownString);
184: c2.close();
185: }
186:
187: System.out.println("Shutdown test completed.");
188: return passed;
189: }
190:
191: // for the shutdown test
192: private Connection cc;
193: private String sql;
194: String result;
195:
196: private closed(Connection cc, String sql) {
197: this .cc = cc;
198: this .sql = sql;
199: }
200:
201: public void run() {
202:
203: try {
204: cc.createStatement().execute(sql);
205: result = "Sleep thread completed " + sql;
206: } catch (SQLException sqle) {
207:
208: // this is to avoid different cannons for different JVMs since
209: // an java.lang.InterruptedException is thrown.
210: StringBuffer sb = new StringBuffer();
211: sb.append(sql);
212: sb.append(" - ");
213: sb.append(sqle.getSQLState());
214: while (sqle != null) {
215: if (sqle != null) {
216: sb.append(", ");
217: sb.append(sqle.getSQLState());
218: sb.append(" -- ");
219: if (sqle.getMessage().indexOf(
220: "InterruptedException") != -1)
221: sb.append("InterruptedException");
222: else {
223: sb.append(sqle.getMessage());
224: sqle.printStackTrace(System.out);
225: }
226: } else {
227: sb.append(sqle.getMessage());
228: }
229: sqle = sqle.getNextException();
230: }
231: result = sb.toString();
232: }
233: }
234:
235: static boolean testStatement(Connection conn) throws SQLException {
236: Statement s;
237: boolean passed = true;
238:
239: s = conn.createStatement();
240: s.execute("create table t (i int)");
241: s.execute("create table s (i int)");
242:
243: try {
244: s.execute("create table u (i int)");
245: } catch (SQLException se) {
246: // out impl lets you execute from closed, as stmt object is reusable
247: // after it is closed.
248: passed = false; // won't pass unless caught
249: // could verify exception #...
250: JDBCDisplayUtil.ShowSQLException(System.out, se);
251: }
252: if (!passed)
253: System.out
254: .println("FAIL -- no error on execute of closed statement");
255: return passed;
256: }
257:
258: static boolean testPreparedStatement(Connection conn)
259: throws SQLException {
260: PreparedStatement ps;
261: boolean passed = true;
262:
263: ps = conn.prepareStatement("insert into t values (1)");
264: ps.execute();
265: ps.execute();
266: ps.close();
267:
268: try {
269: passed = false; // won't pass unless caught
270: ps.execute();
271: } catch (SQLException se) {
272: passed = true;
273: // could verify exception #...
274: JDBCDisplayUtil.ShowSQLException(System.out, se);
275: }
276: if (!passed)
277: System.out
278: .println("FAIL -- no error on execute of closed prepared statement");
279:
280: return passed;
281: }
282:
283: static boolean testResultSet(Connection conn) throws SQLException {
284: PreparedStatement ps;
285: Statement s;
286: ResultSet rs;
287: boolean passed = true;
288:
289: // first, get a few values into a table:
290: ps = conn.prepareStatement("insert into s values (1)");
291: ps.execute();
292: ps.execute();
293: ps.execute();
294: ps.execute();
295: ps.execute();
296: ps.close();
297:
298: s = conn.createStatement();
299: rs = s.executeQuery("select * from s");
300:
301: rs.next();
302: rs.next();
303: rs.close();
304:
305: try {
306: passed = false; // won't pass unless caught
307: rs.next();
308: } catch (SQLException se) {
309: passed = true;
310: // could verify exception #...
311: JDBCDisplayUtil.ShowSQLException(System.out, se);
312: }
313: if (!passed)
314: System.out
315: .println("FAIL -- no error on next of closed result set");
316:
317: // now see that rs after statement closed is closed also
318: rs = s.executeQuery("select * from s");
319:
320: rs.next();
321: rs.next();
322: s.close();
323:
324: try {
325: passed = false; // won't pass unless caught
326: rs.next();
327: } catch (SQLException se) {
328: passed = true;
329: // could verify exception #...
330: JDBCDisplayUtil.ShowSQLException(System.out, se);
331: }
332: if (!passed)
333: System.out
334: .println("FAIL -- no error on next of result set with closed statement");
335:
336: return passed;
337: }
338:
339: static boolean testConnection(Connection conn) throws SQLException {
340: DatabaseMetaData dmd;
341: ResultSet rs;
342: Statement s;
343: PreparedStatement ps;
344: boolean passed = true;
345:
346: dmd = conn.getMetaData();
347: s = conn.createStatement();
348: ps = conn.prepareStatement("create table w (i int)");
349:
350: rs = dmd.getTables("%", "%", "%", null); // should work
351:
352: conn.close();
353:
354: // should not be able to execute an existing statement
355: try {
356: passed = false; // won't pass unless caught
357: s.execute("create table x (i int)");
358: } catch (SQLException se) {
359: passed = true;
360: // could verify exception #...
361: JDBCDisplayUtil.ShowSQLException(System.out, se);
362: }
363: if (!passed)
364: System.out
365: .println("FAIL -- no error on statement execute after connection close");
366:
367: // should not be able to execute an existing prepared statement
368: try {
369: passed = false; // won't pass unless caught
370: ps.execute();
371: } catch (SQLException se) {
372: passed = true;
373: // could verify exception #...
374: JDBCDisplayUtil.ShowSQLException(System.out, se);
375: }
376: if (!passed)
377: System.out
378: .println("FAIL -- no error on prepared statement execute after connection close");
379:
380: // should not be able to create a statement...
381: try {
382: passed = false; // won't pass unless caught
383: s = conn.createStatement();
384: } catch (SQLException se) {
385: passed = true;
386: // could verify exception #...
387: JDBCDisplayUtil.ShowSQLException(System.out, se);
388: }
389: if (!passed)
390: System.out
391: .println("FAIL -- no error on statement creation after connection close");
392:
393: // should not be able to prepare a statement...
394: try {
395: passed = false; // won't pass unless caught
396: ps = conn.prepareStatement("create table z (i int)");
397: } catch (SQLException se) {
398: passed = true;
399: // could verify exception #...
400: JDBCDisplayUtil.ShowSQLException(System.out, se);
401: }
402: if (!passed)
403: System.out
404: .println("FAIL -- no error on statement preparation after connection close");
405:
406: // should not be able to see metadata info...
407: try {
408: passed = false; // won't pass unless caught
409: rs.next();
410: } catch (SQLException se) {
411: passed = true;
412: // could verify exception #...
413: JDBCDisplayUtil.ShowSQLException(System.out, se);
414: }
415: if (!passed)
416: System.out
417: .println("FAIL -- no error on metadata reading after connection close");
418:
419: // should not be able to get any more metadata info...
420: try {
421: passed = false; // won't pass unless caught
422: rs = dmd.getColumns("%", "%", "%", "%");
423: } catch (SQLException se) {
424: passed = true;
425: // could verify exception #...
426: JDBCDisplayUtil.ShowSQLException(System.out, se);
427: }
428: if (!passed)
429: System.out
430: .println("FAIL -- no error on metadata collecting after connection close");
431:
432: // should not be able to get metadata object...
433: try {
434: passed = false; // won't pass unless caught
435: dmd = conn.getMetaData();
436: } catch (SQLException se) {
437: passed = true;
438: // could verify exception #...
439: JDBCDisplayUtil.ShowSQLException(System.out, se);
440: }
441: if (!passed)
442: System.out
443: .println("FAIL -- no error on getting metadata after connection close");
444:
445: return passed;
446: }
447:
448: static boolean testDerby62(Connection conn) throws SQLException {
449:
450: System.out
451: .println("Test case for Derby-62 - serialization error with SQLException");
452: try {
453: conn.createStatement().execute(
454: "DROP TABLE APP.DERBY62_DAIN_SUNDSTROM");
455: return false;
456: } catch (SQLException sqle) {
457: boolean passed = true;
458: try {
459: // ensure we can serialize this exception.
460: java.io.ObjectOutputStream oos = new java.io.ObjectOutputStream(
461: new java.io.ByteArrayOutputStream(1024));
462: oos.writeObject(sqle);
463: oos.close();
464: } catch (java.io.IOException ioe) {
465: System.out.println("IOException " + ioe.getMessage());
466: passed = false;
467:
468: }
469: System.out.println(sqle.getMessage());
470: return passed;
471: }
472: }
473:
474: }
|