[jboss-svn-commits] JBL Code SVN: r28306 - in labs/jbosstm/trunk: ArjunaCore/arjuna and 2 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Wed Jul 22 09:21:15 EDT 2009


Author: adinn
Date: 2009-07-22 09:21:15 -0400 (Wed, 22 Jul 2009)
New Revision: 28306

Modified:
   labs/jbosstm/trunk/ArjunaCore/arjuna/build.xml
   labs/jbosstm/trunk/ArjunaCore/arjuna/tests/byteman-scripts/objectstore.txt
   labs/jbosstm/trunk/ArjunaCore/arjuna/tests/byteman-scripts/reaper.txt
   labs/jbosstm/trunk/ArjunaCore/arjuna/tests/byteman-scripts/recovery.txt
   labs/jbosstm/trunk/ArjunaCore/arjuna/tests/classes/com/hp/mwtests/ts/arjuna/reaper/ReaperMonitorTest.java
   labs/jbosstm/trunk/ArjunaCore/arjuna/tests/classes/com/hp/mwtests/ts/arjuna/reaper/ReaperTestCase.java
   labs/jbosstm/trunk/sharedbuild.xml
Log:
ensured desired synchronization for 2 reaper tests via byteman scripts, fixed timing issue in recovery test, added extra check to objectstore test and modified sharedbuild run.tests macro so that it allows output to be displayed by setting attribute showoutput=true -- fixes for JBTM-576

Modified: labs/jbosstm/trunk/ArjunaCore/arjuna/build.xml
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/build.xml	2009-07-22 13:08:56 UTC (rev 28305)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/build.xml	2009-07-22 13:21:15 UTC (rev 28306)
@@ -58,9 +58,9 @@
                     <exclude name="**/ReaperTestCase3.java"/>
                     <!-- tests which have been modified to run using byteman scripts -->
                     <exclude name="**/reaper/ReaperMonitorTest.java"/>
+                    <exclude name="**/reaper/ReaperTestCase.java"/>
                     <exclude name="**/objectstore/LogStoreRecoveryTest.java"/>
                     <exclude name="**/objectstore/LogStoreTest2.java"/>
-                    <exclude name="**/recovery/RecoveryManagerStartStopTest.java"/>
                 </fileset>
             </tests>
         </run.tests.macro>
@@ -69,6 +69,7 @@
             <tests>
                 <fileset dir="tests/classes">
                     <include name="**/reaper/ReaperMonitorTest.java"/>
+                    <include name="**/reaper/ReaperTestCase.java"/>
                 </fileset>
             </tests>
             <!--

Modified: labs/jbosstm/trunk/ArjunaCore/arjuna/tests/byteman-scripts/objectstore.txt
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/tests/byteman-scripts/objectstore.txt	2009-07-22 13:08:56 UTC (rev 28305)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/tests/byteman-scripts/objectstore.txt	2009-07-22 13:21:15 UTC (rev 28306)
@@ -34,6 +34,7 @@
 IF TRUE
 DO debug("LogStore waiting before purge"),
    waitFor("LogStore.purge"),
+   flag("LogStore do purge"),
    debug("LogStore proceeding with purge")
 ENDRULE
 
@@ -48,6 +49,7 @@
 IF TRUE
 DO debug("Signalling purge complete"),
    signalWake("LogStore.purged", true),
+   flag("LogStore done purge"),
    debug("Signalled purge complete")
 ENDRULE
 
@@ -77,6 +79,17 @@
    debug("Purge completed")
 ENDRULE
 
+# throw an error if the purge did not start and finish correctly
+
+RULE log store recovery test throw error if not purged
+CLASS com.hp.mwtests.ts.arjuna.objectstore.LogStoreRecoveryTest
+METHOD test()
+AT EXIT
+BIND NOTHING
+IF !(flagged("LogStore do purge") && flagged("LogStore done purge"))
+DO throw RuntimeException("failed to run purge")
+ENDRULE
+
 #########################################################################
 # LogStoreTest2 wants to delay the purge until it is ready for it
 # and then delay proceeding with the test until the purge has actually

Modified: labs/jbosstm/trunk/ArjunaCore/arjuna/tests/byteman-scripts/reaper.txt
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/tests/byteman-scripts/reaper.txt	2009-07-22 13:08:56 UTC (rev 28305)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/tests/byteman-scripts/reaper.txt	2009-07-22 13:21:15 UTC (rev 28306)
@@ -9,43 +9,173 @@
 # rules to control progress of the transaction reaper thread
 #
 
