[jboss-cvs] JBossAS SVN: r80304 - in projects/ejb3/trunk/core/src: test/java/org/jboss/ejb3/core/test/ejbthree1549 and 1 other directories.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Fri Oct 31 03:30:36 EDT 2008
Author: ALRubinger
Date: 2008-10-31 03:30:36 -0400 (Fri, 31 Oct 2008)
New Revision: 80304
Modified:
projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/cache/simple/SimpleStatefulCache.java
projects/ejb3/trunk/core/src/test/java/org/jboss/ejb3/core/test/ejbthree1549/BlockingPersistenceManager.java
projects/ejb3/trunk/core/src/test/java/org/jboss/ejb3/core/test/ejbthree1549/ForcePassivationCache.java
projects/ejb3/trunk/core/src/test/java/org/jboss/ejb3/core/test/ejbthree1549/unit/PassivationDoesNotPreventNewActivityUnitTestCase.java
Log:
[EJBTHREE-1549] Replace Thread.sleep() in tests with more reliable locks/barriers for blocking
Modified: projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/cache/simple/SimpleStatefulCache.java
===================================================================
--- projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/cache/simple/SimpleStatefulCache.java 2008-10-31 04:57:33 UTC (rev 80303)
+++ projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/cache/simple/SimpleStatefulCache.java 2008-10-31 07:30:36 UTC (rev 80304)
@@ -54,7 +54,7 @@
protected CacheMap cacheMap;
private int maxSize = 1000;
private StatefulSessionPersistenceManager pm;
- private long sessionTimeout = 300; // 5 minutes
+ protected long sessionTimeout = 300; // 5 minutes
private long removalTimeout = 0;
private Thread timeoutTask;
private RemovalTimeoutTask removalTask = null;
@@ -182,6 +182,14 @@
{
Thread.sleep(sessionTimeout * 1000);
}
+
+ /**
+ * Just provides a hook
+ */
+ public void passivationCompleted()
+ {
+
+ }
public void run()
{
@@ -276,6 +284,9 @@
assert removed == centry : "Removed " + removed
+ " from internal cacheMap did not match the object we were expecting: " + centry;
+ // Make internal callback that we're done
+ this.passivationCompleted();
+
/*
* End EJBTHREE-1549
*/
Modified: projects/ejb3/trunk/core/src/test/java/org/jboss/ejb3/core/test/ejbthree1549/BlockingPersistenceManager.java
===================================================================
--- projects/ejb3/trunk/core/src/test/java/org/jboss/ejb3/core/test/ejbthree1549/BlockingPersistenceManager.java 2008-10-31 04:57:33 UTC (rev 80303)
+++ projects/ejb3/trunk/core/src/test/java/org/jboss/ejb3/core/test/ejbthree1549/BlockingPersistenceManager.java 2008-10-31 07:30:36 UTC (rev 80304)
@@ -21,6 +21,8 @@
*/
package org.jboss.ejb3.core.test.ejbthree1549;
+import java.util.concurrent.BrokenBarrierException;
+import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
@@ -47,10 +49,20 @@
private static final Logger log = Logger.getLogger(BlockingPersistenceManager.class);
/**
- * Publicly-accessible lock to allow tests to block passivation
+ * Publicly-accessible lock
+ *
+ * Used by the test to block the act of passivation
*/
- public static final Lock LOCK = new ReentrantLock();
+ public static final Lock PASSIVATION_LOCK = new ReentrantLock();
+ /**
+ * Publicly-accessible barrier
+ *
+ * Will block until both the test and the PM agree that passivation
+ * should take place
+ */
+ public static final CyclicBarrier BARRIER = new CyclicBarrier(2);
+
// --------------------------------------------------------------------------------||
// Required Implementations -------------------------------------------------------||
// --------------------------------------------------------------------------------||
@@ -58,21 +70,46 @@
@Override
public void passivateSession(StatefulBeanContext ctx)
{
- // Block until the lock may be acquired,
- // may currently be held by the test Thread
- LOCK.lock();
try
{
- // Mock Passivate
- log.info("Mock Passivation on " + ctx);
+ /*
+ * Block until the lock may be acquired,
+ * may currently be held by the test Thread until the test is ready.
+ * So here both the test and passivation will block until this barrier
+ * is agreed by both Threads to be released
+ */
+ log.info("Waiting until the test is ready for passivation to start...");
+ BARRIER.await();
+
+ // Block until the test releases this lock
+ log.info("Blocking until the test tells us that the act of passivation may continue...");
+ PASSIVATION_LOCK.lock();
+
+ try
+ {
+ // Mock Passivate
+ log.info("Mock Passivation on " + ctx);
+ }
+ finally
+ {
+ // Release the passivation lock
+ log.info("We're done with passivation, letting the lock go.");
+ PASSIVATION_LOCK.unlock();
+ }
}
+ catch (InterruptedException e)
+ {
+ throw new RuntimeException("Barrier was interrupted prematurely", e);
+ }
+ catch (BrokenBarrierException e)
+ {
+ throw new RuntimeException("Barrier was broken prematurely", e);
+ }
finally
{
- // Release the lock
- LOCK.unlock();
+ // Reset the Barrier
+ BARRIER.reset();
}
-
}
-
}
Modified: projects/ejb3/trunk/core/src/test/java/org/jboss/ejb3/core/test/ejbthree1549/ForcePassivationCache.java
===================================================================
--- projects/ejb3/trunk/core/src/test/java/org/jboss/ejb3/core/test/ejbthree1549/ForcePassivationCache.java 2008-10-31 04:57:33 UTC (rev 80303)
+++ projects/ejb3/trunk/core/src/test/java/org/jboss/ejb3/core/test/ejbthree1549/ForcePassivationCache.java 2008-10-31 07:30:36 UTC (rev 80304)
@@ -22,8 +22,11 @@
package org.jboss.ejb3.core.test.ejbthree1549;
import java.io.Serializable;
+import java.util.concurrent.BrokenBarrierException;
+import java.util.concurrent.CyclicBarrier;
import org.jboss.ejb3.cache.simple.SimpleStatefulCache;
+import org.jboss.ejb3.stateful.StatefulBeanContext;
import org.jboss.logging.Logger;
/**
@@ -43,8 +46,17 @@
private static final Logger log = Logger.getLogger(ForcePassivationCache.class);
- private static final Object PASSIVATION_LOCK = new Object();
+ /**
+ * Shared barrier between the Cache and the test so that
+ * the test may block until passivation is completed
+ */
+ public static final CyclicBarrier POST_PASSIVATE_BARRIER = new CyclicBarrier(2);
+ /**
+ * Internal lock used to manually block the passivation task from running
+ */
+ private static final Object START_PASSIVATION_LOCK = new Object();
+
// --------------------------------------------------------------------------------||
// Functional Methods -------------------------------------------------------------||
// --------------------------------------------------------------------------------||
@@ -56,15 +68,44 @@
{
// Get a lock
log.info("Awaiting lock to force passivation");
- synchronized (PASSIVATION_LOCK)
+ synchronized (START_PASSIVATION_LOCK)
{
// Notify that passivation should run
log.info("Notifying passivation via manual force...");
- PASSIVATION_LOCK.notify();
+ START_PASSIVATION_LOCK.notify();
}
}
/**
+ * Manually sets the session with the specified sessionId
+ * past expiry for passivation
+ *
+ * @param sessionId
+ */
+ public void makeSessionEligibleForPassivation(Serializable sessionId)
+ {
+ // Get the cacheMap
+ CacheMap cm = this.cacheMap;
+
+ // Synchronize on it
+ synchronized (cm)
+ {
+ // Find the session
+ StatefulBeanContext session = (StatefulBeanContext) cm.get(sessionId);
+
+ // Synchronize on the session
+ synchronized (session)
+ {
+ // Get now
+ long now = System.currentTimeMillis();
+
+ // Manually set past expiry
+ session.lastUsed = (now - (sessionTimeout * 1000)) - 1;
+ }
+ }
+ }
+
+ /**
* Exposed for testing only
*
* Returns whether or not the internal cacheMap contains
@@ -76,9 +117,9 @@
{
// Get the cacheMap
CacheMap cm = this.cacheMap;
-
+
// Synchronize on it
- synchronized(cm)
+ synchronized (cm)
{
// Return whether the specified key was found
return cm.containsKey(sessionId);
@@ -112,24 +153,54 @@
*/
private class BlockingPassivationTask extends SessionTimeoutTask
{
+
public BlockingPassivationTask(String name)
{
super(name);
}
+ @Override
public void block() throws InterruptedException
{
// Get a lock on our monitor
- synchronized (PASSIVATION_LOCK)
+ synchronized (START_PASSIVATION_LOCK)
{
// Wait until we're signaled
log.info("Waiting to be notified to run passivation...");
- PASSIVATION_LOCK.wait();
+ START_PASSIVATION_LOCK.wait();
}
// Log that we've been notified
log.info("Notified to run passivation");
}
+
+ @Override
+ public void passivationCompleted()
+ {
+ // Call super
+ super.passivationCompleted();
+
+ // Tell the barrier we've arrived
+ try
+ {
+ log.info("Waiting on the post-passivate barrier...");
+ POST_PASSIVATE_BARRIER.await();
+ }
+ catch (InterruptedException e)
+ {
+ throw new RuntimeException("Post Passivate prematurely interrupted", e);
+ }
+ catch (BrokenBarrierException e)
+ {
+ throw new RuntimeException("Post Passivate prematurely broken", e);
+ }
+ finally
+ {
+ // Reset the barrier
+ log.info("Post-passivate of PM is done, resetting the barrier");
+ POST_PASSIVATE_BARRIER.reset();
+ }
+ }
}
}
\ No newline at end of file
Modified: projects/ejb3/trunk/core/src/test/java/org/jboss/ejb3/core/test/ejbthree1549/unit/PassivationDoesNotPreventNewActivityUnitTestCase.java
===================================================================
--- projects/ejb3/trunk/core/src/test/java/org/jboss/ejb3/core/test/ejbthree1549/unit/PassivationDoesNotPreventNewActivityUnitTestCase.java 2008-10-31 04:57:33 UTC (rev 80303)
+++ projects/ejb3/trunk/core/src/test/java/org/jboss/ejb3/core/test/ejbthree1549/unit/PassivationDoesNotPreventNewActivityUnitTestCase.java 2008-10-31 07:30:36 UTC (rev 80304)
@@ -39,7 +39,6 @@
import org.jboss.ejb3.core.test.ejbthree1549.MyStatefulBean;
import org.jboss.ejb3.core.test.ejbthree1549.MyStatefulLocal;
import org.jboss.ejb3.proxy.handler.session.stateful.StatefulLocalProxyInvocationHandler;
-import org.jboss.ejb3.session.SessionContainer;
import org.jboss.ejb3.stateful.StatefulContainer;
import org.jboss.logging.Logger;
import org.junit.AfterClass;
@@ -61,7 +60,7 @@
// Class Members ------------------------------------------------------------------||
// --------------------------------------------------------------------------------||
- private static SessionContainer container;
+ private static StatefulContainer container;
private static final Logger log = Logger.getLogger(PassivationDoesNotPreventNewActivityUnitTestCase.class);
@@ -197,8 +196,16 @@
log.info("Got counter from bean1 : " + next);
TestCase.assertEquals("SFSB did not return expected next counter", 0, next);
+ // Get our bean's Session ID
+ StatefulLocalProxyInvocationHandler handler = (StatefulLocalProxyInvocationHandler) Proxy
+ .getInvocationHandler(bean1);
+ Serializable sessionId = handler.getSessionId();
+
+ // Get the Cache
+ ForcePassivationCache cache = (ForcePassivationCache) container.getCache();
+
// Get the lock to block the PM, now
- boolean gotLock = BlockingPersistenceManager.LOCK.tryLock();
+ boolean gotLock = BlockingPersistenceManager.PASSIVATION_LOCK.tryLock();
// Once PM lock is acquired, everything is in "try" so we release in "finally"
try
@@ -207,16 +214,25 @@
TestCase.assertTrue("Test was not able to immediately get the lock to block the PersistenceManager", gotLock);
log.info("Locked " + BlockingPersistenceManager.class.getSimpleName());
- // Wait to allow bean to be eligible for passivation
- long sleepTime = MyStatefulLocal.PASSIVATION_TIMEOUT * 1000 + 1000; // Add 1/2 a second to the configured passivation timeout
- Thread.sleep(sleepTime);
+ /*
+ * Mark our session as expired
+ */
+ // Mark
+ cache.makeSessionEligibleForPassivation(sessionId);
+
+ /*
+ * Passivate
+ */
+
// Trigger Passivation
ForcePassivationCache.forcePassivation();
log.info("Passivation forced, carrying out test");
- // Wait to allow passivation to actually start
- Thread.sleep(2000);
+ // Block until the PM is ready to passivate
+ log.info("Waiting on common barrier for PM to run...");
+ BlockingPersistenceManager.BARRIER.await();
+ log.info("PM and test have met barrier, passivation running (but will be blocked to complete by test)");
/*
* At this point, we've told the passivation Thread to start, and have
@@ -259,23 +275,19 @@
{
// Allow the Persistence Manager to finish up
- BlockingPersistenceManager.LOCK.unlock();
-
- // We need to allow time to let PM do its thing, so use the lock to block then release
- Thread.sleep(150); // Just to make sure the PM gets the lock back first
- BlockingPersistenceManager.LOCK.lock(); // Block until PM is done
- BlockingPersistenceManager.LOCK.unlock(); // PM must be done, we don't really need the lock, release it
+ log.info("Letting the PM perform passivation...");
+ BlockingPersistenceManager.PASSIVATION_LOCK.unlock();
}
-
-
+
+ // We need to allow time to let the Cache finish passivation, so block until it's done
+ log.info("Waiting on Cache to tell us passivation is completed...");
+ ForcePassivationCache.POST_PASSIVATE_BARRIER.await();
+ log.info("Test sees Cache reports passivation completed.");
+
/*
* Here we ensure that the session was removed from the internal cacheMap
*/
- StatefulLocalProxyInvocationHandler handler = (StatefulLocalProxyInvocationHandler) Proxy
- .getInvocationHandler(bean1);
- Serializable sessionId = handler.getSessionId();
- boolean beanIsInCache = ((ForcePassivationCache) ((StatefulContainer) container).getCache())
- .doesCacheMapContainKey(sessionId);
+ boolean beanIsInCache = cache.doesCacheMapContainKey(sessionId);
assertFalse("bean was not removed from cache", beanIsInCache);
// Ensure we're good
@@ -339,7 +351,7 @@
// Deploy the test SFSB
Class<?> ejbImplClass = MyStatefulBean.class;
log.info("Deploying SFSB: " + ejbImplClass.getName());
- container = deploySessionEjb(ejbImplClass);
+ container = (StatefulContainer) deploySessionEjb(ejbImplClass);
}
@AfterClass
More information about the jboss-cvs-commits
mailing list