[jboss-svn-commits] JBL Code SVN: r37804 - in labs/jbosstm/trunk/XTS/localjunit/crash-recovery-tests/src: test/java/com/arjuna/qa/junit and 1 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Thu Dec 15 02:52:45 EST 2011


Author: zhfeng
Date: 2011-12-15 02:52:45 -0500 (Thu, 15 Dec 2011)
New Revision: 37804

Added:
   labs/jbosstm/trunk/XTS/localjunit/crash-recovery-tests/src/test/java/com/arjuna/qa/junit/TestATHeuristicRecoveryAfterDelayedCommit.java
   labs/jbosstm/trunk/XTS/localjunit/crash-recovery-tests/src/test/java/com/arjuna/qa/junit/TestATParticipantCrashAndRecover.java
   labs/jbosstm/trunk/XTS/localjunit/crash-recovery-tests/src/test/java/com/arjuna/qa/junit/TestATSubordinateCrashDuringCommit.java
   labs/jbosstm/trunk/XTS/localjunit/crash-recovery-tests/src/test/java/com/arjuna/qa/junit/TestATSubordinateCrashDuringPrepare.java
   labs/jbosstm/trunk/XTS/localjunit/crash-recovery-tests/src/test/resources/scripts/ATParticipantCrashAndRecover.txt
   labs/jbosstm/trunk/XTS/localjunit/crash-recovery-tests/src/test/resources/scripts/ATSubordinateCrashDuringCommit.txt
   labs/jbosstm/trunk/XTS/localjunit/crash-recovery-tests/src/test/resources/scripts/ATSubordinateCrashDuringPrepare.txt
   labs/jbosstm/trunk/XTS/localjunit/crash-recovery-tests/src/test/resources/scripts/BACrashDuringCommit.txt
   labs/jbosstm/trunk/XTS/localjunit/crash-recovery-tests/src/test/resources/scripts/BACrashDuringOnePhaseCommit.txt
   labs/jbosstm/trunk/XTS/localjunit/crash-recovery-tests/src/test/resources/scripts/BASubordinateCrashDuringCommit.txt
   labs/jbosstm/trunk/XTS/localjunit/crash-recovery-tests/src/test/resources/scripts/BASubordinateCrashDuringCommitAfterSubordinateExit.txt
   labs/jbosstm/trunk/XTS/localjunit/crash-recovery-tests/src/test/resources/scripts/BASubordinateCrashDuringComplete.txt
Modified:
   labs/jbosstm/trunk/XTS/localjunit/crash-recovery-tests/src/main/java/com/arjuna/qa/extension/JBossAS7ServerKillProcessor.java
Log:
JBTM-817 update to add remaining AT tests and byteman scripts

Modified: labs/jbosstm/trunk/XTS/localjunit/crash-recovery-tests/src/main/java/com/arjuna/qa/extension/JBossAS7ServerKillProcessor.java
===================================================================
--- labs/jbosstm/trunk/XTS/localjunit/crash-recovery-tests/src/main/java/com/arjuna/qa/extension/JBossAS7ServerKillProcessor.java	2011-12-14 21:54:18 UTC (rev 37803)
+++ labs/jbosstm/trunk/XTS/localjunit/crash-recovery-tests/src/main/java/com/arjuna/qa/extension/JBossAS7ServerKillProcessor.java	2011-12-15 07:52:45 UTC (rev 37804)
@@ -44,6 +44,7 @@
 				killed = true;
 				break;
 			}
