[jboss-cvs] JBossAS SVN: r79410 - in projects/ejb3/trunk/testsuite/src/test: java/org/jboss/ejb3/test/singleton/unit and 1 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Mon Oct 13 12:28:41 EDT 2008


Author: alex.loubyansky at jboss.com
Date: 2008-10-13 12:28:41 -0400 (Mon, 13 Oct 2008)
New Revision: 79410

Added:
   projects/ejb3/trunk/testsuite/src/test/java/org/jboss/ejb3/test/singleton/AbstractSingletonBean.java
   projects/ejb3/trunk/testsuite/src/test/java/org/jboss/ejb3/test/singleton/SingletonBean2.java
   projects/ejb3/trunk/testsuite/src/test/java/org/jboss/ejb3/test/singleton/SingletonRemote2.java
Modified:
   projects/ejb3/trunk/testsuite/src/test/java/org/jboss/ejb3/test/singleton/SingletonBean.java
   projects/ejb3/trunk/testsuite/src/test/java/org/jboss/ejb3/test/singleton/SingletonLockInterceptor.java
   projects/ejb3/trunk/testsuite/src/test/java/org/jboss/ejb3/test/singleton/unit/SingletonUnitTestCase.java
   projects/ejb3/trunk/testsuite/src/test/resources/test/singleton/aspectdomain-ejb3-interceptors-aop.xml
Log:
EJBTHREE-1518 more tests and a couple of fixes

Added: projects/ejb3/trunk/testsuite/src/test/java/org/jboss/ejb3/test/singleton/AbstractSingletonBean.java
===================================================================
--- projects/ejb3/trunk/testsuite/src/test/java/org/jboss/ejb3/test/singleton/AbstractSingletonBean.java	                        (rev 0)
+++ projects/ejb3/trunk/testsuite/src/test/java/org/jboss/ejb3/test/singleton/AbstractSingletonBean.java	2008-10-13 16:28:41 UTC (rev 79410)
@@ -0,0 +1,143 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt 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.ejb3.test.singleton;
+
+/**
+ * @author <a href="alex at jboss.com">Alexey Loubyansky</a>
+ * @version $Revision: 1.1 $
+ */
+public class AbstractSingletonBean
+{
+   private static Object instanceLock = new Object();
+   private static Thread lockerThread;
+   
+   protected int value;
+   
+   private String lastReturnedValueMethod;
+
+   public AbstractSingletonBean()
+   {
+      super();
+   }
+
+   /**
+    * This method demonstrates that once one thread is entered an instance method
+    * no other thread can enter any method of the same instance in case of write concurrency.
+    */
+   public void writeLock(long pause)
+   {
+      Thread currentThread = Thread.currentThread();
+      synchronized(instanceLock)
+      {
+         if(lockerThread == null)
+            lockerThread = currentThread;
+         else if(!lockerThread.equals(currentThread))
+         {
+            throw new IllegalStateException("Another thread is active in the instance: " + lockerThread + ", current thread: " + currentThread);
+         }
+      }
+   
+      try
+      {
+         Thread.sleep(pause);
+      }
+      catch (InterruptedException e)
+      {
+      }
+      
+      synchronized(instanceLock)
+      {
+         if(!currentThread.equals(lockerThread))
+         {
+            throw new IllegalStateException("Another thread is/was active in the instance: " + lockerThread + ", current thread: " + currentThread);
+         }
+         lockerThread = null;
+      }
+   }
+
+   /**
+    * This method demonstrates that two threads can be active in the same session bean instance in case of read concurrency.
+    *  
+    * 1. if current value is bigger than or equal the valueThreshold then return the current value.
+    * 2. Increase the current value
+    * 3. If the current value is less than valueThreshold then wait and let other threads to increase the value
+    *    until it reaches the valueThreshold.
+    * 4. Return the current value (which should be bigger than or equal to valueThreshold).
+    *    
+    * if waiting takes longer than timeout then throw an exception.
+    */
+   public int getValue(int valueThreshold, long timeout)
+   {
+      synchronized (instanceLock)
+      {
+         if (value >= valueThreshold)
+         {
+            lastReturnedValueMethod = "getValue";
+            return value;
+         }
+   
+         ++this.value;
+   
+         // wait until the other thread increases the current value
+         long startTime = System.currentTimeMillis();
+         while (this.value < valueThreshold)
+         {
+            long waitTime = System.currentTimeMillis() - startTime;
+            if (waitTime > timeout)
+               throw new IllegalStateException("The method took too long. Timeout=" + timeout + ", waitTime=" + waitTime + ", value=" + value);
+   
+            instanceLock.notify();
+   
+            try
+            {
+               instanceLock.wait(timeout);
+            }
+            catch (InterruptedException e)
+            {
+            }
+         }
+   
+         lastReturnedValueMethod = "getValue";
+         instanceLock.notify();
+         return this.value;
+      }
+   }
+
+   public int setValue(int newValue)
+   {
+      try
+      {
+         int prev = this.value;
+         this.value = newValue;
+         return prev;
+      }
+      finally
+      {
+         lastReturnedValueMethod = "setValue";
+      }
+   }
+
+   public String getLastReturnedValueMethod()
+   {
+      return lastReturnedValueMethod;
+   }
+}
\ No newline at end of file