-# rule to pause the reaper thread inside its check method before it processes
-# a timed out entry. this rule also counts how many times this point has been
-# reached allowing other rules to ensure that they know which reapable is being
-# processes. It also signals before waiting so that other rules can delay until
-# this point is reached.
+# for each possible point at which a client may want to pause the
+# reaper check if a rendezvous has been set up and if so make the
+# reaper rendezvous twice so the client can latch it and then unleash it
 
-RULE pause transaction reaper
+# rendezvous before checking the reaper element queue
+
+RULE pause transaction reaper 1
 CLASS com.arjuna.ats.arjuna.coordinator.TransactionReaper
 METHOD check
+AT CALL first()
+BIND NOTHING
+IF isRendezvous("reaper1", 2)
+DO debug("reaper1"),
+   rendezvous("reaper1"),
+   debug("reaper1"),
+   rendezvous("reaper1")
+ENDRULE
+
+# rendezvous before processing a timed out reaper element
+
+RULE pause transaction reaper 2
+CLASS com.arjuna.ats.arjuna.coordinator.TransactionReaper
+METHOD check
 AT READ _status
-BIND reaper: TransactionReaper = $0,
-     element : ReaperElement = $e
-IF isRendezvous(reaper, 2)
-DO createCounter(element, 0),
-   rendezvous(reaper)
+BIND NOTHING
+IF isRendezvous("reaper2", 2)
+DO debug("reaper2"),
+   rendezvous("reaper2"),
+   debug("reaper2"),
+   rendezvous("reaper2")
 ENDRULE
 
+# rendezvous before queueing in the worker queue a timed out reaper element tagged for cancellation
+
+RULE pause transaction reaper 3
+CLASS com.arjuna.ats.arjuna.coordinator.TransactionReaper
+METHOD check
+AT CALL add 2
+BIND NOTHING
+IF isRendezvous("reaper3", 2)
+DO debug("reaper3"),
+   rendezvous("reaper3"),
+   debug("reaper3"),
+   rendezvous("reaper3")
+ENDRULE
+
+# rendezvous before rescheduling checkup on a timed out reaper element tagged for cancellation
+
+RULE pause transaction reaper 4
+CLASS com.arjuna.ats.arjuna.coordinator.TransactionReaper
+METHOD check
+AT CALL add 3
+BIND NOTHING
+IF isRendezvous("reaper4", 2)
+DO debug("reaper4"),
+   rendezvous("reaper4"),
+   debug("reaper4"),
+   rendezvous("reaper4")
+ENDRULE
+
+# rendezvous before interrupting a timed out reaper element tagged for cancellation
+
+RULE pause transaction reaper 5
+CLASS com.arjuna.ats.arjuna.coordinator.TransactionReaper
+METHOD check
+AT CALL interrupt
+BIND NOTHING
+IF isRendezvous("reaper5", 2)
+DO debug("reaper5"),
+   rendezvous("reaper5"),
+   debug("reaper5"),
+   rendezvous("reaper5")
+ENDRULE
+
+# rendezvous before setting a worker thread to be a zombie
+
+RULE pause transaction reaper 6
+CLASS com.arjuna.ats.arjuna.coordinator.TransactionReaper
+METHOD check
+AT WRITE _status 3
+BIND NOTHING
+IF isRendezvous("reaper6", 2)
+DO debug("reaper6"),
+   rendezvous("reaper6"),
+   debug("reaper6"),
+   rendezvous("reaper6")
+ENDRULE
+
+# rendezvous before calling prevent commit on a reaper element tagged cancel interrupted
+
+RULE pause transaction reaper 7
+CLASS com.arjuna.ats.arjuna.coordinator.TransactionReaper
+METHOD check
+AT WRITE _status 3
+BIND NOTHING
+IF isRendezvous("reaper7", 2)
+DO debug("reaper7"),
+   rendezvous("reaper7"),
+   debug("reaper7"),
+   rendezvous("reaper7")
+ENDRULE
+
 #########################################################################
-# rules to control progress of the transaction reaper worker threads
+# rules to control progress of the transaction reaper worker thread
 #
 
-# this rule makes sure the reaper worker thread pauses before starting
-# to process a queued reapable. this rule alsoadds a counter associated
-# with the reapable which is incremented as the status of the reapable
-# changes to reflect the new state.
+# for each possible point at which a client may want to pause the
+# reaper worker thread check if a rendezvous has been set up and if so
+# make the reaper worker rendezvous twice so the client can latch it and
+# then unleash it
 
-RULE pause transaction reaper worker
+# rendezvous before removing an element from the reaper element queue
+
+RULE pause transaction reaper worker 1
 CLASS com.arjuna.ats.arjuna.coordinator.TransactionReaper
 METHOD doCancellations
