You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ai...@apache.org on 2008/02/08 11:10:11 UTC

svn commit: r619823 [18/19] - in /incubator/qpid/branches/thegreatmerge/qpid: ./ cpp/ dotnet/ dotnet/Qpid.Buffer.Tests/Properties/ dotnet/Qpid.Buffer/Properties/ dotnet/Qpid.Client.Tests/ dotnet/Qpid.Client.Tests/Channel/ dotnet/Qpid.Client.Tests/Commo...

Added: incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/TestCaseVector.java
URL: http://svn.apache.org/viewvc/incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/TestCaseVector.java?rev=619823&view=auto
==============================================================================
--- incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/TestCaseVector.java (added)
+++ incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/TestCaseVector.java Fri Feb  8 02:09:37 2008
@@ -0,0 +1,88 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.test.framework;
+
+/**
+ * <p/><table id="crc"><caption>CRC Card</caption>
+ * <tr><th> Responsibilities <th> Collaborations
+ * <tr><td>
+ * </table>
+ */
+public class TestCaseVector
+{
+    /** The test case name. */
+    private String testCase;
+
+    /** The test cycle number within the test case. */
+    private int testCycleNumber;
+
+    public TestCaseVector(String testCase, int testCycleNumber)
+    {
+        this.testCase = testCase;
+        this.testCycleNumber = testCycleNumber;
+    }
+
+    public String getTestCase()
+    {
+        return testCase;
+    }
+
+    public int getTestCycleNumber()
+    {
+        return testCycleNumber;
+    }
+
+    public boolean equals(Object o)
+    {
+        if (this == o)
+        {
+            return true;
+        }
+
+        if ((o == null) || (getClass() != o.getClass()))
+        {
+            return false;
+        }
+
+        TestCaseVector that = (TestCaseVector) o;
+
+        if (testCycleNumber != that.testCycleNumber)
+        {
+            return false;
+        }
+
+        if ((testCase != null) ? (!testCase.equals(that.testCase)) : (that.testCase != null))
+        {
+            return false;
+        }
+
+        return true;
+    }
+
+    public int hashCode()
+    {
+        int result;
+        result = ((testCase != null) ? testCase.hashCode() : 0);
+        result = (31 * result) + testCycleNumber;
+
+        return result;
+    }
+}

Modified: incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/TestUtils.java
URL: http://svn.apache.org/viewvc/incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/TestUtils.java?rev=619823&r1=619822&r2=619823&view=diff
==============================================================================
--- incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/TestUtils.java (original)
+++ incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/TestUtils.java Fri Feb  8 02:09:37 2008
@@ -32,7 +32,6 @@
 import javax.naming.NamingException;
 
 import java.util.Map;
-import java.util.Properties;
 
 /**
  * TestUtils provides static helper methods that are usefull for writing tests against QPid.

Modified: incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/clocksynch/ClockSynchFailureException.java
URL: http://svn.apache.org/viewvc/incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/clocksynch/ClockSynchFailureException.java?rev=619823&r1=619822&r2=619823&view=diff
==============================================================================
--- incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/clocksynch/ClockSynchFailureException.java (original)
+++ incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/clocksynch/ClockSynchFailureException.java Fri Feb  8 02:09:37 2008
@@ -21,8 +21,8 @@
 package org.apache.qpid.test.framework.clocksynch;
 
 /**
- * ClockSynchFailureException represents failure of a {@link ClockSynchronizer} to achieve synchronization. This could
- * be because a reference signal is not available, or because a desired accurracy cannot be attained, for example.
+ * ClockSynchFailureException represents failure of a {@link ClockSynchronizer} to achieve synchronization. For example,
+ * this could be because a reference signal is not available, or because a desired accurracy cannot be attained.
  *
  * <p/><table id="crc"><caption>CRC Card</caption>
  * <tr><th> Responsibilities <th> Collaborations

Modified: incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/clocksynch/ClockSynchronizer.java
URL: http://svn.apache.org/viewvc/incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/clocksynch/ClockSynchronizer.java?rev=619823&r1=619822&r2=619823&view=diff
==============================================================================
--- incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/clocksynch/ClockSynchronizer.java (original)
+++ incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/clocksynch/ClockSynchronizer.java Fri Feb  8 02:09:37 2008
@@ -32,7 +32,7 @@
  *
  * <p/><table id="crc"><caption>CRC Card</caption>
  * <tr><th> Responsibilities <th> Collaborations
- * <tr><td> Trigger a clock synchronziation.
+ * <tr><td> Trigger a clock synchronization.
  * <tr><td> Compute a clock delta to apply to the local clock.
  * <tr><td> Estimate the error in the synchronzation.
  * </table>

Modified: incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/clocksynch/UDPClockReference.java
URL: http://svn.apache.org/viewvc/incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/clocksynch/UDPClockReference.java?rev=619823&r1=619822&r2=619823&view=diff
==============================================================================
--- incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/clocksynch/UDPClockReference.java (original)
+++ incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/clocksynch/UDPClockReference.java Fri Feb  8 02:09:37 2008
@@ -22,12 +22,12 @@
 
 import org.apache.log4j.Logger;
 
+import uk.co.thebadgerset.junit.extensions.ShutdownHookable;
+
 import java.io.IOException;
 import java.net.*;
 import java.nio.ByteBuffer;
 
-import uk.co.thebadgerset.junit.extensions.ShutdownHookable;
-
 /**
  * UDPClockReference supplies a refernce clock signal (generated from System.nanoTime()).
  *
@@ -49,7 +49,7 @@
     private static final int TIMEOUT = 200;
 
     /** Defines the port to run the clock reference on. */
-    public static final int REFERENCE_PORT = 4445;
+    public static final int REFERENCE_PORT = 4444;
 
     /** Holds the socket to receive clock reference requests on. */
     protected DatagramSocket socket = null;

Modified: incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/distributedcircuit/DistributedPublisherImpl.java
URL: http://svn.apache.org/viewvc/incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/distributedcircuit/DistributedPublisherImpl.java?rev=619823&r1=619822&r2=619823&view=diff
==============================================================================
--- incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/distributedcircuit/DistributedPublisherImpl.java (original)
+++ incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/distributedcircuit/DistributedPublisherImpl.java Fri Feb  8 02:09:37 2008
@@ -23,10 +23,17 @@
 import org.apache.qpid.test.framework.Assertion;
 import org.apache.qpid.test.framework.Publisher;
 
+import uk.co.thebadgerset.junit.extensions.util.ParsedProperties;
+
 /**
+ * DistributedPublisherImpl represents the status of the publishing side of a test circuit. Its main purpose is to
+ * provide assertions that can be applied to verify the behaviour of a non-local publisher.
+ *
  * <p/><table id="crc"><caption>CRC Card</caption>
  * <tr><th> Responsibilities <th> Collaborations
- * <tr><td>
+ * <tr><td> Provide assertion that the publishers received no exceptions.
+ * <tr><td> Provide assertion that the publishers received a no consumers error code on every message.
+ * <tr><td> Provide assertion that the publishers received a no route error code on every message.
  * </table>
  */
 public class DistributedPublisherImpl implements Publisher
@@ -35,8 +42,9 @@
      * Provides an assertion that the publisher encountered no exceptions.
      *
      * @return An assertion that the publisher encountered no exceptions.
+     * @param testProps
      */
-    public Assertion noExceptionsAssertion()
+    public Assertion noExceptionsAssertion(ParsedProperties testProps)
     {
         throw new RuntimeException("Not implemented.");
     }
@@ -57,6 +65,29 @@
      * @return An assertion that the publisher got a no rout exception on every message.
      */
     public Assertion noRouteAssertion()
+    {
+        throw new RuntimeException("Not implemented.");
+    }
+
+    /**
+     * Provides an assertion that the AMQP channel was forcibly closed by an error condition.
+     *
+     * @param testProps The test configuration properties.
+     * @return An assertion that the AMQP channel was forcibly closed by an error condition.
+     */
+    public Assertion channelClosedAssertion(ParsedProperties testProps)
+    {
+        throw new RuntimeException("Not implemented.");
+    }
+
+    /**
+     * Provides an assertion that the publisher got a given exception during the test.
+     *
+     * @param testProps      The test configuration properties.
+     * @param exceptionClass The exception class to check for.
+     * @return An assertion that the publisher got a given exception during the test.
+     */
+    public Assertion exceptionAssertion(ParsedProperties testProps, Class<? extends Exception> exceptionClass)
     {
         throw new RuntimeException("Not implemented.");
     }

Modified: incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/distributedcircuit/DistributedReceiverImpl.java
URL: http://svn.apache.org/viewvc/incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/distributedcircuit/DistributedReceiverImpl.java?rev=619823&r1=619822&r2=619823&view=diff
==============================================================================
--- incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/distributedcircuit/DistributedReceiverImpl.java (original)
+++ incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/distributedcircuit/DistributedReceiverImpl.java Fri Feb  8 02:09:37 2008
@@ -23,10 +23,16 @@
 import org.apache.qpid.test.framework.Assertion;
 import org.apache.qpid.test.framework.Receiver;
 