Property changes on: projects/ejb3/trunk/testsuite/src/test/java/org/jboss/ejb3/test/singleton/AbstractSingletonBean.java
___________________________________________________________________
Name: svn:executable
   + *

Modified: projects/ejb3/trunk/testsuite/src/test/java/org/jboss/ejb3/test/singleton/SingletonBean.java
===================================================================
--- projects/ejb3/trunk/testsuite/src/test/java/org/jboss/ejb3/test/singleton/SingletonBean.java	2008-10-13 16:24:53 UTC (rev 79409)
+++ projects/ejb3/trunk/testsuite/src/test/java/org/jboss/ejb3/test/singleton/SingletonBean.java	2008-10-13 16:28:41 UTC (rev 79410)
@@ -33,26 +33,15 @@
  * @author <a href="alex at jboss.com">Alexey Loubyansky</a>
  * @version $Revision: 1.1 $
  */
- at Stateless
+ at Stateless(name="SingletonBean")
 @Remote(SingletonRemote.class)
 @Pool (value="SingletonPool")
 @AspectDomain(value = "Singleton Stateless Bean")
-public class SingletonBean implements SingletonRemote
+public class SingletonBean extends AbstractSingletonBean implements SingletonRemote
 {
    // counter for created instances
    private static Integer instanceCount = 0;
    
-   // these are static to catch not only threads in the same instance but also in other instances
-   // (if the singleton appears to be not a singleton)
-   private static Object instanceLock = new Object();
-   private static Thread lockerThread;
-   
-   // some instance variable
-   private int value;
-   
-   // the name of the last executed method
-   private String lastReturnedValueMethod;
-   
    // instance initialization
    {
       synchronized(instanceCount)
@@ -65,106 +54,4 @@
    {
       return instanceCount;
    }
-   
-   /**
-    * This method demonstrates that once one thread is entered an instance method
-    * no other thread can enter any method of the same instance in case of write concurrency.
-    */
-   public void writeLock(long pause)
-   {
-      Thread currentThread = Thread.currentThread();
-      synchronized(instanceLock)
-      {
-         if(lockerThread == null)
-            lockerThread = currentThread;
-         else if(!lockerThread.equals(currentThread))
-         {
-            throw new IllegalStateException("Another thread is active in the instance: " + lockerThread + ", current thread: " + currentThread);
-         }
-      }
-
-      try
-      {
-         Thread.sleep(pause);
-      }
-      catch (InterruptedException e)
-      {
-      }
-      
-      synchronized(instanceLock)
-      {
-         if(!currentThread.equals(lockerThread))
-         {
-            throw new IllegalStateException("Another thread is/was active in the instance: " + lockerThread + ", current thread: " + currentThread);
-         }
-         lockerThread = null;
-      }
-   }
-   
-   /**
-    * This method demonstrates that two threads can be active in the same session bean instance in case of read concurrency.
-    *  
-    * 1. if current value is bigger than or equal the valueThreshold then return the current value.
-    * 2. Increase the current value
-    * 3. If the current value is less than valueThreshold then wait and let other threads to increase the value
-    *    until it reaches the valueThreshold.
-    * 4. Return the current value (which should be bigger than or equal to valueThreshold).
-    *    
-    * if waiting takes longer than timeout then throw an exception.
-    */
-   public int getValue(int valueThreshold, long timeout)
-   {
-      synchronized (instanceLock)
-      {
-         if (value >= valueThreshold)
-         {
-            lastReturnedValueMethod = "getValue";
-            return value;
-         }
-
-         ++this.value;
-
-         instanceLock.notify();
-
-         // wait until the other thread increases the current value
-         long startTime = System.currentTimeMillis();
-         while (this.value < valueThreshold)
-         {
-            long waitTime = System.currentTimeMillis() - startTime;
-            if (waitTime > timeout)
-               throw new IllegalStateException("The method took too long. Timeout=" + timeout + ", waitTime=" + waitTime + ", value=" + value);
-
-            try
-            {
-               instanceLock.wait(timeout);
-            }
-            catch (InterruptedException e)
-            {
-            }
-         }
-
-         lastReturnedValueMethod = "getValue";
-         instanceLock.notify();
-         return this.value;
-      }
-   }
-   
-   public int setValue(int newValue)
-   {
-      try
-      {
-         int prev = this.value;
-         this.value = newValue;
-         return prev;
-      }
-      finally
-      {
-         lastReturnedValueMethod = "setValue";
-      }
-   }
-   
-   public String getLastReturnedValueMethod()
-   {
-      return lastReturnedValueMethod;
-   }
 }

Added: projects/ejb3/trunk/testsuite/src/test/java/org/jboss/ejb3/test/singleton/SingletonBean2.java
===================================================================
--- projects/ejb3/trunk/testsuite/src/test/java/org/jboss/ejb3/test/singleton/SingletonBean2.java	                        (rev 0)
+++ projects/ejb3/trunk/testsuite/src/test/java/org/jboss/ejb3/test/singleton/SingletonBean2.java	2008-10-13 16:28:41 UTC (rev 79410)
@@ -0,0 +1,76 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt 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.ejb3.test.singleton;
+
+import javax.ejb.Remote;
+import javax.ejb.Stateless;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+
+import org.jboss.ejb3.annotation.AspectDomain;
+import org.jboss.ejb3.annotation.Pool;
+
+/**
+ * A SingletonBean2.
+ * 
+ * @author <a href="alex at jboss.com">Alexey Loubyansky</a>
+ * @version $Revision: 1.1 $
+ */
+ at Stateless(name="SingletonBean2")
+ at Remote(SingletonRemote2.class)
+ at Pool (value="SingletonPool")
+ at AspectDomain(value = "Singleton Stateless Bean")
+public class SingletonBean2 extends AbstractSingletonBean implements SingletonRemote2
+{
+   // counter for created instances
+   private static Integer instanceCount = 0;
+
+   // instance initialization
+   {
+      synchronized(instanceCount)
+      {
+         ++instanceCount;
+      }
+   }
+   
+   public int getInstanceCount()
+   {
+      return instanceCount;
+   }
+   
+   public int setValueToSingleton1Value(int singleton1ValueThreshold, long singleton1Timeout)
+   {
+      SingletonRemote singleton;
+      try
+      {
+         singleton = (SingletonRemote) new InitialContext().lookup("SingletonBean/remote");
+      }
+      catch (NamingException e)
+      {
+         throw new IllegalStateException("Failed to lookup SingletonBean/remote: " + e.getMessage());
+      }
+     
+      value = singleton.getValue(singleton1ValueThreshold, singleton1Timeout);
+      
+      return value;
+   }
+}


Property changes on: projects/ejb3/trunk/testsuite/src/test/java/org/jboss/ejb3/test/singleton/SingletonBean2.java
___________________________________________________________________
Name: svn:executable
   + *

Modified: projects/ejb3/trunk/testsuite/src/test/java/org/jboss/ejb3/test/singleton/SingletonLockInterceptor.java
===================================================================
--- projects/ejb3/trunk/testsuite/src/test/java/org/jboss/ejb3/test/singleton/SingletonLockInterceptor.java	2008-10-13 16:24:53 UTC (rev 79409)
+++ projects/ejb3/trunk/testsuite/src/test/java/org/jboss/ejb3/test/singleton/SingletonLockInterceptor.java	2008-10-13 16:28:41 UTC (rev 79410)
@@ -47,7 +47,7 @@
 
    public Object invoke(Invocation invocation) throws Throwable
    {
-      EJBContainer container = getEJBContainer(invocation);
+      //EJBContainer container = getEJBContainer(invocation);
       /* way to get to the metadata and determine whether the method has READ or WRITE lock
       JBossEnterpriseBeanMetaData xml = container.getXml();
       if(xml != null)
@@ -56,12 +56,15 @@
       
       // for now consider methods starting with "get" as having READ lock
       boolean isReadMethod = false;
+      String methodName = null;
       MethodInvocation mi = (MethodInvocation) invocation;
       if(mi.getMethod() != null)
       {
-         String methodName = mi.getMethod().getName();
+         methodName = mi.getMethod().getName();
          isReadMethod = methodName.startsWith("get") || methodName.startsWith("is");
          //log.info(container.getEjbName() + '.' + methodName + " is read concurrency: " + isReadMethod);
+         //if(mi.getArguments() != null && mi.getArguments().length > 0)
+         //   methodName += "(" + mi.getArguments()[0] + ')';
       }
       
       lock.sync();
@@ -75,6 +78,7 @@
          
          while(wait)
          {
+            //log.info(methodName + " is waiting; active threads=" + lock.activeThreads);
             synchronized (lock)
             {
                lock.releaseSync();
@@ -95,7 +99,9 @@
             else
                wait = lock.hasActiveThreads();
          }
-         
+
+         //log.info(methodName + " coming through; active threads=" + lock.activeThreads);
+
          lock.increaseActiveThreads();
          if(!isReadMethod)
             lock.setWriteInProgress(true);
@@ -120,6 +126,7 @@
          }
          finally
          {
+            //log.info(methodName + " is done; active threads=" + lock.activeThreads);
             lock.releaseSync();
          }
       }

Added: projects/ejb3/trunk/testsuite/src/test/java/org/jboss/ejb3/test/singleton/SingletonRemote2.java
===================================================================
--- projects/ejb3/trunk/testsuite/src/test/java/org/jboss/ejb3/test/singleton/SingletonRemote2.java	                        (rev 0)
+++ projects/ejb3/trunk/testsuite/src/test/java/org/jboss/ejb3/test/singleton/SingletonRemote2.java	2008-10-13 16:28:41 UTC (rev 79410)
@@ -0,0 +1,33 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt 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.ejb3.test.singleton;
+
+/**
+ * A SingletonRemote2.
+ * 
+ * @author <a href="alex at jboss.com">Alexey Loubyansky</a>
+ * @version $Revision: 1.1 $
+ */
+public interface SingletonRemote2 extends SingletonRemote
+{
+   int setValueToSingleton1Value(int valueThreshold, long timeout);
+}


Property changes on: projects/ejb3/trunk/testsuite/src/test/java/org/jboss/ejb3/test/singleton/SingletonRemote2.java
___________________________________________________________________
Name: svn:executable
   + *

Modified: projects/ejb3/trunk/testsuite/src/test/java/org/jboss/ejb3/test/singleton/unit/SingletonUnitTestCase.java
===================================================================
--- projects/ejb3/trunk/testsuite/src/test/java/org/jboss/ejb3/test/singleton/unit/SingletonUnitTestCase.java	2008-10-13 16:24:53 UTC (rev 79409)
+++ projects/ejb3/trunk/testsuite/src/test/java/org/jboss/ejb3/test/singleton/unit/SingletonUnitTestCase.java	2008-10-13 16:28:41 UTC (rev 79410)
@@ -23,6 +23,7 @@
 
 
 import org.jboss.ejb3.test.singleton.SingletonRemote;
+import org.jboss.ejb3.test.singleton.SingletonRemote2;
 import org.jboss.test.JBossTestCase;
 
 import junit.framework.Test;
@@ -67,8 +68,8 @@
    }
    
    /**
-    * This method demonstrates that once one thread is entered an instance method
-    * no other thread can enter any method of the same instance in case of write concurrency.
+    * This method demonstrates that once one thread has entered an instance method with write concurrency
+    * no other thread can proceed with the invocation of any method on the same instance.
     */
    public void testWriteConcurrency() throws Exception
    {
@@ -106,9 +107,7 @@
       }
       
       for(Thread t : threads)
-      {
          t.start();
-      }
       
       synchronized(finishedCount)
       {
@@ -133,71 +132,36 @@
     */
    public void testReadConcurrency() throws Throwable
    {
-      final SingletonRemote remote = (SingletonRemote) getInitialContext().lookup("SingletonBean/remote");
+      final SingletonRemote singleton = (SingletonRemote) getInitialContext().lookup("SingletonBean/remote");
 
-      final Thread[] threads = new Thread[5];
-      final int[] results = new int[threads.length];
-      final Throwable error[] = new Throwable[1];
-      final int[] finishedThreads = new int[1];
+      GetValueThread[] threads = new GetValueThread[5];
       for(int i = 0; i < threads.length; ++i)
-      {
-         final int threadIndex = i;
-         threads[threadIndex] = new Thread(new Runnable()
-         {
-            public void run()
-            {
-               try
-               {
-                  results[threadIndex] = remote.getValue(threads.length, 1000);
-               }
-               catch(Throwable t)
-               {
-                  log.error(t);
-                  error[0] = t;
-               }
-               finally
-               {
-                  synchronized (finishedThreads)
-                  {
-                     ++finishedThreads[0];
-                     finishedThreads.notify();
-                  }
-               }
-            }
-         });
-      }
+         threads[i] = new GetValueThread(singleton, threads.length);
 
-      for(int i = 0; i < threads.length; ++i)
-         threads[i].start();
-
-      synchronized(finishedThreads)
+      for(GetValueThread thread : threads)
+         thread.start();
+      
+      for(GetValueThread thread : threads)
       {
-         while(finishedThreads[0] < threads.length)
-         {
-            try
-            {
-               finishedThreads.wait();
-            }
-            catch(InterruptedException e)
-            {
-            }
-         }
+         thread.waitOnTheResult();
+         thread.assertResult(threads.length);
       }
-
-      if(error[0] != null)
-         throw error[0];
       
-      for(int i = 0; i < threads.length; ++i)
-         assertEquals(threads.length, results[i]);
-
-      assertEquals(1, remote.getInstanceCount());
+      assertEquals(1, singleton.getInstanceCount());
    }
-
+   
+   public void testWriteThreadWaitingOnReadThreadsToComplete() throws Throwable
+   {
+      // run a few times
+      for(int i = 0; i < 10; ++i)
+         writeThreadWaitingOnReadThreadsToComplete();
+   }
+   
    /**
     * This method demonstrates that an invocation of a method with write concurrency
     * can't proceed until all the currently in progress methods with read concurrency are done.
     */
-   public void testWriteThreadWaitingOnReadThreadsToComplete() throws Throwable
+   private void writeThreadWaitingOnReadThreadsToComplete() throws Throwable
    {
       final SingletonRemote singleton = (SingletonRemote) getInitialContext().lookup("SingletonBean/remote");
 
@@ -229,31 +193,29 @@
       // current value should now be 3
       // this getter will make it 4 and resume getter4
       getter = new GetValueThread(singleton, 4);
-      assertFalse(getter6.isDone());
-      assertFalse(getter5.isDone());
-      assertFalse(getter4.isDone());
+      getter6.assertNotDone();
+      getter5.assertNotDone();
+      getter4.assertNotDone();
       getter.start();
       
       getter.waitOnTheResult();
-      assertTrue(getter.isDone());
       getter.assertResult(4);
       
       getter4.waitOnTheResult();
-      assertTrue(getter4.isDone());
       getter4.assertResult(4);
       
       // at this point getter5 and getter6 are blocked
       // invoke setter (which would block until the getters are done) and set the value to 1 again
       setter = new SetValueThread(singleton, 1);
-      assertFalse(getter6.isDone());
-      assertFalse(getter5.isDone());
+      getter6.assertNotDone();
+      getter5.assertNotDone();
       setter.start();
       
       // invoke getter again which would unblock getter5
       getter = new GetValueThread(singleton, 5);
-      assertFalse(getter6.isDone());
-      assertFalse(getter5.isDone());
-      assertFalse(setter.isDone());
+      getter6.assertNotDone();
+      getter5.assertNotDone();
+      setter.assertNotDone();
       getter.start();
 
       getter.waitOnTheResult();
@@ -261,11 +223,11 @@
       getter5.waitOnTheResult();
       getter5.assertResult(5);
       
-      // at this point getter5 is blocked and blocking the setter
-      // invoke getter again and unblock getter5
+      // at this point getter6 is blocked and blocking the setter
+      // invoke getter again and unblock getter6
       getter = new GetValueThread(singleton, 6);
-      assertFalse(getter6.isDone());
-      assertFalse(setter.isDone());
+      getter6.assertNotDone();
+      setter.assertNotDone();
       getter.start();
       
       // wait for the results on all threads
@@ -288,6 +250,87 @@
       
       assertEquals(1, singleton.getInstanceCount());
    }
+
+   /**
+    * This method demonstrates that invocations of a method with read concurrency
+    * can't proceed until the currently in progress method with write concurrency is done.
+    */
+   public void testReadThreadsWaitingOnWriteThreadToComplete() throws Throwable
+   {
+      final SingletonRemote singleton1 = (SingletonRemote) getInitialContext().lookup("SingletonBean/remote");
+      final SingletonRemote2 singleton2 = (SingletonRemote2) getInitialContext().lookup("SingletonBean2/remote");
+      
+      // initialize both to 0
+      SetValueThread setter = new SetValueThread(singleton1, 0);
+      setter.start();
+      setter.waitOnTheResult();
+      
+      GetValueThread getter = new GetValueThread(singleton1);
+      getter.start();
+      getter.waitOnTheResult();
+      assertEquals(0, getter.getResult());
+
+      setter = new SetValueThread(singleton2, 0);
+      setter.start();
+      setter.waitOnTheResult();
+      
+      getter = new GetValueThread(singleton2);
+      getter.start();
+      getter.waitOnTheResult();
+      assertEquals(0, getter.getResult());
+
+      // invoke getter on singleton with threshold 2
+      GetValueThread singleton1Getter2 = new GetValueThread(singleton1, 2);
+      singleton1Getter2.start();
+      
+      // invoke setValueToSingleton1Value with threshold 3 for singleton1
+      // this will unblock singletonGetter2
+      AbstractValueThread setValueToSingleton1Value = new AbstractValueThread(singleton2)
+      {
+         @Override
+         protected int execute(SingletonRemote singleton)
+         {
+            return ((SingletonRemote2)singleton).setValueToSingleton1Value(3, 10000);
+         }
+      };
+      setValueToSingleton1Value.start();
+
+      // wait for the singleton1Getter2 to come back
+      singleton1Getter2.waitOnTheResult();
+      singleton1Getter2.assertResult(2);
+      
+      // now callGetSingleton1Value is blocked in singleton1
+      setValueToSingleton1Value.assertNotDone();
+
+      // start a few read threads on the singleton2
+      // setValueToSingleton1Value will set singleton2.value to 3
+      GetValueThread singleton2GetterA = new GetValueThread(singleton2, 4);
+      singleton2GetterA.start();
+      GetValueThread singleton2GetterB = new GetValueThread(singleton2, 4);
+      singleton2GetterB.start();
+
+      // unblock callGetSingleton1Value
+      GetValueThread singleton1Getter3 = new GetValueThread(singleton1, 3);
+      setValueToSingleton1Value.assertNotDone();
+      singleton2GetterA.assertNotDone();
+      singleton2GetterB.assertNotDone();
+      
+      singleton1Getter3.start();
+      singleton1Getter3.waitOnTheResult();
+      singleton1Getter3.assertResult(3);
+      
+      setValueToSingleton1Value.waitOnTheResult();
+      setValueToSingleton1Value.assertResult(3);
+      
+      singleton2GetterA.waitOnTheResult();
+      singleton2GetterA.assertResult(4);
+      
+      singleton2GetterB.waitOnTheResult();
+      singleton2GetterB.assertResult(4);
+      
+      assertEquals(1, singleton1.getInstanceCount());
+      assertEquals(1, singleton2.getInstanceCount());
+   }
    
    private static abstract class AbstractValueThread extends Thread
    {
@@ -355,11 +398,24 @@
       {
          return error;
       }
+
+      public void assertDone()
+      {
+         if(error != null)
+            fail(error.getMessage());
+         assertTrue(done[0]);
+      }
+
+      public void assertNotDone()
+      {
+         if(error != null)
+            fail(error.getMessage());
+         assertFalse(done[0]);
+      }
       
       public void assertResult(int expected)
       {
-         if(error != null)
-            fail(error.getMessage());
+         assertDone();
          assertEquals(expected, result);
       }
    }
@@ -393,7 +449,7 @@
 
       public GetValueThread(SingletonRemote singleton, int valueThreshold)
       {
-         this(singleton, valueThreshold, 2000);
+         this(singleton, valueThreshold, 10000);
       }
       
       public GetValueThread(SingletonRemote singleton, int valueThreshold, int timeout)

Modified: projects/ejb3/trunk/testsuite/src/test/resources/test/singleton/aspectdomain-ejb3-interceptors-aop.xml
===================================================================
--- projects/ejb3/trunk/testsuite/src/test/resources/test/singleton/aspectdomain-ejb3-interceptors-aop.xml	2008-10-13 16:24:53 UTC (rev 79409)
+++ projects/ejb3/trunk/testsuite/src/test/resources/test/singleton/aspectdomain-ejb3-interceptors-aop.xml	2008-10-13 16:28:41 UTC (rev 79410)
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <aop xmlns="urn:jboss:aop-beans:1.0">
-   <interceptor class="org.jboss.ejb3.test.singleton.SingletonLockInterceptor" scope="PER_VM"/>
+   <interceptor class="org.jboss.ejb3.test.singleton.SingletonLockInterceptor" scope="PER_CLASS"/>
 
    <domain name="Singleton Stateless Bean" extends="Intercepted Bean" inheritBindings="true">
       <bind pointcut="execution(public * *->*(..))">




More information about the jboss-cvs-commits mailing list