[jboss-svn-commits] JBL Code SVN: r29253 - in labs/jbosstm/trunk/ArjunaCore/arjuna: tests/byteman-scripts and 1 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Tue Sep 8 12:10:02 EDT 2009


Author: adinn
Date: 2009-09-08 12:10:02 -0400 (Tue, 08 Sep 2009)
New Revision: 29253

Added:
   labs/jbosstm/trunk/ArjunaCore/arjuna/tests/classes/com/hp/mwtests/ts/arjuna/reaper/ReaperTestCaseControl.java
Modified:
   labs/jbosstm/trunk/ArjunaCore/arjuna/build.xml
   labs/jbosstm/trunk/ArjunaCore/arjuna/tests/byteman-scripts/reaper.txt
   labs/jbosstm/trunk/ArjunaCore/arjuna/tests/classes/com/hp/mwtests/ts/arjuna/reaper/ReaperTestCase.java
   labs/jbosstm/trunk/ArjunaCore/arjuna/tests/classes/com/hp/mwtests/ts/arjuna/reaper/ReaperTestCase2.java
   labs/jbosstm/trunk/ArjunaCore/arjuna/tests/classes/com/hp/mwtests/ts/arjuna/reaper/ReaperTestCase3.java
Log:
got reaper test case 3 working so now all reaper tests shoudl execute correctly -- fix for JBTM-567

Modified: labs/jbosstm/trunk/ArjunaCore/arjuna/build.xml
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/build.xml	2009-09-08 15:59:04 UTC (rev 29252)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/build.xml	2009-09-08 16:10:02 UTC (rev 29253)
@@ -64,11 +64,10 @@
 
                     <!-- LogStressTest2 takes too long - needs moving to /qa -->
                     <exclude name="**/LogStressTest2.java"/>
-                    <!-- ReaperTestCase2 and 3 have timing issues - adinn to fix - JBTM-567 -->
-                    <exclude name="**/ReaperTestCase3.java"/>
                     <!-- tests which have been modified to run using byteman scripts -->
                     <exclude name="**/reaper/ReaperMonitorTest.java"/>
-                    <exclude name="**/ReaperTestCase2.java"/>
+                    <exclude name="**/reaper/ReaperTestCase3.java"/>
+                    <exclude name="**/reaper/ReaperTestCase2.java"/>
                     <exclude name="**/reaper/ReaperTestCase.java"/>
                     <exclude name="**/objectstore/LogStoreRecoveryTest.java"/>
                     <exclude name="**/objectstore/LogStoreTest2.java"/>
@@ -83,6 +82,7 @@
                     <include name="**/reaper/ReaperMonitorTest.java"/>
                     <include name="**/reaper/ReaperTestCase.java"/>
                     <include name="**/reaper/ReaperTestCase2.java"/>
+                    <include name="**/reaper/ReaperTestCase3.java"/>
                 </fileset>
             </tests>
             <!--

Modified: labs/jbosstm/trunk/ArjunaCore/arjuna/tests/byteman-scripts/reaper.txt
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/tests/byteman-scripts/reaper.txt	2009-09-08 15:59:04 UTC (rev 29252)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/tests/byteman-scripts/reaper.txt	2009-09-08 16:10:02 UTC (rev 29253)
@@ -234,12 +234,12 @@
 ENDRULE
 
 #########################################################################
-# ReaperTestCase wants to ensure that the reaper is single stepped
-# through processing of inserted reaper elements
-#
+# ReaperTestCaseControl provides methods used by its three
+# ReaperTestCase<N> subclasses to enable, disable and trigger rule
+# activity during the course of the test.
 
-RULE ReaperTestCase enable trigger rendezvous
-CLASS com.hp.mwtests.ts.arjuna.reaper.ReaperTestCase
+RULE ReaperTestCaseControl enable trigger rendezvous
+CLASS com.hp.mwtests.ts.arjuna.reaper.ReaperTestCaseControl
 METHOD enableRendezvous(Object, boolean)
 AT ENTRY
 BIND NOTHING
@@ -247,8 +247,8 @@
 DO createRendezvous($1, 2, $2)
 ENDRULE
 