+import uk.co.thebadgerset.junit.extensions.util.ParsedProperties;
+
 /**
+ * DistributedReceiverImpl represents the status of the receiving side of a test circuit. Its main purpose is to
+ * provide assertions that can be applied to verify the behaviour of a non-local receiver.
+ *
  * <p/><table id="crc"><caption>CRC Card</caption>
  * <tr><th> Responsibilities <th> Collaborations
- * <tr><td>
+ * <tr><td> Provide assertion that the receivers received no exceptions.
+ * <tr><td> Provide assertion that the receivers received all test messages sent to it.
  * </table>
  */
 public class DistributedReceiverImpl implements Receiver
@@ -35,8 +41,9 @@
      * Provides an assertion that the receivers encountered no exceptions.
      *
      * @return An assertion that the receivers encountered no exceptions.
+     * @param testProps
      */
-    public Assertion noExceptionsAssertion()
+    public Assertion noExceptionsAssertion(ParsedProperties testProps)
     {
         throw new RuntimeException("Not implemented.");
     }
@@ -45,9 +52,44 @@
      * Provides an assertion that the receivers got all messages that were sent to it.
      *
      * @return An assertion that the receivers got all messages that were sent to it.
+     * @param testProps
+     */
+    public Assertion allMessagesReceivedAssertion(ParsedProperties testProps)
+    {
+        throw new RuntimeException("Not implemented.");
+    }
+
+    /**
+     * Provides an assertion that the receivers got none of the messages that were sent to it.
+     *
+     * @return An assertion that the receivers got none of the messages that were sent to it.
+     * @param testProps
      */
-    public Assertion allMessagesAssertion()
+    public Assertion noMessagesReceivedAssertion(ParsedProperties testProps)
+    {
+        throw new RuntimeException("Not implemented.");
+    }
+
+    /**
+     * Provides an assertion that the AMQP channel was forcibly closed by an error condition.
+     *
+     * @param testProps The test configuration properties.
+     * @return An assertion that the AMQP channel was forcibly closed by an error condition.
+     */
+    public Assertion channelClosedAssertion(ParsedProperties testProps)
+    {
+        throw new RuntimeException("Not implemented.");
+    }
+
+    /**
+     * Provides an assertion that the receiver got a given exception during the test.
+     *
+     * @param testProps
+     *@param exceptionClass The exception class to check for. @return An assertion that the receiver got a given exception during the test.
+     */
+    public Assertion exceptionAssertion(ParsedProperties testProps, Class<? extends Exception> exceptionClass)
     {
         throw new RuntimeException("Not implemented.");
     }
 }
+

Modified: incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/distributedcircuit/TestClientCircuitEnd.java
URL: http://svn.apache.org/viewvc/incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/distributedcircuit/TestClientCircuitEnd.java?rev=619823&r1=619822&r2=619823&view=diff
==============================================================================
--- incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/distributedcircuit/TestClientCircuitEnd.java (original)
+++ incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/distributedcircuit/TestClientCircuitEnd.java Fri Feb  8 02:09:37 2008
@@ -24,7 +24,6 @@
 
 import org.apache.qpid.test.framework.*;
 import org.apache.qpid.test.framework.distributedtesting.TestClientControlledTest;
-import org.apache.qpid.test.framework.localcircuit.LocalCircuitImpl;
 
 import uk.co.thebadgerset.junit.extensions.util.ParsedProperties;
 import uk.co.thebadgerset.junit.extensions.util.TestContextProperties;
@@ -48,7 +47,15 @@
  *
  * <p/><table id="crc"><caption>CRC Card</caption>
  * <tr><th> Responsibilities <th> Collaborations
- * <tr><td>
+ * <tr><td> Provide a message producer for sending messages.
+ *     <td> {@link CircuitEnd}, {@link LocalCircuitFactory}, {@link TestUtils}
+ * <tr><td> Provide a message consumer for receiving messages.
+ *     <td> {@link CircuitEnd}, {@link LocalCircuitFactory}, {@link TestUtils}
+ * <tr><td> Supply the name of the test case that this implements.
+ * <tr><td> Accept/Reject invites based on test parameters. <td> {@link MessagingTestConfigProperties}
+ * <tr><td> Adapt to assigned roles. <td> {@link TestClientControlledTest.Roles}
+ * <tr><td> Perform test case actions. <td> {@link MessageMonitor}
+ * <tr><td> Generate test reports. <td> {@link MessageMonitor}
  * </table>
  */
 public class TestClientCircuitEnd implements CircuitEnd, TestClientControlledTest
@@ -145,13 +152,15 @@
         connection = TestUtils.createConnection(testProps);
 
         // Create a circuit end that matches the assigned role and test parameters.
+        LocalCircuitFactory circuitFactory = new LocalCircuitFactory();
+
         switch (role)
         {
         // Check if the sender role is being assigned, and set up a message producer if so.
         case SENDER:
 
             // Set up the publisher.
-            circuitEnd = LocalCircuitImpl.createPublisherCircuitEnd(connection, testProps, 0L);
+            circuitEnd = circuitFactory.createPublisherCircuitEnd(connection, testProps, 0L);
 
             // Create a custom message monitor that will be updated on every message sent.
             messageMonitor = new MessageMonitor();
@@ -162,7 +171,7 @@
         case RECEIVER:
 
             // Set up the receiver.
-            circuitEnd = LocalCircuitImpl.createReceiverCircuitEnd(connection, testProps, 0L);
+            circuitEnd = circuitFactory.createReceiverCircuitEnd(connection, testProps, 0L);
 
             // Use the message monitor from the consumer for stats.
             messageMonitor = getMessageMonitor();

Modified: incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/distributedtesting/Coordinator.java
URL: http://svn.apache.org/viewvc/incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/distributedtesting/Coordinator.java?rev=619823&r1=619822&r2=619823&view=diff
==============================================================================
--- incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/distributedtesting/Coordinator.java (original)
+++ incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/distributedtesting/Coordinator.java Fri Feb  8 02:09:37 2008
@@ -33,7 +33,6 @@
 import org.apache.qpid.test.framework.TestUtils;
 import org.apache.qpid.test.framework.clocksynch.UDPClockReference;
 import org.apache.qpid.util.ConversationFactory;
-import org.apache.qpid.util.PrettyPrintingUtils;
 
 import uk.co.thebadgerset.junit.extensions.TKTestRunner;
 import uk.co.thebadgerset.junit.extensions.WrappedSuiteTestDecorator;
@@ -56,7 +55,7 @@
  * <p><table id="crc"><caption>CRC Card</caption>
  * <tr><th> Responsibilities <th> Collaborations
  * <tr><td> Find out what test clients are available. <td> {@link ConversationFactory}
- * <tr><td> Decorate available tests to run all available clients. <td> {@link DistributedTestDecorator}
+ * <tr><td> Decorate available tests to run on all available clients. <td> {@link DistributedTestDecorator}
  * <tr><td> Attach XML test result logger.
  * <tr><td> Terminate the interop testing framework.
  * </table>
@@ -64,8 +63,6 @@
  * @todo Should accumulate failures over all tests, and return with success or fail code based on all results. May need
  *       to write a special TestResult to do this properly. At the moment only the last one used will be tested for
  *       errors, as the start method creates a fresh one for each test case run.
- *
- * @todo Remove hard coding of test cases and put on command line instead.
  */
 public class Coordinator extends TKTestRunner
 {
@@ -119,27 +116,29 @@
     /**
      * Creates an interop test coordinator on the specified broker and virtual host.
      *
-     * @param repetitions   The number of times to repeat the test, or test batch size.
-     * @param duration      The length of time to run the tests for. -1 means no duration has been set.
-     * @param threads       The concurrency levels to ramp up to.
-     * @param delay         A delay in milliseconds between test runs.
-     * @param params        The sets of 'size' parameters to pass to test.
-     * @param testCaseName  The name of the test case to run.
-     * @param reportDir     The directory to output the test results to.
-     * @param runName       The name of the test run; used to name the output file.
-     * @param verbose       Whether to print comments during test run.
-     * @param brokerUrl     The URL of the broker to connect to.
-     * @param virtualHost   The virtual host to run all tests on. Optional, may be <tt>null</tt>.
-     * @param engine        The distributed test engine type to run the tests with.
-     * @param terminate     <tt>true</tt> if test client nodes should be terminated at the end of the tests.
-     * @param csv           <tt>true</tt> if the CSV results listener should be attached.
-     * @param xml           <tt>true</tt> if the XML results listener should be attached.
+     * @param repetitions        The number of times to repeat the test, or test batch size.
+     * @param duration           The length of time to run the tests for. -1 means no duration has been set.
+     * @param threads            The concurrency levels to ramp up to.
+     * @param delay              A delay in milliseconds between test runs.
+     * @param params             The sets of 'size' parameters to pass to test.
+     * @param testCaseName       The name of the test case to run.
+     * @param reportDir          The directory to output the test results to.
+     * @param runName            The name of the test run; used to name the output file.
+     * @param verbose            Whether to print comments during test run.
+     * @param brokerUrl          The URL of the broker to connect to.
+     * @param virtualHost        The virtual host to run all tests on. Optional, may be <tt>null</tt>.
+     * @param engine             The distributed test engine type to run the tests with.
+     * @param terminate          <tt>true</tt> if test client nodes should be terminated at the end of the tests.
+     * @param csv                <tt>true</tt> if the CSV results listener should be attached.
+     * @param xml                <tt>true</tt> if the XML results listener should be attached.
+     * @param decoratorFactories List of factories for user specified decorators.
      */
     public Coordinator(Integer repetitions, Long duration, int[] threads, int delay, int[] params, String testCaseName,
         String reportDir, String runName, boolean verbose, String brokerUrl, String virtualHost, TestEngine engine,
-        boolean terminate, boolean csv, boolean xml)
+        boolean terminate, boolean csv, boolean xml, List<TestDecoratorFactory> decoratorFactories)
     {
-        super(repetitions, duration, threads, delay, params, testCaseName, reportDir, runName, csv, xml, verbose);
+        super(repetitions, duration, threads, delay, params, testCaseName, reportDir, runName, csv, xml, verbose,
+            decoratorFactories);
 
         log.debug("public Coordinator(Integer repetitions = " + repetitions + " , Long duration = " + duration
             + ", int[] threads = " + Arrays.toString(threads) + ", int delay = " + delay + ", int[] params = "
@@ -221,7 +220,11 @@
                                 },
                                 { "s", "The size parameter to run tests with.", "size", "false", MathUtils.SEQUENCE_REGEXP },
                                 { "v", "Verbose mode.", null, "false" },
-                                { "n", "A name for this test run, used to name the output file.", "name", "true" }
+                                { "n", "A name for this test run, used to name the output file.", "name", "true" },
+                                {
+                                    "X:decorators", "A list of additional test decorators to wrap the tests in.",
+                                    "\"class.name[:class.name]*\"", "false"
+                                }
                             }), testContextProperties));
 
             // Extract the command line options.
