001: /*
002: * This software is released under a licence similar to the Apache Software Licence.
003: * See org.logicalcobwebs.proxool.package.html for details.
004: * The latest version is available at http://proxool.sourceforge.net
005: */
006: package org.logicalcobwebs.proxool;
007:
008: import org.apache.commons.logging.Log;
009: import org.apache.commons.logging.LogFactory;
010: import org.logicalcobwebs.proxool.admin.SnapshotIF;
011:
012: import java.sql.Connection;
013: import java.sql.DriverManager;
014: import java.sql.Statement;
015: import java.sql.SQLException;
016: import java.util.Properties;
017:
018: /**
019: * Test the house keeper in ConnectionPool
020: *
021: * @author bill
022: * @author $Author: billhorsman $ (current maintainer)
023: * @version $Revision: 1.13 $, $Date: 2006/03/24 00:17:32 $
024: * @since Proxool 0.8
025: */
026: public class HouseKeeperTest extends AbstractProxoolTest {
027:
028: private static final Log LOG = LogFactory
029: .getLog(HouseKeeperTest.class);
030:
031: public HouseKeeperTest(String alias) {
032: super (alias);
033: }
034:
035: /**
036: * Test that connections that remain active for longer than the configured
037: * time are closed (and destroyed) automatically.
038: */
039: public void testMaximumActiveTime() throws Exception {
040:
041: ConnectionResetter.setTriggerResetException(true);
042: String testName = "maximumActiveTime";
043: String alias = testName;
044:
045: String url = TestHelper.buildProxoolUrl(alias,
046: TestConstants.HYPERSONIC_DRIVER,
047: TestConstants.HYPERSONIC_TEST_URL);
048: Properties info = new Properties();
049: info.setProperty(ProxoolConstants.USER_PROPERTY,
050: TestConstants.HYPERSONIC_USER);
051: info.setProperty(ProxoolConstants.PASSWORD_PROPERTY,
052: TestConstants.HYPERSONIC_PASSWORD);
053: info.setProperty(ProxoolConstants.MAXIMUM_ACTIVE_TIME_PROPERTY,
054: "1000");
055: info
056: .setProperty(
057: ProxoolConstants.MINIMUM_CONNECTION_COUNT_PROPERTY,
058: "1");
059: info.setProperty(ProxoolConstants.TRACE_PROPERTY, "true");
060: info.setProperty(
061: ProxoolConstants.HOUSE_KEEPING_SLEEP_TIME_PROPERTY,
062: "1000");
063: ProxoolFacade.registerConnectionPool(url, info);
064:
065: assertEquals("Shouldn't be any active connections yet", 0,
066: ProxoolFacade.getSnapshot(alias, false)
067: .getServedCount());
068:
069: final Connection connection = DriverManager.getConnection(url);
070: connection.setAutoCommit(false);
071: connection.createStatement().executeQuery(
072: TestConstants.HYPERSONIC_TEST_SQL);
073: long start = System.currentTimeMillis();
074:
075: assertEquals("We just opened 1 connection", 1, ProxoolFacade
076: .getSnapshot(alias, false).getServedCount());
077:
078: new ResultMonitor() {
079: public boolean check() throws Exception {
080: return connection.isClosed();
081: }
082: }.getResult();
083: try {
084: Thread.sleep(3000);
085: } catch (InterruptedException e) {
086: LOG.debug("Awoken.");
087: }
088:
089: long elapsed = System.currentTimeMillis() - start;
090: assertTrue("Connection has not been closed after " + elapsed
091: + " milliseconds as expected", connection.isClosed());
092: assertEquals("Expected the connection to be inactive", 0,
093: ProxoolFacade.getSnapshot(alias, false)
094: .getActiveConnectionCount());
095:
096: try {
097: connection.createStatement().executeQuery(
098: TestConstants.HYPERSONIC_TEST_SQL);
099: fail("Calling createStatement() on a closed connection should fail");
100: } catch (Exception e) {
101: // s'okay. We expected this
102: LOG.debug("Ignoring expected exception: " + e.getMessage());
103: }
104:
105: // Now close the connection ourselves. It's already been closed by the House Keeper but nothing bad should
106: // happen if we do it again now.
107: connection.close();
108:
109: // Let's see if the prototyper builds another one
110: try {
111: Thread.sleep(3000);
112: } catch (InterruptedException e) {
113: LOG.debug("Awoken.");
114: }
115: SnapshotIF snapshot = ProxoolFacade.getSnapshot(alias, false);
116: assertEquals("activeConnectionCount", 0, snapshot
117: .getActiveConnectionCount());
118: assertEquals("availableConnectionCount", 1, snapshot
119: .getAvailableConnectionCount());
120: assertEquals("connectionCount", 1, snapshot
121: .getConnectionCount());
122:
123: }
124:
125: /**
126: * Test that connections that remain active for longer than the configured
127: * time are closed (and destroyed) automatically. Also, it gets errors during
128: * reset. We don't want the connectionCount to be decremented twice.
129: */
130: public void testMaximumActiveTimeWithResetFailure()
131: throws Exception {
132:
133: try {
134: ConnectionResetter.setTriggerResetException(true);
135: String testName = "maximumActiveTimeWithResetFailure";
136: String alias = testName;
137:
138: String url = TestHelper.buildProxoolUrl(alias,
139: TestConstants.HYPERSONIC_DRIVER,
140: TestConstants.HYPERSONIC_TEST_URL);
141: Properties info = new Properties();
142: info.setProperty(ProxoolConstants.USER_PROPERTY,
143: TestConstants.HYPERSONIC_USER);
144: info.setProperty(ProxoolConstants.PASSWORD_PROPERTY,
145: TestConstants.HYPERSONIC_PASSWORD);
146: info.setProperty(
147: ProxoolConstants.MAXIMUM_ACTIVE_TIME_PROPERTY,
148: "1000");
149: info.setProperty(ProxoolConstants.TRACE_PROPERTY, "true");
150: info.setProperty(
151: ProxoolConstants.HOUSE_KEEPING_SLEEP_TIME_PROPERTY,
152: "1000");
153: ProxoolFacade.registerConnectionPool(url, info);
154:
155: assertEquals("Shouldn't be any active connections yet", 0,
156: ProxoolFacade.getSnapshot(alias, false)
157: .getServedCount());
158:
159: final Connection connection = DriverManager
160: .getConnection(url);
161: connection.setAutoCommit(false);
162: connection.createStatement().executeQuery(
163: TestConstants.HYPERSONIC_TEST_SQL);
164: long start = System.currentTimeMillis();
165:
166: assertEquals("We just opened 1 connection", 1,
167: ProxoolFacade.getSnapshot(alias, false)
168: .getServedCount());
169:
170: new ResultMonitor() {
171: public boolean check() throws Exception {
172: return connection.isClosed();
173: }
174: }.getResult();
175: try {
176: Thread.sleep(3000);
177: } catch (InterruptedException e) {
178: LOG.debug("Awoken.");
179: }
180:
181: long elapsed = System.currentTimeMillis() - start;
182: assertTrue("Connection has not been closed after "
183: + elapsed + " milliseconds as expected", connection
184: .isClosed());
185: assertEquals("Expected the connection to be inactive", 0,
186: ProxoolFacade.getSnapshot(alias, false)
187: .getActiveConnectionCount());
188:
189: try {
190: connection.createStatement().executeQuery(
191: TestConstants.HYPERSONIC_TEST_SQL);
192: fail("Calling createStatement() on a closed connection should fail");
193: } catch (Exception e) {
194: // s'okay. We expected this
195: LOG.debug("Ignoring expected exception: "
196: + e.getMessage());
197: }
198:
199: // Now close the connection ourselves. It's already been closed by the House Keeper but nothing bad should
200: // happen if we do it again now.
201: connection.close();
202:
203: // Let's see if the prototyper builds another one
204: try {
205: Thread.sleep(3000);
206: } catch (InterruptedException e) {
207: LOG.debug("Awoken.");
208: }
209: SnapshotIF snapshot = ProxoolFacade.getSnapshot(alias,
210: false);
211: assertEquals("activeConnectionCount", 0, snapshot
212: .getActiveConnectionCount());
213: assertEquals("availableConnectionCount", 0, snapshot
214: .getAvailableConnectionCount());
215: assertEquals("connectionCount", 0, snapshot
216: .getConnectionCount());
217: } finally {
218: // Back to normal
219: ConnectionResetter.setTriggerResetException(false);
220: }
221:
222: }
223:
224: /**
225: * Test that house keeper destroys connections that fail configured
226: * the test sql
227: */
228: public void testHouseKeeperTestSql() throws Exception {
229:
230: String testName = "houseKeeperTestSql";
231: String alias = testName;
232:
233: String url = TestHelper.buildProxoolUrl(alias,
234: TestConstants.HYPERSONIC_DRIVER,
235: TestConstants.HYPERSONIC_TEST_URL);
236: Properties info = new Properties();
237: info.setProperty(ProxoolConstants.USER_PROPERTY,
238: TestConstants.HYPERSONIC_USER);
239: info.setProperty(ProxoolConstants.PASSWORD_PROPERTY,
240: TestConstants.HYPERSONIC_PASSWORD);
241: info.setProperty(
242: ProxoolConstants.HOUSE_KEEPING_TEST_SQL_PROPERTY,
243: "SELECT NOW");
244: info.setProperty(
245: ProxoolConstants.HOUSE_KEEPING_SLEEP_TIME_PROPERTY,
246: "1000");
247: ProxoolFacade.registerConnectionPool(url, info);
248:
249: DriverManager.getConnection(url).close();
250:
251: try {
252: Thread.sleep(3000);
253: } catch (InterruptedException e) {
254: LOG.debug("Awoken.");
255: }
256:
257: DriverManager.getConnection(url).close();
258: }
259:
260: /**
261: * Test that house keeper destroys connections that fail configured
262: * the test sql
263: */
264: public void testInvalidBeforeUse() throws Exception {
265:
266: String testName = "invalidBeforeUse";
267: String alias = testName;
268:
269: String url = TestHelper.buildProxoolUrl(alias,
270: TestConstants.HYPERSONIC_DRIVER,
271: TestConstants.HYPERSONIC_TEST_URL);
272: Properties info = new Properties();
273: info.setProperty(ProxoolConstants.USER_PROPERTY,
274: TestConstants.HYPERSONIC_USER);
275: info.setProperty(ProxoolConstants.PASSWORD_PROPERTY,
276: TestConstants.HYPERSONIC_PASSWORD);
277: info.setProperty(
278: ProxoolConstants.HOUSE_KEEPING_TEST_SQL_PROPERTY,
279: "Invalid test");
280: info.setProperty(ProxoolConstants.TEST_BEFORE_USE_PROPERTY,
281: Boolean.TRUE.toString());
282: info.setProperty(ProxoolConstants.VERBOSE_PROPERTY,
283: Boolean.TRUE.toString());
284: info.setProperty(ProxoolConstants.TRACE_PROPERTY, Boolean.TRUE
285: .toString());
286: ProxoolFacade.registerConnectionPool(url, info);
287:
288: // This should trigger a test followed the actual executed command. Because we've
289: // deliberately made the test invalid, we should get an exception when getting a
290: // connection
291: Connection connection = null;
292: Statement s = null;
293: try {
294: connection = DriverManager.getConnection(url);
295: s = connection.createStatement();
296: s.execute(TestConstants.HYPERSONIC_TEST_SQL);
297: fail("Expected to get an exception because the test failed");
298: } catch (SQLException e) {
299: // Log message only so we don't get a worrying stack trace
300: LOG.debug("Expected exception: " + e.getMessage());
301: }
302:
303: }
304:
305: /**
306: * Test that house keeper destroys connections that fail configured
307: * the test sql
308: */
309: public void testInvalidAfterUse() throws Exception {
310:
311: String testName = "invalidAfterUse";
312: String alias = testName;
313:
314: String url = TestHelper.buildProxoolUrl(alias,
315: TestConstants.HYPERSONIC_DRIVER,
316: TestConstants.HYPERSONIC_TEST_URL);
317: Properties info = new Properties();
318: info.setProperty(ProxoolConstants.USER_PROPERTY,
319: TestConstants.HYPERSONIC_USER);
320: info.setProperty(ProxoolConstants.PASSWORD_PROPERTY,
321: TestConstants.HYPERSONIC_PASSWORD);
322: info.setProperty(
323: ProxoolConstants.HOUSE_KEEPING_TEST_SQL_PROPERTY,
324: "Invalid test");
325: info.setProperty(ProxoolConstants.TEST_AFTER_USE_PROPERTY,
326: Boolean.TRUE.toString());
327: info.setProperty(ProxoolConstants.VERBOSE_PROPERTY,
328: Boolean.TRUE.toString());
329: info.setProperty(ProxoolConstants.TRACE_PROPERTY, Boolean.TRUE
330: .toString());
331: ProxoolFacade.registerConnectionPool(url, info);
332:
333: // This should trigger a test as soon as we close the connection. Because we've
334: // deliberately made the test invalid then it should get thrown away
335: Connection connection = null;
336: Statement s = null;
337: try {
338: connection = DriverManager.getConnection(url);
339: s = connection.createStatement();
340: s.execute(TestConstants.HYPERSONIC_TEST_SQL);
341: } finally {
342: if (connection != null) {
343: connection.close();
344: }
345: }
346:
347: // There should be no available connections. We don't have a minimum setup and the one we
348: // just created on demand got thrown away because it failed its test
349: assertEquals("Available connections", 0, ProxoolFacade
350: .getSnapshot(alias).getAvailableConnectionCount());
351:
352: }
353:
354: public void testBeforeAndAfterUse() throws Exception {
355:
356: String testName = "beforeAndAfterUse";
357: String alias = testName;
358:
359: String url = TestHelper.buildProxoolUrl(alias,
360: TestConstants.HYPERSONIC_DRIVER,
361: TestConstants.HYPERSONIC_TEST_URL);
362: Properties info = new Properties();
363: info.setProperty(ProxoolConstants.USER_PROPERTY,
364: TestConstants.HYPERSONIC_USER);
365: info.setProperty(ProxoolConstants.PASSWORD_PROPERTY,
366: TestConstants.HYPERSONIC_PASSWORD);
367: info.setProperty(
368: ProxoolConstants.HOUSE_KEEPING_TEST_SQL_PROPERTY,
369: TestConstants.HYPERSONIC_TEST_SQL);
370: info.setProperty(ProxoolConstants.TEST_BEFORE_USE_PROPERTY,
371: Boolean.TRUE.toString());
372: info.setProperty(ProxoolConstants.TEST_AFTER_USE_PROPERTY,
373: Boolean.TRUE.toString());
374: info.setProperty(ProxoolConstants.VERBOSE_PROPERTY,
375: Boolean.TRUE.toString());
376: info.setProperty(ProxoolConstants.TRACE_PROPERTY, Boolean.TRUE
377: .toString());
378: ProxoolFacade.registerConnectionPool(url, info);
379:
380: Connection connection = null;
381: Statement s = null;
382: try {
383: connection = DriverManager.getConnection(url);
384: s = connection.createStatement();
385: s.execute(TestConstants.HYPERSONIC_TEST_SQL);
386: } finally {
387: if (connection != null) {
388: connection.close();
389: }
390: }
391:
392: // There should be one available connection.
393: assertEquals("Available connections", 1, ProxoolFacade
394: .getSnapshot(alias).getAvailableConnectionCount());
395:
396: }
397:
398: }
399:
400: /*
401: Revision history:
402: $Log: HouseKeeperTest.java,v $
403: Revision 1.13 2006/03/24 00:17:32 billhorsman
404: Correct alias name
405:
406: Revision 1.12 2006/01/18 14:40:06 billhorsman
407: Unbundled Jakarta's Commons Logging.
408:
409: Revision 1.11 2005/10/07 08:11:34 billhorsman
410: New test for reset failure
411:
412: Revision 1.10 2005/10/02 12:30:59 billhorsman
413: Improved test by checking connectionCount
414:
415: Revision 1.9 2004/06/02 21:05:19 billhorsman
416: Don't log worrying stack traces for expected exceptions.
417:
418: Revision 1.8 2003/09/30 18:40:16 billhorsman
419: New tests for test-before-use and test-after-use
420:
421: Revision 1.7 2003/09/11 23:58:05 billhorsman
422: New test for house-keeper-test-sql
423:
424: Revision 1.6 2003/03/04 10:24:40 billhorsman
425: removed try blocks around each test
426:
427: Revision 1.5 2003/03/03 17:08:57 billhorsman
428: all tests now extend AbstractProxoolTest
429:
430: Revision 1.4 2003/03/03 11:12:04 billhorsman
431: fixed licence
432:
433: Revision 1.3 2003/03/02 00:53:49 billhorsman
434: more robust wait
435:
436: Revision 1.2 2003/03/01 15:27:24 billhorsman
437: checkstyle
438:
439: Revision 1.1 2003/02/27 18:01:48 billhorsman
440: completely rethought the test structure. it's now
441: more obvious. no new tests yet though.
442:
443: */
|