-RULE ReaperTestCase disable trigger rendezvous
-CLASS com.hp.mwtests.ts.arjuna.reaper.ReaperTestCase
+RULE ReaperTestCaseControl disable trigger rendezvous
+CLASS com.hp.mwtests.ts.arjuna.reaper.ReaperTestCaseControl
 METHOD disableRendezvous(Object)
 AT ENTRY
 BIND NOTHING
@@ -258,19 +258,19 @@
 
 # if the supplied string matches a known rendezvous then trigger it
 
-RULE ReaperTestCase rendezvous
-CLASS com.hp.mwtests.ts.arjuna.reaper.ReaperTestCase
+RULE ReaperTestCaseControl rendezvous
+CLASS com.hp.mwtests.ts.arjuna.reaper.ReaperTestCaseControl
 METHOD triggerRendezvous(Object)
 AT ENTRY
-BIND NOTHING
+BIND thread = Thread.currentThread()
 IF isRendezvous($1, 2)
-DO debug("" + $1),
+DO debug("" + $1 + " " + thread),
    rendezvous($1),
    return
 ENDRULE
 
-RULE ReaperTestCase rendezvous 2
-CLASS com.hp.mwtests.ts.arjuna.reaper.ReaperTestCase
+RULE ReaperTestCaseControl rendezvous 2
+CLASS com.hp.mwtests.ts.arjuna.reaper.ReaperTestCaseControl
 METHOD triggerRendezvous(Object)
 AT ENTRY
 BIND NOTHING
@@ -280,8 +280,8 @@
 
 # trigger a delay
 
-RULE ReaperTestCase wait
-CLASS com.hp.mwtests.ts.arjuna.reaper.ReaperTestCase
+RULE ReaperTestCaseControl wait
+CLASS com.hp.mwtests.ts.arjuna.reaper.ReaperTestCaseControl
 METHOD triggerWait(int)
 AT ENTRY
 BIND NOTHING
@@ -291,6 +291,22 @@
    return
 ENDRULE
 
+RULE ReaperTestCaseControl check and clear
+CLASS com.hp.mwtests.ts.arjuna.reaper.ReaperTestCaseControl
+METHOD checkAndClearFlag(Object)
+AT ENTRY
+BIND value = flagged($1)
+IF TRUE
+DO debug("setAndClear(" + $1 + ") => " + value),
+   clear($1),
+   return value
+ENDRULE
+
+#########################################################################
+# ReaperTestCase wants to ensure that the reaper is single stepped
+# through processing of inserted reaper elements
+#
+
 # debug tracing rules
 # RULE ReaperTestCase trace element remove
 # CLASS com.arjuna.ats.arjuna.coordinator.TransactionReaper
@@ -311,71 +327,18 @@
 # ENDRULE
 
 #########################################################################
-# ReaperTestCase2 wants to ensure that the reaper is single stepped
-# through processing of inserted reaper elements
+# ReaperTestCase3 wants the reaper and reaper worker threads to
+# be suspended until it has reset the timeouts for the reapables
+# to zero forcing them to be cancelled early
 #
 
-RULE ReaperTestCase2 enable trigger rendezvous
-CLASS com.hp.mwtests.ts.arjuna.reaper.ReaperTestCase2
-METHOD enableRendezvous(Object, boolean)
-AT ENTRY
+RULE ReaperTestCase3 unlatch reaper and reaper worker
+CLASS com.arjuna.ats.arjuna.coordinator.TransactionReaper
+METHOD shutdown
+AT CALL wait
 BIND NOTHING
 IF TRUE
-DO createRendezvous($1, 2, $2)
+DO debug("removing latches on reaper and reaper worker"),
+   deleteRendezvous("reaper1", 2),
+   deleteRendezvous("reaperworker1", 2)   
 ENDRULE