@@ -234,13 +237,13 @@
             boolean terminate = options.getPropertyAsBoolean("t");
             boolean csvResults = options.getPropertyAsBoolean("-csv");
             boolean xmlResults = options.getPropertyAsBoolean("-xml");
-
             String threadsString = options.getProperty("c");
             Integer repetitions = options.getPropertyAsInteger("r");
             String durationString = options.getProperty("d");
             String paramsString = options.getProperty("s");
             boolean verbose = options.getPropertyAsBoolean("v");
             String testRunName = options.getProperty("n");
+            String decorators = options.getProperty("X:decorators");
 
             int[] threads = (threadsString == null) ? null : MathUtils.parseSequence(threadsString);
             int[] params = (paramsString == null) ? null : MathUtils.parseSequence(paramsString);
@@ -253,6 +256,9 @@
             Collection<Class<? extends FrameworkBaseCase>> testCaseClasses =
                 new ArrayList<Class<? extends FrameworkBaseCase>>();
 
+            // Create a list of test decorator factories for use specified decorators to be applied.
+            List<TestDecoratorFactory> decoratorFactories = parseDecorators(decorators);
+
             // Scan for available test cases using a classpath scanner.
             // ClasspathScanner.getMatches(DistributedTestCase.class, "^Test.*", true);
 
@@ -306,7 +312,7 @@
             // Create a coordinator and begin its test procedure.
             Coordinator coordinator =
                 new Coordinator(repetitions, duration, threads, 0, params, null, reportDir, testRunName, verbose, brokerUrl,
-                    virtualHost, engine, terminate, csvResults, xmlResults);
+                    virtualHost, engine, terminate, csvResults, xmlResults, decoratorFactories);
 
             TestResult testResult = coordinator.start(testClassNames);
 
@@ -324,6 +330,7 @@
         {
             log.debug("Top level handler caught execption.", e);
             console.info(e.getMessage());
+            e.printStackTrace();
             System.exit(EXCEPTION_EXIT);
         }
     }
@@ -339,8 +346,7 @@
      */
     public TestResult start(String[] testClassNames) throws Exception
     {
-        log.debug("public TestResult start(String[] testClassNames = " + PrettyPrintingUtils.printArray(testClassNames)
-            + ": called");
+        log.debug("public TestResult start(String[] testClassNames = " + Arrays.toString(testClassNames) + ": called");
 
         // Connect to the broker.
         connection = TestUtils.createConnection(TestContextProperties.getInstance());
@@ -494,6 +500,9 @@
             log.debug("Wrapped with a WrappedSuiteTestDecorator.");
         }
 
+        // Apply any optional user specified decorators.
+        targetTest = applyOptionalUserDecorators(targetTest);
+
         // Wrap the tests in a suitable distributed test decorator, to perform the invite/test cycle.
         targetTest = newTestDecorator(targetTest, enlistedClients, conversationFactory, connection);
 
@@ -529,4 +538,4 @@
             return new InteropTestDecorator(targetTest, enlistedClients, conversationFactory, connection);
         }
     }
-}
+}
\ No newline at end of file

Modified: incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/distributedtesting/InteropTestDecorator.java
URL: http://svn.apache.org/viewvc/incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/distributedtesting/InteropTestDecorator.java?rev=619823&r1=619822&r2=619823&view=diff
==============================================================================
--- incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/distributedtesting/InteropTestDecorator.java (original)
+++ incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/distributedtesting/InteropTestDecorator.java Fri Feb  8 02:09:37 2008
@@ -50,7 +50,7 @@
  * <tr><td> Broadcast test invitations and collect enlists. <td> {@link org.apache.qpid.util.ConversationFactory}.
  * <tr><td> Output test failures for clients unwilling to run the test case. <td> {@link Coordinator}
  * <tr><td> Execute distributed test cases. <td> {@link FrameworkBaseCase}
- * <tr><td> Fail non participating pairings. <td> {@link OptOutTestCase}
+ * <tr><td> Fail non-participating pairings. <td> {@link OptOutTestCase}
  * </table>
  */
 public class InteropTestDecorator extends DistributedTestDecorator

