/** * Proper closure test * * @throws SecurityException * @throws NoSuchFieldException * @throws IllegalArgumentException * @throws IllegalAccessException * @throws SQLException */ @SuppressWarnings({"unchecked", "rawtypes"}) @Test public void testStatementCacheCheckForProperClosure() throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException, SQLException { ConcurrentMap mockCache = createNiceMock(ConcurrentMap.class); List<StatementHandle> mockStatementCollections = createNiceMock(List.class); StatementCache testClass = new StatementCache(1, false, null); Field field = testClass.getClass().getDeclaredField("cache"); field.setAccessible(true); field.set(testClass, mockCache); field = testClass.getClass().getDeclaredField("logger"); field.setAccessible(true); field.set(null, mockLogger); Iterator<StatementHandle> mockIterator = createNiceMock(Iterator.class); StatementHandle mockStatement = createNiceMock(StatementHandle.class); expect(mockCache.values()).andReturn(mockStatementCollections).anyTimes(); expect(mockStatementCollections.iterator()).andReturn(mockIterator).anyTimes(); expect(mockIterator.hasNext()).andReturn(true).once().andReturn(false).once(); expect(mockIterator.next()).andReturn(mockStatement).anyTimes(); expect(mockStatement.isClosed()).andReturn(false).once(); mockLogger.error((String) anyObject()); expectLastCall().once(); replay(mockCache, mockStatementCollections, mockIterator, mockStatement, mockLogger); testClass.checkForProperClosure(); verify(mockCache, mockStatement, mockLogger); }
// @Override public void checkForProperClosure() { for (StatementHandle statement : this.cache.values()) { if (!statement.isClosed()) { logger.error( "Statement not closed properly in application\n\n" + statement.getOpenStackTrace()); } } }
// @Override public void clear() { for (StatementHandle statement : this.cache.values()) { try { if (!statement.isClosed()) { statement.close(); } } catch (SQLException e) { // don't log, we might fail if the connection link has died // logger.error("Error closing off statement", e); } } this.cache.clear(); }
// @Override public void clear() { for (StatementHandle statement : this.cache.values()) { try { if (!(statement.isClosed() || statement .isEnqueuedForClosure())) { // this might race with statement release helper but // nothing bad should occur statement.close(); } } catch (SQLException e) { // don't log, we might fail if the connection link has died // logger.error("Error closing off statement", e); } } this.cache.clear(); }
// @Override public StatementHandle get(String key) { StatementHandle statement = this.cache.get(key); if (statement != null && (statement.isEnqueuedForClosure() || !statement.logicallyClosed.compareAndSet(true, false))) { statement = null; } if (this.maintainStats) { if (statement != null) { this.statistics.incrementCacheHits(); } else { this.statistics.incrementCacheMiss(); } } return statement; }
// @Override public void putIfAbsent(String key, StatementHandle handle) { if (this.cache.size() < this.cacheSize && key != null) { // perhaps use LRU in future?? Worth the overhead? Hmm.... if (this.cache.putIfAbsent(key, handle) == null) { handle.inCache = true; if (this.maintainStats) { this.statistics.incrementStatementsCached(); } } } }
/** * Test routine for callable statements. * * @param args * @throws SecurityException * @throws NoSuchFieldException * @throws IllegalArgumentException * @throws IllegalAccessException * @throws NoSuchMethodException * @throws InvocationTargetException */ @SuppressWarnings("unchecked") private void callableStatementTest(Class... args) throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException, NoSuchMethodException, InvocationTargetException { Object[] params = new Object[args.length]; for (int i = 0; i < args.length; i++) { params[i] = CommonTestUtils.instanceMap.get(args[i]); } Method prepCallMethod = testClass.getClass().getMethod("prepareCall", args); CallableStatementHandle mockStatement = createNiceMock(CallableStatementHandle.class); ConcurrentLinkedQueue<Statement> mockStatementHandles = createNiceMock(ConcurrentLinkedQueue.class); testClass.renewConnection(); // logically open the connection // fetching a statement that is found in cache. Statement should be returned and marked as being // (logically) open doStatementMock(mockCallableStatementCache, mockStatement, params, args); // // expect(mockCallableStatementCache.get((String)anyObject())).andReturn(mockStatement).anyTimes(); ((StatementHandle) mockStatement).setLogicallyOpen(); expectLastCall(); replay(mockStatement, mockCallableStatementCache); prepCallMethod.invoke(testClass, params); verify(mockStatement, mockCallableStatementCache); reset(mockStatement, mockCallableStatementCache, mockStatementHandles); // test for a cache miss doStatementMock(mockCallableStatementCache, null, params, args); // we should be creating the preparedStatement because it's not in the cache expect(prepCallMethod.invoke(mockConnection, params)).andReturn(mockStatement); // we should be tracking this statement expect(mockStatementHandles.add(mockStatement)).andReturn(true); replay(mockStatement, mockCallableStatementCache, mockConnection, mockStatementHandles); prepCallMethod.invoke(testClass, params); verify(mockStatement, mockCallableStatementCache, mockConnection); // test for cache miss + sql exception reset(mockStatement, mockCallableStatementCache, mockConnection); Method mockConnectionPrepareCallMethod = mockConnection.getClass().getMethod("prepareCall", args); // expect(mockCallableStatementCache.get((String)anyObject())).andReturn(null).once(); doStatementMock(mockCallableStatementCache, null, params, args); // we should be creating the preparedStatement because it's not in the cache expect(mockConnectionPrepareCallMethod.invoke(mockConnection, params)) .andThrow(new SQLException("test", "Z")); replay(mockStatement, mockCallableStatementCache, mockConnection); try { prepCallMethod.invoke(testClass, params); fail("Should have thrown an exception"); } catch (Throwable t) { // do nothing } verify(mockStatement, mockCallableStatementCache, mockConnection); // test for no cache defined reset(mockStatement, mockCallableStatementCache, mockConnection); boolean oldState = testClass.statementCachingEnabled; testClass.statementCachingEnabled = false; // we should be creating the preparedStatement because it's not in the cache expect(mockConnectionPrepareCallMethod.invoke(mockConnection, params)).andReturn(mockStatement); replay(mockStatement, mockCallableStatementCache, mockConnection); prepCallMethod.invoke(testClass, params); verify(mockStatement, mockCallableStatementCache, mockConnection); // restore sanity testClass.statementCachingEnabled = oldState; reset(mockStatement, mockCallableStatementCache, mockConnection); }