-
-RULE ReaperTestCase2 disable trigger rendezvous
-CLASS com.hp.mwtests.ts.arjuna.reaper.ReaperTestCase2
-METHOD disableRendezvous(Object)
-AT ENTRY
-BIND NOTHING
-IF TRUE
-DO deleteRendezvous($1, 2)
-ENDRULE
-
-# if the supplied string matches a known rendezvous then trigger it
-
-RULE ReaperTestCase2 rendezvous
-CLASS com.hp.mwtests.ts.arjuna.reaper.ReaperTestCase2
-METHOD triggerRendezvous(Object)
-AT ENTRY
-BIND thread = Thread.currentThread()
-IF isRendezvous($1, 2)
-DO debug("" + $1 + " " + thread),
-   rendezvous($1),
-   return
-ENDRULE
-
-RULE ReaperTestCase2 rendezvous 2
-CLASS com.hp.mwtests.ts.arjuna.reaper.ReaperTestCase2
-METHOD triggerRendezvous(Object)
-AT ENTRY
-BIND NOTHING
-IF NOT isRendezvous($1, 2)
-DO throw RuntimeException("invalid rendezvous for trigger " + $1)
-ENDRULE
-
-# trigger a delay
-
-RULE ReaperTestCase2 wait
-CLASS com.hp.mwtests.ts.arjuna.reaper.ReaperTestCase2
-METHOD triggerWait(int)
-AT ENTRY
-BIND NOTHING
-IF TRUE
-DO debug("wait " + $1),
-   delay($1),
-   return
-ENDRULE
-
-RULE ReapertestCase2 check and clear
-CLASS com.hp.mwtests.ts.arjuna.reaper.ReaperTestCase2
-METHOD checkAndClearFlag(Object)
-AT ENTRY
-BIND value = flagged($1)
-IF TRUE
-DO debug("setAndClear(" + $1 + ") => " + value),
-   clear($1),
-   return value
-ENDRULE
-

Modified: labs/jbosstm/trunk/ArjunaCore/arjuna/tests/classes/com/hp/mwtests/ts/arjuna/reaper/ReaperTestCase.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/tests/classes/com/hp/mwtests/ts/arjuna/reaper/ReaperTestCase.java	2009-09-08 15:59:04 UTC (rev 29252)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/tests/classes/com/hp/mwtests/ts/arjuna/reaper/ReaperTestCase.java	2009-09-08 16:10:02 UTC (rev 29253)
@@ -36,7 +36,7 @@
  *
  * @author jonathan.halliday at redhat.com, 2007-04-30
  */
-public class ReaperTestCase
+public class ReaperTestCase extends ReaperTestCaseControl
 {
     @Test
     public void testReaper() throws Exception
@@ -148,21 +148,6 @@
         assertEquals(0, reaper.numberOfTimeouts());
     }
 