Added: incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/distributedtesting/TestClient.java
URL: http://svn.apache.org/viewvc/incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/distributedtesting/TestClient.java?rev=619823&view=auto
==============================================================================
--- incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/distributedtesting/TestClient.java (added)
+++ incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/distributedtesting/TestClient.java Fri Feb  8 02:09:37 2008
@@ -0,0 +1,497 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.test.framework.distributedtesting;
+
+import org.apache.log4j.Logger;
+import org.apache.log4j.NDC;
+
+import org.apache.qpid.test.framework.MessagingTestConfigProperties;
+import org.apache.qpid.test.framework.TestUtils;
+import org.apache.qpid.test.framework.clocksynch.ClockSynchThread;
+import org.apache.qpid.test.framework.clocksynch.UDPClockSynchronizer;
+import org.apache.qpid.util.ReflectionUtils;
+import org.apache.qpid.util.ReflectionUtilsException;
+
+import uk.co.thebadgerset.junit.extensions.SleepThrottle;
+import uk.co.thebadgerset.junit.extensions.util.ParsedProperties;
+import uk.co.thebadgerset.junit.extensions.util.TestContextProperties;
+
+import javax.jms.*;
+
+import java.util.*;
+
+/**
+ * Implements a test client as described in the interop testing spec
+ * (http://cwiki.apache.org/confluence/display/qpid/Interop+Testing+Specification). A test client is an agent that
+ * reacts to control message sequences send by the test {@link Coordinator}.
+ *
+ * <p/><table><caption>Messages Handled by TestClient</caption>
+ * <tr><th> Message               <th> Action
+ * <tr><td> Invite(compulsory)    <td> Reply with Enlist.
+ * <tr><td> Invite(test case)     <td> Reply with Enlist if test case available.
+ * <tr><td> AssignRole(test case) <td> Reply with Accept Role if matches an enlisted test. Keep test parameters.
+ * <tr><td> Start                 <td> Send test messages defined by test parameters. Send report on messages sent.
+ * <tr><td> Status Request        <td> Send report on messages received.
+ * <tr><td> Terminate             <td> Terminate the test client.
+ * <tr><td> ClockSynch            <td> Synch clock against the supplied UDP address.
+ * </table>
+ *
+ * <p><table id="crc"><caption>CRC Card</caption>
+ * <tr><th> Responsibilities <th> Collaborations
+ * <tr><td> Handle all incoming control messages. <td> {@link TestClientControlledTest}
+ * <tr><td> Configure and look up test cases by name. <td> {@link TestClientControlledTest}
+ * </table>
+ */
+public class TestClient implements MessageListener
+{
+    /** Used for debugging. */
+    private static final Logger log = Logger.getLogger(TestClient.class);
+
+    /** Used for reporting to the console. */
+    private static final Logger console = Logger.getLogger("CONSOLE");
+
+    /** Holds the default identifying name of the test client. */
+    public static final String CLIENT_NAME = "java";
+
+    /** Holds the URL of the broker to run the tests on. */
+    public static String brokerUrl;
+
+    /** Holds the virtual host to run the tests on. If <tt>null</tt>, then the default virtual host is used. */
+    public static String virtualHost;
+
+    /**
+     * Holds the test context properties that provides the default test parameters, plus command line overrides.
+     * This is initialized with the default test parameters, to which command line overrides may be applied.
+     */
+    public static ParsedProperties testContextProperties =
+        TestContextProperties.getInstance(MessagingTestConfigProperties.defaults);
+
+    /** Holds all the test cases loaded from the classpath. */
+    Map<String, TestClientControlledTest> testCases = new HashMap<String, TestClientControlledTest>();
+
+    /** Holds the test case currently being run by this client. */
+    protected TestClientControlledTest currentTestCase;
+
+    /** Holds the connection to the broker that the test is being coordinated on. */
+    protected Connection connection;
+
+    /** Holds the message producer to hold the test coordination over. */
+    protected MessageProducer producer;
+
+    /** Holds the JMS controlSession for the test coordination. */
+    protected Session session;
+
+    /** Holds the name of this client, with a default value. */
+    protected String clientName = CLIENT_NAME;
+
+    /** This flag indicates that the test client should attempt to join the currently running test case on start up. */
+    protected boolean join;
+
+    /** Holds the clock synchronizer for the test node. */
+    ClockSynchThread clockSynchThread;
+
+    /**
+     * Creates a new interop test client, listenting to the specified broker and virtual host, with the specified client
+     * identifying name.
+     *
+     * @param pBrokerUrl   The url of the broker to connect to.
+     * @param pVirtualHost The virtual host to conect to.
+     * @param clientName  The client name to use.
+     * @param join        Flag to indicate that this client should attempt to join running tests.
+     */
+    public TestClient(String pBrokerUrl, String pVirtualHost, String clientName, boolean join)
+    {
+        log.debug("public TestClient(String pBrokerUrl = " + pBrokerUrl + ", String pVirtualHost = " + pVirtualHost
+            + ", String clientName = " + clientName + ", boolean join = " + join + "): called");
+
+        // Retain the connection parameters.
+        brokerUrl = pBrokerUrl;
+        virtualHost = pVirtualHost;
+        this.clientName = clientName;
+        this.join = join;
+    }
+
+    /**
+     * The entry point for the interop test coordinator. This client accepts the following command line arguments:
+     *
+     * <p/><table>
+     * <tr><td> -b         <td> The broker URL.       <td> Optional.
+     * <tr><td> -h         <td> The virtual host.     <td> Optional.
+     * <tr><td> -n         <td> The test client name. <td> Optional.
+     * <tr><td> name=value <td> Trailing argument define name/value pairs. Added to system properties. <td> Optional.
+     * </table>
+     *
+     * @param args The command line arguments.
+     */
+    public static void main(String[] args)
+    {
+        log.debug("public static void main(String[] args = " + Arrays.toString(args) + "): called");
+        console.info("Qpid Distributed Test Client.");
+
+        // Override the default broker url to be localhost:5672.
+        testContextProperties.setProperty(MessagingTestConfigProperties.BROKER_PROPNAME, "tcp://localhost:5672");
+
+        // Use the command line parser to evaluate the command line with standard handling behaviour (print errors
+        // and usage then exist if there are errors).
+        // Any options and trailing name=value pairs are also injected into the test context properties object,
+        // to override any defaults that may have been set up.
+        ParsedProperties options =
+            new ParsedProperties(uk.co.thebadgerset.junit.extensions.util.CommandLineParser.processCommandLine(args,
+                    new uk.co.thebadgerset.junit.extensions.util.CommandLineParser(
+                        new String[][]
+                        {
+                            { "b", "The broker URL.", "broker", "false" },
+                            { "h", "The virtual host to use.", "virtual host", "false" },
+                            { "o", "The name of the directory to output test timings to.", "dir", "false" },
+                            { "n", "The name of the test client.", "name", "false" },
+                            { "j", "Join this test client to running test.", "false" }
+                        }), testContextProperties));
+
+        // Extract the command line options.
+        String brokerUrl = options.getProperty("b");
+        String virtualHost = options.getProperty("h");
+        String clientName = options.getProperty("n");
+        clientName = (clientName == null) ? CLIENT_NAME : clientName;
+        boolean join = options.getPropertyAsBoolean("j");
+
+        // To distinguish logging output set up an NDC on the client name.
+        NDC.push(clientName);
+
+        // Create a test client and start it running.
+        TestClient client = new TestClient(brokerUrl, virtualHost, clientName, join);
+
+        // Use a class path scanner to find all the interop test case implementations.
+        // Hard code the test classes till the classpath scanner is fixed.
+        Collection<Class<? extends TestClientControlledTest>> testCaseClasses =
+            new ArrayList<Class<? extends TestClientControlledTest>>();
+        // ClasspathScanner.getMatches(TestClientControlledTest.class, "^TestCase.*", true);
+        testCaseClasses.addAll(loadTestCases("org.apache.qpid.interop.clienttestcases.TestCase1DummyRun",
+                "org.apache.qpid.interop.clienttestcases.TestCase2BasicP2P",
+                "org.apache.qpid.interop.clienttestcases.TestCase3BasicPubSub",
+                "org.apache.qpid.interop.clienttestcases.TestCase4P2PMessageSize",
+                "org.apache.qpid.interop.clienttestcases.TestCase5PubSubMessageSize",
+                "org.apache.qpid.test.framework.distributedcircuit.TestClientCircuitEnd"));
+
+        try
+        {
+            client.start(testCaseClasses);
+        }
+        catch (Exception e)
+        {
+            log.error("The test client was unable to start.", e);
+            console.info(e.getMessage());
+            System.exit(1);
+        }
+    }
+
+    /**
+     * Parses a list of class names, and loads them if they are available on the class path.
+     *
+     * @param classNames The names of the classes to load.
+     *
+     * @return A list of the loaded test case classes.
+     */
+    public static List<Class<? extends TestClientControlledTest>> loadTestCases(String... classNames)
+    {
+        List<Class<? extends TestClientControlledTest>> testCases =
+            new LinkedList<Class<? extends TestClientControlledTest>>();
+
+        for (String className : classNames)
+        {
+            try
+            {
+                Class<?> cls = ReflectionUtils.forName(className);
+                testCases.add((Class<? extends TestClientControlledTest>) cls);
+            }
+            catch (ReflectionUtilsException e)
+            {
+                // Ignore, class could not be found, so test not available.
+                console.warn("Requested class " + className + " cannot be found, ignoring it.");
+            }
+            catch (ClassCastException e)
+            {
+                // Ignore, class was not of correct type to be a test case.
+                console.warn("Requested class " + className + " is not an instance of TestClientControlledTest.");
+            }
+        }
+
+        return testCases;
+    }
+
+    /**
+     * Starts the interop test client running. This causes it to start listening for incoming test invites.
+     *
+     * @param testCaseClasses The classes of the available test cases. The test case names from these are used to
+     *                        matchin incoming test invites against.
+     *
+     * @throws JMSException Any underlying JMSExceptions are allowed to fall through.
+     */
+    protected void start(Collection<Class<? extends TestClientControlledTest>> testCaseClasses) throws JMSException
+    {
+        log.debug("protected void start(Collection<Class<? extends TestClientControlledTest>> testCaseClasses = "
+            + testCaseClasses + "): called");
+
+        // Create all the test case implementations and index them by the test names.
+        for (Class<? extends TestClientControlledTest> nextClass : testCaseClasses)
+        {
+            try
+            {
+                TestClientControlledTest testCase = nextClass.newInstance();
+                testCases.put(testCase.getName(), testCase);
+            }
+            catch (InstantiationException e)
+            {
+                log.warn("Could not instantiate test case class: " + nextClass.getName(), e);
+                // Ignored.
+            }
+            catch (IllegalAccessException e)
+            {
+                log.warn("Could not instantiate test case class due to illegal access: " + nextClass.getName(), e);
+                // Ignored.
+            }
+        }
+
+        // Open a connection to communicate with the coordinator on.
+        connection = TestUtils.createConnection(testContextProperties);
+        session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+        // Set this up to listen for control messages.
+        Topic privateControlTopic = session.createTopic("iop.control." + clientName);
+        MessageConsumer consumer = session.createConsumer(privateControlTopic);
+        consumer.setMessageListener(this);
+
+        Topic controlTopic = session.createTopic("iop.control");
+        MessageConsumer consumer2 = session.createConsumer(controlTopic);
+        consumer2.setMessageListener(this);
+
+        // Create a producer to send replies with.
+        producer = session.createProducer(null);
+
+        // If the join flag was set, then broadcast a join message to notify the coordinator that a new test client
+        // is available to join the current test case, if it supports it. This message may be ignored, or it may result
+        // in this test client receiving a test invite.
+        if (join)
+        {
+            Message joinMessage = session.createMessage();
+
+            joinMessage.setStringProperty("CONTROL_TYPE", "JOIN");
+            joinMessage.setStringProperty("CLIENT_NAME", clientName);
+            joinMessage.setStringProperty("CLIENT_PRIVATE_CONTROL_KEY", "iop.control." + clientName);
+            producer.send(controlTopic, joinMessage);
+        }
+
+        // Start listening for incoming control messages.
+        connection.start();
+    }
+
+    /**
+     * Handles all incoming control messages.
+     *
+     * @param message The incoming message.
+     */
+    public void onMessage(Message message)
+    {
+        NDC.push(clientName);
+        log.debug("public void onMessage(Message message = " + message + "): called");
+
+        try
+        {
+            String controlType = message.getStringProperty("CONTROL_TYPE");
+            String testName = message.getStringProperty("TEST_NAME");
+
+            log.debug("Received control of type '" + controlType + "' for the test '" + testName + "'");
+
+            // Check if the message is a test invite.
+            if ("INVITE".equals(controlType))
+            {
+                // Flag used to indicate that an enlist should be sent. Only enlist to compulsory invites or invites
+                // for which test cases exist.
+                boolean enlist = false;
+
+                if (testName != null)
+                {
+                    log.debug("Got an invite to test: " + testName);
+
+                    // Check if the requested test case is available.
+                    TestClientControlledTest testCase = testCases.get(testName);
+
+                    if (testCase != null)
+                    {
+                        log.debug("Found implementing class for test '" + testName + "', enlisting for it.");
+
+                        // Check if the test case will accept the invitation.
+                        enlist = testCase.acceptInvite(message);
+
+                        log.debug("The test case "
+                            + (enlist ? " accepted the invite, enlisting for it."
+                                      : " did not accept the invite, not enlisting."));
+
+                        // Make the requested test case the current test case.
+                        currentTestCase = testCase;
+                    }
+                    else
+                    {
+                        log.debug("Received an invite to the test '" + testName + "' but this test is not known.");
+                    }
+                }
+                else
+                {
+                    log.debug("Got a compulsory invite, enlisting for it.");
+
+                    enlist = true;
+                }
+
+                if (enlist)
+                {
+                    // Reply with the client name in an Enlist message.
+                    Message enlistMessage = session.createMessage();
+                    enlistMessage.setStringProperty("CONTROL_TYPE", "ENLIST");
+                    enlistMessage.setStringProperty("CLIENT_NAME", clientName);
+                    enlistMessage.setStringProperty("CLIENT_PRIVATE_CONTROL_KEY", "iop.control." + clientName);
+                    enlistMessage.setJMSCorrelationID(message.getJMSCorrelationID());
+
+                    log.debug("Sending enlist message '" + enlistMessage + "' to " + message.getJMSReplyTo());
+
+                    producer.send(message.getJMSReplyTo(), enlistMessage);
+                }
+                else
+                {
+                    // Reply with the client name in an Decline message.
+                    Message enlistMessage = session.createMessage();
+                    enlistMessage.setStringProperty("CONTROL_TYPE", "DECLINE");
+                    enlistMessage.setStringProperty("CLIENT_NAME", clientName);
+                    enlistMessage.setStringProperty("CLIENT_PRIVATE_CONTROL_KEY", "iop.control." + clientName);
+                    enlistMessage.setJMSCorrelationID(message.getJMSCorrelationID());
+
+                    log.debug("Sending decline message '" + enlistMessage + "' to " + message.getJMSReplyTo());
+
+                    producer.send(message.getJMSReplyTo(), enlistMessage);
+                }
+            }
+            else if ("ASSIGN_ROLE".equals(controlType))
+            {
+                // Assign the role to the current test case.
+                String roleName = message.getStringProperty("ROLE");
+
+                log.debug("Got a role assignment to role: " + roleName);
+
+                TestClientControlledTest.Roles role = Enum.valueOf(TestClientControlledTest.Roles.class, roleName);
+
+                currentTestCase.assignRole(role, message);
+
+                // Reply by accepting the role in an Accept Role message.
+                Message acceptRoleMessage = session.createMessage();
+                acceptRoleMessage.setStringProperty("CLIENT_NAME", clientName);
+                acceptRoleMessage.setStringProperty("CONTROL_TYPE", "ACCEPT_ROLE");
+                acceptRoleMessage.setJMSCorrelationID(message.getJMSCorrelationID());
+
+                log.debug("Sending accept role message '" + acceptRoleMessage + "' to " + message.getJMSReplyTo());
+
+                producer.send(message.getJMSReplyTo(), acceptRoleMessage);
+            }
+            else if ("START".equals(controlType) || "STATUS_REQUEST".equals(controlType))
+            {
+                if ("START".equals(controlType))
+                {
+                    log.debug("Got a start notification.");
+
+                    // Extract the number of test messages to send from the start notification.
+                    int numMessages;
+
+                    try
+                    {
+                        numMessages = message.getIntProperty("MESSAGE_COUNT");
+                    }
+                    catch (NumberFormatException e)
+                    {
+                        // If the number of messages is not specified, use the default of one.
+                        numMessages = 1;
+                    }
+
+                    // Start the current test case.
+                    currentTestCase.start(numMessages);
+                }
+                else
+                {
+                    log.debug("Got a status request.");
+                }
+
+                // Generate the report from the test case and reply with it as a Report message.
+                Message reportMessage = currentTestCase.getReport(session);
+                reportMessage.setStringProperty("CLIENT_NAME", clientName);
+                reportMessage.setStringProperty("CONTROL_TYPE", "REPORT");
+                reportMessage.setJMSCorrelationID(message.getJMSCorrelationID());
+
+                log.debug("Sending report message '" + reportMessage + "' to " + message.getJMSReplyTo());
+
+                producer.send(message.getJMSReplyTo(), reportMessage);
+            }
+            else if ("TERMINATE".equals(controlType))
+            {
+                console.info("Received termination instruction from coordinator.");
+
+                // Is a cleaner shutdown needed?
+                connection.close();
+                System.exit(0);
+            }
+            else if ("CLOCK_SYNCH".equals(controlType))
+            {
+                log.debug("Received clock synch command.");
+                String address = message.getStringProperty("ADDRESS");
+
+                log.debug("address = " + address);
+
+                // Re-create (if necessary) and start the clock synch thread to synch the clock every ten seconds.
+                if (clockSynchThread != null)
+                {
+                    clockSynchThread.terminate();
+                }
+
+                SleepThrottle throttle = new SleepThrottle();
+                throttle.setRate(0.1f);
+
+                clockSynchThread = new ClockSynchThread(new UDPClockSynchronizer(address), throttle);
+                clockSynchThread.start();
+            }
+            else
+            {
+                // Log a warning about this but otherwise ignore it.
+                log.warn("Got an unknown control message, controlType = " + controlType + ", message = " + message);
+            }
+        }
+        catch (JMSException e)
+        {
+            // Log a warning about this, but otherwise ignore it.
+            log.warn("Got JMSException whilst handling message: " + message, e);
+        }
+        // Log any runtimes that fall through this message handler. These are fatal errors for the test client.
+        catch (RuntimeException e)
+        {
+            log.error("The test client message handler got an unhandled exception: ", e);
+            console.info("The message handler got an unhandled exception, terminating the test client.");
+            System.exit(1);
+        }
+        finally
+        {
+            NDC.pop();
+        }
+    }
+}