-AT READ _control
-BIND element : ReaperElement = $e,
-     worker : Thread = element._worker
-IF isRendezvous(worker, 2)
-DO incrementCounter(worker),
-   rendezvous(worker, 2)
+AT SYNCHRONIZE
+BIND NOTHING
+IF isRendezvous("reaperworker1", 2)
+DO debug("reaperworker1"),
+   rendezvous("reaperworker1"),
+   debug("reaperworker1"),
+   rendezvous("reaperworker1")
 ENDRULE
 
+# rendezvous before marking an element as CANCELLED
+
+RULE pause transaction reaper worker 2
+CLASS com.arjuna.ats.arjuna.coordinator.TransactionReaper
+METHOD doCancellations
+AT SYNCHRONIZE 2
+BIND NOTHING
+IF isRendezvous("reaperworker2", 2)
+DO debug("reaperworker2"),
+   rendezvous("reaperworker2"),
+   debug("reaperworker2"),
+   rendezvous("reaperworker2")
+ENDRULE
+
+# rendezvous before calling cancel on an element
+
+RULE pause transaction reaper worker 3
+CLASS com.arjuna.ats.arjuna.coordinator.TransactionReaper
+METHOD doCancellations
+AT CALL cancel
+BIND NOTHING
+IF isRendezvous("reaperworker3", 2)
+DO debug("reaperworker3"),
+   rendezvous("reaperworker3"),
+   debug("reaperworker3"),
+   rendezvous("reaperworker3")
+ENDRULE
+
+# rendezvous before calling prevent_commit on an element
+
+RULE pause transaction reaper worker 4
+CLASS com.arjuna.ats.arjuna.coordinator.TransactionReaper
+METHOD doCancellations
+AT CALL prevent_commit
+BIND NOTHING
+IF isRendezvous("reaperworker4", 2)
+DO debug("reaperworker4"),
+   rendezvous("reaperworker4"),
+   debug("reaperworker4"),
+   rendezvous("reaperworker4")
+ENDRULE
+
 #########################################################################
 #
 # rules appropriate to specific tests
@@ -57,10 +187,10 @@
 RULE ReaperMonitorTest reaper remote control
 CLASS com.hp.mwtests.ts.arjuna.reaper.ReaperMonitorTest
 METHOD test()
-AT CALL AtomicAction.begin
+AT CALL TransactionReaper.insert
 BIND NOTHING
 IF TRUE
-DO createRendezvous($reaper, 2)
+DO createRendezvous("reaper1", 2, true)
 ENDRULE
 
 # ReaperMonitorTest wants to delay the reaper check until it has inserted
@@ -72,5 +202,78 @@
 AFTER CALL TransactionReaper.insert
 BIND NOTHING
 IF TRUE
-DO rendezvous($reaper)
+DO debug("reaper1"),
+   rendezvous("reaper1"),
+   # ensure timed out
+   delay(1000),
+   debug("reaper1"),
+   rendezvous("reaper1")
 ENDRULE
+
+#########################################################################
+# ReaperTestCase wants to ensure that the reaper is single stepped
+# through processing of inserted reaper elements
+#
+
+RULE ReaperTestCase enable trigger rendezvous
+CLASS com.hp.mwtests.ts.arjuna.reaper.ReaperTestCase
+METHOD enableRendezvous(Object, boolean)
+AT ENTRY
+BIND NOTHING
+IF TRUE
+DO createRendezvous($1, 2, $2)
+ENDRULE
+
+# if the supplied string matches a known rendezvous then trigger it
+
+RULE ReaperTestCase rendezvous
+CLASS com.hp.mwtests.ts.arjuna.reaper.ReaperTestCase
+METHOD triggerRendezvous(Object)
+AT ENTRY
+BIND NOTHING
+IF isRendezvous($1, 2)
+DO debug("" + $1),
+   rendezvous($1),
+   return
+ENDRULE
+
+RULE ReaperTestCase rendezvous 2
+CLASS com.hp.mwtests.ts.arjuna.reaper.ReaperTestCase
+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 ReaperTestCase wait
+CLASS com.hp.mwtests.ts.arjuna.reaper.ReaperTestCase
+METHOD triggerWait(int)
+AT ENTRY
+BIND NOTHING
+IF TRUE
+DO debug("wait " + $1),
+   delay($1),
+   return
+ENDRULE
+
+# debug tracing rules
+# RULE ReaperTestCase trace element remove
+# CLASS com.arjuna.ats.arjuna.coordinator.TransactionReaper
+# METHOD doCancellations
+# AT CALL removeElement
+# BIND NOTHING
+# IF TRUE
+# DO debug("removing reapable " + $e)
+# ENDRULE
+
+# RULE ReaperTestCase trace element add
+# CLASS com.arjuna.ats.arjuna.coordinator.TransactionReaper
+# METHOD check
+# AT CALL List.add
+# BIND NOTHING
+# IF TRUE
+# DO debug("adding reapable " + $e)
+# ENDRULE