-    private void enableRendezvous(Object o, boolean repeatable)
-    {
-        // do nothing this is just used for synchronization
-    }
-
-    private void triggerRendezvous(Object o)
-    {
-        // do nothing this is just used for synchronization
-    }
-
-    private void triggerWait(int msecs)
-    {
-        // do nothing this is just used for synchronization
-    }
-
     public class MockReapable implements Reapable
     {
         public MockReapable(Uid uid)

Modified: labs/jbosstm/trunk/ArjunaCore/arjuna/tests/classes/com/hp/mwtests/ts/arjuna/reaper/ReaperTestCase2.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/tests/classes/com/hp/mwtests/ts/arjuna/reaper/ReaperTestCase2.java	2009-09-08 15:59:04 UTC (rev 29252)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/tests/classes/com/hp/mwtests/ts/arjuna/reaper/ReaperTestCase2.java	2009-09-08 16:10:02 UTC (rev 29253)
@@ -37,7 +37,7 @@
  * @author Andrwe Dinn (adinn at redhat.com), 2007-07-09
  */
 
-public class ReaperTestCase2
+public class ReaperTestCase2  extends ReaperTestCaseControl
 {
     @Test
     public void testReaper() throws Exception
@@ -366,148 +366,4 @@
         assertTrue(reapable2.getRollbackTried());
         assertTrue(reapable3.getRollbackTried());
     }
-
-    private void enableRendezvous(Object o, boolean repeatable)
-    {
-        // do nothing this is just used for synchronization
-    }
-
-    private void triggerRendezvous(Object o)
-    {
-        // do nothing this is just used for synchronization
-    }
-
-    private void triggerWait(int msecs)
-    {
-        // do nothing this is just used for synchronization
-    }
-
-    private boolean checkAndClearFlag(Object o)
-    {
-        // return false by default -- rule system will intercept and return the relevant flag
-        // setting
-        
-        return false;
-    }
-
-    public class TestReapable implements Reapable
-    {
-        /**
-         * create a mock reapable
-         * @param uid
-         * @param doCancel true if the reapable should return ABORTED from the cancel call and false if it should
- * return RUNNING
-         * @param rendezvousInCancel true iff the reapable should rendezvous with the test code when cancel is called
-         * @param doRollback the value that the reapable should return true from the prevent_commit call
-         * @param rendezvousInInterrupt  true iff the reapable should rendezvous with the test code when it is
-         */
-        public TestReapable(Uid uid, boolean doCancel, boolean rendezvousInCancel, boolean doRollback, boolean rendezvousInInterrupt)
-        {
-            this.uid = uid;
-            this.rendezvousInCancel = rendezvousInCancel;
-            this.rendezvousInInterrupt = rendezvousInInterrupt;
-            this.doCancel = doCancel;
-            this.doRollback = doRollback;
-            cancelTried = false;
-            rollbackTried = false;
-            running = true;
-        }
-
-        public boolean running()
-        {
-            return getRunning();
-        }
-
-        public boolean preventCommit()
-        {
-            setRollbackTried();
-
-            if (rendezvousInInterrupt) {
-                triggerRendezvous(uid);
-                triggerRendezvous(uid);
-            }
-
-            clearRunning();
-            return doRollback;
-        }
-
-        public int cancel()
-        {
-            boolean interrupted = false;
-
-            setCancelTried();
-
-            // track the worker trying to do the cancel so we can
-            // detect if it becomes a zombie
-
-            setCancelThread(Thread.currentThread());
-
-            if (rendezvousInCancel) {
-                triggerRendezvous(uid);
-                triggerRendezvous(uid);
-            }
-
-            if (doCancel) {
-                clearRunning();
-                return ActionStatus.ABORTED;
-            } else {
-                return ActionStatus.RUNNING;
-            }
-        }
-
-        public Uid get_uid()
-        {
-            return uid;
-        }
-
-        private Uid uid;
-        private boolean doCancel;
-        private boolean doRollback;
-        private boolean rendezvousInCancel;
-        private boolean rendezvousInInterrupt;
-        private boolean cancelTried;
-        private boolean rollbackTried;
-        private boolean running;
-        private Thread cancelThread;
-
-        public synchronized void setCancelTried()
-        {
-            cancelTried = true;
-        }
-
-        public synchronized boolean getCancelTried()
-        {
-            return cancelTried;
-        }
-
-        public synchronized void setCancelThread(Thread cancelThread)
-        {
-            this.cancelThread = cancelThread;
-        }
-
-        public synchronized Thread getCancelThread()
-        {
-            return cancelThread;
-        }
-
-        public synchronized void setRollbackTried()
-        {
-            rollbackTried = true;
-        }
-
-        public synchronized boolean getRollbackTried()
-        {
-            return rollbackTried;
-        }
-
-        public synchronized void clearRunning()
-        {
-            running = false;
-        }
-
-        public synchronized boolean getRunning()
-        {
-            return running;
-        }
-    }
 }

Modified: labs/jbosstm/trunk/ArjunaCore/arjuna/tests/classes/com/hp/mwtests/ts/arjuna/reaper/ReaperTestCase3.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/tests/classes/com/hp/mwtests/ts/arjuna/reaper/ReaperTestCase3.java	2009-09-08 15:59:04 UTC (rev 29252)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/tests/classes/com/hp/mwtests/ts/arjuna/reaper/ReaperTestCase3.java	2009-09-08 16:10:02 UTC (rev 29253)
@@ -28,7 +28,7 @@
 import org.junit.Test;
 import static org.junit.Assert.*;
 