Added: incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/localcircuit/LocalAMQPPublisherImpl.java
URL: http://svn.apache.org/viewvc/incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/localcircuit/LocalAMQPPublisherImpl.java?rev=619823&view=auto
==============================================================================
--- incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/localcircuit/LocalAMQPPublisherImpl.java (added)
+++ incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/localcircuit/LocalAMQPPublisherImpl.java Fri Feb  8 02:09:37 2008
@@ -0,0 +1,133 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.test.framework.localcircuit;
+
+import org.apache.qpid.client.AMQNoConsumersException;
+import org.apache.qpid.client.AMQNoRouteException;
+import org.apache.qpid.test.framework.*;
+
+import uk.co.thebadgerset.junit.extensions.util.ParsedProperties;
+
+import javax.jms.MessageConsumer;
+import javax.jms.MessageProducer;
+import javax.jms.Session;
+
+/**
+ * LocalAMQPPublisherImpl is an extension of {@link LocalPublisherImpl} that adds AMQP specific features. Specifically
+ * extra assertions for AMQP features not available through generic JMS.
+ *
+ * <p/><table id="crc"><caption>CRC Card</caption>
+ * <tr><th> Responsibilities <th> Collaborations
+ * <tr><td>
+ * </table>
+ */
+public class LocalAMQPPublisherImpl extends LocalPublisherImpl implements AMQPPublisher
+{
+    /**
+     * Creates a circuit end point on the specified producer, consumer and controlSession. Monitors are also configured
+     * for messages and exceptions received by the circuit end.
+     *
+     * @param producer         The message producer for the circuit end point.
+     * @param consumer         The message consumer for the circuit end point.
+     * @param session          The controlSession for the circuit end point.
+     * @param messageMonitor   The monitor to notify of all messages received by the circuit end.
+     * @param exceptionMonitor The monitor to notify of all exceptions received by the circuit end.
+     */
+    public LocalAMQPPublisherImpl(MessageProducer producer, MessageConsumer consumer, Session session,
+        MessageMonitor messageMonitor, ExceptionMonitor exceptionMonitor)
+    {
+        super(producer, consumer, session, messageMonitor, exceptionMonitor);
+    }
+
+    /**
+     * Creates a circuit end point from the producer, consumer and controlSession in a circuit end base implementation.
+     *
+     * @param end The circuit end base implementation to take producers and consumers from.
+     */
+    public LocalAMQPPublisherImpl(CircuitEndBase end)
+    {
+        super(end);
+    }
+
+    /**
+     * Provides an assertion that the publisher got a no consumers exception on every message.
+     *
+     * @param testProps The test configuration properties.
+     *
+     * @return An assertion that the publisher got a no consumers exception on every message.
+     */
+    public Assertion noConsumersAssertion(ParsedProperties testProps)
+    {
+        return new AssertionBase()
+            {
+                public boolean apply()
+                {
+                    boolean passed = true;
+                    ExceptionMonitor connectionExceptionMonitor = circuit.getConnectionExceptionMonitor();
+
+                    if (!connectionExceptionMonitor.assertOneJMSExceptionWithLinkedCause(AMQNoConsumersException.class))
+                    {
+                        passed = false;
+
+                        addError("Was expecting linked exception type " + AMQNoConsumersException.class.getName()
+                            + " on the connection.\n");
+                        addError((connectionExceptionMonitor.size() > 0)
+                            ? ("Actually got the following exceptions on the connection, " + connectionExceptionMonitor)
+                            : "Got no exceptions on the connection.");
+                    }
+
+                    return passed;
+                }
+            };
+    }
+
+    /**
+     * Provides an assertion that the publisher got a no rout exception on every message.
+     *
+     * @param testProps The test configuration properties.
+     *
+     * @return An assertion that the publisher got a no rout exception on every message.
+     */
+    public Assertion noRouteAssertion(ParsedProperties testProps)
+    {
+        return new AssertionBase()
+            {
+                public boolean apply()
+                {
+                    boolean passed = true;
+                    ExceptionMonitor connectionExceptionMonitor = circuit.getConnectionExceptionMonitor();
+
+                    if (!connectionExceptionMonitor.assertOneJMSExceptionWithLinkedCause(AMQNoRouteException.class))
+                    {
+                        passed = false;
+
+                        addError("Was expecting linked exception type " + AMQNoRouteException.class.getName()
+                            + " on the connection.\n");
+                        addError((connectionExceptionMonitor.size() > 0)
+                            ? ("Actually got the following exceptions on the connection, " + connectionExceptionMonitor)
+                            : "Got no exceptions on the connection.");
+                    }
+
+                    return passed;
+                }
+            };
+    }
+}