+			checkn ++;
 		} while(checkn < numofCheck);
 		
 		if(killed) {

Added: labs/jbosstm/trunk/XTS/localjunit/crash-recovery-tests/src/test/java/com/arjuna/qa/junit/TestATHeuristicRecoveryAfterDelayedCommit.java
===================================================================
--- labs/jbosstm/trunk/XTS/localjunit/crash-recovery-tests/src/test/java/com/arjuna/qa/junit/TestATHeuristicRecoveryAfterDelayedCommit.java	                        (rev 0)
+++ labs/jbosstm/trunk/XTS/localjunit/crash-recovery-tests/src/test/java/com/arjuna/qa/junit/TestATHeuristicRecoveryAfterDelayedCommit.java	2011-12-15 07:52:45 UTC (rev 37804)
@@ -0,0 +1,26 @@
+package com.arjuna.qa.junit;
+
+import org.jboss.arquillian.junit.Arquillian;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+ at RunWith(Arquillian.class)
+public class TestATHeuristicRecoveryAfterDelayedCommit extends BaseCrashTest {
+	public TestATHeuristicRecoveryAfterDelayedCommit() {
+		scriptName ="ATHeuristicRecoveryAfterDelayedCommit";
+	}
+	
+	@Test
+	public void MultiParticipantPrepareAndCommitTest() throws Exception {
+		testName = "MultiParticipantPrepareAndCommitTest";
+		String testClass = "org.jboss.jbossts.xts.servicetests.test.at.MultiParticipantPrepareAndCommitTest";
+		runTest(testClass);
+	}
+	
+	@Test
+	public void MultiServicePrepareAndCommitTest() throws Exception {
+		testName = "MultiServicePrepareAndCommitTest";
+		String testClass = "org.jboss.jbossts.xts.servicetests.test.at.MultiServicePrepareAndCommitTest";
+		runTest(testClass);
+	}
+}


Property changes on: labs/jbosstm/trunk/XTS/localjunit/crash-recovery-tests/src/test/java/com/arjuna/qa/junit/TestATHeuristicRecoveryAfterDelayedCommit.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: labs/jbosstm/trunk/XTS/localjunit/crash-recovery-tests/src/test/java/com/arjuna/qa/junit/TestATParticipantCrashAndRecover.java
===================================================================
--- labs/jbosstm/trunk/XTS/localjunit/crash-recovery-tests/src/test/java/com/arjuna/qa/junit/TestATParticipantCrashAndRecover.java	                        (rev 0)
+++ labs/jbosstm/trunk/XTS/localjunit/crash-recovery-tests/src/test/java/com/arjuna/qa/junit/TestATParticipantCrashAndRecover.java	2011-12-15 07:52:45 UTC (rev 37804)
@@ -0,0 +1,37 @@
+package com.arjuna.qa.junit;
+
+import org.jboss.arquillian.junit.Arquillian;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+ at RunWith(Arquillian.class)
+public class TestATParticipantCrashAndRecover extends BaseCrashTest {
+	public TestATParticipantCrashAndRecover() {
+		scriptName = "ATParticipantCrashAndRecover";
+	}
+	
+	@Ignore("Not complete")
+	@Test
+	public void SingleParticipantPrepareAndCommit() throws Exception {
+		testName = "SingleParticipantPrepareAndCommit";
+		String testClass = "org.jboss.jbossts.xts.servicetests.test.at.SingleParticipantPrepareAndCommitTest";
+		runTest(testClass);
+	}
+	
+	@Ignore("Not complete")
+	@Test
+	public void MultiParticipantPrepareAndCommitTest() throws Exception {
+		testName = "MultiParticipantPrepareAndCommitTest";
+		String testClass = "org.jboss.jbossts.xts.servicetests.test.at.MultiParticipantPrepareAndCommitTest";
+		runTest(testClass);
+	}
+	
+	@Ignore("Not complete")
+	@Test
+	public void MultiServicePrepareAndCommitTest() throws Exception {
+		testName = "MultiServicePrepareAndCommitTest";
+		String testClass = "org.jboss.jbossts.xts.servicetests.test.at.MultiServicePrepareAndCommitTest";
+		runTest(testClass);
+	}
+}


Property changes on: labs/jbosstm/trunk/XTS/localjunit/crash-recovery-tests/src/test/java/com/arjuna/qa/junit/TestATParticipantCrashAndRecover.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: labs/jbosstm/trunk/XTS/localjunit/crash-recovery-tests/src/test/java/com/arjuna/qa/junit/TestATSubordinateCrashDuringCommit.java
===================================================================
--- labs/jbosstm/trunk/XTS/localjunit/crash-recovery-tests/src/test/java/com/arjuna/qa/junit/TestATSubordinateCrashDuringCommit.java	                        (rev 0)
+++ labs/jbosstm/trunk/XTS/localjunit/crash-recovery-tests/src/test/java/com/arjuna/qa/junit/TestATSubordinateCrashDuringCommit.java	2011-12-15 07:52:45 UTC (rev 37804)
@@ -0,0 +1,19 @@
+package com.arjuna.qa.junit;
+
+import org.jboss.arquillian.junit.Arquillian;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+ at RunWith(Arquillian.class)
+public class TestATSubordinateCrashDuringCommit extends BaseCrashTest {
+	public TestATSubordinateCrashDuringCommit() {
+		scriptName = "ATSubordinateCrashDuringCommit";
+	}
+	
+	@Test
+	public void subordinateMultiParticipantPrepareAndCommitTest() throws Exception {
+		testName = "subordinate.MultiParticipantPrepareAndCommitTest";
+		String testClass = "org.jboss.jbossts.xts.servicetests.test.at.subordinate.MultiParticipantPrepareAndCommitTest";
+		runTest(testClass);
+	}
+}


Property changes on: labs/jbosstm/trunk/XTS/localjunit/crash-recovery-tests/src/test/java/com/arjuna/qa/junit/TestATSubordinateCrashDuringCommit.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: labs/jbosstm/trunk/XTS/localjunit/crash-recovery-tests/src/test/java/com/arjuna/qa/junit/TestATSubordinateCrashDuringPrepare.java
===================================================================
--- labs/jbosstm/trunk/XTS/localjunit/crash-recovery-tests/src/test/java/com/arjuna/qa/junit/TestATSubordinateCrashDuringPrepare.java	                        (rev 0)
+++ labs/jbosstm/trunk/XTS/localjunit/crash-recovery-tests/src/test/java/com/arjuna/qa/junit/TestATSubordinateCrashDuringPrepare.java	2011-12-15 07:52:45 UTC (rev 37804)
@@ -0,0 +1,21 @@
+package com.arjuna.qa.junit;
+
+import org.jboss.arquillian.junit.Arquillian;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+ at RunWith(Arquillian.class)
+public class TestATSubordinateCrashDuringPrepare extends BaseCrashTest {
+	public TestATSubordinateCrashDuringPrepare() {
+		scriptName = "ATSubordinateCrashDuringPrepare";
+	}
+	
+	@Ignore("Not stop with byteman when recovering")
+	@Test
+	public void subordinateMultiParticipantPrepareAndCommitTest() throws Exception {
+		testName = "subordinate.MultiParticipantPrepareAndCommitTest";
+		String testClass = "org.jboss.jbossts.xts.servicetests.test.at.subordinate.MultiParticipantPrepareAndCommitTest";
+		runTest(testClass);
+	}
+}


Property changes on: labs/jbosstm/trunk/XTS/localjunit/crash-recovery-tests/src/test/java/com/arjuna/qa/junit/TestATSubordinateCrashDuringPrepare.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: labs/jbosstm/trunk/XTS/localjunit/crash-recovery-tests/src/test/resources/scripts/ATParticipantCrashAndRecover.txt
===================================================================
--- labs/jbosstm/trunk/XTS/localjunit/crash-recovery-tests/src/test/resources/scripts/ATParticipantCrashAndRecover.txt	                        (rev 0)
+++ labs/jbosstm/trunk/XTS/localjunit/crash-recovery-tests/src/test/resources/scripts/ATParticipantCrashAndRecover.txt	2011-12-15 07:52:45 UTC (rev 37804)
@@ -0,0 +1,296 @@
+##############################################################################
+# JBoss, Home of Professional Open Source
+# Copyright 2008-9, Red Hat Middleware LLC, and individual contributors
+# 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.
+#
+# @authors Andrew Dinn
+#
+# Participant Recovery with Remote Coordinator
+#
+# This script automates testing of a specific recovery scenario for the
+# JBossTS XTS implementation of the WS-AT 1.1 protocol using orchestration
+# rules. The basic scenario employs a client (XTS Service Test program)
+# and 2 web services located in one JVM/AS and a coordinator located in another
+# JVM/AS but it is possible for the client and web services to be located in
+# separate JVMs/ASs. The scenario is as follows (note ** AS<n> indicates
+# intercession by a Byteman rule executed in a specific AS):
+#
+# AS1 boots
+# AS2 boots
+# AS1 Client starts a WS-AT transaction talking to coordinator in AS2
+# AS1 Client invokes web service 1
+# AS1 Web service 1 registers as participant P1
+# AS1 Client invokes web service 2
+# AS1 Web service 2 registers as participant P2
+# AS1 Client commits WS-AT transaction
+#
+# AS2 Coordinator initiates commit of participant P1
+# AS2 Coordinator sends commit to P1
+#
+# AS1 P1 receives commit
+# ** AS1 Rule system intercepts commit and crashes JVM
+#
+# AS2 Coordinator attempts to resend message
+# ** AS2 Rule system suspends coordinator waiting on incoming prepared
+#    message from P1
+#    (commit messages continue to be resent in the meantime)
+#
+# AS1 reboots
+# AS1 Recovery system starts after 2 minutes
+# AS1 Recovery system recreates PREPARED WS-AT participant P1
+# ** AS1 Rule system traces recreate
+# AS1 Participant P1 resends prepared
+# AS1 Participant P1 receives commit for P1
+# AS1 Participant P1 sends committed
+#
+# AS2 Participant stub receives committed message for P1
+# ** AS2 Rule system signals coordinator clearing wait
+# ** AS2 rule system traces receipt of committed message for P1
+#
+# AS2 Coordinator detects committed from P1
+# AS2 Coordinator sends commit for P2
+# AS2 Coordinator receives committed from P2
+# AS2 Coordinator completes transaction
+# ** AS2 Rule system traces successful completion
+#
+# Use of this script
+#
+# The default way of exercising this test is to deploy the xtstest war
+# to AS1 and configure it to run the relevant XTS Service Test. It is
+# actually possible to use 1, 2, 3 or more participants and multiple
+# participants may be registered by a single web service or by independent
+# web services. If required the web service(s) may be located in a a separate
+# AS to the one running the XTS Service test.
+#
+# The test should crash AS1 at the point of commit. At AS1 reboot the rest of
+# the test should run automatically. AS2 should be killed after the
+# transaction is successfuly terminated. Still need to work out how to
+# automatically terminate AS1 automatically but exit of AS2 is a signal
+# that AS1 can be killed.
+#
+# !!! N.B. this test currently fails because JBossWS Native fails to cope
+# !!! with requests for services while they are bootstrapping
+#
+# The JVMs hosting AS1 and AS2 both need to be configured to run a Byteman
+# agent supplied with this script. If the web service(s) is relocated
+# to AS3 then it needs to be configured to run the Byteman agent instead of
+# AS1 (rules only refer to participant and coordinator code, not to the
+# XTS service test code).
+#
+# The client AS (AS1) needs to be pointed at the coordinator AS (AS2). The easiest
+# way to do this is to define the system property
+#
+#    org.jboss.jbossts.xts11.coordinatorURL
+#
+# to something like
+#
+#    http://foo.bar.org:8080/ws-c11/soap/ActivationCoordinator
+#
+# or alternatively to redefine one or more of the component properties
+#
+#    org.jboss.jbossts.xts11.coordinator.host
+#    org.jboss.jbossts.xts11.coordinator.port
+#    org.jboss.jbossts.xts11.coordinator.path
+#
+# (you probably only need to reset the host component)
+#
+# XTS Service tests which can operate with this scenario can be selected for
+# execution at AS boot by the XTSServiceTestRunnerBean by setting system
+# property
+#    org.jboss.jbossts.xts.servicetests.XTSServiceTestName
+# to the name of a class which will execute the test. This property must
+# be defined in AS1, the client AS. n.b. if the client is colocated with
+# the seb service(s) then this property must be left undefined at AS1 reboot
+# otherwise the client will run again, starting a new TX which may interfere
+# with recovery of the crashed participants.
+#
+# Available tests include:
+#
+# org.jboss.jbossts.xts.servicetests.test.at.SingleParticipantPrepareAndCommitTest
+# this test invokes a single web service registering 1 participant
+# the location of service is defined by defining a system property:
+#    org.jboss.jbossts.xts.servicetests.ServiceURL1
+# which should be set to something like
+#    http://baz.bar.org:8080/xtstest/xtsservicetest1
+#
+# org.jboss.jbossts.xts.servicetests.test.at.MultiParticipantPrepareAndCommitTest
+# this test invokes a single service registering 3 participants
+# the location of service is defined by defining a system property:
+#    org.jboss.jbossts.xts.servicetests.ServiceURL1
+# which should be set to something like
+#    http://baz.bar.org:8080/xtstest/xtsservicetest1
+#
+# org.jboss.jbossts.xts.servicetests.test.at.MultiServicePrepareAndCommitTest
+# this test invokes 3 separate services registering a participant for each service
+# the location of service is defined by defining by system properties:
+#    org.jboss.jbossts.xts.servicetests.ServiceURL1
+#    org.jboss.jbossts.xts.servicetests.ServiceURL2
+#    org.jboss.jbossts.xts.servicetests.ServiceURL3
+# which should be set to something like
+#    http://mumble.bar.org:8080/xtstest/xtsservicetest1
+#    http://mumble.bar.org:8080/xtstest/xtsservicetest2
+#    http://mumble.bar.org:8080/xtstest/xtsservicetest3
+# if you are feeling really adventurous you can host the services
+# in different ASs
+#    http://mumble.bar.org:8080/xtstest/xtsservicetest1
+#    http://grumble.bar.org:8080/xtstest/xtsservicetest1
+#    http://bletch.bar.org:8080/xtstest/xtsservicetest1
+#
+# Expected output AS1
+# -------------------
+#
+# After the first boot AS1 should exit leaving the following in file testlog1
+#
+#   JVM exit
+#
+# After reboot AS1 should add output in the following format in file testlog1.
+# Clearly the ids for the TX/participants may vary and the number of
+# ??? lines will depend upon the number of participants employed.
+#
+#   JVM exit
+#   replay commit for prepared transaction 7f000001:cebc:496f3b83:6e
+#   replay commit for heuristic committed transaction 7f000001:cebc:496f3b83:6e
+#   countdown completed for D7f000001:cebc:496f3b83:70
+#   countdown completed for D7f000001:cebc:496f3b83:73
+#   countdown completed for D7f000001:cebc:496f3b83:76
+#   removed committed transaction
+#
+# Expected output AS2
+# -------------------
+# ???
+
+######################################################################
+# AS1 Rule set
+#######################################################################
+# This rule opens a file for the trace output during XTS startup
+# It will be opened for append at reboot so messages from both runs
+# will go to this file
+
+RULE open trace file
+CLASS org.jboss.jbossts.XTSService
+METHOD start()
+BIND NOTHING
+IF TRUE
+DO openTrace("log1", "testlog1")
+ENDRULE
+
+
+#######################################################################
+# This rule is triggered in the AS1 when a non-recovered WS-AT
+# participant receives a commit message. It causes the JVM to crash.
+# The trigger point is the start of the method.
+RULE crash unrecovered participant at commit
+CLASS com.arjuna.wst11.messaging.engines.ParticipantEngine
+METHOD commit
+AT ENTRY
+BIND engine:ParticipantEngine = $0,
+     recovered:boolean = engine.isRecovered(),
+     identifier:String = engine.getId()
+IF (NOT recovered)
+   AND
+   traceln("log", "commit on non-recovered participant engine " + identifier)
+DO traceln("log", "JVM exit"),
+   debug("!!!killing JVM!!!"),
+   killJVM()
+ENDRULE
+
+#######################################################################
+# This rule is triggered in the AS1 when a recovered WS-AT participant
+# is recreated from the log. It traces the call to allow success of the
+# test to be detected.
+# The trigger point is the end of the constructor so that the rule can
+# safely read all the fields.
+
+RULE trace recovered participant recreate
+CLASS com.arjuna.wst11.messaging.engines.ParticipantEngine
+METHOD <init>(Participant, String, State, W3CEndpointReference, boolean)
+AFTER WRITE persisted
+BIND engine:ParticipantEngine = $0,
+     recovered:boolean = engine.isRecovered(),
+     identifier:String = engine.getId()
+IF recovered
+DO traceln("log", "recreated recovered participant engine " + identifier)
+ENDRULE
+
+
+######################################################################
+# AS2 Rule set
+#######################################################################
+# This rule opens a file for the trace output during XTS startup
+
+# RULE open trace file
+# CLASS org.jboss.jbossts.XTSService
+# METHOD start()
+# BIND NOTHING
+# IF TRUE
+# DO openTrace("log2", "testlog2")
+# ENDRULE
+
+######################################################################
+# This rule is triggered in AS2 when a participant stub
+# (CoordinatorEngine) first posts a commit message to the participant.
+# The coordinator thread suspends until a committed message is received
+# from the participant. This ensures that it waits until AS1
+# has restarted allowing the transaction to then complete. The
+# condition tests whether a flag with key "firstCommit" has been set.
+# By default this is clear so the condition is true first time the
+# rule is called. The action sets te flag causing the condition to
+# evaluate to false on subsequent commit calls.
+# The trigger point is just before calling waitForState.
+
+RULE suspend coordinator after sending first commit
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorEngine
+METHOD commit
+LINE 330
+BIND engine:CoordinatorEngine = $0,
+     identifier:String = engine.getId()
+IF (NOT flagged("firstCommit"))
+DO traceln("log", "coordinator waiting for participant to resend prepare" + identifier),
+   flag("firstCommit"),
+   waitFor(identifier)
+ENDRULE
+
+#######################################################################
+
+# This rule is triggered when a committed message is received from P1.
+# This indicates that the participant has been recreated and
+# successfully responded to a commit message after reboot of AS1. The
+# rule uses a call to signal to wake up the coordinator which was
+# suspended when the first commit was sent. This call only returns true
+# if the identifier is for P1 and the coordinator has not already been
+# signalled. Note that the call to signal is made in the condition to
+# avoid a race between threads handling successive committed messages.
+# If instead the condition called waiting() and the action called
+# signal() then, depending upon scheduling, both threads might find the
+# condition to be true before one of them could execute signal().
+# Although this would be harmless in this case it could be significant
+# when using other rules.
+# The triogger point is at the sttart of the method.
+
+RULE signal waiting coordinator
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorEngine
+METHOD committed
+AT ENTRY
+BIND engine : CoordinatorEngine = $0,
+     identifier:String = engine.getId()
+IF debug("received committed for participant " + identifier)
+   AND
+   signalWake(identifier)
+DO traceln("log", "signalled coordinator waiting on " + identifier)
+ENDRULE

Added: labs/jbosstm/trunk/XTS/localjunit/crash-recovery-tests/src/test/resources/scripts/ATSubordinateCrashDuringCommit.txt
===================================================================
--- labs/jbosstm/trunk/XTS/localjunit/crash-recovery-tests/src/test/resources/scripts/ATSubordinateCrashDuringCommit.txt	                        (rev 0)
+++ labs/jbosstm/trunk/XTS/localjunit/crash-recovery-tests/src/test/resources/scripts/ATSubordinateCrashDuringCommit.txt	2011-12-15 07:52:45 UTC (rev 37804)
@@ -0,0 +1,618 @@
+##############################################################################
+# JBoss, Home of Professional Open Source
+# Copyright 2009, Red Hat Middleware LLC, and individual contributors
+# 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.
+#
+# @authors Andrew Dinn
+#
+# AT Subordinate Transaction Crash During Commit
+#
+# This script automates testing of a specific recovery scenario for the
+# JBossTS XTS implementation of the WS-AT 1.1 protocol using orchestration
+# rules. The basic scenario employs a coordinator, a subordinate coordinator
+# and 2 web services running in a single JVM. The scenario is as follows
+# (** indicates intercession by a Byteman rule):
+#
+# AS boots
+# Cient starts a WS-AT transaction T1
+# Client invokes web service 1 with register request
+# Web service 1 registers participant P1 in T2
+# Client requests web service 1 to start a subordinate transaction T2
+# Web service 1 creates a subordinate AT transaction
+# Web service 1 registers pseudo-participant PP2 in T1
+# Client invokes web service 1 with subordinate register command
+# Web service 1 resumes T2 and invokes Web Service 2
+# Web service 2 registers participant P2 in T2
+# Client invokes web service 1 with subordinate register command
+# Web service 1 resumes T2 and invokes Web Service 2
+# Web service 2 registers participant P3 in T2
+#
+# Client initiates transaction commit for T1
+#
+# Coordinator initiates prepare of participant P1
+# ** Rule system logs dispatch of prepare to P1
+# ** Rule system logs receipt of prepared from P1
+# Coordinator initiates prepare of subordinate participant PP1
+# ** Rule system logs dispatch of prepare to P1
+# Subordinate coordinator initiates prepare of participant P2
+# ** Rule system logs dispatch of prepare to P1
+# ** Rule system logs receipt of prepared from P1
+# Subordinate coordinator initiates prepare of participant P3
+# ** Rule system logs dispatch of prepare to P1
+# ** Rule system logs receipt of prepared from P1
+# ** Rule system logs receipt of prepared from PP1
+#
+# Coordinator initiates commit of participant P1
+# ** Rule system intercepts commit and crashes JVM
+#
+# AS reboots
+# Recovery system starts after 2 minutes
+# Recovery system recreates PREPARED WS-AT activity coordinator
+# ** Rule system traces create
+# Recovery system recreates participant stub for P1
+# ** Rule system traces create
+# Recovery system recreates participant stub for PP1
+# ** Rule system traces create
+# Recovery system recreates participant stub for P2
+# ** Rule system traces create
+# Recovery system recreates participant stub for P3
+# ** Rule system traces create
+# Recovery system calls replay of PREPARED transaction
+# ** Rule system traces PREPARED replay invocation
+#
+# Coordinator sends commit to P1
+# P1 replies with committed
+# ** Rule system traces receipt of committed
+#
+# Coordinator sends commit to PP1
+#
+# Subordinate coordinator sends commit to P2
+# P2 replies with committed
+# ** Rule system traces receipt of committed
+#
+# Subordinate oordinator sends commit to P3
+# P3 replies with committed
+# ** Rule system traces receipt of committed
+#
+# PP1 replies with committed
+# ** Rule system traces receipt of committed
+#
+# Coordinator clears log record and completes commit
+# ** Rule system detects completed commit and kills JVM
+#
+# Use of this script
+#
+# The default way of exercising this test is to deploy the xtstest war
+# to a single AS and configure it to run the relevant XTS Service Test.
+# The web services and coordinator will be located with the client.
+# The number of participants and subordinate participants can actually be
+# 2, 3 or more. The  web service(s), client (i.e. the XTS Service Test which
+# drives the test) and coordinator and subordinate coordinator service must
+# be colocated for this scritp to work (it is possible to distribute all of
+# these agents if desired but that woud lrequire more complex script rules).
+# The AS should crash when the client commits. At reboot the rest of the test
+# should run automatically and the server should be killed after the recovered
+# transaction is successfuly replayed.
+#
+# This script needs to be passed to a Byteman agent in the JVM running
+# the coordinator service both at first boot and at reboot. Output will be
+# written to file testlog in the working directory of the AS.
+#
+# XTS Service tests which can operate with this scenario can be selected for
+# execution at AS boot by the XTSServiceTestRunnerBean by setting system
+# property
+#    org.jboss.jbossts.xts.servicetests.XTSServiceTestName
+# to the name of a class which will execute the test. This property must
+# be defined in the JVM running the AS to which the xtstest war is deployed
+# i.e. the client AS. n.b. if the client is colocated with the coordinator then
+# this property must be left undefined at AS reboot otherwise the client
+# will run again, starting a new TX which may interfere with recovery of the
+# crashed TX.
+#
+# Available tests include:
+#
+# org.jboss.jbossts.xts.servicetests.test.at.subordinate.MultiParticipantPrepareAndCommitTest
+# this test invokes a service to register a participant and start the suborindate
+# transaction whose location is defined by defining a system property:
+#    org.jboss.jbossts.xts.servicetests.ServiceURL1
+# if this is not set the value used defaults to
+#    http://localhost:8080/xtstest/xtsservicetest1
+# the test forwards a recursive request for registration in the subordinate tarnsaction
+# to a second web service whose location is defined by defining a system property:
+#    org.jboss.jbossts.xts.servicetests.ServiceURL2
+# if this is not set the value used defaults to
+#    http://localhost:8080/xtstest/xtsservicetest2
+#
+# Expected output
+#
+# After the first boot the JVM should exit leaving the following in file testlog
+#
+#   prepare received for participant XXXXXX
+#   prepared sent for participant XXXXXX
+#   prepare called for pseudo-participant XXXXXX
+#   prepare completed for pseudo-participant XXXXXX
+#   prepare received for participant XXXXXX
+#   prepare received for participant XXXXXX
+#   prepared sent for coordinator engine XXXXXX
+#   prepared sent for coordinator engine XXXXXX
+#   JVM exit
+#
+# n.b. there should be at least one prepared message received for each participant
+# and in some cases there may be repeat messages
+#
+# After reboot the JVM should exit leaving output in the following format in file
+# testlog.
+#
+#   prepare sent for participant engine XXXXXX
+#   prepare received for participant XXXXXX
+#   prepared sent for participant XXXXXX
+#   prepare called for pseudo-participant XXXXXX
+#   prepare completed for pseudo-participant XXXXXX
+#   prepare received for participant XXXXXX
+#   prepare called for pseudo participant XXXXXX
+#   prepare sent for participant engine XXXXXX
+#   prepare received for participant XXXXXX
+#   prepared sent for coordinator engine XXXXXX
+#   prepared sent for coordinator engine XXXXXX
+#   JVM exit
+#   created recovered participant engine XXXXXX
+#   created recovered participant engine XXXXXX
+#   created recovered participant engine XXXXXX
+#   created recovered participant engine XXXXXX
+#   created recovered coordinator engine XXXXXX
+#   created recovered coordinator engine XXXXXX
+#   created recovered coordinator engine XXXXXX
+#   created recovered coordinator engine XXXXXX
+#   received commit for recovered participant engine XXXXXX
+#   send committed for recovered participant engine XXXXXX
+#   received commit for recovered participant engine XXXXXX
+#   commit called for pseudo-participant XXXXXX
+#   received commit for recovered participant engine XXXXXX
+#   send committed for recovered participant engine XXXXXX
+#   received commit for recovered participant engine XXXXXX
+#   send committed for recovered participant engine XXXXXX
+#   commit completed for pseudo-participant XXXXXX
+#   send committed for recovered participant engine XXXXXX
+#   removed committed transaction XXXXXX
+#   JVM exit
+#
+#######################################################################
+# This rule opens a file for the trace output during XTS startup
+# It will be opened for append at reboot so messages from both runs
+# will go to this file
+#
+RULE open trace file
+CLASS org.jboss.jbossts.XTSService
+METHOD start()
+BIND NOTHING
+IF TRUE
+DO openTrace("log", "testlog")
+ENDRULE
+
+#######################################################################
+## rules for first run of AS
+
+#######################################################################
+# This rule is triggered when a non-recovered coordinator engine
+# (CoordinatorEngine) is sent a commit message. It exits the JVM,
+# simulating a crash. The trigger location is on entry
+
+RULE kill JVM at commit
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorEngine
+METHOD commit
+AT ENTRY
+BIND engine:CoordinatorEngine = $0,
+     recovered:boolean = engine.isRecovered(),
+     identifier:String = engine.getId()
+IF (NOT recovered)
+   AND
+   debug("commit on non-recovered coordinator engine " + identifier)
+DO traceln("log", "JVM exit"),
+   debug("!!!killing JVM!!!"),
+   killJVM()
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a non-recovered coordinator engine
+# (CoordinatorEngine) is requested to send a prepare message. It
+# traces the call.
+
+RULE trace send participant prepare
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorEngine
+METHOD prepare
+AFTER SYNCHRONIZE
+BIND engine:CoordinatorEngine = $0,
+     recovered:boolean = engine.isRecovered(),
+     identifier:String = engine.getId()
+IF NOT recovered
+DO debug("prepare sent for coordinator engine " + identifier),
+   traceln("log", "prepare sent for coordinator engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a non-recovered coordinator engine
+# (CoordinatorEngine) receives a prepared message. It traces the call.
+
+RULE trace receive participant prepared
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorEngine
+METHOD prepared(Notification, MAP, ArjunaContext)
+AT ENTRY
+BIND engine:CoordinatorEngine = $0,
+     recovered:boolean = engine.isRecovered(),
+     identifier:String = engine.getId()
+IF NOT recovered
+DO debug("prepared received for coordinator engine " + identifier),
+   traceln("log", "prepared received for coordinator engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a non-recovered participant
+# (ParticipantEngine) receives a prepare message. It
+# traces the call.
+
+RULE trace receive participant prepare
+CLASS com.arjuna.wst11.messaging.engines.ParticipantEngine
+METHOD prepare
+AFTER SYNCHRONIZE
+BIND engine:ParticipantEngine = $0,
+     recovered:boolean = engine.isRecovered(),
+     identifier:String = engine.getId()
+IF NOT recovered
+DO debug("prepare received for participant " + identifier),
+   traceln("log", "prepare received for participant " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a non-recovered participant
+# (ParticipantEngine) is requested to send a prepared message. It
+# traces the call.
+
+RULE trace send participant prepared
+CLASS com.arjuna.wst11.messaging.engines.ParticipantEngine
+METHOD sendPrepared(boolean)
+AT INVOKE sendPrepared
+BIND engine:ParticipantEngine = $0,
+     recovered:boolean = engine.isRecovered(),
+     identifier:String = engine.getId()
+IF NOT recovered
+DO debug("prepared sent for participant " + identifier),
+   traceln("log", "prepared sent for participant " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a subordinate pseudo participant
+# (SubordinateDurable2PCStub) is requested to send a prepare message. It
+# traces the call.
+
+RULE trace subordinate participant stub prepare before
+CLASS com.arjuna.wst11.stub.SubordinateDurable2PCStub
+METHOD prepare
+AT ENTRY
+BIND NOTHING
+IF TRUE
+DO debug("prepare called for pseudo-participant " + $0),
+   traceln("log", "prepare called for pseudo-participant " + $0)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a subordinate pseudo participant
+# (SubordinateDurable2PCStub) is requested to send a prepare message. It
+# traces the call.
+
+RULE trace subordinate participant stub prepare after
+CLASS com.arjuna.wst11.stub.SubordinateDurable2PCStub
+METHOD prepare
+AFTER INVOKE prepare
+BIND NOTHING
+IF TRUE
+DO debug("prepare completed for pseudo-participant " + $0),
+   traceln("log", "prepare completed for pseudo-participant " + $0)
+ENDRULE
+
+#######################################################################
+## rules for reboot run of AS
+
+#######################################################################
+# This rule is triggered when a coordinator engine (CoordinatorEngine)
+# is created from details located in the log record. It traces the
+# create operation. The trigger location is at entry but the rule
+# should only be triggered after calling the super constructor
+RULE trace coordinator engine create
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorEngine
+METHOD <init>(String, boolean, W3CEndpointReference, boolean, State)
+AT ENTRY
+BIND identifier = $1,
+     recovered=$4
+IF recovered
+DO debug("created recovered coordinator engine " + identifier),
+   traceln("log", "created recovered coordinator engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a participant (ParticipantEngine)
+# is created from details located in the log record. It traces the
+# create operation. The trigger location is at entry but the rule
+# should only be triggered after calling the super constructor
+
+RULE trace participant create
+CLASS com.arjuna.wst11.messaging.engines.ParticipantEngine
+METHOD <init>(Participant, String, State, W3CEndpointReference, boolean)
+AT ENTRY
+BIND identifier = $2,
+     recovered=$5
+IF recovered
+DO debug("created recovered participant engine " + identifier),
+   traceln("log", "created recovered participant engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a recovered coordinator engine
+# (CoordinatorEngine) is requested to send a commit message. This
+# happens during replay of a prepared TX from
+# the log. It traces the call.
+
+RULE trace send recovered participant commit
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorEngine
+METHOD commit
+AFTER SYNCHRONIZE
+BIND engine:CoordinatorEngine = $0,
+     recovered:boolean = engine.isRecovered(),
+     identifier:String = engine.getId()
+IF recovered
+DO debug("send commit for recovered coordinator engine " + identifier),
+   traceln("log", "send commit for recovered coordinator engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a recovered coordinator engine
+# (CoordinatorEngine) receives a committed message. This
+# happens during replay of a prepared TX from
+# the log. It traces the call.
+
+RULE trace receive recovered participant committed
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorEngine
+METHOD committed
+AFTER SYNCHRONIZE
+BIND engine:CoordinatorEngine = $0,
+     recovered:boolean = engine.isRecovered(),
+     identifier:String = engine.getId()
+IF recovered
+DO debug("received committed for recovered coordinator engine " + identifier),
+   traceln("log", "received committed for recovered coordinator engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a recovered participant engine
+# (ParticipantEngine) is requested to send a committed message. This
+# happens during replay of a prepared TX from
+# the log. It traces the call.
+
+RULE trace send recovered participant committed
+CLASS com.arjuna.wst11.messaging.engines.ParticipantEngine
+METHOD sendCommitted
+AFTER INVOKE sendCommitted
+BIND engine:ParticipantEngine = $0,
+     recovered:boolean = engine.isRecovered(),
+     identifier:String = engine.getId()
+IF recovered
+DO debug("send committed for recovered participant engine " + identifier),
+   traceln("log", "send committed for recovered participant engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a recovered participant engine
+# (ParticipantEngine) receives a commit message. This
+# happens during replay of a prepared TX from
+# the log. It traces the call.
+
+RULE trace receive recovered participant commit
+CLASS com.arjuna.wst11.messaging.engines.ParticipantEngine
+METHOD commit
+AFTER SYNCHRONIZE
+BIND engine:ParticipantEngine = $0,
+     recovered:boolean = engine.isRecovered(),
+     identifier:String = engine.getId()
+IF recovered
+DO debug("received commit for recovered participant engine " + identifier),
+   traceln("log", "received commit for recovered participant engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a subordinate pseudo participant
+# (SubordinateDurable2PCStub) is requested to send a commit message. It
+# traces the call.
+
+RULE trace subordinate participant stub commit
+CLASS com.arjuna.wst11.stub.SubordinateDurable2PCStub
+METHOD commit
+AT ENTRY
+BIND NOTHING
+IF TRUE
+DO debug("commit called for pseudo-participant " + $0),
+   traceln("log", "commit called for pseudo-participant " + $0)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a subordinate pseudo participant
+# (SubordinateDurable2PCStub) forwards a commit message to its subordinate
+# coordinator during recovery. It traces the call.
+
+RULE trace subordinate participant stub commit forward
+CLASS com.arjuna.wst11.stub.SubordinateDurable2PCStub
+METHOD commit
+AT INVOKE commit 2
+BIND NOTHING
+IF TRUE
+DO debug("forwarding commit for pseudo-participant " + $0 + " to subordinate coordinator"),
+   traceln("log", "forwarding commit for pseudo-participant " + $0 + " to subordinate coordinator")
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a subordinate pseudo participant
+# (SubordinateDurable2PCStub) throws an error from its commit method
+# because the subordinate coordinator has not yet been recovered. It
+# traces the throw.
+
+RULE trace subordinate participant stub commit with no coordinator
+CLASS com.arjuna.wst11.stub.SubordinateDurable2PCStub
+METHOD commit
+AT THROW
+BIND NOTHING
+IF TRUE
+DO debug("throw during commit for pseudo-participant " + $0 + " with no subordinate coordinator"),
+   traceln("log", "throw during commit for pseudo-participant " + $0 + " with no subordinate coordinator")
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a subordinate pseudo participant
+# (SubordinateDurable2PCStub) throws an error from its commit method
+# because the subordinate coordinator has not yet been activated. It
+# traces the throw.
+
+
+RULE trace subordinate participant stub commit commit with unactivated coordinator
+CLASS com.arjuna.wst11.stub.SubordinateDurable2PCStub
+METHOD commit
+AT THROW 2
+BIND NOTHING
+IF TRUE
+DO debug("throw during commit for pseudo-participant " + $0 + " with unactivated subordinate coordinator"),
+   traceln("log", "throw during commit for pseudo-participant " + $0 + " with unactivated subordinate coordinator")
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a subordinate pseudo participant
+# (SubordinateDurable2PCStub) returns from sending a commit message. It
+# traces the call.
+
+RULE trace subordinate participant stub commit return
+CLASS com.arjuna.wst11.stub.SubordinateDurable2PCStub
+METHOD commit
+AT EXIT
+BIND NOTHING
+IF TRUE
+DO debug("commit completed for pseudo-participant " + $0),
+   traceln("log", "commit completed for pseudo-participant " + $0)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a subordinate coordinator
+# (SubordinateATCoordinator) is requested to perform a commit. It
+# traces the call.
+
+RULE trace subordinate coordinator commit
+CLASS com.arjuna.mwlabs.wscf.model.twophase.arjunacore.subordinate.SubordinateATCoordinator
+METHOD commit
+AT ENTRY
+BIND NOTHING
+IF TRUE
+DO debug("commit called for subordinate coordinator " + $0),
+   traceln("log", "commit called for subordinate coordinator " + $0)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a subordinate coordinator
+# (SubordinateATCoordinator) is requested to perform a commit. It
+# traces the call.
+
+RULE trace subordinate coordinator commit 2
+CLASS com.arjuna.mwlabs.wscf.model.twophase.arjunacore.subordinate.SubordinateATCoordinator
+METHOD commit
+AT EXIT
+BIND NOTHING
+IF TRUE
+DO debug("commit completed for subordinate coordinator " + $0),
+   traceln("log", "commit completed for subordinate coordinator " + $0)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when the recovery system finds a PREPARED
+# parent activity in the log and reruns the phase 2 commit operation.
+# It prints a message which can be used to verify that the test has
+# progressed as expected and creates a countdown used to detect exit of
+# both transactions
+
+RULE trace prepared replay
+CLASS org.jboss.jbossts.xts.recovery.coordinator.at.RecoveryATCoordinator
+METHOD replayPhase2
+AT INVOKE phase2Commit
+BIND coordinator = $0,
+     uid : Uid = coordinator.identifier(),
+     status : int = coordinator.status()
+IF (status == com.arjuna.ats.arjuna.coordinator.ActionStatus.PREPARED)
+     OR
+     (status == com.arjuna.ats.arjuna.coordinator.ActionStatus.COMMITTING)
+DO debug("replaying commit for prepared transaction " + uid),
+   traceln("log", "replaying commit for prepared transaction " + uid),
+   createCountDown("exit countdown", 1)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when the recovery system finds a PREPARED
+# subordinate activity in the log and reruns the phase 2 commit operation.
+# It prints a message which can be used to verify that the test has
+# progressed as expected
+
+RULE trace subordinate prepared replay
+CLASS org.jboss.jbossts.xts.recovery.coordinator.at.RecoverySubordinateATCoordinator
+METHOD replayPhase2
+AT INVOKE removeRecoveredCoordinator
+BIND coordinator = $0,
+     uid : Uid = coordinator.identifier(),
+     status : int = coordinator.status()
+IF (status == com.arjuna.ats.arjuna.coordinator.ActionStatus.PREPARED)
+     OR
+     (status == com.arjuna.ats.arjuna.coordinator.ActionStatus.COMMITTING)
+DO debug("replaying commit for prepared subordinate transaction " + uid),
+   traceln("log", "replaying commit for prepared subordinate transaction " + uid)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when the recovery system deletes the COMMITTED
+# activity from the log. It prints a message which can be used to
+# verify that the test has completed.
+
+RULE trace remove committed state
+CLASS com.arjuna.ats.arjuna.coordinator.BasicAction
+METHOD updateState
+AFTER CALL remove_committed
+BIND action : BasicAction = $0,
+     uid  = action.get_uid()
+IF TRUE
+DO traceln("log", "removed committed transaction " + uid),
+   debug("removed committed transaction " + uid)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when the recovery system deletes the COMMITTED
+# activity from the log for the second time. It ensures that the JVM
+# exits. n.b. it waits for the second delete because both the subordinate
+# tx and the parent tx need to be deleted.
+
+RULE trace remove committed state and exit JVM
+CLASS com.arjuna.ats.arjuna.coordinator.BasicAction
+METHOD updateState
+AFTER CALL remove_committed
+BIND action : BasicAction = $0,
+     uid  = action.get_uid()
+IF countDown("exit countdown")
+DO traceln("log", "JVM exit after removing both transactions"),
+   debug("JVM exit after removing both transactions"),
+   killJVM()
+ENDRULE

Added: labs/jbosstm/trunk/XTS/localjunit/crash-recovery-tests/src/test/resources/scripts/ATSubordinateCrashDuringPrepare.txt
===================================================================
--- labs/jbosstm/trunk/XTS/localjunit/crash-recovery-tests/src/test/resources/scripts/ATSubordinateCrashDuringPrepare.txt	                        (rev 0)
+++ labs/jbosstm/trunk/XTS/localjunit/crash-recovery-tests/src/test/resources/scripts/ATSubordinateCrashDuringPrepare.txt	2011-12-15 07:52:45 UTC (rev 37804)
@@ -0,0 +1,720 @@
+##############################################################################
+# JBoss, Home of Professional Open Source
+# Copyright 2009, Red Hat Middleware LLC, and individual contributors
+# 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.
+#
+# @authors Andrew Dinn
+#
+# BA Subordinate Transaction Crash During Prepare
+#
+# This script automates testing of a specific recovery scenario for the
+# JBossTS XTS implementation of the WS-AT 1.1 protocol using orchestration
+# rules. The basic scenario employs a coordinator, a subordinate coordinator
+# and 2 web services running in a single JVM, the second one employing local
+# (subordinate) coordination. It checks that the transaction rolls back
+# all prepared participants afetr crashing in the middle of prepare.
+# The crash happens after the subordinate transaction has been prepared and
+# logged to disk but before its proxy participant is able to write a log record.
+# The scenario is as follows
+# (** indicates intercession by a Byteman rule):
+#
+# AS boots
+# Cient starts a WS-AT transaction T1
+# Client invokes web service S1 with enlist durable request
+# S1 registers Participant P1 in T1
+# Client invokes subordinate web service S2 with enlist durable request
+# S2 creates a subordinate BA transaction T2
+# S2 registers pseudo-participant PP in T1
+# S2 registers Participant P2 in T2
+# Client invokes subordinate web service S2 with enlist durable request
+# S2 resumes T2
+# S2 registers Participant P3 in T2
+#
+# Client initiates transaction close for T1
+#
+# Coordinator initiates prepare of participant P1
+# ** Rule system logs dispatch of prepare to P1
+# ** Rule system logs receipt of prepared from P1
+#
+# Coordinator initiates prepare of subordinate participant PP
+# ** Rule system logs dispatch of prepare to PP
+# PP calls subordinate coordinator prepare
+# ** Rule system logs call to prepare
+#
+# Subordinate coordinator initiates prepare of participant P2
+# ** Rule system logs dispatch of prepare to P1
+# ** Rule system logs receipt of prepared from P1
+# Subordinate coordinator initiates prepare of participant P3
+# ** Rule system logs dispatch of prepare to P1
+# ** Rule system logs receipt of prepared from P1
+# Subordinate coordinator writes T2 to log
+# Subordinate coordinator complete returns
+# ** Rule system intercepts return and crashes JVM
+#
+# AS reboots
+# Recovery system starts after 2 minutes
+# Recovery system recreates transaction T2
+# ** Rule system traces create
+# ** Rule system traces create
+# Recovery system recreates participant engine for P1
+# ** Rule system traces create
+# Recovery system recreates participant engine for P2
+# ** Rule system traces create
+# Recovery system recreates participant engine for P3
+# ** Rule system traces create
+# Recovery system recreates coordinator engine for P2
+# ** Rule system traces create
+# Recovery system recreates coordinator engine for P3
+# ** Rule system traces create
+#
+# (parallel optional)
+# prepared sent for P2/P3 and ignored during recovery
+# ** Rule system traces dispatch of prepared
+# (parallel)
+# Recovery system detects missing proxy P2 for transaction T2
+# Recovery system calls rollback for subordinate coordinator
+# ** Rule system traces call to rollback
+#
+# Coordinator sends rollback to P2
+# ** Rule system traces dispatch of rollback
+# P2 replies with aborted
+# ** Rule system traces dispatch of aborted
+# ** Rule system detects removal of P2
+#
+# Coordinator sends rollback to P3
+# ** Rule system traces dispatch of rollback
+# P3 replies with aborted
+# ** Rule system traces dispatch of aborted
+# ** Rule system detects removal of P3
+# Subordinate coordinator rol;back call returns
+# ** Rule system traces return from rollback
+#
+# Recovery system removes transaction T2
+# ** Rule system traces removal of transaction
+# (parallel)
+# completed sent for P1
+# ** Rule system traces dispatch of completed
+# rollback sent to P1
+# ** Rule system traces dispatch of rollback
+# ** Rule system detects removal of P1
+# (end parallel)
+#
+# ** Rule system detects 3 participant deletes and 1 tx delete and kills JVM
+#
+# Use of this script
+#
+# The default way of exercising this test is to deploy the xtstest war
+# to a single AS and configure it to run the relevant XTS Service Test.
+# The web services and coordinator will be located with the client.
+# The number of participants and subordinate participants must be
+# exactly 3. The  web service(s), client (i.e. the XTS Service Test which
+# drives the test) and coordinator and subordinate coordinator service must
+# be colocated for this script to work (it is possible to distribute all of
+# these agents if desired but that woud lrequire more complex script rules).
+# The AS should crash when the client closes. At reboot the rest of the test
+# should run automatically and the server should be killed after the recovered
+# transaction is successfuly replayed.
+#
+# This script needs to be passed to a Byteman agent in the JVM running
+# the coordinator service both at first boot and at reboot. Output will be
+# written to file testlog in the working directory of the AS.
+#
+# XTS Service tests which can operate with this scenario can be selected for
+# execution at AS boot by the XTSServiceTestRunnerBean by setting system
+# property
+#    org.jboss.jbossts.xts.servicetests.XTSServiceTestName
+# to the name of a class which will execute the test. This property must
+# be defined in the JVM running the AS to which the xtstest war is deployed
+# i.e. the client AS. n.b. if the client is colocated with the coordinator then
+# this property must be left undefined at AS reboot otherwise the client
+# will run again, starting a new TX which may interfere with recovery of the
+# crashed TX. It is also possible to run the service test using the form
+# interface provided on the xtstest war's main index page.
+#
+# Available tests include:
+#
+# org.jboss.jbossts.xts.servicetests.test.at.subordinate.MultiParticipantPrepareAndCommitTest
+# this test starts an activity then registers a durable participant with the service whose location is defined by
+# system property:
+#    org.jboss.jbossts.xts.servicetests.ServiceURL1
+# if this is not set the value used defaults to
+#    http://localhost:8080/xtstest/xtsservicetest1
+# the test then registers two durable participants with a second web service (which must install a
+# subordinate transaction) whose location is defined system property:
+#    org.jboss.jbossts.xts.servicetests.serviceURL1
+# if this is not set the value used defaults to
+#    http://localhost:8080/xtstest/xtssubservicetest1
+# The test then closes the transaction
+#
+# Expected output
+#
+# After the first boot the JVM should exit leaving the following in file testlog
+# (the number and order of entries depends upon how many and which type of participants
+# are enlisted)
+#
+#   prepare sent for Coordinator engine XXXXXX
+#   prepare received for participant XXXXXX
+#   prepared sent for participant XXXXXX
+#   prepare sent for Coordinator engine XXXXXX
+#   prepare received for participant XXXXXX
+#   prepared sent for participant XXXXXX
+#   prepare sent for Coordinator engine XXXXXX
+#   prepare called for pseudo participant XXXXXX
+#   prepare sent for participant XXXXXX
+#   prepare received for participant XXXXXX
+#   prepared sent for participant XXXXXX
+#   prepared received for participant XXXXXX
+#   prepare returned for subordinate transaction XXXXXX
+#   saved to disk transaction XXXXXX
+#   prepare returned for pseudo participant XXXXXX
+#   JVM exit
+#
+# n.b. there should be at least one prepare/prepared sent/received message received for each participant
+#      there should be at least one prepare called/prepare returned message for the pseudo participant
+#
+# and in some cases there may be repeat messages
+#
+# After reboot the JVM should exit leaving output in the following format in file
+# testlog.
+#
+#   prepare sent for Coordinator engine XXXXXX
+#   prepare received for participant XXXXXX
+#   prepared sent for participant XXXXXX
+#   prepare sent for Coordinator engine XXXXXX
+#   prepare received for participant XXXXXX
+#   prepared sent for participant XXXXXX
+#   prepare sent for Coordinator engine XXXXXX
+#   prepare called for pseudo participant XXXXXX
+#   prepare sent for participant XXXXXX
+#   prepare received for participant XXXXXX
+#   prepared sent for participant XXXXXX
+#   prepared received for participant XXXXXX
+#   prepare returned for subordinate transaction XXXXXX
+#   saved to disk transaction XXXXXX
+#   prepare returned for pseudo participant XXXXXX
+#   JVM exit
+#   created recovered Participant engine XXXXXX
+#   created recovered Participant engine XXXXXX
+#   created recovered Participant engine XXXXXX
+#   created recovered Coordinator engine XXXXXX
+#   created recovered Coordinator engine XXXXXX
+#   reinstated prepared subordinate transaction XXXXXX
+#
+#   (parallel)
+#   prepared sent for Participant P1
+#   prepared received for Coordinator engine P1'
+#   rollback sent for Coordinator engine P1
+#   rollback received for Participant P1
+#   (parallel)
+
+#   rollback called for pseudo-participant XXXXXX
+#   rollback called for subordinate coordinator XXX
+#   rollback sent for Coordinator engine XXXXXX
+#   rollback received for Participant XXXXXX
+#   aborted sent for Participant XXXXXX
+#   aborted received for Coordinator engine XXXXXX
+#   rollback sent for Coordinator engine XXXXXX
+#   rollback received for Participant XXXXXX
+#   aborted sent for Participant XXXXXX
+#   aborted received for Coordinator engine XXXXXX
+#   rollback returned for subordinate coordinator XXX
+#   rollback completed for pseudo-participant XXXXXX
+
+#   removed transaction XXXXXX
+#   (end parallel)
+#
+#   JVM exit
+#
+#######################################################################
+# This rule opens a file for the trace output during XTS startup
+# It will be opened for append at reboot so messages from both runs
+# will go to this file
+#
+RULE open trace file
+CLASS org.jboss.jbossts.XTSService
+METHOD start()
+BIND NOTHING
+IF TRUE
+DO openTrace("log", "testlog")
+ENDRULE
+
+#######################################################################
+# This rule creates a counter used to track the number of participant
+# records which have been deleted
+RULE create participant deletes counter
+CLASS org.jboss.jbossts.XTSService
+METHOD start()
+BIND NOTHING
+IF TRUE
+DO createCounter("participant deletes")
+ENDRULE
+
+#######################################################################
+# This rule resets the periodic recovery wait period to 10 seconds
+# in order to speed up the test
+#
+RULE reset periodic recovery wait time
+CLASS com.arjuna.ats.arjuna.common.RecoveryEnvironmentBean
+METHOD getPeriodicRecoveryPeriod()
+AT ENTRY
+IF TRUE
+DO return 10
+ENDRULE
+
+#######################################################################
+## rules for first run of AS
+
+#######################################################################
+# This rule is triggered when a Coordinator engine
+# (CoordinatorEngine) is requested to send a prepare message. It
+# traces the call.
+
+RULE trace send participant prepare
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorEngine
+METHOD prepare
+AFTER SYNCHRONIZE
+BIND engine:CoordinatorEngine = $0,
+     identifier:String = engine.getId()
+IF TRUE
+DO debug("prepare sent for Coordinator engine " + identifier),
+   traceln("log", "prepare sent for Coordinator engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a Coordinator engine
+# (CoordinatorEngine) receives a prepared message. It traces the call.
+
+RULE trace receive participant prepared
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorEngine
+METHOD prepared(Notification, MAP, ArjunaContext)
+AT ENTRY
+BIND engine:CoordinatorEngine = $0,
+     identifier:String = engine.getId()
+IF TRUE
+DO debug("prepared received for Coordinator engine " + identifier),
+   traceln("log", "prepared received for Coordinator engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a participant
+# (ParticipantEngine) receives a prepare message. It
+# traces the call.
+
+RULE trace receive participant prepare
+CLASS com.arjuna.wst11.messaging.engines.ParticipantEngine
+METHOD prepare
+AFTER SYNCHRONIZE
+BIND engine:ParticipantEngine = $0,
+     identifier:String = engine.getId()
+IF TRUE
+DO debug("prepare received for participant " + identifier),
+   traceln("log", "prepare received for participant " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a Participant
+# (ParticipantEngine) is requested to send a prepared message. It
+# traces the call.
+
+RULE trace send Participant prepared
+CLASS com.arjuna.wst11.messaging.engines.ParticipantEngine
+METHOD sendPrepared(boolean)
+AT INVOKE sendPrepared
+BIND engine:ParticipantEngine = $0,
+     identifier:String = engine.getId()
+IF TRUE
+DO debug("prepared sent for Participant " + identifier),
+   traceln("log", "prepared sent for Participant " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a Coordinator engine
+# (CoordinatorEngine) is requested to send a rollback message. It
+# traces the call.
+
+RULE trace send Participant rollback
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorEngine
+METHOD rollback
+AFTER SYNCHRONIZE
+BIND engine:CoordinatorEngine = $0,
+     identifier:String = engine.getId()
+IF TRUE
+DO debug("rollback sent for Coordinator engine " + identifier),
+   traceln("log", "rollback sent for Coordinator engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a Coordinator engine
+# (CoordinatorEngine) receives an aborted message. It traces the call.
+
+RULE trace receive Participant aborted
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorEngine
+METHOD aborted(Notification, MAP, ArjunaContext)
+AT ENTRY
+BIND engine:CoordinatorEngine = $0,
+     identifier:String = engine.getId()
+IF TRUE
+DO debug("aborted received for Coordinator engine " + identifier),
+   traceln("log", "aborted received for Coordinator engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a Participant
+# (ParticipantEngine) receives a rollback message. It
+# traces the call.
+
+RULE trace receive Participant rollback
+CLASS com.arjuna.wst11.messaging.engines.ParticipantEngine
+METHOD rollback
+AFTER SYNCHRONIZE
+BIND engine:ParticipantEngine = $0,
+     identifier:String = engine.getId()
+IF TRUE
+DO debug("rollback received for Participant " + identifier),
+   traceln("log", "rollback received for Participant " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a Participant
+# (ParticipantEngine) is requested to send an aborted message. It
+# traces the call.
+
+RULE trace send Participant aborted
+CLASS com.arjuna.wst11.messaging.engines.ParticipantEngine
+METHOD sendAborted()
+AT INVOKE sendAborted
+BIND engine:ParticipantEngine = $0,
+     identifier:String = engine.getId()
+IF TRUE
+DO debug("aborted sent for Participant " + identifier),
+   traceln("log", "aborted sent for Participant " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a subordinate pseudo participant
+# (SubordinateDurable2PCStub) is requested to send a prepared message. It
+# traces the call.
+
+RULE trace subordinate participant stub prepare
+CLASS com.arjuna.wst11.stub.SubordinateDurable2PCStub
+METHOD prepare
+AT ENTRY
+BIND NOTHING
+IF TRUE
+DO debug("prepare called for pseudo-participant " + $0),
+   traceln("log", "prepare called for pseudo-participant " + $0)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a subordinate pseudo participant
+# (SubordinateDurable2PCStub) has forwarded a prepare message. It
+# kills the JVM.
+
+RULE trace subordinate participant stub prepare 2
+CLASS com.arjuna.wst11.stub.SubordinateDurable2PCStub
+METHOD prepare
+AFTER INVOKE prepare
+BIND NOTHING
+IF TRUE
+DO traceln("log", "JVM exit"),
+   debug("JVM exit"),
+   killJVM()
+ENDRULE
+
+#######################################################################
+## rules for reboot run of AS
+
+#######################################################################
+# This rule is triggered when a Coordinator engine (CoordinatorEngine)
+# is created from details located in the log record. It traces the
+# create operation. The trigger location is at entry but the rule
+# should only be triggered after calling the super constructor
+
+RULE trace Coordinator engine create
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorEngine
+METHOD <init>(String, boolean, W3CEndpointReference, boolean, State)
+AT ENTRY
+BIND identifier = $1,
+     recovered=$4
+IF recovered
+DO debug("created recovered Coordinator engine " + identifier),
+   traceln("log", "created recovered Coordinator engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a Participant (ParticipantEngine)
+# is created from details located in the log record. It traces the
+# create operation. The trigger location is at entry but the rule
+# should only be triggered after calling the super constructor
+
+RULE trace Participant create
+CLASS com.arjuna.wst11.messaging.engines.ParticipantEngine
+METHOD <init>(Participant, String, State, W3CEndpointReference, boolean)
+AT ENTRY
+BIND identifier = $2,
+     recovered=$5
+IF recovered
+DO debug("created recovered Participant engine " + identifier),
+   traceln("log", "created recovered Participant engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a Coordinator processor
+# (CoordinatorProcessorImpl) sends a rollback.
+# This happens during replay of a prepared TX from
+# the log. It traces the call.
+
+RULE trace Participant send rollback
+CLASS com.arjuna.wst11.messaging.CoordinatorProcessorImpl
+METHOD prepared(Notification, MAP, ArjunaContext)
+AT CALL sendRollback
+BIND identifier:String = $3.getInstanceIdentifier().getInstanceIdentifier()
+IF TRUE
+DO debug("sent rollback for unknown Coordinator engine " + identifier),
+   traceln("log", "sent rollback for unknown Coordinator engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a subordinate pseudo participant
+# (SubordinateDurable2PCStub) is requested to forward a rollback message. It
+# traces the call.
+
+RULE trace subordinate participant stub rollback
+CLASS com.arjuna.wst11.stub.SubordinateDurable2PCStub
+METHOD rollback
+AT ENTRY
+BIND NOTHING
+IF TRUE
+DO debug("rollback called for pseudo-participant " + $0),
+   traceln("log", "rollback called for pseudo-participant " + $0)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a subordinate pseudo participant
+# (SubordinateDurable2PCStub) forwards a rollback message to its subordinate
+# coordinator during recovery. It traces the call.
+
+RULE trace subordinate participant stub rollback forward
+CLASS com.arjuna.wst11.stub.SubordinateDurable2PCStub
+METHOD rollback
+AT INVOKE rollback 2
+BIND NOTHING
+IF TRUE
+DO debug("forwarding rollback or pseudo-participant " + $0 + " as rollback to subordinate coordinator"),
+   traceln("log", "forwarding rollback for pseudo-participant " + $0 + " as rollback to subordinate coordinator")
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a subordinate pseudo participant
+# (SubordinateDurable2PCStub) throws an error from its rollback method
+# because the subordinate coordinator has not yet been recovered. It
+# traces the throw.
+
+RULE trace subordinate participant stub rollback with no coordinator
+CLASS com.arjuna.wst11.stub.SubordinateDurable2PCStub
+METHOD rollback
+AT THROW
+BIND NOTHING
+IF TRUE
+DO debug("throw during rollback for pseudo-participant " + $0 + " with no subordinate coordinator"),
+   traceln("log", "throw during rollback for pseudo-participant " + $0 + " with no subordinate coordinator")
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a subordinate pseudo participant
+# (SubordinateDurable2PCStub) throws an error from its rollback method
+# because the subordinate coordinator has not yet been activated. It
+# traces the throw.
+
+
+RULE trace subordinate participant stub rollback with unactivated coordinator
+CLASS com.arjuna.wst11.stub.SubordinateDurable2PCStub
+METHOD rollback
+AT THROW 2
+BIND NOTHING
+IF TRUE
+DO debug("throw during rollback for pseudo-participant " + $0 + " with unactivated subordinate coordinator"),
+   traceln("log", "throw during rollback for pseudo-participant " + $0 + " with unactivated subordinate coordinator")
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a subordinate pseudo participant
+# (SubordinateDurable2PCStub) returns from frowarding a rollback message. It
+# traces the call.
+
+RULE trace subordinate participant stub rollback return
+CLASS com.arjuna.wst11.stub.SubordinateDurable2PCStub
+METHOD rollback
+AT EXIT
+BIND NOTHING
+IF TRUE
+DO debug("rollback completed for pseudo-participant " + $0),
+   traceln("log", "rollback completed for pseudo-participant " + $0)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a subordinate coordinator
+# (SubordinateATCoordinator) calls prepare during completion. It
+# traces the call.
+
+RULE trace subordinate coordinator prepare
+CLASS com.arjuna.mwlabs.wscf.model.twophase.arjunacore.subordinate.SubordinateATCoordinator
+METHOD prepare
+AT INVOKE prepare
+BIND uid = $0.get_uid()
+IF TRUE
+DO debug("prepare for subordinate transaction " + uid),
+   traceln("log", "prepare for subordinate transaction " + uid)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a subordinate coordinator
+# (SubordinateCoordinator) is requested to perform a rollback. It
+# traces the call.
+
+RULE trace subordinate coordinator close
+CLASS com.arjuna.mwlabs.wscf.model.twophase.arjunacore.subordinate.SubordinateATCoordinator
+METHOD rollback
+AT ENTRY
+BIND NOTHING
+IF TRUE
+DO debug("rollback called for subordinate coordinator " + $0),
+   traceln("log", "rollback called for subordinate coordinator " + $0)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a subordinate coordinator
+# (SubordinateCoordinator) is requested to perform a close. It
+# traces the call.
+
+RULE trace subordinate coordinator rollback 2
+CLASS com.arjuna.mwlabs.wscf.model.twophase.arjunacore.subordinate.SubordinateATCoordinator
+METHOD rollback
+AT EXIT
+BIND NOTHING
+IF TRUE
+DO debug("rollback returned for subordinate coordinator " + $0),
+   traceln("log", "rollback returned for subordinate coordinator " + $0)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when the recovery system finds a PREPARED
+# parent activity in the log and reruns the phase 2 commit operation.
+# It prints a message which can be used to verify that the test has
+# progressed as expected and creates a countdown used to detect exit of
+# both transactions
+
+RULE trace prepared replay
+CLASS org.jboss.jbossts.xts.recovery.coordinator.at.RecoveryATCoordinator
+METHOD replayPhase2
+AT INVOKE phase2Commit
+BIND coordinator = $0,
+     uid : Uid = coordinator.identifier(),
+     status : int = coordinator.status()
+IF (status == com.arjuna.ats.arjuna.coordinator.ActionStatus.PREPARED)
+     OR
+     (status == com.arjuna.ats.arjuna.coordinator.ActionStatus.COMMITTING)
+DO debug("replaying commit for prepared transaction " + uid),
+   traceln("log", "replaying commit for prepared transaction " + uid),
+   createCountDown("exit countdown", 1)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when the recovery system finds a PREPARED
+# subordinate activity in the log. It prints a message which can be
+# used to verify that the test has progressed as expected
+
+RULE trace subordinate prepared replay
+CLASS org.jboss.jbossts.xts.recovery.coordinator.at.RecoverySubordinateATCoordinator
+METHOD replayPhase2
+AT ENTRY
+BIND coordinator = $0,
+     uid : Uid = coordinator.identifier(),
+     status : int = coordinator.status()
+IF (status == com.arjuna.ats.arjuna.coordinator.ActionStatus.PREPARED)
+     OR
+     (status == com.arjuna.ats.arjuna.coordinator.ActionStatus.COMMITTING)
+DO debug("reinstated prepared subordinate transaction " + uid),
+   traceln("log", "reinstated prepared subordinate transaction " + uid)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a TX is saved to disk during prepare.
+
+RULE trace TX save at prepare
+CLASS com.arjuna.ats.arjuna.coordinator.BasicAction
+METHOD prepare(boolean)
+AFTER CALL save_state
+BIND action : BasicAction = $0,
+     uid  = action.get_uid()
+IF TRUE
+DO traceln("log", "saved to disk transaction " + uid),
+   debug("saved to disk transaction " + uid)
+ENDRULE
+
+#######################################################################
+# This rule is called when removing a transaction from the log. It
+# ensures that the JVM exits but only after we have seen all the
+# necessary aborted messages
+
+RULE trace remove committed state and exit JVM
+CLASS com.arjuna.ats.arjuna.coordinator.BasicAction
+METHOD updateState
+AFTER CALL remove_committed
+BIND action : BasicAction = $0,
+     uid  = action.get_uid(),
+     dummy = flag("tx removed")
+IF readCounter("participant deletes") == 3
+DO traceln("log", "JVM exit"),
+   debug("JVM exit"),
+   killJVM()
+ENDRULE
+
+#######################################################################
+# This rule is called when deleting a participant record from the log.
+# It ensures that the JVM exits but only after we have seen 3 deletes
+# and also seen the tx removed
+
+RULE trace delete participant and exit JVM
+CLASS org.jboss.jbossts.xts.recovery.participant.at.XTSATRecoveryManagerImple
+METHOD deleteParticipantRecoveryRecord
+AFTER CALL remove_committed
+BIND dummy = flag("tx removed")
+IF incrementCounter("participant deletes") == 3 &&
+   flagged("tx removed")
+DO traceln("log", "JVM exit"),
+   debug("JVM exit"),
+   killJVM()
+ENDRULE
+
+#######################################################################
+# This rule is triggered when the recovery system deletes an
+# activity from the log. It prints a message which can be used to
+# verify that the test has completed.
+
+RULE trace remove committed state
+CLASS com.arjuna.ats.arjuna.coordinator.BasicAction
+METHOD updateState
+AFTER CALL remove_committed
+BIND action : BasicAction = $0,
+     uid  = action.get_uid()
+IF TRUE
+DO traceln("log", "removed transaction " + uid),
+   debug("removed transaction " + uid)
+ENDRULE

Added: labs/jbosstm/trunk/XTS/localjunit/crash-recovery-tests/src/test/resources/scripts/BACrashDuringCommit.txt
===================================================================
--- labs/jbosstm/trunk/XTS/localjunit/crash-recovery-tests/src/test/resources/scripts/BACrashDuringCommit.txt	                        (rev 0)
+++ labs/jbosstm/trunk/XTS/localjunit/crash-recovery-tests/src/test/resources/scripts/BACrashDuringCommit.txt	2011-12-15 07:52:45 UTC (rev 37804)
@@ -0,0 +1,568 @@
+##############################################################################
+# JBoss, Home of Professional Open Source
+# Copyright 2009, Red Hat Middleware LLC, and individual contributors
+# 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.
+#
+# @authors Andrew Dinn
+#
+# BA Crash During Commit
+#
+# This script automates testing of a specific recovery scenario for the
+# JBossTS XTS implementation of the WS-BA 1.1 protocol using orchestration
+# rules. The basic scenario employs a coordinator and 3 web services
+# running in a single JVM but other variants are possible (see below). The
+# scenario is as follows (** indicates intercession by a Byteman rule):
+#
+# AS boots
+# Cient starts a WS-BA activity
+# Client invokes web service 1
+# Web service 1 registers participant P1
+# Client invokes web service 2
+# Web service 2 registers participant P2
+# Client invokes web service 3
+# Web service 3 registers participant P3
+#
+# Alternative A (assumes participant completion participants)
+# Client invokes web service 1 with command P1 complete
+# Web service sends completed for participant 1
+# ** Rule system traces receipt of completed
+# Client invokes web service 2 with command P2 complete
+# Web service sends completed for participant 2
+# ** Rule system traces receipt of completed
+# Client invokes web service 3 with command P3 complete
+# Web service sends completed for participant 3
+# ** Rule system traces receipt of completed
+# End Alternative A
+#
+# Alternative B
+# Client invokes web service 1 with command P1 exit
+# Web service sends exit for participant 1
+# ** Rule system traces receipt of exit
+# Coordinator sends exited for participant 1
+# ** Rule system traces send of exited
+# <possibly repeat for other participants>
+# End Alternative B
+# Client closes WS-BA activity
+#
+# Alternative C (assumes coordinator completion participants)
+# Coordinator initiates complete of participant P1
+# P1 replies with completed
+# ** Rule system traces receipt of completed
+# Coordinator initiates complete of participant P2
+# P2 replies with completed
+# ** Rule system traces receipt of completed
+# Coordinator initiates complete of participant P3
+# P3 replies with completed
+# ** Rule system traces receipt of completed
+# End Alternative C
+# Coordinator initiates close of participant P1
+# ** Rule system intercepts close and crashes JVM
+#
+# AS reboots
+# Recovery system starts after 2 minutes
+# Recovery system recreates PREPARED WS-BA activity coordinator
+# ** Rule system traces create
+# Recovery system recreates participant stub for P1
+# ** Rule system traces create
+# Recovery system recreates participant stub for P2
+# ** Rule system traces create
+# Recovery system recreates participant stub for P3
+# ** Rule system traces create
+# Recovery system calls replay of PREPARED transaction
+# ** Rule system traces PREPARED replay invocation
+#
+# Coordinator sends close to P1
+# P1 replies with closed
+# ** Rule system traces receipt of closed
+#
+# Coordinator sends close to P2
+# P2 replies with closed
+# ** Rule system traces receipt of closed
+#
+# Coordinator sends close to P3
+# P3 replies with closed
+# ** Rule system traces receipt of closed
+#
+# Coordinator clears heuristic log record and completes close of activity
+# ** Rule system detects completed activity close and kills JVM
+#
+# Use of this script
+#
+# The default way of exercising this test is to deploy the xtstest war
+# to a single AS and configure it to run the relevant XTS Service Test.
+# The web services and coordinator will be located with the client.
+# The number of participants can actually be 2, 3 or more. The
+# web service(s), client (i.e. the XTS Service Test which drives
+# the test) and coordinator service can optionally be located in separate
+# ASs. It is also possible to use just a single web service and have the
+# client register multiple participants. The coordinator AS should crash
+# when the client closes. At reboot the rest of the test should run
+# automatically and the server should be killed after a the heuristic
+# transaction is successfuly replayed.
+#
+# n.b. this test is not appropriate foir the case where only one participant
+# is registered since the coordinator employs the one phase optimization,
+# omitting to log the activity. In this case the lone participant should be
+# automatically compensated at restart.
+#
+# This script allows for registration of either participant completion
+# or coordinator completion participants (alternatives A or C). It is
+# legitimate to mix the different types. However, if participant completion
+# participants are used then the client must script the participants
+# to perform a complete. It is also possible to script an exit for
+# either type of participant (alternative B). In this case the completed
+# message should not be traced.
+#
+# This script needs to be passed to a Byteman agent in the JVM running
+# the coordinator service both at first boot and at reboot. Output will be
+# written to file testlog in the working directory of the AS. n.b. the rules in
+# this script only refer to code executed by the coordinator. If the client
+# (the selected XTS Service Test) or the web services are located in another
+# AS/JVM then the other JVM does not require a Byteman agent or script.
+#
+# XTS Service tests which can operate with this scenario can be selected for
+# execution at AS boot by the XTSServiceTestRunnerBean by setting system
+# property
+#    org.jboss.jbossts.xts.servicetests.XTSServiceTestName
+# to the name of a class which will execute the test. This property must
+# be defined in the JVM running the AS to which the xtstest war is deployed
+# i.e. the client AS. n.b. if the client is collocated with the coordinator then
+# this property must be left undefined at AS reboot otherwise the client
+# will run again, starting a new TX which may interfere with recovery of the
+# crashed TX.
+#
+# Available tests include:
+#
+# org.jboss.jbossts.xts.servicetests.test.ba.MultiParticipantCoordinatorCompletionParticipantCloseTest
+# this test invokes a single service registering 3 coordinator completion participants
+# and then closing the activity
+# the location of service is defined by defining a system property:
+#    org.jboss.jbossts.xts.servicetests.ServiceURL1
+# if this is not set the value used defaults to
+#    http://localhost:8080/xtstest/xtsservicetest1
+#
+# org.jboss.jbossts.xts.servicetests.test.ba.MultiParticipantParticipantCompletionParticipantCloseTest
+# this test invokes a single service registering 3 participant completion participants
+# it sends completed to each of the 3 participants before closing the activity
+# the location of service is defined by defining a system property:
+#    org.jboss.jbossts.xts.servicetests.ServiceURL1
+# if this is not set the value used defaults to
+#    http://localhost:8080/xtstest/xtsservicetest1
+#
+# org.jboss.jbossts.xts.servicetests.test.ba.MultiParticipantCoordinatorCompletionParticipantExitAndCloseTest
+# this test invokes a single service registering 3 coordinator completion participants
+# it sends an exit to the first participant before closing the activity
+# the location of service is defined by defining a system property:
+#    org.jboss.jbossts.xts.servicetests.ServiceURL1
+# if this is not set the value used defaults to
+#    http://localhost:8080/xtstest/xtsservicetest1
+#
+# org.jboss.jbossts.xts.servicetests.test.ba.MultiParticipantParticipantCompletionParticipantExitAndCloseTest
+# this test invokes a single service registering 3 participant completion participants
+# it sends an exit to the first participant and completed to the other participants
+# before closing the activity
+# the location of service is defined by defining a system property:
+#    org.jboss.jbossts.xts.servicetests.ServiceURL1
+# if this is not set the value used defaults to
+#    http://localhost:8080/xtstest/xtsservicetest1
+#
+# org.jboss.jbossts.xts.servicetests.test.ba.MultiServiceCoordinatorCompletionParticipantCloseTest
+# this test invokes 3 separate services registering a coordinator completion participant with each service
+# and then closing the activity
+# the location of service is defined by defining by system properties:
+#    org.jboss.jbossts.xts.servicetests.ServiceURL1
+#    org.jboss.jbossts.xts.servicetests.ServiceURL2
+#    org.jboss.jbossts.xts.servicetests.ServiceURL3
+# if these are not set the values used default to
+#    http://localhost:8080/xtstest/xtsservicetest1
+#    http://localhost:8080/xtstest/xtsservicetest2
+#    http://localhost:8080/xtstest/xtsservicetest3
+#
+# org.jboss.jbossts.xts.servicetests.test.ba.MultiServiceParticipantCompletionParticipantCloseTest
+# this test invokes 3 separate services registering a participant completion participant with each service
+# it sends completed to each of the 3 participants before closing the activity
+# the location of service is defined by defining by system properties:
+#    org.jboss.jbossts.xts.servicetests.ServiceURL1
+#    org.jboss.jbossts.xts.servicetests.ServiceURL2
+#    org.jboss.jbossts.xts.servicetests.ServiceURL3
+# if these are not set the values used default to
+#    http://localhost:8080/xtstest/xtsservicetest1
+#    http://localhost:8080/xtstest/xtsservicetest2
+#    http://localhost:8080/xtstest/xtsservicetest3
+#
+# org.jboss.jbossts.xts.servicetests.test.ba.MultiServiceCoordinatorCompletionParticipantCloseAndExitTest
+# this test invokes 3 separate services registering a coordinator completion participant with each service
+# it sends an exit to the first participant before closing the activity
+# the location of service is defined by defining by system properties:
+#    org.jboss.jbossts.xts.servicetests.ServiceURL1
+#    org.jboss.jbossts.xts.servicetests.ServiceURL2
+#    org.jboss.jbossts.xts.servicetests.ServiceURL3
+# if these are not set the values used default to
+#    http://localhost:8080/xtstest/xtsservicetest1
+#    http://localhost:8080/xtstest/xtsservicetest2
+#    http://localhost:8080/xtstest/xtsservicetest3
+#
+# org.jboss.jbossts.xts.servicetests.test.ba.MultiServiceParticipantCompletionParticipantCloseAndExitTest
+# this test invokes 3 separate services registering a participant completion participant with each service
+# it sends an exit to the first participant and completed to the other participants
+# before closing the activity
+# the location of service is defined by defining by system properties:
+#    org.jboss.jbossts.xts.servicetests.ServiceURL1
+#    org.jboss.jbossts.xts.servicetests.ServiceURL2
+#    org.jboss.jbossts.xts.servicetests.ServiceURL3
+# if these are not set the values used default to
+#    http://localhost:8080/xtstest/xtsservicetest1
+#    http://localhost:8080/xtstest/xtsservicetest2
+#    http://localhost:8080/xtstest/xtsservicetest3
+#
+# If the client is run in a different AS to the coordinator then the client
+# AS needs to be pointed at the coordinator AS. The easiest
+# way to do this is to define the system property
+#
+#    org.jboss.jbossts.xts11.coordinatorURL
+#
+# to something like
+#
+#    http://foo.bar.org:8080/ws-c11/soap/ActivationCoordinator
+#
+# or alternatively to redefine one or more of the component properties
+#
+#    org.jboss.jbossts.xts11.coordinator.host
+#    org.jboss.jbossts.xts11.coordinator.port
+#    org.jboss.jbossts.xts11.coordinator.path
+#
+# (you probably only need to reset the host component)
+#
+# Expected output
+#
+# After the first boot the JVM should exit leaving the following in file testlog
+#
+#   received exit message for XXXXXXX completion participant stub XXXXXX       (only for CloseAndExit tests)
+#   received completed message for XXXXXXX completion participant stub XXXXXX  (number of occcurences depends upon test)
+#   complete on recovered XXXXXXX completion participant engine XXXXXXX        (number of occcurences depends upon test)
+#   JVM exit
+#
+# After reboot the JVM should exit leaving output in the following format in file
+# testlog.
+#
+#   received exit message for XXXXXXX completion participant stub XXXXXX       (only for CloseAndExit tests)
+#   received completed message for XXXXXXX completion participant stub XXXXXX  (number of occcurences depends upon test)
+#   complete on recovered XXXXXXX completion participant engine XXXXXXX        (number of occcurences depends upon test)
+#   JVM exit
+#   created recovered XXXXXXX completion participant stub XXXXXX
+#   created recovered XXXXXXX completion participant stub XXXXXX
+#   created recovered XXXXXXX completion participant stub XXXXXX
+#   replaying close for prepared activity XXXXXX
+#   close on recovered XXXXXXX completion participant engine XXXXXX
+#   received closed message for XXXXXXX completion participant stub XXXXXX
+#   close on recovered XXXXXXX completion participant engine XXXXXX
+#   received closed message for XXXXXXX completion participant stub XXXXXX
+#   close on recovered XXXXXXX completion participant engine XXXXXX
+#   received closed message for XXXXXXX completion participant stub XXXXXX
+#   removed committed activity XXXXXX
+#
+#######################################################################
+# This rule opens a file for the trace output during XTS startup
+# It will be opened for append at reboot so messages from both runs
+# will go to this file
+#
+RULE open trace file
+CLASS org.jboss.jbossts.XTSService
+METHOD start()
+BIND NOTHING
+IF TRUE
+DO openTrace("log", "testlog")
+ENDRULE
+
+#######################################################################
+## rules for first run of AS
+
+#######################################################################
+# This rule is triggered when a non-recovered participant completion
+# participant stub (ParticipantCompletionCoordinatorEngine) is sent
+# a close message. It exits the JVM, simulating a crash.
+# The trigger location is on entry
+
+RULE kill JVM at participant completion close
+CLASS com.arjuna.wst11.messaging.engines.ParticipantCompletionCoordinatorEngine
+METHOD close
+AT ENTRY
+BIND engine:ParticipantCompletionCoordinatorEngine = $0,
+     recovered:boolean = engine.isRecovered(),
+     identifier:String = engine.getId()
+IF (NOT recovered)
+   AND
+   debug("close on non-recovered participant completion engine " + identifier)
+DO traceln("log", "JVM exit"),
+   debug("!!!killing JVM!!!"),
+   killJVM()
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a non-recovered coordinator completion
+# participant stub (CoordinatorCompletionCoordinatorEngine) is sent
+# a close message. It exits the JVM, simulating a crash.
+# The trigger location is on entry
+
+RULE kill JVM at coordinator completion close
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorCompletionCoordinatorEngine
+METHOD close
+AT ENTRY
+BIND engine:CoordinatorCompletionCoordinatorEngine = $0,
+     recovered:boolean = engine.isRecovered(),
+     identifier:String = engine.getId()
+IF (NOT recovered)
+DO traceln("log", "JVM exit"),
+   debug("close on non-recovered coordinator completion engine " + identifier),
+   debug("!!!killing JVM!!!"),
+   killJVM()
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a non-recovered coordinator completion
+# participant stub (CoordinatorCompletionCoordinatorEngine) is requested
+# to send a complete message. It traces the call.
+
+RULE trace coordinator completion complete
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorCompletionCoordinatorEngine
+METHOD complete
+AFTER SYNCHRONIZE
+BIND engine:CoordinatorEngine = $0,
+     recovered:boolean = engine.isRecovered(),
+     identifier:String = engine.getId()
+IF NOT recovered
+DO debug("complete on recovered coordinator completion participant engine " + identifier),
+   traceln("log", "complete on recovered coordinator completion participant engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a non-recovered participant completion
+# participant stub (ParticipantCompletionCoordinatorEngine) receives a
+# completed message. It traces the call.
+
+RULE trace participant completion completed
+CLASS com.arjuna.wst11.messaging.engines.ParticipantCompletionCoordinatorEngine
+METHOD completed(NotificationType, MAP, ArjunaContext)
+AT ENTRY
+BIND engine:CoordinatorEngine = $0,
+     recovered:boolean = engine.isRecovered(),
+     identifier:String = engine.getId()
+IF NOT recovered
+DO debug("received completed message for participant completion participant stub " + identifier),
+   traceln("log", "received completed message for participant completion participant stub " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a non-recovered coordinator completion
+# participant stub (CoordinatorCompletionCoordinatorEngine) receives a
+# completed message. It traces the call.
+
+RULE trace coordinator completion completed
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorCompletionCoordinatorEngine
+METHOD completed(NotificationType, MAP, ArjunaContext)
+AT ENTRY
+BIND engine:CoordinatorEngine = $0,
+     recovered:boolean = engine.isRecovered(),
+     identifier:String = engine.getId()
+IF NOT recovered
+DO debug("received completed message for coordinator completion participant stub " + identifier),
+   traceln("log", "received completed message for coordinator completion participant stub " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a non-recovered participant completion
+# participant stub (ParticipantCompletionCoordinatorEngine) receives an
+# exit message. It traces the call.
+
+RULE trace participant completion exit
+CLASS com.arjuna.wst11.messaging.engines.ParticipantCompletionCoordinatorEngine
+METHOD exit(NotificationType, MAP, ArjunaContext)
+AT ENTRY
+BIND engine:CoordinatorEngine = $0,
+     recovered:boolean = engine.isRecovered(),
+     identifier:String = engine.getId()
+IF NOT recovered
+DO debug("received exit message for participant completion participant stub " + identifier),
+   traceln("log", "received exit message for participant completion participant stub " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a non-recovered coordinator completion
+# participant stub (CoordinatorCompletionCoordinatorEngine) receives an
+# exit message. It traces the call.
+
+RULE trace coordinator completion exit
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorCompletionCoordinatorEngine
+METHOD exit(NotificationType, MAP, ArjunaContext)
+AT ENTRY
+BIND engine:CoordinatorEngine = $0,
+     recovered:boolean = engine.isRecovered(),
+     identifier:String = engine.getId()
+IF NOT recovered
+DO debug("received exit message for coordinator completion participant stub " + identifier),
+   traceln("log", "received exit message for coordinator completion participant stub " + identifier)
+ENDRULE
+
+#######################################################################
+## rules for reboot run of AS
+
+#######################################################################
+# This rule is triggered when a participant completion participant stub
+# (ParticipantCompletionCoordinatorEngine) is created from details
+# located in the log record. It traces the create operation
+# The trigger location is at entry but the rule should only be triggered
+# after calling the super constructor
+
+RULE trace participant completion engine create
+CLASS com.arjuna.wst11.messaging.engines.ParticipantCompletionCoordinatorEngine
+METHOD <init>(String, W3CEndpointReference, State, boolean)
+AT ENTRY
+BIND identifier = $1,
+     recovered=$4
+IF recovered
+DO debug("created recovered participant completion participant stub " + identifier),
+   traceln("log", "created recovered participant completion participant stub " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a coordinator completion participant stub
+# (CoordinatorCompletionCoordinatorEngine) is created from details
+# located in the log record. It traces the create operation
+# The trigger location is at entry but the rule should only be triggered
+# after calling the super constructor
+
+RULE trace coordinator completion engine create
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorCompletionCoordinatorEngine
+METHOD <init>(String, W3CEndpointReference, State, boolean)
+AT ENTRY
+BIND identifier = $1,
+     recovered=$4
+IF recovered
+DO debug("created recovered coordinator completion participant stub " + identifier),
+   traceln("log", "created recovered coordinator completion participant stub " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a recovered participant completion
+# participant stub (ParticipantCompletionCoordinatorEngine) is requested
+# to send a close message. This happens during replay of a prepared TX from
+# the log. It traces the call.
+
+RULE trace participant completion close
+CLASS com.arjuna.wst11.messaging.engines.ParticipantCompletionCoordinatorEngine
+METHOD close
+AFTER SYNCHRONIZE
+BIND engine:CoordinatorEngine = $0,
+     recovered:boolean = engine.isRecovered(),
+     identifier:String = engine.getId()
+IF recovered
+DO debug("close on recovered participant completion participant engine " + identifier),
+   traceln("log", "close on recovered participant completion participant engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a recovered coordinator completion
+# participant stub (CoordinatorCompletionCoordinatorEngine) is requested
+# to send a close message. This happens during replay of a prepared TX from
+# the log. It traces the call.
+
+RULE trace coordinator completion close
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorCompletionCoordinatorEngine
+METHOD close
+AFTER SYNCHRONIZE
+BIND engine:CoordinatorEngine = $0,
+     recovered:boolean = engine.isRecovered(),
+     identifier:String = engine.getId()
+IF recovered
+DO debug("close on recovered coordinator completion participant engine " + identifier),
+   traceln("log", "close on recovered coordinator completion participant engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a non-recovered participant completion
+# participant stub (ParticipantCompletionCoordinatorEngine) receives a
+# closed message. It traces the call.
+
+RULE trace participant completion closed
+CLASS com.arjuna.wst11.messaging.engines.ParticipantCompletionCoordinatorEngine
+METHOD closed(NotificationType, MAP, ArjunaContext)
+AT ENTRY
+BIND engine:CoordinatorEngine = $0,
+     recovered:boolean = engine.isRecovered(),
+     identifier:String = engine.getId()
+IF NOT recovered
+DO debug("received closed message for participant completion participant stub " + identifier),
+   traceln("log", "received closed message for participant completion participant stub " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a non-recovered coordinator completion
+# participant stub (CoordinatorCompletionCoordinatorEngine) receives a
+# closed message. It traces the call.
+
+RULE trace coordinator completion closed
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorCompletionCoordinatorEngine
+METHOD closed(NotificationType, MAP, ArjunaContext)
+AT ENTRY
+BIND engine:CoordinatorEngine = $0,
+     recovered:boolean = engine.isRecovered(),
+     identifier:String = engine.getId()
+IF NOT recovered
+DO debug("received closed message for coordinator completion participant stub " + identifier),
+   traceln("log", "received closed message for coordinator completion participant stub " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when the recovery system finds a PREPARED
+# activity in the log and reruns the phase 2 commit operation.
+# It prints a message which can be used to verify that the test has
+# progressed as expected.
+
+RULE trace prepared replay
+CLASS org.jboss.jbossts.xts.recovery.coordinator.ba.RecoverACCoordinator
+METHOD replayPhase2
+AT INVOKE phase2Commit
+BIND coordinator = $0,
+     uid : Uid = coordinator.identifier(),
+     status : int = coordinator.status()
+IF (status == com.arjuna.ats.arjuna.coordinator.ActionStatus.PREPARED)
+     OR
+     (status == com.arjuna.ats.arjuna.coordinator.ActionStatus.COMMITTING)
+DO debug("replaying close for prepared activity " + uid),
+   traceln("log", "replaying close for prepared activity " + uid)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when the recovery system deletes the COMMITTED
+# activity from the log. It prints a message which can be used to
+# verify that the test has completed. As a convenience itt also kills
+# the JVM to halt the test.
+
+RULE trace remove committed state
+CLASS com.arjuna.ats.arjuna.coordinator.BasicAction
+METHOD updateState
+AFTER CALL remove_committed
+BIND action : BasicAction = $0,
+     uid  = action.get_uid()
+IF TRUE
+DO traceln("log", "removed committed activity " + uid),
+   debug("removed committed transaction " + uid),
+   debug("!!!killing JVM!!!"),
+   killJVM()
+ENDRULE

Added: labs/jbosstm/trunk/XTS/localjunit/crash-recovery-tests/src/test/resources/scripts/BACrashDuringOnePhaseCommit.txt
===================================================================
--- labs/jbosstm/trunk/XTS/localjunit/crash-recovery-tests/src/test/resources/scripts/BACrashDuringOnePhaseCommit.txt	                        (rev 0)
+++ labs/jbosstm/trunk/XTS/localjunit/crash-recovery-tests/src/test/resources/scripts/BACrashDuringOnePhaseCommit.txt	2011-12-15 07:52:45 UTC (rev 37804)
@@ -0,0 +1,688 @@
+##############################################################################
+# JBoss, Home of Professional Open Source
+# Copyright 2009, Red Hat Middleware LLC, and individual contributors
+# 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.
+#
+# @authors Andrew Dinn
+#
+# BA Crash During Commit
+#
+# This script automates testing of a specific recovery scenario for the
+# JBossTS XTS implementation of the WS-BA 1.1 protocol using orchestration
+# rules. The basic scenario employs a client, coordinator and a web service
+# running in a single JVM but it is possible for the coordinator and web
+# service to be lcoated in separate JVMs if a supplementary rule set is employed
+# in the coordinator JVM. The description below refers to two ASes AS1 and AS2
+# running the client/coordinator and web service, respectively. In the conventional
+# scenario these refer to the same AS running in one JVM.
+#
+# The scenario contains variations depending upon whether the web service employed
+# uses Participant Completion or Coordinator Completion. The same script can be
+# used for either of these cases, the choice of which participant is used being
+# determined by the test program.
+#
+# The scenario is as follows (** indicates intercession by a Byteman rule):
+#
+# AS1 boots
+# AS2 boots
+# AS1 Client starts a WS-BA activity
+# AS1 Client invokes web service
+# AS2 Web service registers participant P1
+#
+# Alternative A (assumes participant completion participants)
+# Client invokes web service with command P1 complete
+# Web service sends completed for participant 1
+# ** AS2 Rule system traces send of completed
+# Coordinator receives completed for participant 1
+# ** AS1 Rule system traces receipt of completed
+# End Alternative A
+#
+# AS1 Client closes WS-BA activity
+#
+# Alternative B (assumes coordinator completion participants)
+# AS1 Coordinator sends complete to participant P1
+# ** AS1 Rule system traces send of complete
+# Web service receives complete for participant 1
+# ** AS2 Rule system traces receipt of complete
+# Web service sends completed for participant 1
+# ** AS2 Rule system traces send of completed
+# Coordinator receives completed for participant 1
+# ** AS1 Rule system traces receipt of completed
+# End Alternative B
+#
+# AS1 Coordinator initiates close of participant P1
+# AS1 Coordinator sends close to participant P1
+# -- Extra steps if AS1 != AS2
+# ** AS1 Rule system intercepts after send of close has
+#    completed and crashes JVM
+# -- End of extra steps
+#
+# AS2 Participant receives close for participant P1
+# ** AS2 Rule system traces receipt of close and kills JVM
+#
+# AS1 reboots
+# AS2 reboots
+# AS2 Recovery system starts after 2 minutes
+# AS2 Recovery system recreates PREPARED WS-BA activity coordinator
+# ** AS2 Rule system traces create
+# AS2 Recovery system recreates participant stub for P1
+# ** AS2 Rule system traces create
+# AS2 Recovery system sends getstatus for P1
+# ** AS2 Rule system traces send of getstatus
+#
+# AS1 Coordinator receives getstatus for P1
+# ** AS1 Rule system traces receipt of getstatus
+# AS1 Coordinator sends invalidstate fault for P1
+# ** AS1 Rule system traces send of invalidstate fault
+# -- Extra steps if AS1 != AS2
+# AS1 Coordinator completes send invalidstate fault
+# ** AS1 Rule system kills JVM
+# -- End of extra steps
+#
+# AS2 P1 receives invalidstate fault
+# ** AS2 Rule system traces receipt of invalidstate fault
+# AS2 P1 calls participant compensate method
+# ** AS2 Rule system traces call of participant compensate method
+# AS2 P1 completes handling invalidstate fault
+# ** AS2 Rule system kills JVM
+#
+# Use of this script
+#
+# The default way of exercising this test is to deploy the xtstest war
+# to a single AS and configure it to run the relevant XTS Service Test.
+# The web service and coordinator will normally be located with the client.
+# The AS should crash when the participant is told to close. At reboot
+# the recovery should run automatically and the server should be killed
+# once the participant compensate method has returned.
+#
+# This script allows for registration of either participant completion
+# or coordinator completion participants (alternatives A or B). It is
+# legitimate to mix the different types. However, if participant completion
+# participants are used then the client must script the participants
+# to perform a complete.
+#
+# This script contians rules which respond to events triggered by either the
+# XTS coordinator services or the XTS participant services. It needs to be
+# passed to a Byteman agent in the JVM running these services both at first boot
+# and at reboot. Output will be written to file testlog in the working directory
+# of the coordinator/participant AS. If two separate ASes are employed for the
+# coordinator and participant then they need to employ different working
+# directories so that one AS does not trash the output from the other AS.
+# With two ASes the coordinator AS needs to be provided with a supplementary
+# script containing the extra rules needed to crash the coordinator JVM.
+#
+# XTS Service tests which can operate with this scenario can be selected for
+# execution by the XTSServiceTestRunnerBean at AS boot by setting system
+# property
+#    org.jboss.jbossts.xts.servicetests.XTSServiceTestName
+# to the name of a class which will execute the test. This property must
+# be defined in the JVM running the AS to which the xtstest war is deployed
+# i.e. the client AS. n.b. if the client is colocated with the coordinator then
+# this property must be left undefined at AS reboot otherwise the client
+# will run again, starting a new TX which may interfere with recovery of the
+# crashed TX.
+#
+# Available tests include:
+#
+# org.jboss.jbossts.xts.servicetests.test.ba.SingleCoordinatorCompletionParticipantCloseTest
+# this test invokes a single service registering a coordinator completion participant
+# and then closing the activity
+# the location of the service is defined by defining a system property:
+#    org.jboss.jbossts.xts.servicetests.ServiceURL1
+# if this is not set the value used defaults to
+#    http://localhost:8080/xtstest/xtsservicetest1
+#
+# org.jboss.jbossts.xts.servicetests.test.ba.SingleParticipantCompletionParticipantCloseTest
+# this test invokes a single service registering a participant completion participant
+# it sends completed to the participant before closing the activity
+# the location of service is defined by defining a system property:
+#    org.jboss.jbossts.xts.servicetests.ServiceURL1
+# if this is not set the value used defaults to
+#    http://localhost:8080/xtstest/xtsservicetest1
+#
+# If the client is run in a different AS to the coordinator then the client
+# AS needs to be pointed at the coordinator AS. The easiest
+# way to do this is to define the system property
+#
+#    org.jboss.jbossts.xts11.coordinatorURL
+#
+# to something like
+#
+#    http://foo.bar.org:8080/ws-c11/soap/ActivationCoordinator
+#
+# or alternatively to redefine one or more of the component properties
+#
+#    org.jboss.jbossts.xts11.coordinator.host
+#    org.jboss.jbossts.xts11.coordinator.port
+#    org.jboss.jbossts.xts11.coordinator.path
+#
+# (you probably only need to reset the host component)
+#
+# Expected output
+#
+# After the first boot AS1 should exit leaving output in the following
+# format in file testlog
+#
+#   sent complete message for XXXXXXX completion engine XXXXXX
+#   received completed message for XXXXXXX completion engine XXXXXX
+#   sent close message for XXXXXXX completion engine XXXXXX
+#   JVM exit
+#
+# AS2 should exit leaving output in the following format in file testlog
+#
+#   received complete message for XXXXXXX completion participant XXXXXX
+#   sent completed message for XXXXXXX completion participant XXXXXX
+#   received close message for XXXXXXX completion participant XXXXXX
+#   JVM exit
+#
+# After reboot AS1 should exit leaving output in the following format in file
+# testlog
+#
+#   sent complete message for XXXXXXX completion engine XXXXXX
+#   received completed message for XXXXXXX completion engine XXXXXX
+#   sent close message for XXXXXXX completion engine XXXXXX
+#   JVM exit
+#   received getstatus for unknown XXXXXXX completion participant XXXXXX
+#   sent invalidstate fault for unknown XXXXXXX completion participant XXXXXX
+#   JVM exit
+#
+# AS2 should exit leaving output in the following format in file testlog
+#
+#   received complete message for XXXXXXX completion participant XXXXXX
+#   sent completed message for XXXXXXX completion participant XXXXXX
+#   received close message for XXXXXXX completion participant XXXXXX
+#   JVM exit
+#   recreated XXXXXXX completion participant XXXXXX
+#   sent getstatus for XXXXXXX completion participant XXXXXX
+#   received invalidstate fault for XXXXXXX completion participant XXXXXX
+#   compensated recovered XXXXXXX completion participant XXXXXX
+#   JVM exit
+#
+#######################################################################
+# This rule opens a file for the trace output during XTS startup
+# It will be opened for append at reboot so messages from both runs
+# will go to this file
+#
+RULE open trace file
+CLASS org.jboss.jbossts.XTSService
+METHOD start()
+BIND NOTHING
+IF TRUE
+DO openTrace("log", "testlog")
+ENDRULE
+
+#######################################################################
+## rules for first run of AS1 (coordinator AS)
+
+#######################################################################
+# This rule is triggered when a non-recovered coordinator completion
+# participant stub (CoordinatorCompletionCoordinatorEngine) is sent
+# a complete message. It traces the message.
+# The trigger location is at the call to waitForState which ensures
+# that the complete message has been dispatched to the participant.
+
+RULE trace coordinator completion complete
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorCompletionCoordinatorEngine
+METHOD complete
+AT INVOKE waitForState
+BIND engine:CoordinatorCompletionCoordinatorEngine = $0,
+     recovered:boolean = engine.isRecovered(),
+     identifier:String = engine.getId()
+IF (NOT recovered)
+DO traceln("log", "sent complete message for coordinator completion engine " + identifier),
+   debug("sent complete message for coordinator completion engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a non-recovered coordinator completion
+# participant stub (CoordinatorCompletionCoordinatorEngine) receives
+# a completed message. It traces the message.
+
+RULE trace coordinator completion completed
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorCompletionCoordinatorEngine
+METHOD completed
+AT ENTRY
+BIND engine:CoordinatorCompletionCoordinatorEngine = $0,
+     recovered:boolean = engine.isRecovered(),
+     identifier:String = engine.getId()
+IF (NOT recovered)
+DO traceln("log", "received completed message for coordinator completion engine " + identifier),
+   debug("received completed message for coordinator completion engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a non-recovered participant completion
+# participant stub (CoordinatorCompletionCoordinatorEngine) receives
+# a completed message. It traces the message.
+
+RULE trace participant completion completed
+CLASS com.arjuna.wst11.messaging.engines.ParticipantCompletionCoordinatorEngine
+METHOD completed
+AT ENTRY
+BIND engine:ParticipantCompletionCoordinatorEngine = $0,
+     recovered:boolean = engine.isRecovered(),
+     identifier:String = engine.getId()
+IF (NOT recovered)
+DO traceln("log", "received completed message for participant completion engine " + identifier),
+   debug("received completed message for participant completion engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a non-recovered participant completion
+# participant stub (ParticipantCompletionCoordinatorEngine) is sent
+# a close message. It exits the JVM, simulating a crash.
+# The trigger location is at the call to waitForState which ensures
+# that the close message has been dispatched to the participant.
+# This rule is only required when the coordinator is located in a
+# separate JVM to the participant
+
+# RULE kill JVM at participant completion close
+# CLASS com.arjuna.wst11.messaging.engines.ParticipantCompletionCoordinatorEngine
+# METHOD close
+# AT INVOKE waitForState
+# BIND engine:ParticipantCompletionCoordinatorEngine = $0,
+#      recovered:boolean = engine.isRecovered(),
+#      identifier:String = engine.getId()
+# IF (NOT recovered)
+# DO traceln("log", "sent close message for participant completion engine " + identifier),
+#    debug("sent close message for participant completion engine " + identifier),
+#    traceln("log", "JVM exit"),
+#    debug("!!!killing JVM!!!"),
+#    killJVM()
+# ENDRULE
+
+#######################################################################
+# This rule is triggered when a non-recovered coordinator completion
+# participant stub (CoordinatorCompletionCoordinatorEngine) is sent
+# a close message. It exits the JVM, simulating a crash.
+# The trigger location is at the call to waitForState which ensures
+# that the close message has been dispatched to the participant.
+# This rule is only required when the coordinator is located in a
+# separate JVM to the participant
+
+# RULE kill JVM at coordinator completion close
+# CLASS com.arjuna.wst11.messaging.engines.CoordinatorCompletionCoordinatorEngine
+# METHOD close
+# AT ENTRY
+# BIND engine:CoordinatorCompletionCoordinatorEngine = $0,
+#      recovered:boolean = engine.isRecovered(),
+#      identifier:String = engine.getId()
+# IF (NOT recovered)
+# DO traceln("log", "sent close message for coordinator completion engine " + identifier),
+#    debug("sent close message for coordinator completion engine " + identifier),
+#    traceln("log", "JVM exit"),
+#    debug("!!!killing JVM!!!"),
+#    killJVM()
+# ENDRULE
+
+#######################################################################
+## rules for first run of AS2 (participant)
+
+#######################################################################
+# This rule is triggered when a non-recovered participant completion
+# participant (ParticipantCompletionParticipantEngine) receives
+# a close message. It exits the JVM, simulating a crash.
+
+RULE kill JVM at participant completion participant close
+CLASS com.arjuna.wst11.messaging.engines.ParticipantCompletionParticipantEngine
+METHOD close
+AT ENTRY
+BIND engine:ParticipantCompletionParticipantEngine = $0,
+     recovered:boolean = engine.isRecovered(),
+     identifier:String = engine.getId()
+IF (NOT recovered)
+DO traceln("log", "received close message for participant completion participant " + identifier),
+   debug("received close message for participant completion participant " + identifier),
+   traceln("log", "JVM exit"),
+   debug("!!!killing JVM!!!"),
+   killJVM()
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a non-recovered coordinator completion
+# participant (CoordinatorCompletionParticipantEngine) receives
+# a close message. It exits the JVM, simulating a crash.
+
+RULE kill JVM at coordinator completion participant close
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorCompletionParticipantEngine
+METHOD close
+AT ENTRY
+BIND engine:CoordinatorCompletionParticipantEngine = $0,
+     recovered:boolean = engine.isRecovered(),
+     identifier:String = engine.getId()
+IF (NOT recovered)
+DO traceln("log", "received close message for coordinator completion participant " + identifier),
+   debug("received close message for coordinator completion participant " + identifier),
+   traceln("log", "JVM exit"),
+   debug("!!!killing JVM!!!"),
+   killJVM()
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a participant completion
+# participant (ParticipantCompletionParticipantEngine) sends
+# a completed message. It traces the call.
+
+RULE trace participant completion participant send completed
+CLASS com.arjuna.wst11.messaging.engines.ParticipantCompletionParticipantEngine
+METHOD completed
+AFTER INVOKE sendCompleted
+BIND engine:ParticipantCompletionParticipantEngine = $0,
+     identifier:String = engine.getId()
+IF TRUE
+DO traceln("log", "sent completed message for participant completion participant " + identifier),
+   debug("sent completed message for participant completion participant " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a coordinator completion
+# participant (CoordinatorCompletionParticipantEngine) receives
+# a complete message. It traces the call.
+
+RULE trace coordinator completion participant receive complete
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorCompletionParticipantEngine
+METHOD complete
+AT ENTRY
+BIND engine:CoordinatorCompletionParticipantEngine = $0,
+     identifier:String = engine.getId()
+IF TRUE
+DO traceln("log", "received complete message for coordinator completion participant " + identifier),
+   debug("received complete message for coordinator completion participant " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a coordinator completion
+# participant (CoordinatorCompletionParticipantEngine) sends
+# a completed message. It traces the call.
+
+RULE trace coordinator completion participant send completed
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorCompletionParticipantEngine
+METHOD complete
+AFTER INVOKE sendCompleted
+BIND engine:CoordinatorCompletionParticipantEngine = $0,
+     identifier:String = engine.getId()
+IF TRUE
+DO traceln("log", "sent completed message for coordinator completion participant " + identifier),
+   debug("sent completed message for coordinator completion participant " + identifier)
+ENDRULE
+
+#######################################################################
+## rules for reboot run of AS1 (coordinator)
+
+#######################################################################
+# This rule is triggered when a coordinator completion coordinator
+# processor (CoordinatorCompletionCoordinatorProcessorImpl) receives
+# a getstatus message for an unknown participant. It traces the call.
+
+RULE trace getstatus for unknown coordinator completion participant
+CLASS com.arjuna.wst11.messaging.CoordinatorCompletionCoordinatorProcessorImpl
+METHOD getStatus
+AT INVOKE sendSoapFault
+BIND identifier:String = $3.getInstanceIdentifier().getInstanceIdentifier()
+IF TRUE
+DO traceln("log", "received getstatus message for unknown coordinator completion participant engine " + identifier),
+   debug("received getstatus message for unknown coordinator completion participant engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a participant completion coordinator
+# processor (ParticipantCompletionCoordinatorProcessorImpl) receives
+# a getstatus message for an unknown participant. It traces the call.
+
+RULE trace getstatus for unknown participant completion participant
+CLASS com.arjuna.wst11.messaging.ParticipantCompletionCoordinatorProcessorImpl
+METHOD getStatus
+AT INVOKE sendSoapFault
+BIND identifier:String = $3.getInstanceIdentifier().getInstanceIdentifier()
+IF TRUE
+DO traceln("log", "received getstatus message for unknown participant completion participant engine " + identifier),
+   debug("received getstatus message for unknown participant completion participant engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a coordinator completion coordinator
+# processor (CoordinatorCompletionCoordinatorProcessorImpl) sends
+# an invalidstate fault for an unknown participant. It traces the call.
+
+RULE trace send invalidstate for coordinator completion participant
+CLASS com.arjuna.wst11.messaging.CoordinatorCompletionCoordinatorProcessorImpl
+METHOD getStatus
+AT INVOKE sendSoapFault
+BIND identifier:String = $3.getInstanceIdentifier().getInstanceIdentifier()
+IF TRUE
+DO traceln("log", "sent invalidstate fault for coordinator completion participant engine " + identifier),
+   debug("sent invalidstate fault for coordinator completion participant engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a participant completion coordinator
+# processor (ParticipantCompletionCoordinatorProcessorImpl) sends
+# an invalidstate fault for an unknown participant. It traces the call.
+
+RULE trace send invalidstate for participant completion participant
+CLASS com.arjuna.wst11.messaging.ParticipantCompletionCoordinatorProcessorImpl
+METHOD getStatus
+AT INVOKE sendSoapFault
+BIND identifier:String = $3.getInstanceIdentifier().getInstanceIdentifier()
+IF TRUE
+DO traceln("log", "sent invalidstate fault for participant completion participant engine " + identifier),
+   debug("sent invalidstate fault for participant completion participant engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered after a coordinator completion coordinator
+# processor (CoordinatorCompletionCoordinatorProcessorImpl) sends
+# an invalidstate fault for an unknown participant. It exits the JVM.
+# This rule is only required when the coordinator is located in a
+# separate JVM to the participant
+
+# RULE kill JVM after send invalidstate for coordinator completion participant
+# CLASS com.arjuna.wst11.messaging.CoordinatorCompletionCoordinatorProcessorImpl
+# METHOD getStatus
+# AFTER INVOKE sendSoapFault
+# BIND NOTHING
+# IF TRUE
+# DO traceln("log", "kill JVM"),
+#    debug("!!! killing JVM !!!")
+# ENDRULE
+
+#######################################################################
+# This rule is triggered after a participant completion coordinator
+# processor (ParticipantCompletionCoordinatorProcessorImpl) receives
+# an invalidstate fault for an unknown participant.It exits the JVM.
+# This rule is only required when the coordinator is located in a
+# separate JVM to the participant
+
+# RULE kill JVM after send invalidstate for participant completion participant
+# CLASS com.arjuna.wst11.messaging.ParticipantCompletionCoordinatorProcessorImpl
+# METHOD getStatus
+# AFTER INVOKE sendSoapFault
+# BIND NOTHING
+# IF TRUE
+# DO traceln("log", "kill JVM"),
+#    debug("!!! killing JVM !!!")
+# ENDRULE
+
+#######################################################################
+## rules for reboot run of AS2 (participant)
+
+#######################################################################
+# This rule is triggered when a participant completion participant
+# (ParticipantCompletionParticipantEngine) is created from details
+# located in the log record. It traces the create operation
+# The trigger location is at entry but the rule should only be triggered
+# after calling the super constructor
+RULE trace participant completion participant create
+CLASS com.arjuna.wst11.messaging.engines.ParticipantCompletionParticipantEngine
+METHOD <init>(String, W3CEndpointReference, BusinessAgreementWithParticipantCompletionParticipant, State, boolean)
+AT ENTRY
+BIND identifier = $1,
+     recovered=$5
+IF recovered
+DO debug("created recovered participant completion participant " + identifier),
+   traceln("log", "created recovered participant completion participant " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a coordinator completion participant
+# (CoordinatorCompletionParticipantEngine) is created from details
+# located in the log record. It traces the create operation
+# The trigger location is at entry but the rule should only be triggered
+# after calling the super constructor
+RULE trace coordinator completion participant create
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorCompletionParticipantEngine
+METHOD <init>(String, W3CEndpointReference, BusinessAgreementWithCoordinatorCompletionParticipant, State, boolean)
+AT ENTRY
+BIND identifier = $1,
+     recovered=$5
+IF recovered
+DO debug("created recovered coordinator completion participant " + identifier),
+   traceln("log", "created recovered coordinator completion participant " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a recovered participant completion
+# participant stub (ParticipantCompletionParticipantEngine) sends
+# a getstatus message. It traces the call.
+
+RULE trace participant completion participant send getstatus
+CLASS com.arjuna.wst11.messaging.engines.ParticipantCompletionParticipantEngine
+METHOD sendCompleted(boolean)
+AFTER INVOKE sendGetStatus
+BIND engine:ParticipantCompletionParticipantEngine = $0,
+     recovered:boolean = engine.isRecovered(),
+     identifier:String = engine.getId()
+IF recovered
+DO debug("sent getstaus for recovered participant completion participant " + identifier),
+   traceln("log", "sent getstaus for recovered participant completion participant " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a recovered coordinator completion
+# participant stub (CoordinatorCompletionParticipantEngine) sends
+# a getstatus message. It traces the call.
+
+RULE trace coordinator completion participant send getstatus
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorCompletionParticipantEngine
+METHOD sendCompleted(boolean)
+AFTER INVOKE sendGetStatus
+BIND engine:CoordinatorCompletionParticipantEngine = $0,
+     recovered:boolean = engine.isRecovered(),
+     identifier:String = engine.getId()
+IF recovered
+DO debug("sent getstaus for recovered coordinator completion participant " + identifier),
+   traceln("log", "sent getstaus for recovered coordinator completion participant " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a participant completion participant
+# processor (ParticipantCompletionParticipantProcessorImpl) receives an
+# invalidstate fault and notifies the participant engine. It traces the call.
+
+RULE trace participant completion participant receives invalidstate
+CLASS com.arjuna.wst11.messaging.ParticipantCompletionParticipantProcessorImpl
+METHOD soapFault
+AT INVOKE soapFault
+BIND identifier:String =  $3.getInstanceIdentifier().getInstanceIdentifier()
+IF TRUE
+DO debug("received invalidstate fault for participant completion participant " + identifier),
+   traceln("log", "received invalidstate fault for participant completion participant " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a coordinator completion participant
+# processor (CoordinatorCompletionParticipantProcessorImpl) receives an
+# invalidstate fault and notifies the participant engine. It traces the call.
+
+RULE trace coordinator completion participant receives invalidstate
+CLASS com.arjuna.wst11.messaging.CoordinatorCompletionParticipantProcessorImpl
+METHOD soapFault
+AT INVOKE soapFault
+BIND identifier:String =  $3.getInstanceIdentifier().getInstanceIdentifier()
+IF TRUE
+DO debug("received invalidstate fault for coordinator completion participant " + identifier),
+   traceln("log", "received invalidstate fault for coordinator completion participant " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a recovered participant completion
+# participant stub (ParticipantCompletionParticipantEngine) handles an
+# invalidstate fault. It traces the call then exits the JVM.
+
+RULE trace participant completion participant handles invalidstate
+CLASS com.arjuna.wst11.messaging.engines.ParticipantCompletionParticipantEngine
+METHOD soapFault
+AFTER INVOKE compensate
+BIND engine:ParticipantCompletionParticipantEngine = $0,
+     recovered:boolean = engine.isRecovered(),
+     identifier:String = engine.getId()
+IF recovered
+DO debug("compensated recovered participant completion participant " + identifier),
+   traceln("log", "compensated recovered participant completion participant " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a recovered coordinator completion
+# participant stub (CoordinatorCompletionParticipantEngine) handles an
+# invalidstate fault. It traces the call then exits the JVM.
+
+RULE trace coordinator completion participant handles invalidstate
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorCompletionParticipantEngine
+METHOD soapFault
+AFTER INVOKE compensate
+BIND engine:CoordinatorCompletionParticipantEngine = $0,
+     recovered:boolean = engine.isRecovered(),
+     identifier:String = engine.getId()
+IF recovered
+DO debug("compensated recovered coordinator completion participant " + identifier),
+   traceln("log", "compensated recovered coordinator completion participant " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a participant completion participant
+# processor (ParticipantCompletionParticipantProcessorImpl) has finished
+# handling an invalidstate fault. It exits the JVM.
+
+RULE exit after participant completion participant handles invalidstate
+CLASS com.arjuna.wst11.messaging.ParticipantCompletionParticipantProcessorImpl
+METHOD soapFault
+AFTER INVOKE soapFault
+BIND identifier:String =  $3.getInstanceIdentifier().getInstanceIdentifier()
+IF TRUE
+DO debug("!!! killing JVM !!! " + identifier),
+   traceln("log", "JVM exit"),
+   killJVM()
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a coordinator completion participant
+# processor (CoordinatorCompletionParticipantProcessorImpl) has finished
+# handling an invalidstate fault. It exits the JVM.
+
+RULE exit after coordinator completion participant handles invalidstate
+CLASS com.arjuna.wst11.messaging.CoordinatorCompletionParticipantProcessorImpl
+METHOD soapFault
+AFTER INVOKE soapFault
+BIND identifier:String =  $3.getInstanceIdentifier().getInstanceIdentifier()
+IF TRUE
+DO debug("!!! killing JVM !!! " + identifier),
+   traceln("log", "JVM exit"),
+   killJVM()
+ENDRULE
+

Added: labs/jbosstm/trunk/XTS/localjunit/crash-recovery-tests/src/test/resources/scripts/BASubordinateCrashDuringCommit.txt
===================================================================
--- labs/jbosstm/trunk/XTS/localjunit/crash-recovery-tests/src/test/resources/scripts/BASubordinateCrashDuringCommit.txt	                        (rev 0)
+++ labs/jbosstm/trunk/XTS/localjunit/crash-recovery-tests/src/test/resources/scripts/BASubordinateCrashDuringCommit.txt	2011-12-15 07:52:45 UTC (rev 37804)
@@ -0,0 +1,939 @@
+##############################################################################
+# JBoss, Home of Professional Open Source
+# Copyright 2009, Red Hat Middleware LLC, and individual contributors
+# 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.
+#
+# @authors Andrew Dinn
+#
+# BA Subordinate Transaction Crash During Commit
+#
+# This script automates testing of a specific recovery scenario for the
+# JBossTS XTS implementation of the WS-BA 1.1 protocol using orchestration
+# rules. The basic scenario employs a coordinator, a subordinate coordinator
+# and 2 web services running in a single JVM, the second one employing local
+# (subordinate) coordination. It checks that the transaction rolls forward
+# after crashing the coordinator when it tries to initiate a close. The
+# scenario is as follows
+# (** indicates intercession by a Byteman rule):
+#
+# AS boots
+# Cient starts a WS-BA transaction T1
+# Client invokes web service S1 with enlistPC/CC request
+# S1 registers PC/CC participant P1 in T1
+# Client invokes subordinate web service S2 with enlistPC/CC request
+# S2 creates a subordinate BA transaction T2
+# S2 registers CC pseudo-participant PP in T1
+# S2 registers PC/CC participant P2 in T2
+# Client invokes subordinate web service S2 with enlistPC/CC  request
+# S2 resumes T2
+# S2 registers PC/CC participant P3 in T2
+#
+# (PC Participants only)
+# Client invokes web service S1 with complete request for P1
+# P1 sends completed
+# ** Rule system logs receipt of completed from P1
+# Client invokes subordinate web service S2 with complete request for P2
+# P2 sends completed
+# ** Rule system logs receipt of completed from P2
+# Client invokes subordinate web service S1 with complete request for P3
+# P3 sends completed
+# ** Rule system logs receipt of completed from P2
+# (end of PC Participants only)
+#
+# Client initiates transaction close for T1
+#
+# (CC Participants only)
+# Coordinator initiates complete of participant P1
+# ** Rule system logs dispatch of complete to P1
+# ** Rule system logs receipt of completed from P1
+# (end of CC Participants only)
+#
+# Coordinator initiates complete of subordinate participant PP
+# ** Rule system logs dispatch of complete to PP
+# PP calls subordinate coordinator complete
+# ** Rule system logs call to complete
+#
+# (CC Participants only)
+# Subordinate coordinator initiates complete of participant P2
+# ** Rule system logs dispatch of complete to P1
+# ** Rule system logs receipt of completed from P1
+# Subordinate coordinator initiates complete of participant P3
+# ** Rule system logs dispatch of complete to P1
+# ** Rule system logs receipt of completed from P1
+# (end of CC Participants only)
+#
+# Subordinate coordinator calls prepare for T2
+# ** Rule system logs prepare
+# Subordinate coordinator complete returns
+# ** Rule system logs return from complete
+# PP sends completed to coordinator
+# ** Rule system logs receipt of completed from PP
+#
+# Client closes transaction
+# Coordinator initiates close of participant P1
+# ** Rule system intercepts close and crashes JVM
+#
+# AS reboots
+# Recovery system starts after 2 minutes
+# Recovery system recreates transaction T1
+# ** Rule system traces create
+# Recovery system recreates transaction T2
+# ** Rule system traces create
+# Recovery system recreates participant engine for P1
+# ** Rule system traces create
+# Recovery system recreates participant engine for PP1
+# ** Rule system traces create
+# Recovery system recreates participant engine for P2
+# ** Rule system traces create
+# Recovery system recreates participant engine for P3
+# ** Rule system traces create
+# Recovery system recreates coordinator engine for P1
+# ** Rule system traces create
+# Recovery system recreates coordinator engine for PP1
+# ** Rule system traces create
+# Recovery system recreates coordinator engine for P2
+# ** Rule system traces create
+# Recovery system recreates coordinator engine for P3
+# ** Rule system traces create
+# Recovery system calls replay of COMPLETED transaction
+# ** Rule system traces COMPLETED replay invocation
+#
+# Coordinator sends close to P1
+# ** Rule system traces dispatch of close
+# P1 replies with closed
+# ** Rule system traces dispatch of closed
+#
+# Coordinator sends close to PP
+# ** Rule system traces dispatch of close
+#
+# (optional depending upon recovery timing)
+# PP throws System Exception because subordinate coordinator is not avaiable
+# ** Rule system traces call to close
+# Coordinator resends close to PP
+# ** Rule system traces dispatch of close
+# (end optional section -- n.b. may be repeated)
+#
+# PP calls subordinate coordinator close
+# ** Rule system traces call to close
+#
+# Subordinate coordinator sends close to P2
+# ** Rule system traces dispatch of close
+# P2 replies with closed
+# ** Rule system traces receipt of closed
+#
+# Subordinate oordinator sends close to P3
+# ** Rule system traces dispatch of close
+# P3 replies with closed
+# ** Rule system traces receipt of closed
+#
+# Subordinate coordinator deletes T2 from log
+# ** Rule system traces delete of T2
+#
+# return from subordinate coordinator close
+# ** Rule system traces return from close
+#
+# PP1 replies with closed
+# ** Rule system traces receipt of closed
+#
+# Coordinator deletes T1 from log and completes close
+# ** Rule system traces delete of T1
+# ** Rule system detects 2nd completed close and kills JVM
+#
+# Use of this script
+#
+# The default way of exercising this test is to deploy the xtstest war
+# to a single AS and configure it to run the relevant XTS Service Test.
+# The web services and coordinator will be located with the client.
+# The number of participants and subordinate participants can actually be
+# 2, 3 or more. The  web service(s), client (i.e. the XTS Service Test which
+# drives the test) and coordinator and subordinate coordinator service must
+# be colocated for this scritp to work (it is possible to distribute all of
+# these agents if desired but that woud lrequire more complex script rules).
+# The AS should crash when the client closes. At reboot the rest of the test
+# should run automatically and the server should be killed after the recovered
+# transaction is successfuly replayed.
+#
+# This script needs to be passed to a Byteman agent in the JVM running
+# the coordinator service both at first boot and at reboot. Output will be
+# written to file testlog in the working directory of the AS.
+#
+# XTS Service tests which can operate with this scenario can be selected for
+# execution at AS boot by the XTSServiceTestRunnerBean by setting system
+# property
+#    org.jboss.jbossts.xts.servicetests.XTSServiceTestName
+# to the name of a class which will execute the test. This property must
+# be defined in the JVM running the AS to which the xtstest war is deployed
+# i.e. the client AS. n.b. if the client is colocated with the coordinator then
+# this property must be left undefined at AS reboot otherwise the client
+# will run again, starting a new TX which may interfere with recovery of the
+# crashed TX. It is also possible to run the service test using the form
+# interface provided on the xtstest war's main index page.
+#
+# Available tests include:
+#
+# org.jboss.jbossts.xts.servicetests.test.ba.subordinate.MultiParticipantCoordinatorCompletionParticipantCloseTest
+# this test starts an activity then registers a CC participant with the service whose location is defined by
+# system property:
+#    org.jboss.jbossts.xts.servicetests.ServiceURL1
+# if this is not set the value used defaults to
+#    http://localhost:8080/xtstest/xtsservicetest1
+# the test then registers two CC participants with a second web service (which must install a
+# subordinate transaction) whose location is defined system property:
+#    org.jboss.jbossts.xts.servicetests.serviceURL1
+# if this is not set the value used defaults to
+#    http://localhost:8080/xtstest/xtssubservicetest1
+# The test then closes the transaction
+#
+# org.jboss.jbossts.xts.servicetests.test.ba.subordinate.MultiParticipantParticipantCompletionParticipantCloseTest
+# this test starts an activity then registers a PC participant with the service whose location is defined by
+# system property:
+#    org.jboss.jbossts.xts.servicetests.ServiceURL1
+# if this is not set the value used defaults to
+#    http://localhost:8080/xtstest/xtsservicetest1
+# the test then registers two PC participants with a second web service (which must install a
+# subordinate transaction) whose location is defined system property:
+#    org.jboss.jbossts.xts.servicetests.serviceURL1
+# if this is not set the value used defaults to
+#    http://localhost:8080/xtstest/xtssubservicetest1
+# The test then sends complete requests for all three participants and
+# closes the transaction
+#
+# Expected output
+#
+# After the first boot the JVM should exit leaving the following in file testlog
+# (the number and order of entries depends upon how many and which type of participants
+# are enlisted)
+#
+#   complete sent for CC participant XXXXXX ***
+#   complete received for CC participant XXXXXX  ***
+#   completed sent for CC/PC participant XXXXXX
+#   completed received for CC/PC participant XXXXXX
+#   complete sent for CC participant XXXXXX
+#   complete received for CC participant XXXXXX
+#   complete called for pseudo participant XXXXXX
+#   complete sent for CC participant XXXXXX ***
+#   complete received for CC participant XXXXXX ***
+#   completed sent for CC participant XXXXXX
+#   completed received for CC participant XXXXXX
+#   prepare for transaction XXXXXX
+#   saved to disk transaction XXXXXX
+#   complete returned for pseudo participant XXXXXX
+#   completed sent for CC participant XXXXXX
+#   completed received for CC participant XXXXXX
+#   saved to disk transaction XXXXXX
+#   JVM exit
+#
+# n.b. *** indicates trace which may be omitted
+#      there should be at least one completed sent/received message received for each CC/PC participant
+#        trace for PC participant completed will precede the call to pseudo participant complete
+#      there should also be at least one complete sent/received message received for each CC participant
+#        plus an extra complete sent/received message for the pseduo-participant (it is always registered as CC)
+#      there should be at least one complete called/complete returned message for the pseudo participant
+#
+# and in some cases there may be repeat messages
+#
+# After reboot the JVM should exit leaving output in the following format in file
+# testlog.
+#
+#   complete sent for CC participant XXXXXX ***
+#   complete received for CC participant XXXXXX  ***
+#   completed sent for CC/PC participant XXXXXX
+#   completed received for CC/PC participant XXXXXX
+#   complete sent for CC participant XXXXXX
+#   complete received for CC participant XXXXXX
+#   complete called for pseudo participant XXXXXX
+#   complete sent for CC participant XXXXXX ***
+#   complete received for CC participant XXXXXX ***
+#   completed sent for CC participant XXXXXX
+#   completed received for CC participant XXXXXX
+#   prepare for transaction XXXXXX
+#   saved to disk transaction XXXXXX
+#   complete returned for pseudo participant XXXXXX
+#   completed sent for CC participant XXXXXX
+#   completed received for CC participant XXXXXX
+#   saved to disk transaction XXXXXX
+#   JVM exit
+#   created recovered CC/PC participant engine XXXXXX
+#   created recovered CC/PC participant engine XXXXXX
+#   created recovered CC/PC participant engine XXXXXX
+#   created recovered CC/PC participant engine XXXXXX
+#   created recovered CC/PC coordinator engine XXXXXX
+#   created recovered CC/PC coordinator engine XXXXXX
+#   created recovered CC/PC coordinator engine XXXXXX
+#   created recovered CC/PC coordinator engine XXXXXX
+#   reinstated prepared subordinate transaction XXXXXX
+#   replaying commit for prepared transaction XXXXXX
+#   close sent for participant engine XXXXXX
+#   close received for participant XXXXXX
+#   closed sent for participant XXXXXX
+#   closed received for participant engine XXXXXX
+#   close sent for participant engine XXXXXX
+#   close received for participant XXXXXX
+#   close called for pseudo participant XXXXXX
+#   close called for subordinate coordinator XXXXXX
+#   close sent for participant engine XXXXXX
+#   close received for participant XXXXXX
+#   closed sent for participant XXXXXX
+#   closed received for participant engine XXXXXX
+#   close sent for participant engine XXXXXX
+#   close received for participant XXXXXX
+#   closed sent for participant XXXXXX
+#   closed received for participant engine XXXXXX
+#   removed transaction XXXXXX
+#   close returned for subordinate coordinator XXXXXX
+#   close completed for pseudo participant XXXXXX
+#   closed sent for participant XXXXXX
+#   closed received for participant engine XXXXXX
+#   removed transaction XXXXXX
+#   JVM exit after removing both transactions
+#
+#######################################################################
+# This rule opens a file for the trace output during XTS startup
+# It will be opened for append at reboot so messages from both runs
+# will go to this file
+#
+RULE open trace file
+CLASS org.jboss.jbossts.XTSService
+METHOD start()
+BIND NOTHING
+IF TRUE
+DO openTrace("log", "testlog")
+ENDRULE
+
+#######################################################################
+# This rule resets the periodic recovery wait period to 10 seconds
+# in order to speed up the test
+#
+RULE reset periodic recovery wait time
+CLASS com.arjuna.ats.arjuna.common.RecoveryEnvironmentBean
+METHOD getPeriodicRecoveryPeriod()
+AT ENTRY
+IF TRUE
+DO return 10
+ENDRULE
+
+#######################################################################
+## rules for first run of AS
+
+#######################################################################
+# This rule is triggered when a non-recovered CC coordinator engine
+# (CoordinatorCompletionCoordinatorEngine) is sent a close message. It exits the JVM,
+# simulating a crash. The trigger location is on entry
+
+RULE kill JVM at coordinator completion close
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorCompletionCoordinatorEngine
+METHOD close
+AT ENTRY
+BIND engine:CoordinatorCompletionCoordinatorEngine = $0,
+     recovered:boolean = engine.isRecovered(),
+     identifier:String = engine.getId()
+IF (NOT recovered)
+   AND
+   debug("close on non-recovered CC coordinator engine " + identifier)
+DO traceln("log", "JVM exit"),
+   debug("!!!killing JVM!!!"),
+   killJVM()
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a non-recovered PC coordinator engine
+# (ParticipantCompletionCoordinatorEngine) is sent a close message. It exits the JVM,
+# simulating a crash. The trigger location is on entry
+
+RULE kill JVM at participant completion close
+CLASS com.arjuna.wst11.messaging.engines.ParticipantCompletionCoordinatorEngine
+METHOD close
+AT ENTRY
+BIND engine:ParticipantCompletionCoordinatorEngine = $0,
+     recovered:boolean = engine.isRecovered(),
+     identifier:String = engine.getId()
+IF (NOT recovered)
+   AND
+   debug("close on non-recovered PC coordinator engine " + identifier)
+DO traceln("log", "JVM exit"),
+   debug("!!!killing JVM!!!"),
+   killJVM()
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a CC coordinator engine
+# (CoordinatorCompletionCoordinatorEngine) is requested to send a complete message. It
+# traces the call.
+
+RULE trace send CC participant complete
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorCompletionCoordinatorEngine
+METHOD complete
+AFTER SYNCHRONIZE
+BIND engine:CoordinatorCompletionCoordinatorEngine = $0,
+     identifier:String = engine.getId()
+IF TRUE
+DO debug("complete sent for CC coordinator engine " + identifier),
+   traceln("log", "complete sent for CC coordinator engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a CC coordinator engine
+# (CoordinatorCompletionCoordinatorEngine) receives a completed message. It traces the call.
+
+RULE trace receive CC participant completed
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorCompletionCoordinatorEngine
+METHOD completed(NotificationType, MAP, ArjunaContext)
+AT ENTRY
+BIND engine:CoordinatorCompletionCoordinatorEngine = $0,
+     identifier:String = engine.getId()
+IF TRUE
+DO debug("completed received for CC coordinator engine " + identifier),
+   traceln("log", "completed received for CC coordinator engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a CC participant
+# (CoordinatorCompletionParticipantEngine) receives a complete message. It
+# traces the call.
+
+RULE trace receive CC participant complete
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorCompletionParticipantEngine
+METHOD complete
+AFTER SYNCHRONIZE
+BIND engine:CoordinatorCompletionParticipantEngine = $0,
+     identifier:String = engine.getId()
+IF TRUE
+DO debug("complete received for CC participant " + identifier),
+   traceln("log", "complete received for CC participant " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a CC participant
+# (CoordinatorCompletionParticipantEngine) is requested to send a completed message. It
+# traces the call.
+
+RULE trace send CC participant completed
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorCompletionParticipantEngine
+METHOD sendCompleted(boolean)
+AT INVOKE sendCompleted
+BIND engine:CoordinatorCompletionParticipantEngine = $0,
+     identifier:String = engine.getId()
+IF TRUE
+DO debug("completed sent for CC participant " + identifier),
+   traceln("log", "completed sent for CC participant " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a PC coordinator engine
+# (ParticipantCompletionCoordinatorEngine) receives a completed message. It traces the call.
+
+RULE trace receive participant completed
+CLASS com.arjuna.wst11.messaging.engines.ParticipantCompletionCoordinatorEngine
+METHOD completed(NotificationType, MAP, ArjunaContext)
+AT ENTRY
+BIND engine:ParticipantCompletionCoordinatorEngine = $0,
+     identifier:String = engine.getId()
+IF TRUE
+DO debug("completed received for PC coordinator engine " + identifier),
+   traceln("log", "completed received for PC coordinator engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a PC participant
+# (ParticipantCompletionParticipantEngine) is requested to send a completed message. It
+# traces the call.
+
+RULE trace send participant completed
+CLASS com.arjuna.wst11.messaging.engines.ParticipantCompletionParticipantEngine
+METHOD sendCompleted(boolean)
+AT INVOKE sendCompleted
+BIND engine:ParticipantCompletionParticipantEngine = $0,
+     identifier:String = engine.getId()
+IF TRUE
+DO debug("completed sent for PC participant " + identifier),
+   traceln("log", "completed sent for PC participant " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a subordinate pseudo participant
+# (SubordinateCoordinatorCompletionParticipantStub) is requested to send a completed message. It
+# traces the call.
+
+RULE trace subordinate participant stub complete
+CLASS com.arjuna.wst11.stub.SubordinateCoordinatorCompletionParticipantStub
+METHOD complete
+AT ENTRY
+BIND NOTHING
+IF TRUE
+DO debug("complete called for pseudo-participant " + $0),
+   traceln("log", "complete called for pseudo-participant " + $0)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a subordinate pseudo participant
+# (SubordinateCoordinatorCompletionParticipantStub) has forwarded a complete message. It
+# traces the call.
+
+RULE trace subordinate participant stub complete 2
+CLASS com.arjuna.wst11.stub.SubordinateCoordinatorCompletionParticipantStub
+METHOD complete
+AFTER INVOKE complete
+BIND NOTHING
+IF TRUE
+DO debug("complete returned for pseudo-participant " + $0),
+   traceln("log", "complete returned for pseudo-participant " + $0)
+ENDRULE
+
+#######################################################################
+## rules for reboot run of AS
+
+#######################################################################
+# This rule is triggered when a CC coordinator engine (CoordinatorCompletionCoordinatorEngine)
+# is created from details located in the log record. It traces the
+# create operation. The trigger location is at entry but the rule
+# should only be triggered after calling the super constructor
+
+RULE trace CC coordinator engine create
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorCompletionCoordinatorEngine
+METHOD <init>(String, W3CEndpointReference, State, boolean)
+AT ENTRY
+BIND identifier = $1,
+     recovered=$4
+IF recovered
+DO debug("created recovered CC coordinator engine " + identifier),
+   traceln("log", "created recovered CC coordinator engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a CC participant (CoordinatorCompletionParticipantEngine)
+# is created from details located in the log record. It traces the
+# create operation. The trigger location is at entry but the rule
+# should only be triggered after calling the super constructor
+
+RULE trace CC participant create
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorCompletionParticipantEngine
+METHOD <init>(String, W3CEndpointReference, BusinessAgreementWithCoordinatorCompletionParticipant, State, boolean)
+AT ENTRY
+BIND identifier = $1,
+     recovered=$5
+IF recovered
+DO debug("created recovered CC participant engine " + identifier),
+   traceln("log", "created recovered CC participant engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a PC coordinator engine (ParticipantCompletionCoordinatorEngine)
+# is created from details located in the log record. It traces the
+# create operation. The trigger location is at entry but the rule
+# should only be triggered after calling the super constructor
+
+RULE trace PC coordinator engine create
+CLASS com.arjuna.wst11.messaging.engines.ParticipantCompletionCoordinatorEngine
+METHOD <init>(String, W3CEndpointReference, State, boolean)
+AT ENTRY
+BIND identifier = $1,
+     recovered=$4
+IF recovered
+DO debug("created recovered PC coordinator engine " + identifier),
+   traceln("log", "created recovered PC coordinator engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a PC participant (ParticipantCompletionParticipantEngine)
+# is created from details located in the log record. It traces the
+# create operation. The trigger location is at entry but the rule
+# should only be triggered after calling the super constructor
+
+RULE trace PC participant create
+CLASS com.arjuna.wst11.messaging.engines.ParticipantCompletionParticipantEngine
+METHOD <init>(String, W3CEndpointReference, BusinessAgreementWithParticipantCompletionParticipant, State, boolean)
+AT ENTRY
+BIND identifier = $1,
+     recovered=$5
+IF recovered
+DO debug("created recovered PC participant engine " + identifier),
+   traceln("log", "created recovered PC participant engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a recovered CC coordinator engine
+# (CoordinatorCompletionCoordinatorEngine) is requested to send a close message. This
+# happens during replay of a prepared TX from
+# the log. It traces the call.
+
+RULE trace send recovered CC participant close
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorCompletionCoordinatorEngine
+METHOD close
+AFTER SYNCHRONIZE
+BIND engine:CoordinatorCompletionCoordinatorEngine = $0,
+     recovered:boolean = engine.isRecovered(),
+     identifier:String = engine.getId()
+IF recovered
+DO debug("send close for recovered CC coordinator engine " + identifier),
+   traceln("log", "send close for recovered CC coordinator engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a recovered CC coordinator engine
+# (CoordinatorCompletionCoordinatorEngine) receives a closed message. This
+# happens during replay of a prepared TX from
+# the log. It traces the call.
+
+RULE trace receive recovered CC participant closed
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorCompletionCoordinatorEngine
+METHOD closed
+AFTER SYNCHRONIZE
+BIND engine:CoordinatorCompletionCoordinatorEngine = $0,
+     recovered:boolean = engine.isRecovered(),
+     identifier:String = engine.getId()
+IF recovered
+DO debug("received closed for recovered CC coordinator engine " + identifier),
+   traceln("log", "received closed for recovered CC coordinator engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a recovered CC participant engine
+# (CoordinatorCompletionParticipantEngine) is requested to send a closed message. This
+# happens during replay of a prepared TX from
+# the log. It traces the call.
+
+RULE trace send recovered participant closed
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorCompletionParticipantEngine
+METHOD sendClosed
+AT INVOKE sendClosed
+BIND engine:CoordinatorCompletionParticipantEngine = $0,
+     recovered:boolean = engine.isRecovered(),
+     identifier:String = engine.getId()
+IF recovered
+DO debug("send closed for recovered CC participant engine " + identifier),
+   traceln("log", "send closed for recovered CC participant engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a recovered CC participant engine
+# (CoordinatorCompletionParticipantEngine) receives a close message. This
+# happens during replay of a prepared TX from
+# the log. It traces the call.
+
+RULE trace receive recovered CC participant close
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorCompletionParticipantEngine
+METHOD close
+AFTER SYNCHRONIZE
+BIND engine:CoordinatorCompletionParticipantEngine = $0,
+     recovered:boolean = engine.isRecovered(),
+     identifier:String = engine.getId()
+IF recovered
+DO debug("received close for recovered CC participant engine " + identifier),
+   traceln("log", "received close for recovered CC participant engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a recovered PC coordinator engine
+# (ParticipantCompletionCoordinatorEngine) is requested to send a close message. This
+# happens during replay of a prepared TX from
+# the log. It traces the call.
+
+RULE trace send recovered PC participant close
+CLASS com.arjuna.wst11.messaging.engines.ParticipantCompletionCoordinatorEngine
+METHOD close
+AFTER SYNCHRONIZE
+BIND engine:ParticipantCompletionCoordinatorEngine = $0,
+     recovered:boolean = engine.isRecovered(),
+     identifier:String = engine.getId()
+IF recovered
+DO debug("send close for recovered PC coordinator engine " + identifier),
+   traceln("log", "send close for recovered PC coordinator engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a recovered PC coordinator engine
+# (CoordinatorCompletionCoordinatorEngine) receives a closed message. This
+# happens during replay of a prepared TX from
+# the log. It traces the call.
+
+RULE trace receive recovered PC participant closed
+CLASS com.arjuna.wst11.messaging.engines.ParticipantCompletionCoordinatorEngine
+METHOD closed
+AFTER SYNCHRONIZE
+BIND engine:ParticipantCompletionCoordinatorEngine = $0,
+     recovered:boolean = engine.isRecovered(),
+     identifier:String = engine.getId()
+IF recovered
+DO debug("received closed for recovered PC coordinator engine " + identifier),
+   traceln("log", "received closed for recovered PC coordinator engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a recovered participant engine PC
+# (ParticipantCompletionParticipantEngine) is requested to send a closed message. This
+# happens during replay of a prepared TX from
+# the log. It traces the call.
+
+RULE trace send recovered PC participant closed
+CLASS com.arjuna.wst11.messaging.engines.ParticipantCompletionParticipantEngine
+METHOD sendClosed
+AT INVOKE sendClosed
+BIND engine:ParticipantCompletionParticipantEngine = $0,
+     recovered:boolean = engine.isRecovered(),
+     identifier:String = engine.getId()
+IF recovered
+DO debug("send closed for recovered PC participant engine " + identifier),
+   traceln("log", "send closed for recovered PC participant engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a recovered PC participant engine
+# (CoordinatorCompletionParticipantEngine) receives a close message. This
+# happens during replay of a prepared TX from
+# the log. It traces the call.
+
+RULE trace receive recovered PC participant close
+CLASS com.arjuna.wst11.messaging.engines.ParticipantCompletionParticipantEngine
+METHOD close
+AFTER SYNCHRONIZE
+BIND engine:ParticipantCompletionParticipantEngine = $0,
+     recovered:boolean = engine.isRecovered(),
+     identifier:String = engine.getId()
+IF recovered
+DO debug("received close for recovered PC participant engine " + identifier),
+   traceln("log", "received close for recovered PC participant engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a subordinate pseudo participant
+# (SubordinateCoordinatorCompletionParticipantStub) is requested to send a close message. It
+# traces the call.
+
+RULE trace subordinate participant stub close
+CLASS com.arjuna.wst11.stub.SubordinateCoordinatorCompletionParticipantStub
+METHOD close
+AT ENTRY
+BIND NOTHING
+IF TRUE
+DO debug("close called for pseudo-participant " + $0),
+   traceln("log", "close called for pseudo-participant " + $0)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a subordinate pseudo participant
+# (SubordinateCoordinatorCompletionParticipantStub) forwards a close message to its subordinate
+# coordinator during recovery. It traces the call.
+
+RULE trace subordinate participant stub close forward
+CLASS com.arjuna.wst11.stub.SubordinateCoordinatorCompletionParticipantStub
+METHOD close
+AT INVOKE close 2
+BIND NOTHING
+IF TRUE
+DO debug("forwarding close for pseudo-participant " + $0 + " to subordinate coordinator"),
+   traceln("log", "forwarding close for pseudo-participant " + $0 + " to subordinate coordinator")
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a subordinate pseudo participant
+# (SubordinateCoordinatorCompletionParticipantStub) throws an error from its close method
+# because the subordinate coordinator has not yet been recovered. It
+# traces the throw.
+
+RULE trace subordinate participant stub close with no coordinator
+CLASS com.arjuna.wst11.stub.SubordinateCoordinatorCompletionParticipantStub
+METHOD close
+AT THROW 3
+BIND NOTHING
+IF TRUE
+DO debug("throw during close for pseudo-participant " + $0 + " with no subordinate coordinator"),
+   traceln("log", "throw during close for pseudo-participant " + $0 + " with no subordinate coordinator")
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a subordinate pseudo participant
+# (SubordinateCoordinatorCompletionParticipantStub) throws an error from its close method
+# because the subordinate coordinator has not yet been activated. It
+# traces the throw.
+
+
+RULE trace subordinate participant stub close close with unactivated coordinator
+CLASS com.arjuna.wst11.stub.SubordinateCoordinatorCompletionParticipantStub
+METHOD close
+AT THROW 4
+BIND NOTHING
+IF TRUE
+DO debug("throw during close for pseudo-participant " + $0 + " with unactivated subordinate coordinator"),
+   traceln("log", "throw during close for pseudo-participant " + $0 + " with unactivated subordinate coordinator")
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a subordinate pseudo participant
+# (SubordinateCoordinatorCompletionParticipantStub) throws an error from its close method
+# because of a system exception being thrown from the close. It
+# traces the throw.
+
+
+RULE trace subordinate participant stub close close with system exception from coordinator
+CLASS com.arjuna.wst11.stub.SubordinateCoordinatorCompletionParticipantStub
+METHOD close
+AT THROW 5
+BIND NOTHING
+IF TRUE
+DO debug("throw during close for pseudo-participant " + $0 + " with system exception from subordinate coordinator"),
+   traceln("log", "throw during close for pseudo-participant " + $0 + " with system exception from subordinate coordinator")
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a subordinate pseudo participant
+# (SubordinateCoordinatorCompletionParticipantStub) returns from sending a close message. It
+# traces the call.
+
+RULE trace subordinate participant stub close return
+CLASS com.arjuna.wst11.stub.SubordinateCoordinatorCompletionParticipantStub
+METHOD close
+AT EXIT
+BIND NOTHING
+IF TRUE
+DO debug("close completed for pseudo-participant " + $0),
+   traceln("log", "close completed for pseudo-participant " + $0)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a subordinate coordinator
+# (SubordinateBACoordinator) calsl prepare during completion. It
+# traces the call.
+
+RULE trace subordinate coordinator prepare
+CLASS com.arjuna.mwlabs.wscf.model.sagas.arjunacore.subordinate.SubordinateBACoordinator
+METHOD complete
+AT INVOKE prepare
+BIND uid = $0.get_uid()
+IF TRUE
+DO debug("prepare for transaction " + uid),
+   traceln("log", "prepare for transaction " + uid)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a subordinate coordinator
+# (SubordinateCoordinator) is requested to perform a close. It
+# traces the call.
+
+RULE trace subordinate coordinator close
+CLASS com.arjuna.mwlabs.wscf.model.sagas.arjunacore.subordinate.SubordinateBACoordinator
+METHOD close
+AT ENTRY
+BIND NOTHING
+IF TRUE
+DO debug("close called for subordinate coordinator " + $0),
+   traceln("log", "close called for subordinate coordinator " + $0)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a subordinate coordinator
+# (SubordinateCoordinator) is requested to perform a close. It
+# traces the call.
+
+RULE trace subordinate coordinator close 2
+CLASS com.arjuna.mwlabs.wscf.model.sagas.arjunacore.subordinate.SubordinateBACoordinator
+METHOD close
+AT EXIT
+BIND NOTHING
+IF TRUE
+DO debug("close returned for subordinate coordinator " + $0),
+   traceln("log", "close returned for subordinate coordinator " + $0)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when the recovery system finds a PREPARED
+# parent activity in the log and reruns the phase 2 commit operation.
+# It prints a message which can be used to verify that the test has
+# progressed as expected and creates a countdown used to detect exit of
+# both transactions
+
+RULE trace prepared replay
+CLASS org.jboss.jbossts.xts.recovery.coordinator.ba.RecoveryBACoordinator
+METHOD replayPhase2
+AT INVOKE phase2Commit
+BIND coordinator = $0,
+     uid : Uid = coordinator.identifier(),
+     status : int = coordinator.status()
+IF (status == com.arjuna.ats.arjuna.coordinator.ActionStatus.PREPARED)
+     OR
+     (status == com.arjuna.ats.arjuna.coordinator.ActionStatus.COMMITTING)
+DO debug("replaying commit for prepared transaction " + uid),
+   traceln("log", "replaying commit for prepared transaction " + uid),
+   createCountDown("exit countdown", 1)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when the recovery system finds a PREPARED
+# subordinate activity in the log. It prints a message which can be
+# used to verify that the test has progressed as expected
+
+RULE trace subordinate prepared replay
+CLASS org.jboss.jbossts.xts.recovery.coordinator.ba.RecoverySubordinateBACoordinator
+METHOD replayPhase2
+AT ENTRY
+BIND coordinator = $0,
+     uid : Uid = coordinator.identifier(),
+     status : int = coordinator.status()
+IF (status == com.arjuna.ats.arjuna.coordinator.ActionStatus.PREPARED)
+     OR
+     (status == com.arjuna.ats.arjuna.coordinator.ActionStatus.COMMITTING)
+DO debug("reinstated prepared subordinate transaction " + uid),
+   traceln("log", "reinstated prepared subordinate transaction " + uid)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a TX is saved to disk during prepare.
+
+RULE trace TX save at prepare
+CLASS com.arjuna.ats.arjuna.coordinator.BasicAction
+METHOD prepare(boolean)
+AFTER CALL save_state
+BIND action : BasicAction = $0,
+     uid  = action.get_uid()
+IF TRUE
+DO traceln("log", "saved to disk transaction " + uid),
+   debug("saved to disk transaction " + uid)
+ENDRULE
+
+#######################################################################
+# activity from the log for the second time. It ensures that the JVM
+# exits. n.b. it waits for the second delete because both the subordinate
+# tx and the parent tx need to be deleted.
+
+RULE trace remove committed state and exit JVM
+CLASS com.arjuna.ats.arjuna.coordinator.BasicAction
+METHOD updateState
+AFTER CALL remove_committed
+BIND action : BasicAction = $0,
+     uid  = action.get_uid()
+IF countDown("exit countdown")
+DO traceln("log", "JVM exit after removing both transactions"),
+   debug("JVM exit after removing both transactions"),
+   killJVM()
+ENDRULE
+
+#######################################################################
+# This rule is triggered when the recovery system deletes an
+# activity from the log. It prints a message which can be used to
+# verify that the test has completed.
+
+RULE trace remove committed state
+CLASS com.arjuna.ats.arjuna.coordinator.BasicAction
+METHOD updateState
+AFTER CALL remove_committed
+BIND action : BasicAction = $0,
+     uid  = action.get_uid()
+IF TRUE
+DO traceln("log", "removed transaction " + uid),
+   debug("removed transaction " + uid)
+ENDRULE

Added: labs/jbosstm/trunk/XTS/localjunit/crash-recovery-tests/src/test/resources/scripts/BASubordinateCrashDuringCommitAfterSubordinateExit.txt
===================================================================
--- labs/jbosstm/trunk/XTS/localjunit/crash-recovery-tests/src/test/resources/scripts/BASubordinateCrashDuringCommitAfterSubordinateExit.txt	                        (rev 0)
+++ labs/jbosstm/trunk/XTS/localjunit/crash-recovery-tests/src/test/resources/scripts/BASubordinateCrashDuringCommitAfterSubordinateExit.txt	2011-12-15 07:52:45 UTC (rev 37804)
@@ -0,0 +1,1014 @@
+##############################################################################
+# JBoss, Home of Professional Open Source
+# Copyright 2009, Red Hat Middleware LLC, and individual contributors
+# 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.
+#
+# @authors Andrew Dinn
+#
+# BA Subordinate Transaction Crash During Commit AFter Subordinate Exit
+#
+# This script automates testing of a specific recovery scenario for the
+# JBossTS XTS implementation of the WS-BA 1.1 protocol using orchestration
+# rules. The basic scenario employs a coordinator, a subordinate coordinator
+# and 2 web services running in a single JVM, the second one employing local
+# (subordinate) coordination. It checks that the proxy participant for the
+# subordinate transaction closes successfully even though its transaction
+# was read-only and, therefore, was not logged during complete processing.
+# The scenario is as follows
+# (** indicates intercession by a Byteman rule):
+#
+# AS boots
+# Cient starts a WS-BA transaction T1
+# Client invokes web service S1 with enlistPC/CC request
+# S1 registers PC/CC participant P1 in T1
+# Client invokes subordinate web service S2 with enlistPC/CC request
+# S2 creates a subordinate BA transaction T2
+# S2 registers CC pseudo-participant PP in T1
+# S2 registers PC/CC participant P2 in T2
+# Client invokes subordinate web service S2 with enlistPC/CC  request
+# S2 resumes T2
+# S2 registers PC/CC participant P3 in T2
+# Client invokes subordinate web service S2 with exit request for P2
+# P2 sends exit to T2
+# ** Rule system logs exit
+# Client invokes subordinate web service S2 with exit request for P3
+# P3 sends exit to T2
+# ** Rule system logs exit
+#
+# (PC Participants only)
+# Client invokes web service S1 with complete request for P1
+# P1 sends completed
+# ** Rule system logs receipt of completed from P1
+# (end of PC Participants only)
+#
+# Client initiates transaction close for T1
+#
+# (CC Participants only)
+# Coordinator initiates complete of participant P1
+# ** Rule system logs dispatch of complete to P1
+# ** Rule system logs receipt of completed from P1
+# (end of CC Participants only)
+#
+# Coordinator initiates complete of subordinate participant PP
+# ** Rule system logs dispatch of complete to PP
+# PP calls subordinate coordinator complete
+# ** Rule system logs call to complete
+# Subordinate coordinator calls prepare for T2
+# ** Rule system logs prepare call
+# ** n.b. the TX is read-only so it does not get logged to disk
+# Subordinate coordinator complete returns
+# ** Rule system logs return from complete
+# PP sends completed to coordinator
+# ** Rule system logs receipt of completed from PP
+#
+# Client closes transaction
+# Coordinator initiates close of participant P1
+# ** Rule system intercepts close and crashes JVM
+#
+# AS reboots
+# Recovery system starts after 2 minutes
+# Recovery system recreates transaction T1
+# ** Rule system traces create
+# Recovery system recreates participant engine for P1
+# ** Rule system traces create
+# Recovery system recreates participant engine for PP
+# ** Rule system traces create
+# Recovery system recreates coordinator engine for P1
+# ** Rule system traces create
+# Recovery system recreates coordinator engine for PP
+# ** Rule system traces create
+# Recovery system calls replay of COMPLETED transaction
+# ** Rule system traces COMPLETED replay invocation
+#
+# Coordinator sends close to P1
+# ** Rule system traces dispatch of close
+# P1 replies with closed
+# ** Rule system traces dispatch of closed
+#
+# Coordinator sends close to PP
+# ** Rule system traces dispatch of close
+#
+# (optional depending upon timing)
+# PP fails to find T2 in before 1st scan so throws SystemException
+# ** Rule system traces throw of exception
+# (end optional -- n.b. may repeat several times)
+#
+# PP fails to find T2 in recovery log after 1st scan so sends closed
+# ** Rule system traces receipt of closed
+#
+# Coordinator deletes T1 from log and completes close
+# ** Rule system traces delete of T1
+# ** Rule system detects completed close and kills JVM
+#
+# Use of this script
+#
+# The default way of exercising this test is to deploy the xtstest war
+# to a single AS and configure it to run the relevant XTS Service Test.
+# The web services and coordinator will be located with the client.
+# The number of participants and subordinate participants can actually be
+# 2, 3 or more. The  web service(s), client (i.e. the XTS Service Test which
+# drives the test) and coordinator and subordinate coordinator service must
+# be colocated for this scritp to work (it is possible to distribute all of
+# these agents if desired but that woud lrequire more complex script rules).
+# The AS should crash when the client closes. At reboot the rest of the test
+# should run automatically and the server should be killed after the recovered
+# transaction is successfuly replayed.
+#
+# This script needs to be passed to a Byteman agent in the JVM running
+# the coordinator service both at first boot and at reboot. Output will be
+# written to file testlog in the working directory of the AS.
+#
+# XTS Service tests which can operate with this scenario can be selected for
+# execution at AS boot by the XTSServiceTestRunnerBean by setting system
+# property
+#    org.jboss.jbossts.xts.servicetests.XTSServiceTestName
+# to the name of a class which will execute the test. This property must
+# be defined in the JVM running the AS to which the xtstest war is deployed
+# i.e. the client AS. n.b. if the client is colocated with the coordinator then
+# this property must be left undefined at AS reboot otherwise the client
+# will run again, starting a new TX which may interfere with recovery of the
+# crashed TX. It is also possible to run the service test using the form
+# interface provided on the xtstest war's main index page.
+#
+# Available tests include:
+#
+# org.jboss.jbossts.xts.servicetests.test.ba.subordinate.MultiParticipantCoordinatorCompletionParticipantCloseAndExitTest
+# this test starts an activity then registers a CC participant with the service whose location is defined by
+# system property:
+#    org.jboss.jbossts.xts.servicetests.ServiceURL1
+# if this is not set the value used defaults to
+#    http://localhost:8080/xtstest/xtsservicetest1
+# the test then registers two CC participants with a second web service
+# (which must install a subordinate transaction) whose location is
+# defined system property:
+#    org.jboss.jbossts.xts.servicetests.serviceURL1
+# if this is not set the value used defaults to
+#    http://localhost:8080/xtstest/xtssubservicetest1
+# The test then sends exit requests for the two participants in the
+# second web service and closes the transaction.
+#
+# org.jboss.jbossts.xts.servicetests.test.ba.subordinate.MultiParticipantParticipantCompletionParticipantCloseAndExitTest
+# this test starts an activity then registers a PC participant with the service whose location is defined by
+# system property:
+#    org.jboss.jbossts.xts.servicetests.ServiceURL1
+# if this is not set the value used defaults to
+#    http://localhost:8080/xtstest/xtsservicetest1
+# the test then registers two PC participants with a second web service
+# (which must install a subordinate transaction) whose location is
+# defined system property:
+#    org.jboss.jbossts.xts.servicetests.serviceURL1
+# if this is not set the value used defaults to
+#    http://localhost:8080/xtstest/xtssubservicetest1
+# The test then sends a comleterequest for the participant in the first
+# web service, sends exit requests for the two participants in the
+# second web service and closes the transaction.
+#
+# Expected output
+#
+# After the first boot the JVM should exit leaving the following in file testlog
+# (the number and order of entries depends upon how many and which type of participants
+# are enlisted)
+#
+#   complete sent for CC participant XXXXXX ***
+#   complete received for CC participant XXXXXX  ***
+#   completed sent for CC/PC participant XXXXXX
+#   completed received for CC/PC participant XXXXXX
+#   complete sent for CC participant XXXXXX
+#   complete received for CC participant XXXXXX
+#   complete called for pseudo participant XXXXXX
+#   complete sent for CC participant XXXXXX ***
+#   complete received for CC participant XXXXXX ***
+#   completed sent for CC participant XXXXXX
+#   completed received for CC participant XXXXXX
+#   prepare for transaction XXXXXX +++
+#   complete returned for pseudo participant XXXXXX
+#   completed sent for CC participant XXXXXX
+#   completed received for CC participant XXXXXX
+#   saved to disk transaction XXXXXX
+#   JVM exit
+#
+# n.b. *** indicates trace which may be omitted
+#      there should be at least one completed sent/received message received for each CC/PC participant
+#        trace for PC participant completed will precede the call to pseudo participant complete
+#      there should also be at least one complete sent/received message received for each CC participant
+#        plus an extra complete sent/received message for the pseduo-participant (it is always registered as CC)
+#      there should be at least one complete called/complete returned message for the pseudo participant
+#      +++ note that there is no saved to disk trace message after this line
+#
+# and in some cases there may be repeat messages
+#
+# After reboot the JVM should exit leaving output in the following format in file
+# testlog.
+#
+#   complete sent for CC participant XXXXXX ***
+#   complete received for CC participant XXXXXX  ***
+#   completed sent for CC/PC participant XXXXXX
+#   completed received for CC/PC participant XXXXXX
+#   complete sent for CC participant XXXXXX
+#   complete received for CC participant XXXXXX
+#   complete called for pseudo participant XXXXXX
+#   complete sent for CC participant XXXXXX ***
+#   complete received for CC participant XXXXXX ***
+#   completed sent for CC participant XXXXXX
+#   completed received for CC participant XXXXXX
+#   prepare for transaction XXXXXX
+#   complete returned for pseudo participant XXXXXX
+#   completed sent for CC participant XXXXXX
+#   completed received for CC participant XXXXXX
+#   saved to disk transaction XXXXXX
+#   JVM exit
+#   created recovered CC/PC participant engine XXXXXX
+#   created recovered CC participant engine XXXXXX
+#   created recovered CC/PC coordinator engine XXXXXX
+#   created recovered CC coordinator engine XXXXXX
+#   replaying commit for prepared transaction XXXXXX
+#   close sent for participant engine XXXXXX
+#   close received for participant XXXXXX
+#   closed sent for participant XXXXXX
+#   closed received for participant engine XXXXXX
+#   close sent for participant engine XXXXXX
+#   close received for participant XXXXXX
+#   close called for pseudo participant XXXXXX
+#
+#   close completed for pseudo participant XXXXXX
+#   closed sent for participant XXXXXX
+#   closed received for participant engine XXXXXX
+#   removed transaction XXXXXX
+#   JVM exit
+#
+#######################################################################
+# This rule opens a file for the trace output during XTS startup
+# It will be opened for append at reboot so messages from both runs
+# will go to this file
+#
+RULE open trace file
+CLASS org.jboss.jbossts.XTSService
+METHOD start()
+BIND NOTHING
+IF TRUE
+DO openTrace("log", "testlog")
+ENDRULE
+
+#######################################################################
+# This rule resets the periodic recovery wait period to 10 seconds
+# in order to speed up the test
+#
+RULE reset periodic recovery wait time
+CLASS com.arjuna.ats.arjuna.common.RecoveryEnvironmentBean
+METHOD getPeriodicRecoveryPeriod()
+AT ENTRY
+IF TRUE
+DO return 10
+ENDRULE
+
+#######################################################################
+## rules for first run of AS
+
+#######################################################################
+# This rule is triggered when a non-recovered CC coordinator engine
+# (CoordinatorCompletionCoordinatorEngine) is sent a close message. It exits the JVM,
+# simulating a crash. The trigger location is on entry
+
+RULE kill JVM at coordinator completion close
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorCompletionCoordinatorEngine
+METHOD close
+AT ENTRY
+BIND engine:CoordinatorCompletionCoordinatorEngine = $0,
+     recovered:boolean = engine.isRecovered(),
+     identifier:String = engine.getId()
+IF (NOT recovered)
+   AND
+   debug("close on non-recovered CC coordinator engine " + identifier)
+DO traceln("log", "JVM exit"),
+   debug("!!!killing JVM!!!"),
+   killJVM()
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a non-recovered PC coordinator engine
+# (ParticipantCompletionCoordinatorEngine) is sent a close message. It exits the JVM,
+# simulating a crash. The trigger location is on entry
+
+RULE kill JVM at participant completion close
+CLASS com.arjuna.wst11.messaging.engines.ParticipantCompletionCoordinatorEngine
+METHOD close
+AT ENTRY
+BIND engine:ParticipantCompletionCoordinatorEngine = $0,
+     recovered:boolean = engine.isRecovered(),
+     identifier:String = engine.getId()
+IF (NOT recovered)
+   AND
+   debug("close on non-recovered PC coordinator engine " + identifier)
+DO traceln("log", "JVM exit"),
+   debug("!!!killing JVM!!!"),
+   killJVM()
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a CC coordinator engine
+# (CoordinatorCompletionCoordinatorEngine) is requested to send a complete message. It
+# traces the call.
+
+RULE trace send CC participant complete
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorCompletionCoordinatorEngine
+METHOD complete
+AFTER SYNCHRONIZE
+BIND engine:CoordinatorCompletionCoordinatorEngine = $0,
+     identifier:String = engine.getId()
+IF TRUE
+DO debug("complete sent for CC coordinator engine " + identifier),
+   traceln("log", "complete sent for CC coordinator engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a CC coordinator engine
+# (CoordinatorCompletionCoordinatorEngine) receives a completed message. It traces the call.
+
+RULE trace receive CC participant completed
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorCompletionCoordinatorEngine
+METHOD completed(NotificationType, MAP, ArjunaContext)
+AT ENTRY
+BIND engine:CoordinatorCompletionCoordinatorEngine = $0,
+     identifier:String = engine.getId()
+IF TRUE
+DO debug("completed received for CC coordinator engine " + identifier),
+   traceln("log", "completed received for CC coordinator engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a CC participant
+# (CoordinatorCompletionParticipantEngine) receives a complete message. It
+# traces the call.
+
+RULE trace receive CC participant complete
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorCompletionParticipantEngine
+METHOD complete
+AFTER SYNCHRONIZE
+BIND engine:CoordinatorCompletionParticipantEngine = $0,
+     identifier:String = engine.getId()
+IF TRUE
+DO debug("complete received for CC participant " + identifier),
+   traceln("log", "complete received for CC participant " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a CC participant
+# (CoordinatorCompletionParticipantEngine) is requested to send a completed message. It
+# traces the call.
+
+RULE trace send CC participant completed
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorCompletionParticipantEngine
+METHOD sendCompleted(boolean)
+AT INVOKE sendCompleted
+BIND engine:CoordinatorCompletionParticipantEngine = $0,
+     identifier:String = engine.getId()
+IF TRUE
+DO debug("completed sent for CC participant " + identifier),
+   traceln("log", "completed sent for CC participant " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a PC coordinator engine
+# (ParticipantCompletionCoordinatorEngine) receives a completed message. It traces the call.
+
+RULE trace receive participant completed
+CLASS com.arjuna.wst11.messaging.engines.ParticipantCompletionCoordinatorEngine
+METHOD completed(NotificationType, MAP, ArjunaContext)
+AT ENTRY
+BIND engine:ParticipantCompletionCoordinatorEngine = $0,
+     identifier:String = engine.getId()
+IF TRUE
+DO debug("completed received for PC coordinator engine " + identifier),
+   traceln("log", "completed received for PC coordinator engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a PC participant
+# (ParticipantCompletionParticipantEngine) is requested to send a completed message. It
+# traces the call.
+
+RULE trace send participant completed
+CLASS com.arjuna.wst11.messaging.engines.ParticipantCompletionParticipantEngine
+METHOD sendCompleted(boolean)
+AT INVOKE sendCompleted
+BIND engine:ParticipantCompletionParticipantEngine = $0,
+     identifier:String = engine.getId()
+IF TRUE
+DO debug("completed sent for PC participant " + identifier),
+   traceln("log", "completed sent for PC participant " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a CC participant engine
+# (CoordinatorCompletionParticipantEngine) is requested to send an exit message. It
+# traces the call.
+
+RULE trace CC participant send exit
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorCompletionParticipantEngine
+METHOD sendExit()
+AT ENTRY
+BIND engine:CoordinatorCompletionParticipantEngine = $0,
+     identifier:String = engine.getId()
+IF TRUE
+DO debug("send exit for CC participant " + identifier),
+   traceln("log", "send exit for CC participant " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a PC participant engine
+# (ParticipantCompletionParticipantEngine) is requested to send an exit message. It
+# traces the call.
+
+RULE trace PC participant send exit
+CLASS com.arjuna.wst11.messaging.engines.ParticipantCompletionParticipantEngine
+METHOD sendExit()
+AT ENTRY
+BIND engine:ParticipantCompletionParticipantEngine = $0,
+     identifier:String = engine.getId()
+IF TRUE
+DO debug("send exit for PC participant " + identifier),
+   traceln("log", "send exit for PC participant " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a CC participant engine
+# (CoordinatorCompletionParticipantEngine) receives an exited message. It
+# traces the call.
+
+RULE trace CC participant received exited
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorCompletionParticipantEngine
+METHOD exited(NotificationType, MAP, ArjunaContext)
+AT ENTRY
+BIND engine:CoordinatorCompletionParticipantEngine = $0,
+     identifier:String = engine.getId()
+IF TRUE
+DO debug("received exited for CC participant " + identifier),
+   traceln("log", "received exited for CC participant " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a PC participant engine
+# (ParticipantCompletionParticipantEngine) receives an exited message. It
+# traces the call.
+
+RULE trace PC participant received exited
+CLASS com.arjuna.wst11.messaging.engines.ParticipantCompletionParticipantEngine
+METHOD exited(NotificationType, MAP, ArjunaContext)
+AT ENTRY
+BIND engine:ParticipantCompletionParticipantEngine = $0,
+     identifier:String = engine.getId()
+IF TRUE
+DO debug("received exited for PC participant " + identifier),
+   traceln("log", "received exited for PC participant " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a CC coordinator engine
+# (CoordinatorCompletionCoordinatorEngine) receives an exit message. It
+# traces the call.
+
+RULE trace CC participant received exit
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorCompletionCoordinatorEngine
+METHOD exit(NotificationType, MAP, ArjunaContext)
+AT ENTRY
+BIND engine:CoordinatorCompletionCoordinatorEngine = $0,
+     identifier:String = engine.getId()
+IF TRUE
+DO debug("received exit for CC participant " + identifier),
+   traceln("log", "received exit for CC participant " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a PC participant engine
+# (ParticipantCompletionCoordinatorEngine) is requested to send an exit message. It
+# traces the call.
+
+RULE trace PC participant received exit
+CLASS com.arjuna.wst11.messaging.engines.ParticipantCompletionCoordinatorEngine
+METHOD exit(NotificationType, MAP, ArjunaContext)
+AT ENTRY
+BIND engine:ParticipantCompletionCoordinatorEngine = $0,
+     identifier:String = engine.getId()
+IF TRUE
+DO debug("received exit for PC participant " + identifier),
+   traceln("log", "received exit for PC participant " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a CC coordinator engine
+# (CoordinatorCompletionCoordinatorEngine) sends an exited message. It
+# traces the call.
+
+RULE trace CC participant send exited
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorCompletionCoordinatorEngine
+METHOD sendExited()
+AT ENTRY
+BIND engine:CoordinatorCompletionCoordinatorEngine = $0,
+     identifier:String = engine.getId()
+IF TRUE
+DO debug("sent exited for CC participant " + identifier),
+   traceln("log", "sent exited for CC participant " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a PC participant engine
+# (ParticipantCompletionCoordinatorEngine) sends an exited message. It
+# traces the call.
+
+RULE trace PC participant send exited
+CLASS com.arjuna.wst11.messaging.engines.ParticipantCompletionCoordinatorEngine
+METHOD sendExited()
+AT ENTRY
+BIND engine:ParticipantCompletionCoordinatorEngine = $0,
+     identifier:String = engine.getId()
+IF TRUE
+DO debug("sent exited for PC participant " + identifier),
+   traceln("log", "sent exited for PC participant " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a subordinate pseudo participant
+# (SubordinateCoordinatorCompletionParticipantStub) is requested to send a completed message. It
+# traces the call.
+
+RULE trace subordinate participant stub complete
+CLASS com.arjuna.wst11.stub.SubordinateCoordinatorCompletionParticipantStub
+METHOD complete
+AT ENTRY
+BIND NOTHING
+IF TRUE
+DO debug("complete called for pseudo-participant " + $0),
+   traceln("log", "complete called for pseudo-participant " + $0)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a subordinate pseudo participant
+# (SubordinateCoordinatorCompletionParticipantStub) has forwarded a complete message. It
+# traces the call.
+
+RULE trace subordinate participant stub complete 2
+CLASS com.arjuna.wst11.stub.SubordinateCoordinatorCompletionParticipantStub
+METHOD complete
+AFTER INVOKE complete
+BIND NOTHING
+IF TRUE
+DO debug("complete returned for pseudo-participant " + $0),
+   traceln("log", "complete returned for pseudo-participant " + $0)
+ENDRULE
+
+#######################################################################
+## rules for reboot run of AS
+
+#######################################################################
+# This rule is triggered when a CC coordinator engine (CoordinatorCompletionCoordinatorEngine)
+# is created from details located in the log record. It traces the
+# create operation. The trigger location is at entry but the rule
+# should only be triggered after calling the super constructor
+
+RULE trace CC coordinator engine create
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorCompletionCoordinatorEngine
+METHOD <init>(String, W3CEndpointReference, State, boolean)
+AT ENTRY
+BIND identifier = $1,
+     recovered=$4
+IF recovered
+DO debug("created recovered CC coordinator engine " + identifier),
+   traceln("log", "created recovered CC coordinator engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a CC participant (CoordinatorCompletionParticipantEngine)
+# is created from details located in the log record. It traces the
+# create operation. The trigger location is at entry but the rule
+# should only be triggered after calling the super constructor
+
+RULE trace CC participant create
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorCompletionParticipantEngine
+METHOD <init>(String, W3CEndpointReference, BusinessAgreementWithCoordinatorCompletionParticipant, State, boolean)
+AT ENTRY
+BIND identifier = $1,
+     recovered=$5
+IF recovered
+DO debug("created recovered CC participant engine " + identifier),
+   traceln("log", "created recovered CC participant engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a PC coordinator engine (ParticipantCompletionCoordinatorEngine)
+# is created from details located in the log record. It traces the
+# create operation. The trigger location is at entry but the rule
+# should only be triggered after calling the super constructor
+
+RULE trace PC coordinator engine create
+CLASS com.arjuna.wst11.messaging.engines.ParticipantCompletionCoordinatorEngine
+METHOD <init>(String, W3CEndpointReference, State, boolean)
+AT ENTRY
+BIND identifier = $1,
+     recovered=$4
+IF recovered
+DO debug("created recovered PC coordinator engine " + identifier),
+   traceln("log", "created recovered PC coordinator engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a PC participant (ParticipantCompletionParticipantEngine)
+# is created from details located in the log record. It traces the
+# create operation. The trigger location is at entry but the rule
+# should only be triggered after calling the super constructor
+
+RULE trace PC participant create
+CLASS com.arjuna.wst11.messaging.engines.ParticipantCompletionParticipantEngine
+METHOD <init>(String, W3CEndpointReference, BusinessAgreementWithParticipantCompletionParticipant, State, boolean)
+AT ENTRY
+BIND identifier = $1,
+     recovered=$5
+IF recovered
+DO debug("created recovered PC participant engine " + identifier),
+   traceln("log", "created recovered PC participant engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a recovered CC coordinator engine
+# (CoordinatorCompletionCoordinatorEngine) is requested to send a close message. This
+# happens during replay of a prepared TX from
+# the log. It traces the call.
+
+RULE trace send recovered CC participant close
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorCompletionCoordinatorEngine
+METHOD close
+AFTER SYNCHRONIZE
+BIND engine:CoordinatorCompletionCoordinatorEngine = $0,
+     recovered:boolean = engine.isRecovered(),
+     identifier:String = engine.getId()
+IF recovered
+DO debug("send close for recovered CC coordinator engine " + identifier),
+   traceln("log", "send close for recovered CC coordinator engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a recovered CC coordinator engine
+# (CoordinatorCompletionCoordinatorEngine) receives a closed message. This
+# happens during replay of a prepared TX from
+# the log. It traces the call.
+
+RULE trace receive recovered CC participant closed
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorCompletionCoordinatorEngine
+METHOD closed
+AFTER SYNCHRONIZE
+BIND engine:CoordinatorCompletionCoordinatorEngine = $0,
+     recovered:boolean = engine.isRecovered(),
+     identifier:String = engine.getId()
+IF recovered
+DO debug("received closed for recovered CC coordinator engine " + identifier),
+   traceln("log", "received closed for recovered CC coordinator engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a recovered CC participant engine
+# (CoordinatorCompletionParticipantEngine) is requested to send a closed message. This
+# happens during replay of a prepared TX from
+# the log. It traces the call.
+
+RULE trace send recovered participant closed
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorCompletionParticipantEngine
+METHOD sendClosed
+AT INVOKE sendClosed
+BIND engine:CoordinatorCompletionParticipantEngine = $0,
+     recovered:boolean = engine.isRecovered(),
+     identifier:String = engine.getId()
+IF recovered
+DO debug("send closed for recovered CC participant engine " + identifier),
+   traceln("log", "send closed for recovered CC participant engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a recovered CC participant engine
+# (CoordinatorCompletionParticipantEngine) receives a close message. This
+# happens during replay of a prepared TX from
+# the log. It traces the call.
+
+RULE trace receive recovered CC participant close
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorCompletionParticipantEngine
+METHOD close
+AFTER SYNCHRONIZE
+BIND engine:CoordinatorCompletionParticipantEngine = $0,
+     recovered:boolean = engine.isRecovered(),
+     identifier:String = engine.getId()
+IF recovered
+DO debug("received close for recovered CC participant engine " + identifier),
+   traceln("log", "received close for recovered CC participant engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a recovered PC coordinator engine
+# (ParticipantCompletionCoordinatorEngine) is requested to send a close message. This
+# happens during replay of a prepared TX from
+# the log. It traces the call.
+
+RULE trace send recovered PC participant close
+CLASS com.arjuna.wst11.messaging.engines.ParticipantCompletionCoordinatorEngine
+METHOD close
+AFTER SYNCHRONIZE
+BIND engine:ParticipantCompletionCoordinatorEngine = $0,
+     recovered:boolean = engine.isRecovered(),
+     identifier:String = engine.getId()
+IF recovered
+DO debug("send close for recovered PC coordinator engine " + identifier),
+   traceln("log", "send close for recovered PC coordinator engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a recovered PC coordinator engine
+# (CoordinatorCompletionCoordinatorEngine) receives a closed message. This
+# happens during replay of a prepared TX from
+# the log. It traces the call.
+
+RULE trace receive recovered PC participant closed
+CLASS com.arjuna.wst11.messaging.engines.ParticipantCompletionCoordinatorEngine
+METHOD closed
+AFTER SYNCHRONIZE
+BIND engine:ParticipantCompletionCoordinatorEngine = $0,
+     recovered:boolean = engine.isRecovered(),
+     identifier:String = engine.getId()
+IF recovered
+DO debug("received closed for recovered PC coordinator engine " + identifier),
+   traceln("log", "received closed for recovered PC coordinator engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a recovered participant engine PC
+# (ParticipantCompletionParticipantEngine) is requested to send a closed message. This
+# happens during replay of a prepared TX from
+# the log. It traces the call.
+
+RULE trace send recovered PC participant closed
+CLASS com.arjuna.wst11.messaging.engines.ParticipantCompletionParticipantEngine
+METHOD sendClosed
+AT INVOKE sendClosed
+BIND engine:ParticipantCompletionParticipantEngine = $0,
+     recovered:boolean = engine.isRecovered(),
+     identifier:String = engine.getId()
+IF recovered
+DO debug("send closed for recovered PC participant engine " + identifier),
+   traceln("log", "send closed for recovered PC participant engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a recovered PC participant engine
+# (CoordinatorCompletionParticipantEngine) receives a close message. This
+# happens during replay of a prepared TX from
+# the log. It traces the call.
+
+RULE trace receive recovered PC participant close
+CLASS com.arjuna.wst11.messaging.engines.ParticipantCompletionParticipantEngine
+METHOD close
+AFTER SYNCHRONIZE
+BIND engine:ParticipantCompletionParticipantEngine = $0,
+     recovered:boolean = engine.isRecovered(),
+     identifier:String = engine.getId()
+IF recovered
+DO debug("received close for recovered PC participant engine " + identifier),
+   traceln("log", "received close for recovered PC participant engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a subordinate pseudo participant
+# (SubordinateCoordinatorCompletionParticipantStub) is requested to send a close message. It
+# traces the call.
+
+RULE trace subordinate participant stub close
+CLASS com.arjuna.wst11.stub.SubordinateCoordinatorCompletionParticipantStub
+METHOD close
+AT ENTRY
+BIND NOTHING
+IF TRUE
+DO debug("close called for pseudo-participant " + $0),
+   traceln("log", "close called for pseudo-participant " + $0)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a subordinate pseudo participant
+# (SubordinateCoordinatorCompletionParticipantStub) forwards a close message to its subordinate
+# coordinator during recovery. It traces the call.
+
+RULE trace subordinate participant stub close forward
+CLASS com.arjuna.wst11.stub.SubordinateCoordinatorCompletionParticipantStub
+METHOD close
+AT INVOKE close 2
+BIND NOTHING
+IF TRUE
+DO debug("forwarding close for pseudo-participant " + $0 + " to subordinate coordinator"),
+   traceln("log", "forwarding close for pseudo-participant " + $0 + " to subordinate coordinator")
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a subordinate pseudo participant
+# (SubordinateCoordinatorCompletionParticipantStub) throws an error from its close method
+# because the subordinate coordinator has not yet been recovered. It
+# traces the throw.
+
+RULE trace subordinate participant stub close with no coordinator
+CLASS com.arjuna.wst11.stub.SubordinateCoordinatorCompletionParticipantStub
+METHOD close
+AT THROW 3
+BIND NOTHING
+IF TRUE
+DO debug("throw during close for pseudo-participant " + $0 + " with no subordinate coordinator"),
+   traceln("log", "throw during close for pseudo-participant " + $0 + " with no subordinate coordinator")
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a subordinate pseudo participant
+# (SubordinateCoordinatorCompletionParticipantStub) throws an error from its close method
+# because the subordinate coordinator has not yet been activated. It
+# traces the throw.
+
+
+RULE trace subordinate participant stub close close with unactivated coordinator
+CLASS com.arjuna.wst11.stub.SubordinateCoordinatorCompletionParticipantStub
+METHOD close
+AT THROW 4
+BIND NOTHING
+IF TRUE
+DO debug("throw during close for pseudo-participant " + $0 + " with unactivated subordinate coordinator"),
+   traceln("log", "throw during close for pseudo-participant " + $0 + " with unactivated subordinate coordinator")
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a subordinate pseudo participant
+# (SubordinateCoordinatorCompletionParticipantStub) throws an error from its close method
+# because of a system exception being thrown from the close. It
+# traces the throw.
+
+
+RULE trace subordinate participant stub close close with system exception from coordinator
+CLASS com.arjuna.wst11.stub.SubordinateCoordinatorCompletionParticipantStub
+METHOD close
+AT THROW 5
+BIND NOTHING
+IF TRUE
+DO debug("throw during close for pseudo-participant " + $0 + " with system exception from subordinate coordinator"),
+   traceln("log", "throw during close for pseudo-participant " + $0 + " with system exception from subordinate coordinator")
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a subordinate pseudo participant
+# (SubordinateCoordinatorCompletionParticipantStub) returns from sending a close message. It
+# traces the call.
+
+RULE trace subordinate participant stub close return
+CLASS com.arjuna.wst11.stub.SubordinateCoordinatorCompletionParticipantStub
+METHOD close
+AT EXIT
+BIND NOTHING
+IF TRUE
+DO debug("close completed for pseudo-participant " + $0),
+   traceln("log", "close completed for pseudo-participant " + $0)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a subordinate coordinator
+# (SubordinateBACoordinator) calsl prepare during completion. It
+# traces the call.
+
+RULE trace subordinate coordinator prepare
+CLASS com.arjuna.mwlabs.wscf.model.sagas.arjunacore.subordinate.SubordinateBACoordinator
+METHOD complete
+AT INVOKE prepare
+BIND uid = $0.get_uid()
+IF TRUE
+DO debug("prepare for transaction " + uid),
+   traceln("log", "prepare for transaction " + uid)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a subordinate coordinator
+# (SubordinateBACoordinator) is requested to perform a close. It
+# traces the call.
+
+RULE trace subordinate coordinator close
+CLASS com.arjuna.mwlabs.wscf.model.sagas.arjunacore.subordinate.SubordinateBACoordinator
+METHOD close
+AT ENTRY
+BIND NOTHING
+IF TRUE
+DO debug("close called for subordinate coordinator " + $0),
+   traceln("log", "close called for subordinate coordinator " + $0)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a subordinate coordinator
+# (SubordinateBACoordinator) is requested to perform a close. It
+# traces the call.
+
+RULE trace subordinate coordinator close 2
+CLASS com.arjuna.mwlabs.wscf.model.sagas.arjunacore.subordinate.SubordinateBACoordinator
+METHOD close
+AT EXIT
+BIND NOTHING
+IF TRUE
+DO debug("close returned for subordinate coordinator " + $0),
+   traceln("log", "close returned for subordinate coordinator " + $0)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when the recovery system finds a PREPARED
+# parent activity in the log and reruns the phase 2 commit operation.
+# It prints a message which can be used to verify that the test has
+# progressed as expected and creates a countdown used to detect exit of
+# both transactions
+
+RULE trace prepared replay
+CLASS org.jboss.jbossts.xts.recovery.coordinator.ba.RecoveryBACoordinator
+METHOD replayPhase2
+AT INVOKE phase2Commit
+BIND coordinator = $0,
+     uid : Uid = coordinator.identifier(),
+     status : int = coordinator.status()
+IF (status == com.arjuna.ats.arjuna.coordinator.ActionStatus.PREPARED)
+     OR
+     (status == com.arjuna.ats.arjuna.coordinator.ActionStatus.COMMITTING)
+DO debug("replaying commit for prepared transaction " + uid),
+   traceln("log", "replaying commit for prepared transaction " + uid)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when the recovery system finds a PREPARED
+# subordinate activity in the log. It prints a message which can be
+# used to verify that the test has progressed as expected
+
+RULE trace subordinate prepared replay
+CLASS org.jboss.jbossts.xts.recovery.coordinator.ba.RecoverySubordinateBACoordinator
+METHOD replayPhase2
+AT ENTRY
+BIND coordinator = $0,
+     uid : Uid = coordinator.identifier(),
+     status : int = coordinator.status()
+IF (status == com.arjuna.ats.arjuna.coordinator.ActionStatus.PREPARED)
+     OR
+     (status == com.arjuna.ats.arjuna.coordinator.ActionStatus.COMMITTING)
+DO debug("reinstated prepared subordinate transaction " + uid),
+   traceln("log", "reinstated prepared subordinate transaction " + uid)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a TX is saved to disk during prepare.
+
+RULE trace TX save at prepare
+CLASS com.arjuna.ats.arjuna.coordinator.BasicAction
+METHOD prepare(boolean)
+AFTER CALL save_state
+BIND action : BasicAction = $0,
+     uid  = action.get_uid()
+IF TRUE
+DO traceln("log", "saved to disk transaction " + uid),
+   debug("saved to disk transaction " + uid)
+ENDRULE
+
+#######################################################################
+# This rule is triggered after deleting an activity from the log. It
+# ensures that the JVM exits.
+
+RULE trace remove committed state and exit JVM
+CLASS com.arjuna.ats.arjuna.coordinator.BasicAction
+METHOD updateState
+AFTER CALL remove_committed
+BIND action : BasicAction = $0,
+     uid  = action.get_uid()
+IF TRUE
+DO traceln("log", "JVM exit"),
+   debug("JVM exit"),
+   killJVM()
+ENDRULE
+
+#######################################################################
+# This rule is triggered when the recovery system deletes an
+# activity from the log. It prints a message which can be used to
+# verify that the test has completed.
+
+RULE trace remove committed state
+CLASS com.arjuna.ats.arjuna.coordinator.BasicAction
+METHOD updateState
+AFTER CALL remove_committed
+BIND action : BasicAction = $0,
+     uid  = action.get_uid()
+IF TRUE
+DO traceln("log", "removed transaction " + uid),
+   debug("removed transaction " + uid)
+ENDRULE

Added: labs/jbosstm/trunk/XTS/localjunit/crash-recovery-tests/src/test/resources/scripts/BASubordinateCrashDuringComplete.txt
===================================================================
--- labs/jbosstm/trunk/XTS/localjunit/crash-recovery-tests/src/test/resources/scripts/BASubordinateCrashDuringComplete.txt	                        (rev 0)
+++ labs/jbosstm/trunk/XTS/localjunit/crash-recovery-tests/src/test/resources/scripts/BASubordinateCrashDuringComplete.txt	2011-12-15 07:52:45 UTC (rev 37804)
@@ -0,0 +1,1065 @@
+##############################################################################
+# JBoss, Home of Professional Open Source
+# Copyright 2009, Red Hat Middleware LLC, and individual contributors
+# 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.
+#
+# @authors Andrew Dinn
+#
+# BA Subordinate Transaction Crash During Complete
+#
+# This script automates testing of a specific recovery scenario for the
+# JBossTS XTS implementation of the WS-BA 1.1 protocol using orchestration
+# rules. The basic scenario employs a coordinator, a subordinate coordinator
+# and 2 web services running in a single JVM, the second one employing local
+# (subordinate) coordination. It checks that the transaction compensates
+# all completed participants afetr crashing in the middle of completion.
+# The crash happens after the subordinate transaction has been prepared and
+# logged to disk but before its proxy participant is able to write a log record.
+# The scenario is as follows
+# (** indicates intercession by a Byteman rule):
+#
+# AS boots
+# Cient starts a WS-BA transaction T1
+# Client invokes web service S1 with enlistPC/CC request
+# S1 registers PC/CC participant P1 in T1
+# Client invokes subordinate web service S2 with enlistPC/CC request
+# S2 creates a subordinate BA transaction T2
+# S2 registers CC pseudo-participant PP in T1
+# S2 registers PC/CC participant P2 in T2
+# Client invokes subordinate web service S2 with enlistPC/CC  request
+# S2 resumes T2
+# S2 registers PC/CC participant P3 in T2
+#
+# (PC Participants only)
+# Client invokes web service S1 with complete request for P1
+# P1 sends completed
+# ** Rule system logs receipt of completed from P1
+# Client invokes subordinate web service S2 with complete request for P2
+# P2 sends completed
+# ** Rule system logs receipt of completed from P2
+# Client invokes subordinate web service S1 with complete request for P3
+# P3 sends completed
+# ** Rule system logs receipt of completed from P2
+# (end of PC Participants only)
+#
+# Client initiates transaction close for T1
+#
+# (CC Participants only)
+# Coordinator initiates complete of participant P1
+# ** Rule system logs dispatch of complete to P1
+# ** Rule system logs receipt of completed from P1
+# (end of CC Participants only)
+# Coordinator initiates complete of subordinate participant PP
+# ** Rule system logs dispatch of complete to PP
+# PP calls subordinate coordinator complete
+# ** Rule system logs call to complete
+#
+# (CC Participants only)
+# Subordinate coordinator initiates complete of participant P2
+# ** Rule system logs dispatch of complete to P1
+# ** Rule system logs receipt of completed from P1
+# Subordinate coordinator initiates complete of participant P3
+# ** Rule system logs dispatch of complete to P1
+# ** Rule system logs receipt of completed from P1
+# (end of CC Participants only)
+#
+# Subordinate coordinator calls prepare for T2
+# ** Rule system logs prepare
+# Subordinate coordinator complete returns
+# ** Rule system intercepts return and crashes JVM
+#
+# AS reboots
+# Recovery system starts after 2 minutes
+# Recovery system recreates transaction T2
+# ** Rule system traces create
+# ** Rule system traces create
+# Recovery system recreates participant engine for P1
+# ** Rule system traces create
+# Recovery system recreates participant engine for P2
+# ** Rule system traces create
+# Recovery system recreates participant engine for P3
+# ** Rule system traces create
+# Recovery system recreates coordinator engine for P2
+# ** Rule system traces create
+# Recovery system recreates coordinator engine for P3
+# ** Rule system traces create
+#
+# (parallel optional)
+# getStatus sent for P2/P3 and ignored during recovery
+# ** Rule system traces dispatch of getStatus
+# (parallel)
+# Recovery system detects missing proxy P2 for transaction T2
+# Recovery system calls cancel for subordinate coordinator
+# ** Rule system traces call to cancel
+#
+# Coordinator sends compensate to P2
+# ** Rule system traces dispatch of compensate
+# P2 replies with compensated
+# ** Rule system traces dispatch of compensated
+# ** Rule system detects removal of P2
+#
+# Coordinator sends compensate to P3
+# ** Rule system traces dispatch of compensate
+# P3 replies with compensated
+# ** Rule system traces dispatch of compensated
+# ** Rule system detects removal of P3
+# Subordinate coordinator cancel call returns
+# ** Rule system traces return from cancel
+#
+# Recovery system removes transaction T2
+# ** Rule system traces removal of transaction
+# (parallel)
+# getStatus sent for P1
+# ** Rule system traces dispatch of getStatus
+# soap fault sent to P1
+# ** Rule system traces dispatch of soap fault
+# ** Rule system detects removal of P1
+# (end parallel)
+#
+# ** Rule system detects 3 participant deletes and 1 tx delete and kills JVM
+#
+# Use of this script
+#
+# The default way of exercising this test is to deploy the xtstest war
+# to a single AS and configure it to run the relevant XTS Service Test.
+# The web services and coordinator will be located with the client.
+# The number of participants and subordinate participants must be
+# exactly 3. The  web service(s), client (i.e. the XTS Service Test which
+# drives the test) and coordinator and subordinate coordinator service must
+# be colocated for this scritp to work (it is possible to distribute all of
+# these agents if desired but that woud lrequire more complex script rules).
+# The AS should crash when the client closes. At reboot the rest of the test
+# should run automatically and the server should be killed after the recovered
+# transaction is successfuly replayed.
+#
+# This script needs to be passed to a Byteman agent in the JVM running
+# the coordinator service both at first boot and at reboot. Output will be
+# written to file testlog in the working directory of the AS.
+#
+# XTS Service tests which can operate with this scenario can be selected for
+# execution at AS boot by the XTSServiceTestRunnerBean by setting system
+# property
+#    org.jboss.jbossts.xts.servicetests.XTSServiceTestName
+# to the name of a class which will execute the test. This property must
+# be defined in the JVM running the AS to which the xtstest war is deployed
+# i.e. the client AS. n.b. if the client is colocated with the coordinator then
+# this property must be left undefined at AS reboot otherwise the client
+# will run again, starting a new TX which may interfere with recovery of the
+# crashed TX. It is also possible to run the service test using the form
+# interface provided on the xtstest war's main index page.
+#
+# Available tests include:
+#
+# org.jboss.jbossts.xts.servicetests.test.ba.subordinate.MultiParticipantCoordinatorCompletionParticipantCloseTest
+# this test starts an activity then registers a CC participant with the service whose location is defined by
+# system property:
+#    org.jboss.jbossts.xts.servicetests.ServiceURL1
+# if this is not set the value used defaults to
+#    http://localhost:8080/xtstest/xtsservicetest1
+# the test then registers two CC participants with a second web service (which must install a
+# subordinate transaction) whose location is defined system property:
+#    org.jboss.jbossts.xts.servicetests.serviceURL1
+# if this is not set the value used defaults to
+#    http://localhost:8080/xtstest/xtssubservicetest1
+# The test then closes the transaction
+#
+# org.jboss.jbossts.xts.servicetests.test.ba.subordinate.MultiParticipantParticipantCompletionParticipantCloseTest
+# this test starts an activity then registers a PC participant with the service whose location is defined by
+# system property:
+#    org.jboss.jbossts.xts.servicetests.ServiceURL1
+# if this is not set the value used defaults to
+#    http://localhost:8080/xtstest/xtsservicetest1
+# the test then registers two PC participants with a second web service (which must install a
+# subordinate transaction) whose location is defined system property:
+#    org.jboss.jbossts.xts.servicetests.serviceURL1
+# if this is not set the value used defaults to
+#    http://localhost:8080/xtstest/xtssubservicetest1
+# The test then sends complete requests for all three participants and
+# closes the transaction
+#
+# Expected output
+#
+# After the first boot the JVM should exit leaving the following in file testlog
+# (the number and order of entries depends upon how many and which type of participants
+# are enlisted)
+#
+#   complete sent for CC participant XXXXXX ***
+#   complete received for CC participant XXXXXX  ***
+#   completed sent for CC/PC participant XXXXXX
+#   completed received for CC/PC participant XXXXXX
+#   complete sent for CC participant XXXXXX
+#   complete received for CC participant XXXXXX
+#   complete called for pseudo participant XXXXXX
+#   complete sent for CC participant XXXXXX ***
+#   complete received for CC participant XXXXXX ***
+#   completed sent for CC participant XXXXXX
+#   completed received for CC participant XXXXXX
+#   prepare for transaction XXXXXX
+#   saved to disk transaction XXXXXX
+#   complete returned for pseudo participant XXXXXX
+#   JVM exit
+#
+# n.b. *** indicates trace which may be omitted
+#      there should be at least one completed sent/received message received for each CC/PC participant
+#        trace for PC participant completed will precede the call to pseudo participant complete
+#      there should also be at least one complete sent/received message received for each CC participant
+#        plus an extra complete sent/received message for the pseduo-participant (it is always registered as CC)
+#      there should be at least one complete called/complete returned message for the pseudo participant
+#
+# and in some cases there may be repeat messages
+#
+# After reboot the JVM should exit leaving output in the following format in file
+# testlog.
+#
+#   complete sent for CC participant XXXXXX ***
+#   complete received for CC participant XXXXXX  ***
+#   completed sent for CC/PC participant XXXXXX
+#   completed received for CC/PC participant XXXXXX
+#   complete sent for CC participant XXXXXX
+#   complete received for CC participant XXXXXX
+#   complete called for pseudo participant XXXXXX
+#   complete sent for CC participant XXXXXX ***
+#   complete received for CC participant XXXXXX ***
+#   completed sent for CC participant XXXXXX
+#   completed received for CC participant XXXXXX
+#   prepare for transaction XXXXXX
+#   saved to disk transaction XXXXXX
+#   complete returned for pseudo participant XXXXXX
+#   JVM exit
+#   created recovered CC/PC participant engine XXXXXX
+#   created recovered CC/PC participant engine XXXXXX
+#   created recovered CC/PC participant engine XXXXXX
+#   created recovered CC participant engine XXXXXX
+#   created recovered CC/PC coordinator engine XXXXXX
+#   created recovered CC/PC coordinator engine XXXXXX
+#   created recovered CC/PC coordinator engine XXXXXX
+#   created recovered CC coordinator engine XXXXXX
+#   reinstated prepared subordinate transaction XXXXXX
+#
+#   (parallel -- optional and may be repeated depending upon timing)
+#   getstatus sent for CC participant P1/P2/P3
+#   getstatus received for CC participant P1/P2/P3
+#   status(COMPLETED) sent for CC participant P2/P3
+#   status(COMPLETED) received for CC participant P3
+#   (parallel)
+#   getstatus sent for CC/PC participant P1
+#   getstatus received for CC/PC participant P1
+#   soap fault sent for CC/PC participant P1
+#   soap fault received for CC/PC participant P1
+#   (parallel)
+#   compensate called for pseudo participant XXXXXX
+#   cancel called for subordinate transaction XXX
+#   compensate sent for PC/CC participant XXXXXX
+#   compensate received for PC/CC participant XXXXXX
+#   compensated sent for PC/CC participant XXXXXX
+#   compensated received for PC/CC participant XXXXXX
+#   compensate sent for PC/CC participant XXXXXX
+#   compensate received for PC/CC participant XXXXXX
+#   compensated sent for PC/CC participant XXXXXX
+#   compensated received for PC/CC participant XXXXXX
+#   cancel returned for subordinate transaction XXX
+#   compensate completed for pseudo participant XXXXXX
+#   removed transaction XXXXXX
+#   (end parallel)
+#
+#   JVM exit
+#
+#######################################################################
+# This rule opens a file for the trace output during XTS startup
+# It will be opened for append at reboot so messages from both runs
+# will go to this file
+#
+RULE open trace file
+CLASS org.jboss.jbossts.XTSService
+METHOD start()
+BIND NOTHING
+IF TRUE
+DO openTrace("log", "testlog")
+ENDRULE
+
+#######################################################################
+# This rule creates a counter used to track the number of participant
+# records which have been deleted
+RULE create participant deletes counter
+CLASS org.jboss.jbossts.XTSService
+METHOD start()
+BIND NOTHING
+IF TRUE
+DO createCounter("participant deletes")
+ENDRULE
+
+#######################################################################
+# This rule resets the periodic recovery wait period to 10 seconds
+# in order to speed up the test
+#
+RULE reset periodic recovery wait time
+CLASS com.arjuna.ats.arjuna.common.RecoveryEnvironmentBean
+METHOD getPeriodicRecoveryPeriod()
+AT ENTRY
+IF TRUE
+DO return 10
+ENDRULE
+
+#######################################################################
+## rules for first run of AS
+
+#######################################################################
+# This rule is triggered when a CC coordinator engine
+# (CoordinatorCompletionCoordinatorEngine) is requested to send a complete message. It
+# traces the call.
+
+RULE trace send CC participant complete
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorCompletionCoordinatorEngine
+METHOD complete
+AFTER SYNCHRONIZE
+BIND engine:CoordinatorCompletionCoordinatorEngine = $0,
+     identifier:String = engine.getId()
+IF TRUE
+DO debug("complete sent for CC coordinator engine " + identifier),
+   traceln("log", "complete sent for CC coordinator engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a CC coordinator engine
+# (CoordinatorCompletionCoordinatorEngine) receives a completed message. It traces the call.
+
+RULE trace receive CC participant completed
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorCompletionCoordinatorEngine
+METHOD completed(NotificationType, MAP, ArjunaContext)
+AT ENTRY
+BIND engine:CoordinatorCompletionCoordinatorEngine = $0,
+     identifier:String = engine.getId()
+IF TRUE
+DO debug("completed received for CC coordinator engine " + identifier),
+   traceln("log", "completed received for CC coordinator engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a CC participant
+# (CoordinatorCompletionParticipantEngine) receives a complete message. It
+# traces the call.
+
+RULE trace receive CC participant complete
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorCompletionParticipantEngine
+METHOD complete
+AFTER SYNCHRONIZE
+BIND engine:CoordinatorCompletionParticipantEngine = $0,
+     identifier:String = engine.getId()
+IF TRUE
+DO debug("complete received for CC participant " + identifier),
+   traceln("log", "complete received for CC participant " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a CC participant
+# (CoordinatorCompletionParticipantEngine) is requested to send a completed message. It
+# traces the call.
+
+RULE trace send CC participant completed
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorCompletionParticipantEngine
+METHOD sendCompleted(boolean)
+AT INVOKE sendCompleted
+BIND engine:CoordinatorCompletionParticipantEngine = $0,
+     identifier:String = engine.getId()
+IF TRUE
+DO debug("completed sent for CC participant " + identifier),
+   traceln("log", "completed sent for CC participant " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a PC coordinator engine
+# (ParticipantCompletionCoordinatorEngine) receives a completed message. It traces the call.
+
+RULE trace receive participant completed
+CLASS com.arjuna.wst11.messaging.engines.ParticipantCompletionCoordinatorEngine
+METHOD completed(NotificationType, MAP, ArjunaContext)
+AT ENTRY
+BIND engine:ParticipantCompletionCoordinatorEngine = $0,
+     identifier:String = engine.getId()
+IF TRUE
+DO debug("completed received for PC coordinator engine " + identifier),
+   traceln("log", "completed received for PC coordinator engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a PC participant
+# (ParticipantCompletionParticipantEngine) is requested to send a completed message. It
+# traces the call.
+
+RULE trace send participant completed
+CLASS com.arjuna.wst11.messaging.engines.ParticipantCompletionParticipantEngine
+METHOD sendCompleted(boolean)
+AT INVOKE sendCompleted
+BIND engine:ParticipantCompletionParticipantEngine = $0,
+     identifier:String = engine.getId()
+IF TRUE
+DO debug("completed sent for PC participant " + identifier),
+   traceln("log", "completed sent for PC participant " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a CC coordinator engine
+# (CoordinatorCompletionCoordinatorEngine) is requested to send a compensate message. It
+# traces the call.
+
+RULE trace send CC participant compensate
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorCompletionCoordinatorEngine
+METHOD compensate
+AFTER SYNCHRONIZE
+BIND engine:CoordinatorCompletionCoordinatorEngine = $0,
+     identifier:String = engine.getId()
+IF TRUE
+DO debug("compensate sent for CC coordinator engine " + identifier),
+   traceln("log", "compensate sent for CC coordinator engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a CC coordinator engine
+# (CoordinatorCompletionCoordinatorEngine) receives a compensated message. It traces the call.
+
+RULE trace receive CC participant compensated
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorCompletionCoordinatorEngine
+METHOD compensated(NotificationType, MAP, ArjunaContext)
+AT ENTRY
+BIND engine:CoordinatorCompletionCoordinatorEngine = $0,
+     identifier:String = engine.getId()
+IF TRUE
+DO debug("compensated received for CC coordinator engine " + identifier),
+   traceln("log", "compensated received for CC coordinator engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a CC participant
+# (CoordinatorCompletionParticipantEngine) receives a compensate message. It
+# traces the call.
+
+RULE trace receive CC participant compensate
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorCompletionParticipantEngine
+METHOD compensate
+AFTER SYNCHRONIZE
+BIND engine:CoordinatorCompletionParticipantEngine = $0,
+     identifier:String = engine.getId()
+IF TRUE
+DO debug("compensate received for CC participant " + identifier),
+   traceln("log", "compensate received for CC participant " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a CC participant
+# (CoordinatorCompletionParticipantEngine) is requested to send a compensated message. It
+# traces the call.
+
+RULE trace send CC participant compensated
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorCompletionParticipantEngine
+METHOD sendCompensated(boolean)
+AT INVOKE sendCompensated
+BIND engine:CoordinatorCompletionParticipantEngine = $0,
+     identifier:String = engine.getId()
+IF TRUE
+DO debug("compensated sent for CC participant " + identifier),
+   traceln("log", "compensated sent for CC participant " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a PC coordinator engine
+# (ParticipantCompletionCoordinatorEngine) receives a compensated message. It traces the call.
+
+RULE trace receive participant compensated
+CLASS com.arjuna.wst11.messaging.engines.ParticipantCompletionCoordinatorEngine
+METHOD compensated(NotificationType, MAP, ArjunaContext)
+AT ENTRY
+BIND engine:ParticipantCompletionCoordinatorEngine = $0,
+     identifier:String = engine.getId()
+IF TRUE
+DO debug("compensated received for PC coordinator engine " + identifier),
+   traceln("log", "compensated received for PC coordinator engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a PC participant
+# (ParticipantCompletionParticipantEngine) is requested to send a compensated message. It
+# traces the call.
+
+RULE trace send participant compensated
+CLASS com.arjuna.wst11.messaging.engines.ParticipantCompletionParticipantEngine
+METHOD sendCompensated(boolean)
+AT INVOKE sendCompensated
+BIND engine:ParticipantCompletionParticipantEngine = $0,
+     identifier:String = engine.getId()
+IF TRUE
+DO debug("compensated sent for PC participant " + identifier),
+   traceln("log", "compensated sent for PC participant " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a subordinate pseudo participant
+# (SubordinateCoordinatorCompletionParticipantStub) is requested to send a completed message. It
+# traces the call.
+
+RULE trace subordinate participant stub complete
+CLASS com.arjuna.wst11.stub.SubordinateCoordinatorCompletionParticipantStub
+METHOD complete
+AT ENTRY
+BIND NOTHING
+IF TRUE
+DO debug("complete called for pseudo-participant " + $0),
+   traceln("log", "complete called for pseudo-participant " + $0)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a subordinate pseudo participant
+# (SubordinateCoordinatorCompletionParticipantStub) has forwarded a complete message. It
+# kills the JVM.
+
+RULE trace subordinate participant stub complete 2
+CLASS com.arjuna.wst11.stub.SubordinateCoordinatorCompletionParticipantStub
+METHOD complete
+AFTER INVOKE complete
+BIND NOTHING
+IF TRUE
+DO traceln("log", "JVM exit"),
+   debug("JVM exit"),
+   killJVM()
+ENDRULE
+
+#######################################################################
+## rules for reboot run of AS
+
+#######################################################################
+# This rule is triggered when a CC coordinator engine (CoordinatorCompletionCoordinatorEngine)
+# is created from details located in the log record. It traces the
+# create operation. The trigger location is at entry but the rule
+# should only be triggered after calling the super constructor
+
+RULE trace CC coordinator engine create
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorCompletionCoordinatorEngine
+METHOD <init>(String, W3CEndpointReference, State, boolean)
+AT ENTRY
+BIND identifier = $1,
+     recovered=$4
+IF recovered
+DO debug("created recovered CC coordinator engine " + identifier),
+   traceln("log", "created recovered CC coordinator engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a CC participant (CoordinatorCompletionParticipantEngine)
+# is created from details located in the log record. It traces the
+# create operation. The trigger location is at entry but the rule
+# should only be triggered after calling the super constructor
+
+RULE trace CC participant create
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorCompletionParticipantEngine
+METHOD <init>(String, W3CEndpointReference, BusinessAgreementWithCoordinatorCompletionParticipant, State, boolean)
+AT ENTRY
+BIND identifier = $1,
+     recovered=$5
+IF recovered
+DO debug("created recovered CC participant engine " + identifier),
+   traceln("log", "created recovered CC participant engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a PC coordinator engine (ParticipantCompletionCoordinatorEngine)
+# is created from details located in the log record. It traces the
+# create operation. The trigger location is at entry but the rule
+# should only be triggered after calling the super constructor
+
+RULE trace PC coordinator engine create
+CLASS com.arjuna.wst11.messaging.engines.ParticipantCompletionCoordinatorEngine
+METHOD <init>(String, W3CEndpointReference, State, boolean)
+AT ENTRY
+BIND identifier = $1,
+     recovered=$4
+IF recovered
+DO debug("created recovered PC coordinator engine " + identifier),
+   traceln("log", "created recovered PC coordinator engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a PC participant (ParticipantCompletionParticipantEngine)
+# is created from details located in the log record. It traces the
+# create operation. The trigger location is at entry but the rule
+# should only be triggered after calling the super constructor
+
+RULE trace PC participant create
+CLASS com.arjuna.wst11.messaging.engines.ParticipantCompletionParticipantEngine
+METHOD <init>(String, W3CEndpointReference, BusinessAgreementWithParticipantCompletionParticipant, State, boolean)
+AT ENTRY
+BIND identifier = $1,
+     recovered=$5
+IF recovered
+DO debug("created recovered PC participant engine " + identifier),
+   traceln("log", "created recovered PC participant engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a recovered CC participant engine
+# (CoordinatorCompletionParticipantEngine) sends a getStatus
+# message. This happens during replay of a prepared TX from
+# the log. It traces the call.
+
+RULE trace recovered CC participant send getStatus
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorCompletionParticipantEngine
+METHOD sendCompleted(boolean)
+AT CALL sendGetStatus
+BIND engine:CoordinatorCompletionParticipantEngine = $0,
+     recovered:boolean = engine.isRecovered(),
+     identifier:String = engine.getId()
+IF recovered
+DO debug("sent getStatus for recovered CC coordinator engine " + identifier),
+   traceln("log", "sent getStatus for recovered CC coordinator engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a recovered PC participant engine
+# (ParticipantCompletionParticipantEngine) sends a getStatus
+# message. This happens during replay of a prepared TX from
+# the log. It traces the call.
+
+RULE trace recovered PC participant send getStatus
+CLASS com.arjuna.wst11.messaging.engines.ParticipantCompletionParticipantEngine
+METHOD sendCompleted(boolean)
+AT CALL sendGetStatus
+BIND engine:ParticipantCompletionParticipantEngine = $0,
+     recovered:boolean = engine.isRecovered(),
+     identifier:String = engine.getId()
+IF recovered
+DO debug("sent getStatus for recovered PC coordinator engine " + identifier),
+   traceln("log", "sent getStatus for recovered PC coordinator engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a CC coordinator processor
+# (CoordinatorCompletionCoordinatorProcessorImpl) receives a getStatus
+# message. This happens during replay of a prepared TX from
+# the log. It traces the call.
+
+RULE trace CC participant receive getStatus
+CLASS com.arjuna.wst11.messaging.CoordinatorCompletionCoordinatorProcessorImpl
+METHOD getStatus(NotificationType, MAP, ArjunaContext)
+AT ENTRY
+BIND identifier:String = $3.getInstanceIdentifier().getInstanceIdentifier()
+IF TRUE
+DO debug("receieved getStatus for CC coordinator engine " + identifier),
+   traceln("log", "receieved getStatus for CC coordinator engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a PC coordinator processor
+# (ParticipantCompletionCoordinatorProcessorImpl) receives a getStatus
+# message. This happens during replay of a prepared TX from
+# the log. It traces the call.
+
+RULE trace PC participant receive getStatus
+CLASS com.arjuna.wst11.messaging.ParticipantCompletionCoordinatorProcessorImpl
+METHOD getStatus(NotificationType, MAP, ArjunaContext)
+AT ENTRY
+BIND identifier:String = $3.getInstanceIdentifier().getInstanceIdentifier()
+IF TRUE
+DO debug("receieved getStatus for PC coordinator engine " + identifier),
+   traceln("log", "receieved getStatus for PC coordinator engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a recovered CC participant engine
+# (CoordinatorCompletionParticipantEngine) receives a status
+# message. This happens during replay of a prepared TX from
+# the log. It traces the call.
+
+RULE trace recovered CC participant received status
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorCompletionParticipantEngine
+METHOD status(StatusType, MAP, ArjunaContext)
+AT ENTRY
+BIND engine:CoordinatorCompletionParticipantEngine = $0,
+     recovered:boolean = engine.isRecovered(),
+     identifier:String = engine.getId(),
+     status = $1.getState().toString
+IF recovered
+DO debug("received status " + status + " for recovered CC coordinator engine " + identifier),
+   traceln("log", "received status " + status + " for recovered CC coordinator engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a recovered PC participant engine
+# (ParticipantCompletionParticipantEngine) sends a getStatus
+# message. This happens during replay of a prepared TX from
+# the log. It traces the call.
+
+RULE trace recovered PC participant received status
+CLASS com.arjuna.wst11.messaging.engines.ParticipantCompletionParticipantEngine
+METHOD status(StatusType, MAP, ArjunaContext)
+AT ENTRY
+BIND engine:ParticipantCompletionParticipantEngine = $0,
+     recovered:boolean = engine.isRecovered(),
+     identifier:String = engine.getId(),
+     status = $1.getState().toString
+IF recovered
+DO debug("received status " + status + " for recovered PC coordinator engine " + identifier),
+   traceln("log", "received status " + status + " for recovered PC coordinator engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a recovered CC coordinator engine
+# (CoordinatorCompletionCoordinatorEngine) sends a status
+# message. This happens during replay of a prepared TX from
+# the log. It traces the call.
+
+RULE trace recovered CC participant send status
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorCompletionCoordinatorEngine
+METHOD sendStatus(State)
+AT ENTRY
+BIND engine:CoordinatorCompletionCoordinatorEngine = $0,
+     recovered:boolean = engine.isRecovered(),
+     identifier:String = engine.getId(),
+     status = $1.getValue().toString()
+IF recovered
+DO debug("sent status " + status + " for recovered CC coordinator engine " + identifier),
+   traceln("log", "sent status " + status + " for recovered CC coordinator engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a recovered PC coordinator engine
+# (ParticipantCompletionCoordinatorEngine) sends a status
+# message. This happens during replay of a prepared TX from
+# the log. It traces the call.
+
+RULE trace recovered PC participant send status
+CLASS com.arjuna.wst11.messaging.engines.ParticipantCompletionCoordinatorEngine
+METHOD sendStatus(State)
+AT ENTRY
+BIND engine:ParticipantCompletionCoordinatorEngine = $0,
+     recovered:boolean = engine.isRecovered(),
+     identifier:String = engine.getId(),
+     status = $1.getValue().toString()
+IF recovered
+DO debug("sent status " + status + " for recovered PC coordinator engine " + identifier),
+   traceln("log", "sent status " + status + " for recovered PC coordinator engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a CC coordinator processor
+# (CoordinatorCompletionCoordinatorProcessorImpl) sends a soap fault.
+# This happens during replay of a prepared TX from
+# the log. It traces the call.
+
+RULE trace CC participant send soap fault
+CLASS com.arjuna.wst11.messaging.CoordinatorCompletionCoordinatorProcessorImpl
+METHOD getStatus(NotificationType, MAP, ArjunaContext)
+AT CALL sendSoapFault
+BIND identifier:String = $3.getInstanceIdentifier().getInstanceIdentifier()
+IF TRUE
+DO debug("sent soap fault for unknown CC coordinator engine " + identifier),
+   traceln("log", "sent soap fault for unknown CC coordinator engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a PC coordinator processor
+# (ParticipantCompletionCoordinatorProcessorImpl) sends a soap fault.
+# This happens during replay of a prepared TX from
+# the log. It traces the call.
+
+RULE trace PC participant send soap fault
+CLASS com.arjuna.wst11.messaging.ParticipantCompletionCoordinatorProcessorImpl
+METHOD getStatus(NotificationType, MAP, ArjunaContext)
+AT CALL sendSoapFault
+BIND identifier:String = $3.getInstanceIdentifier().getInstanceIdentifier()
+IF TRUE
+DO debug("sent soap fault for unknown PC coordinator engine " + identifier),
+   traceln("log", "sent soap fault for unknown PC coordinator engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a CC participant engine
+# (CoordinatorCompletionParticipantEngine) receives a soap fault.
+# This happens during replay of a prepared TX from
+# the log. It traces the call.
+
+RULE trace CC participant receive soap fault
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorCompletionParticipantEngine
+METHOD soapFault(SoapFault, MAP, ArjunaContext)
+AT ENTRY
+BIND identifier:String = $3.getInstanceIdentifier().getInstanceIdentifier()
+IF TRUE
+DO debug("received soap fault for CC coordinator engine " + identifier),
+   traceln("log", "received soap fault for CC coordinator engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a PC coordinator processorparticipant engine
+# (ParticipantCompletionParticipantEngine) receives a soap fault.
+# This happens during replay of a prepared TX from
+# the log. It traces the call.
+
+
+RULE trace PC participant receive soap fault
+CLASS com.arjuna.wst11.messaging.engines.ParticipantCompletionParticipantEngine
+METHOD soapFault(SoapFault, MAP, ArjunaContext)
+AT ENTRY
+BIND identifier:String = $3.getInstanceIdentifier().getInstanceIdentifier()
+IF TRUE
+DO debug("received soap fault for PC coordinator engine " + identifier),
+   traceln("log", "received soap fault for PC coordinator engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a subordinate pseudo participant
+# (SubordinateCoordinatorCompletionParticipantStub) is requested to forward a compensate message. It
+# traces the call.
+
+RULE trace subordinate participant stub compensate
+CLASS com.arjuna.wst11.stub.SubordinateCoordinatorCompletionParticipantStub
+METHOD compensate
+AT ENTRY
+BIND NOTHING
+IF TRUE
+DO debug("compensate called for pseudo-participant " + $0),
+   traceln("log", "compensate called for pseudo-participant " + $0)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a subordinate pseudo participant
+# (SubordinateCoordinatorCompletionParticipantStub) forwards a cancel message to its subordinate
+# coordinator during recovery. It traces the call.
+
+RULE trace subordinate participant stub compensate forward
+CLASS com.arjuna.wst11.stub.SubordinateCoordinatorCompletionParticipantStub
+METHOD compensate
+AT INVOKE cancel 2
+BIND NOTHING
+IF TRUE
+DO debug("forwarding compensate or pseudo-participant " + $0 + " as cancel to subordinate coordinator"),
+   traceln("log", "forwarding compensate for pseudo-participant " + $0 + " as cancel to subordinate coordinator")
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a subordinate pseudo participant
+# (SubordinateCoordinatorCompletionParticipantStub) throws an error from its compensate method
+# because the subordinate coordinator has not yet been recovered. It
+# traces the throw.
+
+RULE trace subordinate participant stub compensate with no coordinator
+CLASS com.arjuna.wst11.stub.SubordinateCoordinatorCompletionParticipantStub
+METHOD compensate
+AT THROW 3
+BIND NOTHING
+IF TRUE
+DO debug("throw during compensate for pseudo-participant " + $0 + " with no subordinate coordinator"),
+   traceln("log", "throw during compensate for pseudo-participant " + $0 + " with no subordinate coordinator")
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a subordinate pseudo participant
+# (SubordinateCoordinatorCompletionParticipantStub) throws an error from its compensate method
+# because the subordinate coordinator has not yet been activated. It
+# traces the throw.
+
+
+RULE trace subordinate participant stub compensate with unactivated coordinator
+CLASS com.arjuna.wst11.stub.SubordinateCoordinatorCompletionParticipantStub
+METHOD compensate
+AT THROW 4
+BIND NOTHING
+IF TRUE
+DO debug("throw during compensate for pseudo-participant " + $0 + " with unactivated subordinate coordinator"),
+   traceln("log", "throw during compensate for pseudo-participant " + $0 + " with unactivated subordinate coordinator")
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a subordinate pseudo participant
+# (SubordinateCoordinatorCompletionParticipantStub) throws an error from its compensate method
+# because of a system exception being thrown from the compensate. It
+# traces the throw.
+
+
+RULE trace subordinate participant stub compensate with system exception from coordinator
+CLASS com.arjuna.wst11.stub.SubordinateCoordinatorCompletionParticipantStub
+METHOD compensate
+AT THROW 5
+BIND NOTHING
+IF TRUE
+DO debug("throw during compensate for pseudo-participant " + $0 + " with system exception from subordinate coordinator"),
+   traceln("log", "throw during compensate for pseudo-participant " + $0 + " with system exception from subordinate coordinator")
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a subordinate pseudo participant
+# (SubordinateCoordinatorCompletionParticipantStub) returns from frowarding a compensate message. It
+# traces the call.
+
+RULE trace subordinate participant stub compensate return
+CLASS com.arjuna.wst11.stub.SubordinateCoordinatorCompletionParticipantStub
+METHOD compensate
+AT EXIT
+BIND NOTHING
+IF TRUE
+DO debug("compensate completed for pseudo-participant " + $0),
+   traceln("log", "compensate completed for pseudo-participant " + $0)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a subordinate coordinator
+# (SubordinateBACoordinator) calls prepare during completion. It
+# traces the call.
+
+RULE trace subordinate coordinator prepare
+CLASS com.arjuna.mwlabs.wscf.model.sagas.arjunacore.subordinate.SubordinateBACoordinator
+METHOD complete
+AT INVOKE prepare
+BIND uid = $0.get_uid()
+IF TRUE
+DO debug("prepare for transaction " + uid),
+   traceln("log", "prepare for transaction " + uid)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a subordinate coordinator
+# (SubordinateCoordinator) is requested to perform a cancel. It
+# traces the call.
+
+RULE trace subordinate coordinator close
+CLASS com.arjuna.mwlabs.wscf.model.sagas.arjunacore.subordinate.SubordinateBACoordinator
+METHOD cancel
+AT ENTRY
+BIND NOTHING
+IF TRUE
+DO debug("cancel called for subordinate coordinator " + $0),
+   traceln("log", "cancel called for subordinate coordinator " + $0)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a subordinate coordinator
+# (SubordinateCoordinator) is requested to perform a close. It
+# traces the call.
+
+RULE trace subordinate coordinator cancel 2
+CLASS com.arjuna.mwlabs.wscf.model.sagas.arjunacore.subordinate.SubordinateBACoordinator
+METHOD cancel
+AT EXIT
+BIND NOTHING
+IF TRUE
+DO debug("cancel returned for subordinate coordinator " + $0),
+   traceln("log", "cancel returned for subordinate coordinator " + $0)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when the recovery system finds a PREPARED
+# parent activity in the log and reruns the phase 2 commit operation.
+# It prints a message which can be used to verify that the test has
+# progressed as expected and creates a countdown used to detect exit of
+# both transactions
+
+RULE trace prepared replay
+CLASS org.jboss.jbossts.xts.recovery.coordinator.ba.RecoveryBACoordinator
+METHOD replayPhase2
+AT INVOKE phase2Commit
+BIND coordinator = $0,
+     uid : Uid = coordinator.identifier(),
+     status : int = coordinator.status()
+IF (status == com.arjuna.ats.arjuna.coordinator.ActionStatus.PREPARED)
+     OR
+     (status == com.arjuna.ats.arjuna.coordinator.ActionStatus.COMMITTING)
+DO debug("replaying commit for prepared transaction " + uid),
+   traceln("log", "replaying commit for prepared transaction " + uid),
+   createCountDown("exit countdown", 1)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when the recovery system finds a PREPARED
+# subordinate activity in the log. It prints a message which can be
+# used to verify that the test has progressed as expected
+
+RULE trace subordinate prepared replay
+CLASS org.jboss.jbossts.xts.recovery.coordinator.ba.RecoverySubordinateBACoordinator
+METHOD replayPhase2
+AT ENTRY
+BIND coordinator = $0,
+     uid : Uid = coordinator.identifier(),
+     status : int = coordinator.status()
+IF (status == com.arjuna.ats.arjuna.coordinator.ActionStatus.PREPARED)
+     OR
+     (status == com.arjuna.ats.arjuna.coordinator.ActionStatus.COMMITTING)
+DO debug("reinstated prepared subordinate transaction " + uid),
+   traceln("log", "reinstated prepared subordinate transaction " + uid)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a TX is saved to disk during prepare.
+
+RULE trace TX save at prepare
+CLASS com.arjuna.ats.arjuna.coordinator.BasicAction
+METHOD prepare(boolean)
+AFTER CALL save_state
+BIND action : BasicAction = $0,
+     uid  = action.get_uid()
+IF TRUE
+DO traceln("log", "saved to disk transaction " + uid),
+   debug("saved to disk transaction " + uid)
+ENDRULE
+
+#######################################################################
+# This rule is called when removing an activity from the log. It
+# ensures that the JVM exits but only after we have seen all the
+# necessary compensated messages
+
+RULE trace remove committed state and exit JVM
+CLASS com.arjuna.ats.arjuna.coordinator.BasicAction
+METHOD updateState
+AFTER CALL remove_committed
+BIND action : BasicAction = $0,
+     uid  = action.get_uid(),
+     dummy = flag("tx removed")
+IF readCounter("participant deletes") == 3
+DO traceln("log", "JVM exit"),
+   debug("JVM exit"),
+   killJVM()
+ENDRULE
+
+#######################################################################
+# This rule is called when deleting a participant record from the log.
+# It ensures that the JVM exits but only after we have seen 3 deletes
+# and also seen the tx removed
+
+RULE trace delete participant and exit JVM
+CLASS org.jboss.jbossts.xts.recovery.participant.ba.XTSBARecoveryManagerImple
+METHOD deleteParticipantRecoveryRecord
+AFTER CALL remove_committed
+BIND dummy = flag("tx removed")
+IF incrementCounter("participant deletes") == 3 &&
+   flagged("tx removed")
+DO traceln("log", "JVM exit"),
+   debug("JVM exit"),
+   killJVM()
+ENDRULE
+
+#######################################################################
+# This rule is triggered when the recovery system deletes an
+# activity from the log. It prints a message which can be used to
+# verify that the test has completed.
+
+RULE trace remove committed state
+CLASS com.arjuna.ats.arjuna.coordinator.BasicAction
+METHOD updateState
+AFTER CALL remove_committed
+BIND action : BasicAction = $0,
+     uid  = action.get_uid()
+IF TRUE
+DO traceln("log", "removed transaction " + uid),
+   debug("removed transaction " + uid)
+ENDRULE



More information about the jboss-svn-commits mailing list