-public class ReaperTestCase3
+public class ReaperTestCase3  extends ReaperTestCaseControl
 {
     @Test
     public void testReaperWait() throws Exception
@@ -40,43 +40,80 @@
 
         Thread.sleep(1000);
 
-        // create slow reapables some of which will not respond immediately
-        // to cancel requests and ensure that they get cancelled
-        // and that the reaper does not get wedged
+        // create test reapables some of which will not respond immediately to cancel requests
 
-        SlowReapable reapable1 = new SlowReapable(new Uid(), 2000, 0, true, true);
-        SlowReapable reapable2 = new SlowReapable(new Uid(), 0, 0, true, true);
-        SlowReapable reapable3 = new SlowReapable(new Uid(), 100, 2000, false, true);
-        SlowReapable reapable4 = new SlowReapable(new Uid(), 1000, 1000, false, false);
+        Uid uid0 = new Uid();
+        Uid uid1 = new Uid();
+        Uid uid2 = new Uid();
+        Uid uid3 = new Uid();
 
+        // reapable0 will return CANCELLED from cancel and will rendezvous inside the cancel call
+        // so we can delay it. prevent_commit should not get called so we don't care about the arguments
+        TestReapable reapable0 = new TestReapable(uid0, true, false, false, false);
+        // reapable1 will return CANCELLED from cancel and will not rendezvous inside the cancel call
+        // prevent_commit should not get called so we don't care about the arguments
+        TestReapable reapable1 = new TestReapable(uid1, true, false, false, false);
+        // reapable2 will return CANCELLED from cancel and will not rendezvous inside the cancel call
+        // prevent_commit should not get called so we don't care about the arguments
+        TestReapable reapable2 = new TestReapable(uid2, true, false, false, false);
+        // reapable3 will return CANCELLED from cancel and will not rendezvous inside the cancel call
+        // prevent_commit should not get called so we don't care about the arguments
+        TestReapable reapable3 = new TestReapable(uid3, true, false, false, false);
+        // enable a repeatable rendezvous before checking the reapable queue
+        // enableRendezvous("reaper1", true);
+        // enable a repeatable rendezvous before processing a timed out reapable
+        // enableRendezvous("reaper2", true);
+        // enable a repeatable rendezvous before scheduling a reapable in the worker queue for cancellation
+        // enableRendezvous("reaper3", true);
+        // enable a repeatable rendezvous before rescheduling a reapable in the worker queue for cancellation
+        // enableRendezvous("reaper4", true);
+        // enable a repeatable rendezvous before interrupting a cancelled reapable
+        // enableRendezvous("reaper5", true);
+        // enable a repeatable rendezvous before marking a worker thread as a zombie
+        // enableRendezvous("reaper6", true);
+        // enable a repeatable rendezvous before marking a reapable as rollback only from the reaper thread
+        // enableRendezvous("reaper7", true);
+        // enable a repeatable rendezvous before checking the worker queue
+        // enableRendezvous("reaperworker1", true);
+        // enable a repeatable rendezvous before marking a reapable as cancel
+        // enableRendezvous("reaperworker2", true);
+        // enable a repeatable rendezvous before calling cancel
+        // enableRendezvous("reaperworker3", true);
+        // enable a repeatable rendezvous before marking a reapable as rollback only from the worker thread
+        // enableRendezvous("reaperworker4", true);
+
+        // enable a repeatable rendezvous for each of the test reapables which we have marked to
+        // perform a rendezvous
+
+        // enableRendezvous(uid0, true);
+
         // insert reapables so they timeout at 1 second intervals then
         // check progress of cancellations and rollbacks
 
-        assertTrue(reaper.insert(reapable1, 1));
+        assertTrue(reaper.insert(reapable0, 1));
 
-        assertTrue(reaper.insert(reapable2, 2));
+        assertTrue(reaper.insert(reapable1, 2));
 
-        assertTrue(reaper.insert(reapable3, 3));
+        assertTrue(reaper.insert(reapable2, 3));
 
-        assertTrue(reaper.insert(reapable4, 4));
+        assertTrue(reaper.insert(reapable3, 4));
 
         // make sure they were all registered
 
         assertEquals(4, reaper.numberOfTransactions());
         assertEquals(4, reaper.numberOfTimeouts());
 
-        // force a termination but wait for the transactions to timeout
-
         TransactionReaper.terminate(true);
 
         assertEquals(0, reaper.numberOfTransactions());
 
+        assertTrue(reapable0.getCancelTried());
         assertTrue(reapable1.getCancelTried());
         assertTrue(reapable2.getCancelTried());
         assertTrue(reapable3.getCancelTried());
-        assertTrue(reapable4.getCancelTried());
     }
 