Modified: incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/localcircuit/LocalCircuitImpl.java
URL: http://svn.apache.org/viewvc/incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/localcircuit/LocalCircuitImpl.java?rev=619823&r1=619822&r2=619823&view=diff
==============================================================================
--- incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/localcircuit/LocalCircuitImpl.java (original)
+++ incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/localcircuit/LocalCircuitImpl.java Fri Feb  8 02:09:37 2008
@@ -22,7 +22,6 @@
 
 import org.apache.log4j.Logger;
 
-import org.apache.qpid.client.AMQSession;
 import org.apache.qpid.test.framework.*;
 
 import uk.co.thebadgerset.junit.extensions.util.ParsedProperties;
@@ -31,7 +30,6 @@
 
 import java.util.LinkedList;
 import java.util.List;
-import java.util.concurrent.atomic.AtomicLong;
 
 /**
  * LocalCircuitImpl provides an implementation of the test circuit. This is a local only circuit implementation that
@@ -47,7 +45,7 @@
  * <tr><td> Apply assertions against the circuits state. <td> {@link Assertion}
  * <tr><td> Send test messages over the circuit.
  * <tr><td> Perform the default test procedure on the circuit.
- * <tr><td> Provide access to connection and controlSession exception monitors <td> {@link ExceptionMonitor}
+ * <tr><td> Provide access to connection and controlSession exception monitors. <td> {@link ExceptionMonitor}
  * </table>
  */
 public class LocalCircuitImpl implements Circuit
@@ -55,9 +53,6 @@
     /** Used for debugging. */
     private static final Logger log = Logger.getLogger(LocalCircuitImpl.class);
 
-    /** Used to create unique destination names for each test. */
-    private static AtomicLong uniqueDestsId = new AtomicLong();
-
     /** Holds the test configuration for the circuit. */
     private ParsedProperties testProps;
 
@@ -86,7 +81,7 @@
      * @param connection                 The connection.
      * @param connectionExceptionMonitor The connection exception monitor.
      */