Modified: labs/jbosstm/trunk/ArjunaCore/arjuna/tests/byteman-scripts/recovery.txt
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/tests/byteman-scripts/recovery.txt	2009-07-22 13:08:56 UTC (rev 28305)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/tests/byteman-scripts/recovery.txt	2009-07-22 13:21:15 UTC (rev 28306)
@@ -42,6 +42,9 @@
 # the periodic recovery worker service has started running
 #
 
+# set up the PR listener rendezvous and add a rendezvous
+# for the Connection class to enter once it is started
+
 RULE RecoveryManagerStartStopTest create rendezvous
 CLASS com.hp.mwtests.ts.arjuna.recovery.RecoveryManagerStartStopTest
 METHOD testStartStop()
@@ -49,9 +52,13 @@
 BIND NOTHING
 IF TRUE
 DO debug("create rendezvous for PR listener run"),
-   createRendezvous("PR listener run", 2)
+   createRendezvous("PR listener run", 2),
+   createRendezvous("RecoveryManagerStartStopTest Connection run", 3)
 ENDRULE
 
+# rendezvous with the PR listener to make sure it has started before
+# any listener clients are added
+
 RULE RecoveryManagerStartStopTest rendezvous before adding clients
 CLASS com.hp.mwtests.ts.arjuna.recovery.RecoveryManagerStartStopTest
 METHOD testStartStop()
@@ -62,3 +69,29 @@
    rendezvous("PR listener run")
 ENDRULE
 
+# make the connection threads rendezvous with the test thread
+
+RULE RecoveryManagerStartStopTest connection rendezvous at run
+CLASS com.arjuna.ats.internal.arjuna.recovery.Connection
+METHOD run()
+AT CALL doWork
+BIND NOTHING
+IF isRendezvous("RecoveryManagerStartStopTest Connection run", 3)
+DO debug("connection rendezvous at doWork"),
+   rendezvous("RecoveryManagerStartStopTest Connection run")
+ENDRULE
+
+# make the test threads rendezvous with the connection thread
+# this ensures the shutdown does not happen until the connection threads
+# have started running
+
+RULE RecoveryManagerStartStopTest rendezvous after client connections started
+CLASS com.hp.mwtests.ts.arjuna.recovery.RecoveryManagerStartStopTest
+METHOD testStartStop()
+AFTER CALL addRecoveryClient 2
+BIND NOTHING
+IF TRUE
+DO debug("RecoveryManagerStartStopTest rendezvous after 2nd addRecoveryClient"),
+   rendezvous("RecoveryManagerStartStopTest Connection run")
+ENDRULE
+

Modified: labs/jbosstm/trunk/ArjunaCore/arjuna/tests/classes/com/hp/mwtests/ts/arjuna/reaper/ReaperMonitorTest.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/tests/classes/com/hp/mwtests/ts/arjuna/reaper/ReaperMonitorTest.java	2009-07-22 13:08:56 UTC (rev 28305)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/tests/classes/com/hp/mwtests/ts/arjuna/reaper/ReaperMonitorTest.java	2009-07-22 13:21:15 UTC (rev 28306)
@@ -80,7 +80,7 @@
         /*
          * the reaper byteman script will make sure we synchronize with the reaper after this call
          * just before it schedules the reapable for processing. the timout in the check method is
-         * there in case something is really wrong and the reapabel does not get cancelled
+         * there in case something is really wrong and the reapable does not get cancelled
          */
         reaper.insert(A, 1);
 

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-07-22 13:08:56 UTC (rev 28305)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/tests/classes/com/hp/mwtests/ts/arjuna/reaper/ReaperTestCase.java	2009-07-22 13:21:15 UTC (rev 28306)
@@ -93,22 +93,76 @@
 
         // test reaping
         reaper.insert(reapable, 1); // seconds
-        reaper.insert(reapable2, 5);
+        reaper.insert(reapable2, 2);
+
+        // enable a repeatable rendezvous before checking the worker queue
+        enableRendezvous("reaper1", true);
+        // enable a repeatable rendezvous before scheduling a reapable in the worker queue for cancellation
+        enableRendezvous("reaper2", true);
+        // enable a repeatable rendezvous before checking the worker queue
+        enableRendezvous("reaperworker1", true);
+
+        // the reaper will be latched before it processes any of the reapables
+        triggerRendezvous("reaper1");
         assertEquals(2, reaper.numberOfTransactions());
         assertEquals(2, reaper.numberOfTimeouts());
