/*
* JBoss, Home of Professional Open Source.
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.test.jca.test;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import javax.resource.ResourceException;
import javax.resource.spi.ConnectionRequestInfo;
import javax.resource.spi.ManagedConnectionFactory;
import javax.security.auth.Subject;
import junit.framework.TestCase;
import org.jboss.logging.Logger;
import org.jboss.resource.connectionmanager.BaseConnectionManager2;
import org.jboss.resource.connectionmanager.CachedConnectionManager;
import org.jboss.resource.connectionmanager.ConnectionListener;
import org.jboss.resource.connectionmanager.InternalManagedConnectionPool;
import org.jboss.resource.connectionmanager.JBossManagedConnectionPool;
import org.jboss.resource.connectionmanager.ManagedConnectionPool;
import org.jboss.resource.connectionmanager.NoTxConnectionManager;
import org.jboss.resource.connectionmanager.JBossManagedConnectionPool.BasePool;
import org.jboss.test.jca.adapter.TestConnectionRequestInfo;
import org.jboss.test.jca.adapter.TestManagedConnectionFactory;
/**
* Unit Test for class ManagedConnectionPool
*
*
* Created: Wed Jan 2 00:06:35 2002
*
* @author <a href="mailto:d_jencks@users.sourceforge.net">David Jencks</a>
* @version
*/
public class BaseConnectionManagerUnitTestCase extends TestCase
{
Logger log = Logger.getLogger(getClass());
Subject subject = new Subject();
ConnectionRequestInfo cri = new TestConnectionRequestInfo();
CachedConnectionManager ccm = new CachedConnectionManager();
private boolean failed;
private String failedDescription;
private Exception failedException;
/**
* Creates a new <code>BaseConnectionManagerUnitTestCase</code> instance.
*
* @param name test name
*/
public BaseConnectionManagerUnitTestCase (String name)
{
super(name);
}
private BaseConnectionManager2 getCM(InternalManagedConnectionPool.PoolParams pp) throws Exception
{
return getCM(pp, 0, 5000);
}
private BaseConnectionManager2 getCM(InternalManagedConnectionPool.PoolParams pp, int ar, int arwm) throws Exception
{
ManagedConnectionFactory mcf = new TestManagedConnectionFactory();
ManagedConnectionPool poolingStrategy = new JBossManagedConnectionPool.OnePool(mcf, pp, false, log);
BaseConnectionManager2 cm = new NoTxConnectionManager(ccm, poolingStrategy);
cm.setAllocationRetry(ar);
cm.setAllocationRetryWaitMillis(arwm);
poolingStrategy.setConnectionListenerFactory(cm);
if (pp.prefill)
{
BasePool bp = (BasePool)poolingStrategy;
bp.prefill(null, null, false);
}
return cm;
}
private void shutdown(BaseConnectionManager2 cm)
{
JBossManagedConnectionPool.OnePool pool = (JBossManagedConnectionPool.OnePool) cm.getPoolingStrategy();
pool.shutdown();
}
public void testGetManagedConnections() throws Exception
{
InternalManagedConnectionPool.PoolParams pp = new InternalManagedConnectionPool.PoolParams();
pp.minSize = 0;
pp.maxSize = 5;
pp.blockingTimeout = 100;
pp.idleTimeout = 500;
BaseConnectionManager2 cm = getCM(pp);
try
{
ArrayList cs = new ArrayList();
for (int i = 0; i < pp.maxSize; i++)
{
ConnectionListener cl = cm.getManagedConnection(null, null);
assertTrue("Got a null connection!", cl.getManagedConnection() != null);
cs.add(cl);
} // end of for ()
assertTrue("Wrong number of connections counted: " + cm.getConnectionCount(), cm.getConnectionCount() == pp.maxSize);
try
{
cm.getManagedConnection(null, null);
fail("Got a connection more than maxSize!");
}
catch (ResourceException re)
{
//expected
} // end of try-catch
for (Iterator i = cs.iterator(); i.hasNext();)
{
cm.returnManagedConnection((ConnectionListener)i.next(), true);
} // end of for ()
assertTrue("Wrong number of connections counted: " + cm.getConnectionCount(), cm.getConnectionCount() == 0);
}
finally
{
shutdown(cm);
}
}
public void testIdleTimeout() throws Exception
{
InternalManagedConnectionPool.PoolParams pp = new InternalManagedConnectionPool.PoolParams();
pp.minSize = 0;
pp.maxSize = 5;
pp.blockingTimeout = 10;
pp.idleTimeout = 1000;
BaseConnectionManager2 cm = getCM(pp);
try
{
Collection mcs = new ArrayList(pp.maxSize);
for (int i = 0 ; i < pp.maxSize; i++)
mcs.add(cm.getManagedConnection(subject, cri));
for (Iterator i = mcs.iterator(); i.hasNext(); )
cm.returnManagedConnection((ConnectionListener)i.next(), false);
assertTrue("Wrong number of connections counted: " + cm.getConnectionCount(), cm.getConnectionCount() == pp.maxSize);
// Let the idle remover kick in
Thread.sleep(2500);
assertTrue("Wrong number of connections counted: " + cm.getConnectionCount(), cm.getConnectionCount() == 0);
}
finally
{
shutdown(cm);
}
}
public void testPartialIdleTimeout() throws Exception
{
InternalManagedConnectionPool.PoolParams pp = new InternalManagedConnectionPool.PoolParams();
pp.minSize = 0;
pp.maxSize = 5;
pp.blockingTimeout = 10;
pp.idleTimeout = 2000;
BaseConnectionManager2 cm = getCM(pp);
try
{
Collection mcs = new ArrayList(pp.maxSize);
for (int i = 0 ; i < pp.maxSize; i++)
mcs.add(cm.getManagedConnection(subject, cri));
for (Iterator i = mcs.iterator(); i.hasNext(); )
cm.returnManagedConnection((ConnectionListener)i.next(), false);
assertTrue("Wrong number of connections counted: " + cm.getConnectionCount(), cm.getConnectionCount() == pp.maxSize);
Thread.sleep(1500);
ConnectionListener cl = cm.getManagedConnection(subject, cri);
cm.returnManagedConnection(cl, false);
// Let the idle remover kick in
Thread.sleep(1500);
assertTrue("Wrong number of connections counted: " + cm.getConnectionCount(), cm.getConnectionCount() == 1);
// Let the idle remover kick in
Thread.sleep(1500);
assertTrue("Wrong number of connections counted: " + cm.getConnectionCount(), cm.getConnectionCount() == 0);
}
finally
{
shutdown(cm);
}
}
public void testFillToMin() throws Exception
{
InternalManagedConnectionPool.PoolParams pp = new InternalManagedConnectionPool.PoolParams();
pp.minSize = 3;
pp.maxSize = 5;
pp.blockingTimeout = 10;
pp.idleTimeout = 2000;
BaseConnectionManager2 cm = getCM(pp);
try
{
ConnectionListener cl = cm.getManagedConnection(subject, cri);
cm.returnManagedConnection(cl, false);
// Allow fill to min to work
Thread.sleep(1000);
assertTrue("Wrong number of connections counted: " + cm.getConnectionCount(), cm.getConnectionCount() == pp.minSize);
// Allow the idle remover to work
Thread.sleep(3000);
assertTrue("Wrong number of connections counted: " + cm.getConnectionCount(), cm.getConnectionCount() == pp.minSize);
}
finally
{
shutdown(cm);
}
}
public void testPrefillPool() throws Exception{
InternalManagedConnectionPool.PoolParams pp = new InternalManagedConnectionPool.PoolParams();
pp.minSize = 1;
pp.maxSize = 5;
pp.blockingTimeout = 10;
pp.idleTimeout = 2000;
pp.prefill = true;
BaseConnectionManager2 cm = getCM(pp);
//Sleep to let pool filler do it's job
Thread.sleep(3000);
assertTrue("Prefilled pool: " + cm.getConnectionCount(), pp.minSize == cm.getConnectionCount());
}
public void testNonStrictMinPool() throws Exception
{
InternalManagedConnectionPool.PoolParams pp = new InternalManagedConnectionPool.PoolParams();
pp.minSize = 10;
pp.maxSize = 15;
pp.blockingTimeout = 10;
pp.idleTimeout = 1000;
pp.prefill = true;
BaseConnectionManager2 cm = getCM(pp);
JBossManagedConnectionPool.OnePool pool = (JBossManagedConnectionPool.OnePool) cm.getPoolingStrategy();
Thread.sleep(5000);
assertTrue("Non StrictMin pool should allow destroyed connections below minimum connections", pool.getConnectionDestroyedCount() > 0);
}
public void testStrictMinPool() throws Exception
{
InternalManagedConnectionPool.PoolParams pp = new InternalManagedConnectionPool.PoolParams();
pp.minSize = 10;
pp.maxSize = 15;
pp.blockingTimeout = 10;
pp.idleTimeout = 1000;
pp.prefill = true;
pp.stictMin = true;
BaseConnectionManager2 cm = getCM(pp);
JBossManagedConnectionPool.OnePool pool = (JBossManagedConnectionPool.OnePool) cm.getPoolingStrategy();
//Let Idle remover run
Thread.sleep(3500);
assertTrue("StrictMin pool should not destroy below minimum connections", pool.getConnectionDestroyedCount() == 0);
}
public void testMisConfiguredFillToMin() throws Exception
{
InternalManagedConnectionPool.PoolParams pp = new InternalManagedConnectionPool.PoolParams();
pp.minSize = 6;
pp.maxSize = 5;
pp.blockingTimeout = 10;
pp.idleTimeout = 2000;
BaseConnectionManager2 cm = getCM(pp);
try
{
ConnectionListener cl = cm.getManagedConnection(subject, cri);
cm.returnManagedConnection(cl, false);
// Allow fill to min to work
Thread.sleep(1000);
assertTrue("Wrong number of connections counted: " + cm.getConnectionCount(), cm.getConnectionCount() == pp.maxSize);
// Allow the idle remover to work
Thread.sleep(3000);
assertTrue("Wrong number of connections counted: " + cm.getConnectionCount(), cm.getConnectionCount() == pp.maxSize);
}
finally
{
shutdown(cm);
}
}
public void testChangedMaximum() throws Exception
{
InternalManagedConnectionPool.PoolParams pp = new InternalManagedConnectionPool.PoolParams();
pp.minSize = 0;
pp.maxSize = 5;
pp.blockingTimeout = 100;
pp.idleTimeout = 0;
BaseConnectionManager2 cm = getCM(pp);
JBossManagedConnectionPool.OnePool pool = (JBossManagedConnectionPool.OnePool) cm.getPoolingStrategy();
try
{
// Checkout all the connections
ArrayList cs = new ArrayList();
for (int i = 0; i < pp.maxSize; i++)
{
ConnectionListener cl = cm.getManagedConnection(null, null);
assertTrue("Got a null connection!", cl.getManagedConnection() != null);
cs.add(cl);
}
assertTrue("Wrong number of connections counted: " + cm.getConnectionCount(), cm.getConnectionCount() == pp.maxSize);
// Reconfigure
pp.maxSize = 6;
pool.flush();
// Put the connections back (should destroy/close them with no errors)
for (Iterator i = cs.iterator(); i.hasNext();)
{
cm.returnManagedConnection((ConnectionListener)i.next(), true);
}
// Checkout all the connections with the new maximum size
cs = new ArrayList();
for (int i = 0; i < pp.maxSize; i++)
{
ConnectionListener cl = cm.getManagedConnection(null, null);
assertTrue("Got a null connection!", cl.getManagedConnection() != null);
cs.add(cl);
}
assertTrue("Wrong number of connections counted: " + cm.getConnectionCount(), cm.getConnectionCount() == pp.maxSize);
try
{
cm.getManagedConnection(null, null);
fail("Got a connection more than maxSize!");
}
catch (ResourceException expected)
{
}
// Put the connections back into the new pool
for (Iterator i = cs.iterator(); i.hasNext();)
cm.returnManagedConnection((ConnectionListener)i.next(), true);
assertTrue("Wrong number of connections counted: " + cm.getConnectionCount(), cm.getConnectionCount() == 0);
}
finally
{
shutdown(cm);
}
}
public void testAllocationRetry() throws Exception
{
InternalManagedConnectionPool.PoolParams pp = new InternalManagedConnectionPool.PoolParams();
pp.minSize = 0;
pp.maxSize = 5;
pp.blockingTimeout = 100;
pp.idleTimeout = 500;
BaseConnectionManager2 cm = getCM(pp, 1, 1000);
assertEquals("Wrong allocation retry value", 1, cm.getAllocationRetry());
assertEquals("Wrong allocation retry wait millis value", 1000, cm.getAllocationRetryWaitMillis());
try
{
ArrayList cs = new ArrayList();
for (int i = 0; i < pp.maxSize; i++)
{
ConnectionListener cl = cm.getManagedConnection(null, null);
assertTrue("Got a null connection!", cl.getManagedConnection() != null);
cs.add(cl);
}
assertTrue("Wrong number of connections counted: " + cm.getConnectionCount(), cm.getConnectionCount() == pp.maxSize);
try
{
cm.getManagedConnection(null, null);
fail("Got a connection more than maxSize!");
}
catch (ResourceException ignore)
{
}
for (Iterator i = cs.iterator(); i.hasNext();)
{
cm.returnManagedConnection((ConnectionListener)i.next(), true);
}
assertTrue("Wrong number of connections counted: " + cm.getConnectionCount(), cm.getConnectionCount() == 0);
}
finally
{
shutdown(cm);
}
}
public void testAllocationRetryMultiThread() throws Exception
{
InternalManagedConnectionPool.PoolParams pp = new InternalManagedConnectionPool.PoolParams();
pp.minSize = 0;
pp.maxSize = 6;
pp.blockingTimeout = 100;
pp.idleTimeout = 2000;
final BaseConnectionManager2 cm = getCM(pp, 1, 1000);
assertEquals("Wrong allocation retry value", 1, cm.getAllocationRetry());
assertEquals("Wrong allocation retry wait millis value", 1000, cm.getAllocationRetryWaitMillis());
final int numOfThreads = 2;
final int iterations = pp.maxSize / numOfThreads;
final CountDownLatch start = new CountDownLatch(1);
final CountDownLatch cont = new CountDownLatch(1);
final CountDownLatch firstPart = new CountDownLatch(numOfThreads);
final CountDownLatch done = new CountDownLatch(numOfThreads);
failed = false;
failedDescription = null;
failedException = null;
try
{
for (int i = 0; i < numOfThreads; i++)
{
Runnable t = new Runnable()
{
public void run()
{
List cs = new ArrayList();
try
{
start.await();
for (int i = 0; i < iterations; i++)
{
try
{
ConnectionListener cl = cm.getManagedConnection(null, null);
assertTrue("Got a null connection!", cl.getManagedConnection() != null);
cs.add(cl);
}
catch (ResourceException re)
{
failed = true;
failedDescription = "Failed to get a connection";
failedException = re;
}
}
assertEquals("1: Wrong number of connections", iterations, cs.size());
firstPart.countDown();
cont.await();
for (Iterator i = cs.iterator(); i.hasNext();)
{
cm.returnManagedConnection((ConnectionListener)i.next(), true);
}
done.countDown();
}
catch (InterruptedException ie)
{
}
}
};
new Thread(t).start();
}
start.countDown();
firstPart.await();
assertTrue("2: Wrong number of connections counted: " + cm.getConnectionCount(), cm.getConnectionCount() == pp.maxSize);
try
{
ConnectionListener cl = cm.getManagedConnection(null, null);
cm.returnManagedConnection(cl, true);
failedDescription = "Got a connection";
failedException = new Exception(cl.toString());
failed = true;
}
catch (ResourceException ignore)
{
}
cont.countDown();
done.await();
assertTrue("3: Wrong number of connections counted: " + cm.getConnectionCount(), cm.getConnectionCount() == 0);
if (failed)
{
if (failedDescription == null)
{
fail("Failed criteria: " + failedException);
}
else
{
fail(failedDescription + ": " + failedException);
}
}
}
finally
{
shutdown(cm);
}
}
}