-    protected LocalCircuitImpl(ParsedProperties testProps, LocalPublisherImpl publisher, LocalReceiverImpl receiver,
+    public LocalCircuitImpl(ParsedProperties testProps, LocalPublisherImpl publisher, LocalReceiverImpl receiver,
         Connection connection, ExceptionMonitor connectionExceptionMonitor)
     {
         this.testProps = testProps;
@@ -102,159 +97,6 @@
     }
 
     /**
-     * Creates a local test circuit from the specified test parameters.
-     *
-     * @param testProps The test parameters.
-     *
-     * @return A connected and ready to start, test circuit.
-     */
-    public static Circuit createCircuit(ParsedProperties testProps)
-    {
-        // Create a standard publisher/receivers test client pair on a shared connection, individual sessions.
-        try
-        {
-            // Cast the test properties into a typed interface for convenience.
-            MessagingTestConfigProperties props = new MessagingTestConfigProperties(testProps);
-
-            // Get a unique offset to append to destination names to make them unique to the connection.
-            long uniqueId = uniqueDestsId.incrementAndGet();
-
-            // Set up the connection.
-            Connection connection = TestUtils.createConnection(testProps);
-
-            // Add the connection exception listener to assert on exception conditions with.
-            // ExceptionMonitor exceptionMonitor = new ExceptionMonitor();
-            // connection.setExceptionListener(exceptionMonitor);
-
-            // Set up the publisher.
-            CircuitEndBase publisherEnd = createPublisherCircuitEnd(connection, props, uniqueId);
-
-            // Set up the receiver.
-            CircuitEndBase receiverEnd = createReceiverCircuitEnd(connection, props, uniqueId);
-
-            // Start listening for incoming messages.
-            connection.start();
-
-            // Package everything up.
-            LocalPublisherImpl publisher = new LocalPublisherImpl(publisherEnd);
-            LocalReceiverImpl receiver = new LocalReceiverImpl(receiverEnd);
-
-            return new LocalCircuitImpl(testProps, publisher, receiver, connection, publisher.getExceptionMonitor());
-        }
-        catch (JMSException e)
-        {
-            throw new RuntimeException("Could not create publisher/receivers pair due to a JMSException.", e);
-        }
-    }
-
-    /**
-     * Builds a circuit end suitable for the publishing side of a test circuit, from standard test parameters.
-     *
-     * @param connection The connection to build the circuit end on.
-     * @param testProps  The test parameters to configure the circuit end construction.
-     * @param uniqueId   A unique number to being numbering destinations from, to make this circuit unique.
-     *
-     * @return A circuit end suitable for the publishing side of a test circuit.
-     *
-     * @throws JMSException Any underlying JMSExceptions are allowed to fall through and fail the creation.
-     */
-    public static CircuitEndBase createPublisherCircuitEnd(Connection connection, ParsedProperties testProps, long uniqueId)
-        throws JMSException
-    {
-        log.debug(
-            "public static CircuitEndBase createPublisherCircuitEnd(Connection connection, ParsedProperties testProps, long uniqueId = "
-            + uniqueId + "): called");
-
-        // Cast the test properties into a typed interface for convenience.
-        MessagingTestConfigProperties props = new MessagingTestConfigProperties(testProps);
-
-        Session session = connection.createSession(props.getTransacted(), props.getAckMode());
-
-        Destination destination =
-            props.getPubsub() ? session.createTopic(props.getSendDestinationNameRoot() + "_" + uniqueId)
-                              : session.createQueue(props.getSendDestinationNameRoot() + "_" + uniqueId);
-
-        MessageProducer producer =
-            props.getPublisherProducerBind()
-            ? ((props.getImmediate() | props.getMandatory())
-                ? ((AMQSession) session).createProducer(destination, props.getMandatory(), props.getImmediate())
-                : session.createProducer(destination)) : null;
-
-        MessageConsumer consumer =
-            props.getPublisherConsumerBind()
-            ? session.createConsumer(session.createQueue(props.getReceiveDestinationNameRoot() + "_" + uniqueId)) : null;
-
-        MessageMonitor messageMonitor = new MessageMonitor();
-
-        if (consumer != null)
-        {
-            consumer.setMessageListener(messageMonitor);
-        }
-
-        ExceptionMonitor exceptionMonitor = new ExceptionMonitor();
-        connection.setExceptionListener(exceptionMonitor);
-
-        if (!props.getPublisherConsumerActive() && (consumer != null))
-        {
-            consumer.close();
-        }
-
-        return new CircuitEndBase(producer, consumer, session, messageMonitor, exceptionMonitor);
-    }
-
-    /**
-     * Builds a circuit end suitable for the receiving side of a test circuit, from standard test parameters.
-     *
-     * @param connection The connection to build the circuit end on.
-     * @param testProps  The test parameters to configure the circuit end construction.
-     * @param uniqueId   A unique number to being numbering destinations from, to make this circuit unique.
-     *
-     * @return A circuit end suitable for the receiving side of a test circuit.
-     *
-     * @throws JMSException Any underlying JMSExceptions are allowed to fall through and fail the creation.
-     */
-    public static CircuitEndBase createReceiverCircuitEnd(Connection connection, ParsedProperties testProps, long uniqueId)
-        throws JMSException
-    {
-        log.debug(
-            "public static CircuitEndBase createReceiverCircuitEnd(Connection connection, ParsedProperties testProps, long uniqueId = "
-            + uniqueId + "): called");
-
-        // Cast the test properties into a typed interface for convenience.
-        MessagingTestConfigProperties props = new MessagingTestConfigProperties(testProps);
-
-        Session session = connection.createSession(props.getTransacted(), props.getAckMode());
-
-        MessageProducer producer =
-            props.getReceiverProducerBind()
-            ? session.createProducer(session.createQueue(props.getReceiveDestinationNameRoot() + "_" + uniqueId)) : null;
-
-        Destination destination =
-            props.getPubsub() ? session.createTopic(props.getSendDestinationNameRoot() + "_" + uniqueId)
-                              : session.createQueue(props.getSendDestinationNameRoot() + "_" + uniqueId);
-
-        MessageConsumer consumer =
-            props.getReceiverConsumerBind()
-            ? ((props.getDurableSubscription() && props.getPubsub())
-                ? session.createDurableSubscriber((Topic) destination, "testsub") : session.createConsumer(destination))
-            : null;
-
-        MessageMonitor messageMonitor = new MessageMonitor();
-
-        if (consumer != null)
-        {
-            consumer.setMessageListener(messageMonitor);
-        }
-
-        if (!props.getReceiverConsumerActive() && (consumer != null))
-        {
-            consumer.close();
-        }
-
-        return new CircuitEndBase(producer, consumer, session, messageMonitor, null);
-    }
-
-    /**
      * Gets the interface on the publishing end of the circuit.
      *
      * @return The publishing end of the circuit.
@@ -342,7 +184,7 @@
         }
         catch (JMSException e)
         {
-            throw new RuntimeException("Got JMSException during close.", e);
+            throw new RuntimeException("Got JMSException during close:" + e.getMessage(), e);
         }
     }
 
@@ -351,16 +193,24 @@
      */
     protected void send()
     {
-        boolean transactional = testProps.getPropertyAsBoolean(MessagingTestConfigProperties.TRANSACTED_PROPNAME);
+        // Cast the test properties into a typed interface for convenience.
+        MessagingTestConfigProperties props = new MessagingTestConfigProperties(testProps);
+
+        boolean transactional = props.getPublisherTransacted();
+        boolean rollback = props.getRollbackPublisher();
 
-        // Send an immediate message through the publisher and ensure that it results in a JMSException.
+        // Send a message through the publisher and log any exceptions raised.
         try
         {
             CircuitEnd end = getLocalPublisherCircuitEnd();
 
             end.send(createTestMessage(end));
 
-            if (transactional)
+            if (rollback)
+            {
+                end.getSession().rollback();
+            }
+            else if (transactional)
             {
                 end.getSession().commit();
             }
@@ -406,12 +256,12 @@
         // Request a status report.
         check();
 
-        // Apply all of the requested assertions, keeping record of any that fail.
-        List<Assertion> failures = applyAssertions(assertions);
-
         // Clean up the publisher/receivers/controlSession/connections.
         close();
 
+        // Apply all of the requested assertions, keeping record of any that fail.
+        List<Assertion> failures = applyAssertions(assertions);
+
         // Return any failed assertions to the caller.
         return failures;
     }
@@ -427,7 +277,10 @@
      */
     private Message createTestMessage(CircuitEnd client) throws JMSException
     {
-        return client.getSession().createTextMessage("Hello");
+        // Cast the test properties into a typed interface for convenience.
+        MessagingTestConfigProperties props = new MessagingTestConfigProperties(testProps);
+
+        return TestUtils.createTestMessageOfSize(client.getSession(), props.getMessageSize());
     }
 
     /**
@@ -450,3 +303,4 @@
         return exceptionMonitor;
     }
 }
+

Modified: incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/localcircuit/LocalPublisherImpl.java
URL: http://svn.apache.org/viewvc/incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/localcircuit/LocalPublisherImpl.java?rev=619823&r1=619822&r2=619823&view=diff
==============================================================================
--- incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/localcircuit/LocalPublisherImpl.java (original)
+++ incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/localcircuit/LocalPublisherImpl.java Fri Feb  8 02:09:37 2008
@@ -20,10 +20,10 @@
  */
 package org.apache.qpid.test.framework.localcircuit;
 
-import org.apache.qpid.client.AMQNoConsumersException;
-import org.apache.qpid.client.AMQNoRouteException;
 import org.apache.qpid.test.framework.*;
 
+import uk.co.thebadgerset.junit.extensions.util.ParsedProperties;
+
 import javax.jms.MessageConsumer;
 import javax.jms.MessageProducer;
 import javax.jms.Session;
@@ -31,7 +31,7 @@
 /**
  * Provides an implementation of the {@link Publisher} interface and wraps a single message producer and consumer on
  * a single controlSession, as a {@link CircuitEnd}. A local publisher also acts as a circuit end, because for a locally
- * located circuit the assertions may be applied directly, there does not need to be any inter process messaging
+ * located circuit the assertions may be applied directly, there does not need to be any inter-process messaging
  * between the publisher and its single circuit end, in order to ascertain its status.
  *
  * <p/><table id="crc"><caption>CRC Card</caption>
@@ -46,14 +46,17 @@
 public class LocalPublisherImpl extends CircuitEndBase implements Publisher
 {
     /** Holds a reference to the containing circuit. */
-    private LocalCircuitImpl circuit;
+    protected LocalCircuitImpl circuit;
 
     /**
-     * Creates a circuit end point on the specified producer, consumer and controlSession.
+     * Creates a circuit end point on the specified producer, consumer and controlSession. Monitors are also configured
+     * for messages and exceptions received by the circuit end.
      *
      * @param producer The message producer for the circuit end point.
      * @param consumer The message consumer for the circuit end point.
      * @param session  The controlSession for the circuit end point.
+     * @param messageMonitor   The monitor to notify of all messages received by the circuit end.
+     * @param exceptionMonitor The monitor to notify of all exceptions received by the circuit end.
      */
     public LocalPublisherImpl(MessageProducer producer, MessageConsumer consumer, Session session,
         MessageMonitor messageMonitor, ExceptionMonitor exceptionMonitor)
@@ -74,9 +77,11 @@
     /**
      * Provides an assertion that the publisher encountered no exceptions.
      *
+     * @param testProps
+     *
      * @return An assertion that the publisher encountered no exceptions.
      */
-    public Assertion noExceptionsAssertion()
+    public Assertion noExceptionsAssertion(ParsedProperties testProps)
     {
         return new AssertionBase()
             {
@@ -109,41 +114,26 @@
     }
 
     /**
-     * Provides an assertion that the publisher got a no consumers exception on every message.
+     * Provides an assertion that the AMQP channel was forcibly closed by an error condition.
+     *
+     * @param testProps The test configuration properties.
      *
-     * @return An assertion that the publisher got a no consumers exception on every message.
+     * @return An assertion that the AMQP channel was forcibly closed by an error condition.
      */
-    public Assertion noConsumersAssertion()
+    public Assertion channelClosedAssertion(ParsedProperties testProps)
     {
-        return new AssertionBase()
-            {
-                public boolean apply()
-                {
-                    boolean passed = true;
-                    ExceptionMonitor connectionExceptionMonitor = circuit.getConnectionExceptionMonitor();
-
-                    if (!connectionExceptionMonitor.assertOneJMSExceptionWithLinkedCause(AMQNoConsumersException.class))
-                    {
-                        passed = false;
-
-                        addError("Was expecting linked exception type " + AMQNoConsumersException.class.getName()
-                            + " on the connection.\n");
-                        addError((connectionExceptionMonitor.size() > 0)
-                            ? ("Actually got the following exceptions on the connection, " + connectionExceptionMonitor)
-                            : "Got no exceptions on the connection.");
-                    }
-
-                    return passed;
-                }
-            };
+        return new NotApplicableAssertion(testProps);
     }
 
     /**
-     * Provides an assertion that the publisher got a no rout exception on every message.
+     * Provides an assertion that the publisher got a given exception during the test.
+     *
+     * @param testProps The test configuration properties.
+     * @param exceptionClass The exception class to check for.
      *
-     * @return An assertion that the publisher got a no rout exception on every message.
+     * @return An assertion that the publisher got a given exception during the test.
      */
-    public Assertion noRouteAssertion()
+    public Assertion exceptionAssertion(ParsedProperties testProps, final Class<? extends Exception> exceptionClass)
     {
         return new AssertionBase()
             {
@@ -152,11 +142,11 @@
                     boolean passed = true;
                     ExceptionMonitor connectionExceptionMonitor = circuit.getConnectionExceptionMonitor();
 
-                    if (!connectionExceptionMonitor.assertOneJMSExceptionWithLinkedCause(AMQNoRouteException.class))
+                    if (!connectionExceptionMonitor.assertExceptionOfType(exceptionClass))
                     {
                         passed = false;
 
-                        addError("Was expecting linked exception type " + AMQNoRouteException.class.getName()
+                        addError("Was expecting linked exception type " + exceptionClass.getName()
                             + " on the connection.\n");
                         addError((connectionExceptionMonitor.size() > 0)
                             ? ("Actually got the following exceptions on the connection, " + connectionExceptionMonitor)
@@ -178,3 +168,4 @@
         this.circuit = circuit;
     }
 }
+

Modified: incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/localcircuit/LocalReceiverImpl.java
URL: http://svn.apache.org/viewvc/incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/localcircuit/LocalReceiverImpl.java?rev=619823&r1=619822&r2=619823&view=diff
==============================================================================
--- incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/localcircuit/LocalReceiverImpl.java (original)
+++ incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/localcircuit/LocalReceiverImpl.java Fri Feb  8 02:09:37 2008
@@ -22,6 +22,8 @@
 
 import org.apache.qpid.test.framework.*;
 
+import uk.co.thebadgerset.junit.extensions.util.ParsedProperties;
+
 import javax.jms.MessageConsumer;
 import javax.jms.MessageProducer;
 import javax.jms.Session;
@@ -46,11 +48,14 @@
     private LocalCircuitImpl circuit;
 
     /**
-     * Creates a circuit end point on the specified producer, consumer and controlSession.
+     * Creates a circuit end point on the specified producer, consumer and controlSession. Monitors are also configured
+     * for messages and exceptions received by the circuit end.
      *
      * @param producer The message producer for the circuit end point.
      * @param consumer The message consumer for the circuit end point.
      * @param session  The controlSession for the circuit end point.
+     * @param messageMonitor   The monitor to notify of all messages received by the circuit end.
+     * @param exceptionMonitor The monitor to notify of all exceptions received by the circuit end.
      */
     public LocalReceiverImpl(MessageProducer producer, MessageConsumer consumer, Session session,
         MessageMonitor messageMonitor, ExceptionMonitor exceptionMonitor)
@@ -71,21 +76,60 @@
     /**
      * Provides an assertion that the receivers encountered no exceptions.
      *
+     * @param testProps The test configuration properties.
+     *
      * @return An assertion that the receivers encountered no exceptions.
      */
-    public Assertion noExceptionsAssertion()
+    public Assertion noExceptionsAssertion(ParsedProperties testProps)
+    {
+        return new NotApplicableAssertion(testProps);
+    }
+
+    /**
+     * Provides an assertion that the AMQP channel was forcibly closed by an error condition.
+     *
+     * @param testProps The test configuration properties.
+     *
+     * @return An assertion that the AMQP channel was forcibly closed by an error condition.
+     */
+    public Assertion channelClosedAssertion(ParsedProperties testProps)
     {
-        return null;
+        return new NotApplicableAssertion(testProps);
     }
 
     /**
      * Provides an assertion that the receivers got all messages that were sent to it.
      *
+     * @param testProps The test configuration properties.
+     *
      * @return An assertion that the receivers got all messages that were sent to it.
      */
-    public Assertion allMessagesAssertion()
+    public Assertion allMessagesReceivedAssertion(ParsedProperties testProps)
+    {
+        return new NotApplicableAssertion(testProps);
+    }
+
+    /**
+     * Provides an assertion that the receivers got none of the messages that were sent to it.
+     *
+     * @param testProps The test configuration properties.
+     *
+     * @return An assertion that the receivers got none of the messages that were sent to it.
+     */
+    public Assertion noMessagesReceivedAssertion(ParsedProperties testProps)
+    {
+        return new NotApplicableAssertion(testProps);
+    }
+
+    /**
+     * Provides an assertion that the receiver got a given exception during the test.
+     *
+     * @param testProps The test configuration properties.
+     * @param exceptionClass The exception class to check for. @return An assertion that the receiver got a given exception during the test.
+     */
+    public Assertion exceptionAssertion(ParsedProperties testProps, Class<? extends Exception> exceptionClass)
     {
-        return null;
+        return new NotApplicableAssertion(testProps);
     }
 
     /**

Modified: incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/qpid/AMQPFeatureDecorator.java
URL: http://svn.apache.org/viewvc/incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/qpid/AMQPFeatureDecorator.java?rev=619823&r1=616809&r2=619823&view=diff
==============================================================================
    (empty)

Modified: incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/qpid/CauseFailureDecorator.java
URL: http://svn.apache.org/viewvc/incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/qpid/CauseFailureDecorator.java?rev=619823&r1=616809&r2=619823&view=diff
==============================================================================
    (empty)

Modified: incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/qpid/CauseFailureInVM.java
URL: http://svn.apache.org/viewvc/incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/qpid/CauseFailureInVM.java?rev=619823&r1=616809&r2=619823&view=diff
==============================================================================
    (empty)

Modified: incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/qpid/InVMBrokerDecorator.java
URL: http://svn.apache.org/viewvc/incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/qpid/InVMBrokerDecorator.java?rev=619823&r1=616809&r2=619823&view=diff
==============================================================================
    (empty)

Modified: incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/sequencers/BaseCircuitFactory.java
URL: http://svn.apache.org/viewvc/incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/sequencers/BaseCircuitFactory.java?rev=619823&r1=619822&r2=619823&view=diff
==============================================================================
--- incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/sequencers/BaseCircuitFactory.java (original)
+++ incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/sequencers/BaseCircuitFactory.java Fri Feb  8 02:09:37 2008
@@ -31,13 +31,20 @@
 import java.util.Properties;
 
 /**
+ * BaseCircuitFactory provides some functionality common to all {@link CircuitFactory}s, such as the details of
+ * all {@link org.apache.qpid.test.framework.distributedtesting.TestClient}s that make up the end-points of
+ * the circuits that the factory creates, and an active {@link ConversationFactory} that can be used to generate
+ * control conversations with those circuit end-points.
+ *
  * <p/><table id="crc"><caption>CRC Card</caption>
  * <tr><th> Responsibilities <th> Collaborations
- * <tr><td>
+ * <tr><td> Hold the details of the sending and receiving end-points to create circuits from.
+ * <tr><td> Provide a conversation factory to create control conversations with the end-points.
  * </table>
  */
 public abstract class BaseCircuitFactory implements CircuitFactory
 {
+
     /** Used for debugging. */
     private final Logger log = Logger.getLogger(BaseCircuitFactory.class);
 
@@ -126,3 +133,4 @@
         return conversationFactory;
     }
 }
+

Modified: incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/sequencers/CircuitFactory.java
URL: http://svn.apache.org/viewvc/incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/sequencers/CircuitFactory.java?rev=619823&r1=619822&r2=619823&view=diff
==============================================================================
--- incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/sequencers/CircuitFactory.java (original)
+++ incubator/qpid/branches/thegreatmerge/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/sequencers/CircuitFactory.java Fri Feb  8 02:09:37 2008
@@ -35,7 +35,7 @@
 import java.util.Properties;
 
 /**
- * A TestCaseSequence is responsibile for creating test circuits appropriate to the context that a test case is
+ * A CircuitFactory is responsibile for creating test circuits appropriate to the context that a test case is
  * running in, and providing an implementation of a standard test procedure over a test circuit.
  *
  * <p/><table id="crc"><caption>CRC Card</caption>
@@ -43,12 +43,6 @@
  * <tr><td> Provide a standard test procedure over a test circuit.
  * <tr><td> Construct test circuits appropriate to a tests context.
  * </table>
- *
- * @todo The sequence test method is deprecated, in favour of using test circuits instead. This interface might be
- *       better renamed to somethign like CircuitFactory, also the split between this interface and
- *       DistributedTestSequencer could be removed and DistributedTestCase functionality merged into FrameworkBaseCase.
- *       This is so that any test case written on top of the framework base case can be distributed, without having
- *       to extend a different base test class.
  */
 public interface CircuitFactory
 {