-        reaper.check();
+        // ensure we have waited at lest 1 second so the first reapable is timed out
+        triggerWait(1000);
+        // let the reaper proceed with the dequeue and add the entry to the work queue
+        triggerRendezvous("reaper1");
+        triggerRendezvous("reaper2");
+        triggerRendezvous("reaper2");
+        // now latch the reaper worker at the dequeue
+        triggerRendezvous("reaperworker1");
+        // we shoudl still have two reapables in the reaper queue
         assertEquals(2, reaper.numberOfTransactions());
-        Thread.sleep(2 * 1000);
-        reaper.check();
+        assertEquals(2, reaper.numberOfTimeouts());
+        // now let the worker process the work queue element -- it should not call cancel since the
+        // mock reapable will not claim to be running
+        triggerRendezvous("reaperworker1");
+        // latch the reaper and reaper worker before they check their respective queues
+        // latch the reaper before it dequeues the next reapable
+        triggerRendezvous("reaper1");
+        triggerRendezvous("reaperworker1");
+        // we should now have only 1 element in the reaper queue
         assertEquals(1, reaper.numberOfTransactions());
         assertEquals(1, reaper.numberOfTimeouts());
-        Thread.sleep(4 * 1000);
-        reaper.check();
+        // ensure we have waited at lest 1 second so the second reapable is timed out
+        triggerWait(1000);
+        // now let the reaper proceed with the next dequeue and enqueue the reapable for the worker to process
+        triggerRendezvous("reaper1");
+        triggerRendezvous("reaper2");
+        triggerRendezvous("reaper2");
+        // relatch the reaper next time round the loop so we can be sure it is not monkeying around
+        // with the transactions queue
+        triggerRendezvous("reaper1");
+        // the worker is still latched so we should still have one entry in the work queue
+        assertEquals(1, reaper.numberOfTransactions());
+        assertEquals(1, reaper.numberOfTimeouts());
+        // now let the worker process the work queue element -- it should not call cancel since the
+        // mock reapable wil not claim to be running
+        triggerRendezvous("reaperworker1");
+        // latch reaper worker again so we know it has finished processing the element
+        triggerRendezvous("reaperworker1");
         assertEquals(0, reaper.numberOfTransactions());
         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/sharedbuild.xml
===================================================================
--- labs/jbosstm/trunk/sharedbuild.xml	2009-07-22 13:08:56 UTC (rev 28305)
+++ labs/jbosstm/trunk/sharedbuild.xml	2009-07-22 13:21:15 UTC (rev 28306)
@@ -384,6 +384,7 @@
 
     <macrodef name="run.tests.macro">
         <attribute name="script" default=""/>
+        <attribute name="showoutput" default="false"/>
         <element name="tests"/>
         <element name="additional.classpath" optional="true"/>
         <element name="additional.jvmargs" optional="true"/>
@@ -391,7 +392,7 @@
 	    <if>
             <equals  arg1="@{script}" arg2=""/>
             <then>
-                <run.tests.macro.aux>
+                <run.tests.macro.aux showoutput="@{showoutput}">
                     <tests.aux>
                         <tests/>
                     </tests.aux>
@@ -404,7 +405,7 @@
                 </run.tests.macro.aux>
             </then>
             <else>
-                <run.tests.macro.aux>
+                <run.tests.macro.aux  showoutput="@{showoutput}">
                     <tests.aux>
                         <tests/>
                     </tests.aux>
@@ -425,6 +426,7 @@
 
     <macrodef name="run.tests.macro.aux">
 
+        <attribute name="showoutput" default="false"/>
         <element name="tests.aux"/>
         <element name="additional.classpath.aux" optional="true"/>
         <element name="additional.jvmargs.aux" optional="true"/>
@@ -437,7 +439,7 @@
         <copy file="${sharedbuild.base.dir}/ArjunaCore/arjuna/etc/log4j.properties" todir="${build.dir}/classes"/>
 
         <mkdir dir="${build.dir}/testresults"/>
-        <junit printsummary="yes" fork="yes" dir="${build.dir}">
+        <junit printsummary="yes" fork="yes" dir="${build.dir}" showoutput="@{showoutput}">
             <formatter type="plain"/>
             <classpath>
                 <pathelement location="etc"/>



More information about the jboss-svn-commits mailing list