+    @Test
     public void testReaperForce() throws Exception
     {
         TransactionReaper.create(5000);
@@ -86,41 +123,102 @@
 
         Thread.sleep(1000);
 
-        // create slow reapables some of which will not respond immediately
-        // to cancel requests and ensure that they get cancelled
-        // and that the reaper does not get wedged
+        // create test reapables some of which will not respond immediately to cancel requests
 
-        SlowReapable reapable1 = new SlowReapable(new Uid(), 2000, 0, true, true);
-        SlowReapable reapable2 = new SlowReapable(new Uid(), 0, 0, true, true);
-        SlowReapable reapable3 = new SlowReapable(new Uid(), 100, 2000, false, true);
-        SlowReapable reapable4 = new SlowReapable(new Uid(), 1000, 1000, false, false);
+        Uid uid0 = new Uid();
+        Uid uid1 = new Uid();
+        Uid uid2 = new Uid();
+        Uid uid3 = new Uid();
 
-        // insert reapables so they timeout at 1 second intervals then
-        // check progress of cancellations and rollbacks
+        // reapable0 will return CANCELLED from cancel and will rendezvous inside the cancel call
+        // so we can delay it. prevent_commit should not get called so we don't care about the arguments
+        TestReapable reapable0 = new TestReapable(uid0, true, false, false, false);
+        // reapable1 will return CANCELLED from cancel and will not rendezvous inside the cancel call
+        // prevent_commit should not get called so we don't care about the arguments
+        TestReapable reapable1 = new TestReapable(uid1, true, false, false, false);
+        // reapable2 will return CANCELLED from cancel and will not rendezvous inside the cancel call
+        // prevent_commit should not get called so we don't care about the arguments
+        TestReapable reapable2 = new TestReapable(uid2, true, false, false, false);
+        // reapable3 will return CANCELLED from cancel and will not rendezvous inside the cancel call
+        // prevent_commit should not get called so we don't care about the arguments
+        TestReapable reapable3 = new TestReapable(uid3, true, false, false, false);
+        // enable a repeatable rendezvous before checking the reapable queue
+        enableRendezvous("reaper1", true);
+        // enable a repeatable rendezvous before processing a timed out reapable
+        // enableRendezvous("reaper2", true);
+        // enable a repeatable rendezvous before scheduling a reapable in the worker queue for cancellation
+        // enableRendezvous("reaper3", true);
+        // enable a repeatable rendezvous before rescheduling a reapable in the worker queue for cancellation
+        // enableRendezvous("reaper4", true);
+        // enable a repeatable rendezvous before interrupting a cancelled reapable
+        // enableRendezvous("reaper5", true);
+        // enable a repeatable rendezvous before marking a worker thread as a zombie
+        // enableRendezvous("reaper6", true);
+        // enable a repeatable rendezvous before marking a reapable as rollback only from the reaper thread
+        // enableRendezvous("reaper7", true);
+        // enable a repeatable rendezvous before checking the worker queue
+        enableRendezvous("reaperworker1", true);
+        // enable a repeatable rendezvous before marking a reapable as cancel
+        // enableRendezvous("reaperworker2", true);
+        // enable a repeatable rendezvous before calling cancel
+        // enableRendezvous("reaperworker3", true);
+        // enable a repeatable rendezvous before marking a reapable as rollback only from the worker thread
+        // enableRendezvous("reaperworker4", true);
 
-        assertTrue(reaper.insert(reapable1, 1));
+        // enable a repeatable rendezvous for each of the test reapables which we have marked to
+        // perform a rendezvous
 
-        assertTrue(reaper.insert(reapable2, 2));
+        // enableRendezvous(uid0, true);
 
-        assertTrue(reaper.insert(reapable3, 3));
+        assertTrue(reaper.insert(reapable0, 1));
 
-        assertTrue(reaper.insert(reapable4, 4));
+        assertTrue(reaper.insert(reapable1, 2));
 
+        assertTrue(reaper.insert(reapable2, 3));
+
+        assertTrue(reaper.insert(reapable3, 4));
+
+        // latch the reaper before it checks the queue
+
+        triggerRendezvous("reaper1");
+
         // make sure they were all registered
 
         assertEquals(4, reaper.numberOfTransactions());
         assertEquals(4, reaper.numberOfTimeouts());
 
+        // ensure the first reapable is ready
+
+        triggerWait(1000);
+
+        // let the reaper process the first reapable then latch it again before it checks the queue
+
+        triggerRendezvous("reaper1");
+
+        triggerRendezvous("reaper1");
+
+        // latch the worker before it checks the worker queue
+
+        triggerRendezvous("reaperworker1");
+
+        // let the worker process the first reapable then latch it again before it checks the queue
+
+        triggerRendezvous("reaperworker1");
+
+        triggerRendezvous("reaperworker1");
+
         // force a termination and don't wait for the normal timeout periods
+        // byteman rules will ensure that the reaper and reaperworker rendezvous gte deleted
+        // under this call
 
         TransactionReaper.terminate(false);
 
         assertEquals(0, reaper.numberOfTransactions());
 
+        assertTrue(reapable0.getCancelTried());
         assertTrue(reapable1.getCancelTried());
         assertTrue(reapable2.getCancelTried());
         assertTrue(reapable3.getCancelTried());
-        assertTrue(reapable4.getCancelTried());
 
         /*
         * Since we've (hopefully) just run two tests with new reapers in the same VM

Added: labs/jbosstm/trunk/ArjunaCore/arjuna/tests/classes/com/hp/mwtests/ts/arjuna/reaper/ReaperTestCaseControl.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/tests/classes/com/hp/mwtests/ts/arjuna/reaper/ReaperTestCaseControl.java	                        (rev 0)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/tests/classes/com/hp/mwtests/ts/arjuna/reaper/ReaperTestCaseControl.java	2009-09-08 16:10:02 UTC (rev 29253)
@@ -0,0 +1,194 @@
+package com.hp.mwtests.ts.arjuna.reaper;
+
+import com.arjuna.ats.arjuna.coordinator.Reapable;
+import com.arjuna.ats.arjuna.coordinator.ActionStatus;
+import com.arjuna.ats.arjuna.common.Uid;
+
+/**
+ * class which provides control methods inherited by the reaper test classes. these methods can be
+ * used to enable, disable and trigger execution of byteman rules which regulate progress of the reaper
+ * and reaper worker thread as the reaper tests progress. they rely on the code being run in a JVM
+ * using the byteman agent with a suitable rule script which performs the desired actions when these
+ * methods are called. See script reaper.txt for the corresponding rules.
+ */
+public class ReaperTestCaseControl
+{
+    /**
+     * called to enable a rendezvous with count 2. this method works by triggering a rule which calls
+     * Byteman helper builtin createRendezvous(o, 2, repeatable)
+     * @param o the key identifying the rendezvous
+     * @param repeatable whether the created rendezvous should be repeatable or not
+     */
+    protected void enableRendezvous(Object o, boolean repeatable)
+    {
+        // do nothing this is just used for rule triggering
+    }
+
+    /**
+     * called to delete a rendezvous with count 2. this method works by triggering a rule which calls
+     * Byteman helper builtin deleteRendezvous(o, 2)
+     * @param o the key identifying the rendezvous
+     */
+    protected void disableRendezvous(Object o)
+    {
+        // do nothing this is just used for rule triggering
+    }
+
+    /**
+     * called to trigger entry into a rendezvous with count 2. this method works by triggering a rule which
+     * calls Byteman helper builtin rendezvous(o). The assumption is that the code under test will also be
+     * trying to enter the rendezvous.
+     * @param o the key identifying the rendezvous
+     */
+    protected void triggerRendezvous(Object o)
+    {
+        // do nothing this is just used for rule triggering
+    }
+
+    /**
+     * called to trigger a delay. this method works by triggering a rule which calls Byteman helper builtin
+     * delay(msecs).
+     * @param msecs the number of milliseconds for which the thread should delay
+     */
+    protected void triggerWait(int msecs)
+    {
+        // do nothing this is just used for rule triggering
+    }
+
+    /**
+     * called to test a rule system flag and clear it at the same time. this method works by triggering a rule
+     * which calls Byteman helper builtin clear(o)
+     * @param o the key which identifies the rule system flag to be tested and cleared
+     */
+    protected boolean checkAndClearFlag(Object o)
+    {
+        // return false by default -- rule system will intercept and return the relevant flag
+        // setting
+
+        return false;
+    }
+
+    /**
+     * reapable which can be controlled using rule actions driven by the test class
+     */
+    public class TestReapable implements Reapable
+    {
+        /**
+         * create a mock reapable
+         * @param uid
+         * @param doCancel true if the reapable should return ABORTED from the cancel call and false if it should
+ * return RUNNING
+         * @param rendezvousInCancel true iff the reapable should rendezvous with the test code when cancel is called
+         * @param doRollback the value that the reapable should return true from the prevent_commit call
+         * @param rendezvousInInterrupt  true iff the reapable should rendezvous with the test code when it is
+         */
+        public TestReapable(Uid uid, boolean doCancel, boolean rendezvousInCancel, boolean doRollback, boolean rendezvousInInterrupt)
+        {
+            this.uid = uid;
+            this.rendezvousInCancel = rendezvousInCancel;
+            this.rendezvousInInterrupt = rendezvousInInterrupt;
+            this.doCancel = doCancel;
+            this.doRollback = doRollback;
+            cancelTried = false;
+            rollbackTried = false;
+            running = true;
+        }
+
+        public boolean running()
+        {
+            return getRunning();
+        }
+
+        public boolean preventCommit()
+        {
+            setRollbackTried();
+
+            if (rendezvousInInterrupt) {
+                triggerRendezvous(uid);
+                triggerRendezvous(uid);
+            }
+
+            clearRunning();
+            return doRollback;
+        }
+
+        public int cancel()
+        {
+            boolean interrupted = false;
+
+            setCancelTried();
+
+            // track the worker trying to do the cancel so we can
+            // detect if it becomes a zombie
+
+            setCancelThread(Thread.currentThread());
+
+            if (rendezvousInCancel) {
+                triggerRendezvous(uid);
+                triggerRendezvous(uid);
+            }
+
+            if (doCancel) {
+                clearRunning();
+                return ActionStatus.ABORTED;
+            } else {
+                return ActionStatus.RUNNING;
+            }
+        }
+
+        public Uid get_uid()
+        {
+            return uid;
+        }
+
+        private Uid uid;
+        private boolean doCancel;
+        private boolean doRollback;
+        private boolean rendezvousInCancel;
+        private boolean rendezvousInInterrupt;
+        private boolean cancelTried;
+        private boolean rollbackTried;
+        private boolean running;
+        private Thread cancelThread;
+
+        public synchronized void setCancelTried()
+        {
+            cancelTried = true;
+        }
+
+        public synchronized boolean getCancelTried()
+        {
+            return cancelTried;
+        }
+
+        public synchronized void setCancelThread(Thread cancelThread)
+        {
+            this.cancelThread = cancelThread;
+        }
+
+        public synchronized Thread getCancelThread()
+        {
+            return cancelThread;
+        }
+
+        public synchronized void setRollbackTried()
+        {
+            rollbackTried = true;
+        }
+
+        public synchronized boolean getRollbackTried()
+        {
+            return rollbackTried;
+        }
+
+        public synchronized void clearRunning()
+        {
+            running = false;
+        }
+
+        public synchronized boolean getRunning()
+        {
+            return running;
+        }
+    }
+}



More information about the jboss-svn-commits mailing list