You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by rg...@apache.org on 2007/05/04 16:27:54 UTC

svn commit: r535254 - in /incubator/qpid/branches/M2/java/integrationtests: ./ src/main/java/org/apache/qpid/interop/coordinator/ src/main/java/org/apache/qpid/interop/coordinator/testcases/ src/main/java/org/apache/qpid/interop/testclient/ src/main/ja...

Author: rgreig
Date: Fri May  4 07:27:53 2007
New Revision: 535254

URL: http://svn.apache.org/viewvc?view=rev&rev=535254
Log:
First two test cases completed. Still to do pub/sub.

Added:
    incubator/qpid/branches/M2/java/integrationtests/jar-with-dependencies.xml
    incubator/qpid/branches/M2/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/testcases/CoordinatingTestCase1DummyRun.java
Modified:
    incubator/qpid/branches/M2/java/integrationtests/pom.xml
    incubator/qpid/branches/M2/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/CoordinatingTestCase.java
    incubator/qpid/branches/M2/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/Coordinator.java
    incubator/qpid/branches/M2/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/InvitingTestDecorator.java
    incubator/qpid/branches/M2/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/OptOutTestCase.java
    incubator/qpid/branches/M2/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/TestClientDetails.java
    incubator/qpid/branches/M2/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/testcases/CoordinatingTestCase2BasicP2P.java
    incubator/qpid/branches/M2/java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/InteropClientTestCase.java
    incubator/qpid/branches/M2/java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/TestClient.java
    incubator/qpid/branches/M2/java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/testcases/TestCase1DummyRun.java
    incubator/qpid/branches/M2/java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/testcases/TestCase2BasicP2P.java
    incubator/qpid/branches/M2/java/integrationtests/src/main/java/org/apache/qpid/util/ConversationFactory.java

Added: incubator/qpid/branches/M2/java/integrationtests/jar-with-dependencies.xml
URL: http://svn.apache.org/viewvc/incubator/qpid/branches/M2/java/integrationtests/jar-with-dependencies.xml?view=auto&rev=535254
==============================================================================
--- incubator/qpid/branches/M2/java/integrationtests/jar-with-dependencies.xml (added)
+++ incubator/qpid/branches/M2/java/integrationtests/jar-with-dependencies.xml Fri May  4 07:27:53 2007
@@ -0,0 +1,29 @@
+<!-- This is an assembly descriptor that produces a jar file that contains all the
+     dependencies, fully expanded into a single jar, required to run the tests of
+     a maven project. 
+ -->
+<assembly>
+  <id>all-test-deps</id>
+  <formats>
+    <format>jar</format>
+  </formats>
+  <includeBaseDirectory>false</includeBaseDirectory>
+  <dependencySets>
+    <dependencySet>
+      <outputDirectory></outputDirectory>
+      <outputFileNameMapping></outputFileNameMapping>
+      <unpack>true</unpack>
+      <scope>test</scope>
+    </dependencySet>
+  </dependencySets>
+  <fileSets>
+    <fileSet>
+      <directory>target/classes</directory>
+      <outputDirectory></outputDirectory>
+    </fileSet>
+    <fileSet>
+      <directory>target/test-classes</directory>
+      <outputDirectory></outputDirectory>
+    </fileSet>
+  </fileSets>
+</assembly>

Modified: incubator/qpid/branches/M2/java/integrationtests/pom.xml
URL: http://svn.apache.org/viewvc/incubator/qpid/branches/M2/java/integrationtests/pom.xml?view=diff&rev=535254&r1=535253&r2=535254
==============================================================================
--- incubator/qpid/branches/M2/java/integrationtests/pom.xml (original)
+++ incubator/qpid/branches/M2/java/integrationtests/pom.xml Fri May  4 07:27:53 2007
@@ -103,6 +103,19 @@
                     </execution>
                 </executions>
             </plugin>
+
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-assembly-plugin</artifactId>
+                <version>2.2-SNAPSHOT</version>
+                <configuration>
+                    <descriptors>
+                        <descriptor>jar-with-dependencies.xml</descriptor>
+                    </descriptors>
+                    <outputDirectory>target</outputDirectory>
+                    <workDirectory>target/assembly/work</workDirectory>
+                </configuration>
+            </plugin>
             
         </plugins>
 

Modified: incubator/qpid/branches/M2/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/CoordinatingTestCase.java
URL: http://svn.apache.org/viewvc/incubator/qpid/branches/M2/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/CoordinatingTestCase.java?view=diff&rev=535254&r1=535253&r2=535254
==============================================================================
--- incubator/qpid/branches/M2/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/CoordinatingTestCase.java (original)
+++ incubator/qpid/branches/M2/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/CoordinatingTestCase.java Fri May  4 07:27:53 2007
@@ -22,6 +22,7 @@
 package org.apache.qpid.interop.coordinator;
 
 import java.util.Collection;
+import java.util.Map;
 import java.util.Properties;
 import java.util.concurrent.LinkedBlockingQueue;
 
@@ -29,6 +30,8 @@
 
 import junit.framework.TestCase;
 
+import org.apache.log4j.Logger;
+
 import org.apache.qpid.util.ConversationFactory;
 
 /**
@@ -67,6 +70,9 @@
  */
 public abstract class CoordinatingTestCase extends TestCase
 {
+    /** Used for debugging. */
+    private static final Logger log = Logger.getLogger(CoordinatingTestCase.class);
+
     /** Holds the contact details for the sending test client. */
     TestClientDetails sender;
 
@@ -93,6 +99,8 @@
      */
     public void setSender(TestClientDetails sender)
     {
+        log.debug("public void setSender(TestClientDetails sender = " + sender + "): called");
+
         this.sender = sender;
     }
 
@@ -103,6 +111,8 @@
      */
     public void setReceiver(TestClientDetails receiver)
     {
+        log.debug("public void setReceiver(TestClientDetails receiver = " + receiver + "): called");
+
         this.receiver = receiver;
     }
 
@@ -127,6 +137,17 @@
     }
 
     /**
+     * Should provide a translation from the junit method name of a test to its test case name as defined in the
+     * interop testing specification. For example the method "testP2P" might map onto the interop test case name
+     * "TC2_BasicP2P".
+     *
+     * @param methodName The name of the JUnit test method.
+     *
+     * @return The name of the corresponding interop test case.
+     */
+    public abstract String getTestCaseNameForTestMethod(String methodName);
+
+    /**
      * Accepts the conversation factory over which to hold the test coordinating conversation.
      *
      * @param conversationFactory The conversation factory to coordinate the test over.
@@ -147,8 +168,10 @@
      *
      * @throws JMSException All underlying JMSExceptions are allowed to fall through.
      */
-    protected Message[] sequenceTest(Properties testProperties) throws JMSException
+    protected Message[] sequenceTest(Map<String, Object> testProperties) throws JMSException
     {
+        log.debug("protected Message[] sequenceTest(Object... testProperties = " + testProperties + "): called");
+
         Session session = conversationFactory.getSession();
         Destination senderControlTopic = session.createTopic(sender.privateControlKey);
         Destination receiverControlTopic = session.createTopic(receiver.privateControlKey);
@@ -158,6 +181,7 @@
 
         // Assign the sender role to the sending test client.
         Message assignSender = conversationFactory.getSession().createMessage();
+        setPropertiesOnMessage(assignSender, testProperties);
         assignSender.setStringProperty("CONTROL_TYPE", "ASSIGN_ROLE");
         assignSender.setStringProperty("ROLE", "SENDER");
 
@@ -165,6 +189,7 @@
 
         // Assign the receiver role the receiving client.
         Message assignReceiver = session.createMessage();
+        setPropertiesOnMessage(assignReceiver, testProperties);
         assignReceiver.setStringProperty("CONTROL_TYPE", "ASSIGN_ROLE");
         assignReceiver.setStringProperty("ROLE", "RECEIVER");
 
@@ -183,6 +208,13 @@
         // Wait for the test sender to return its report.
         Message senderReport = senderConversation.receive();
 
+        try
+        {
+            Thread.sleep(500);
+        }
+        catch (InterruptedException e)
+        { }
+
         // Ask the receiver for its report.
         Message statusRequest = session.createMessage();
         statusRequest.setStringProperty("CONTROL_TYPE", "STATUS_REQUEST");
@@ -193,5 +225,24 @@
         Message receiverReport = receiverConversation.receive();
 
         return new Message[] { senderReport, receiverReport };
+    }
+
+    /**
+     * Sets properties of different types on a JMS Message.
+     *
+     * @param message    The message to set properties on.
+     * @param properties The property name/value pairs to set.
+     *
+     * @throws JMSException All underlying JMSExceptions are allowed to fall through.
+     */
+    public void setPropertiesOnMessage(Message message, Map<String, Object> properties) throws JMSException
+    {
+        for (Map.Entry<String, Object> entry : properties.entrySet())
+        {
+            String name = entry.getKey();
+            Object value = entry.getValue();
+
+            message.setObjectProperty(name, value);
+        }
     }
 }

Modified: incubator/qpid/branches/M2/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/Coordinator.java
URL: http://svn.apache.org/viewvc/incubator/qpid/branches/M2/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/Coordinator.java?view=diff&rev=535254&r1=535253&r2=535254
==============================================================================
--- incubator/qpid/branches/M2/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/Coordinator.java (original)
+++ incubator/qpid/branches/M2/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/Coordinator.java Fri May  4 07:27:53 2007
@@ -31,12 +31,9 @@
 
 import org.apache.log4j.Logger;
 
+import org.apache.qpid.interop.coordinator.testcases.CoordinatingTestCase1DummyRun;
 import org.apache.qpid.interop.coordinator.testcases.CoordinatingTestCase2BasicP2P;
-import org.apache.qpid.interop.testclient.InteropClientTestCase;
 import org.apache.qpid.interop.testclient.TestClient;
-import org.apache.qpid.interop.testclient.testcases.TestCase1DummyRun;
-import org.apache.qpid.interop.testclient.testcases.TestCase2BasicP2P;
-import org.apache.qpid.util.ClasspathScanner;
 import org.apache.qpid.util.CommandLineParser;
 import org.apache.qpid.util.ConversationFactory;
 import org.apache.qpid.util.PrettyPrintingUtils;
@@ -128,7 +125,8 @@
                 new ArrayList<Class<? extends CoordinatingTestCase>>();
             // ClasspathScanner.getMatches(CoordinatingTestCase.class, "^Test.*", true);
             // Hard code the test classes till the classpath scanner is fixed.
-            Collections.addAll(testCaseClasses, new Class[] { CoordinatingTestCase2BasicP2P.class });
+            Collections.addAll(testCaseClasses,
+                new Class[] { CoordinatingTestCase1DummyRun.class, CoordinatingTestCase2BasicP2P.class });
 
             // Check that some test classes were actually found.
             if ((testCaseClasses == null) || testCaseClasses.isEmpty())
@@ -190,6 +188,8 @@
         conversationFactory = new ConversationFactory(connection, responseQueue, LinkedBlockingQueue.class);
         ConversationFactory.Conversation conversation = conversationFactory.startConversation();
 
+        connection.start();
+
         // Broadcast the compulsory invitation to find out what clients are available to test.
         Message invite = session.createMessage();
         invite.setStringProperty("CONTROL_TYPE", "INVITE");
@@ -198,7 +198,7 @@
         conversation.send(controlTopic, invite);
 
         // Wait for a short time, to give test clients an opportunity to reply to the invitation.
-        Collection<Message> enlists = conversation.receiveAll(0, 10000);
+        Collection<Message> enlists = conversation.receiveAll(0, 3000);
 
         enlistedClients = extractEnlists(enlists);
 

Modified: incubator/qpid/branches/M2/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/InvitingTestDecorator.java
URL: http://svn.apache.org/viewvc/incubator/qpid/branches/M2/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/InvitingTestDecorator.java?view=diff&rev=535254&r1=535253&r2=535254
==============================================================================
--- incubator/qpid/branches/M2/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/InvitingTestDecorator.java (original)
+++ incubator/qpid/branches/M2/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/InvitingTestDecorator.java Fri May  4 07:27:53 2007
@@ -115,12 +115,12 @@
                 ConversationFactory.Conversation conversation = conversationFactory.startConversation();
 
                 invite.setStringProperty("CONTROL_TYPE", "INVITE");
-                invite.setStringProperty("TEST_NAME", coordTest.getName());
+                invite.setStringProperty("TEST_NAME", coordTest.getTestCaseNameForTestMethod(coordTest.getName()));
 
                 conversation.send(controlTopic, invite);
 
                 // Wait for a short time, to give test clients an opportunity to reply to the invitation.
-                Collection<Message> replies = conversation.receiveAll(allClients.size(), 10000);
+                Collection<Message> replies = conversation.receiveAll(allClients.size(), 3000);
                 enlists = Coordinator.extractEnlists(replies);
             }
             catch (JMSException e)

Modified: incubator/qpid/branches/M2/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/OptOutTestCase.java
URL: http://svn.apache.org/viewvc/incubator/qpid/branches/M2/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/OptOutTestCase.java?view=diff&rev=535254&r1=535253&r2=535254
==============================================================================
--- incubator/qpid/branches/M2/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/OptOutTestCase.java (original)
+++ incubator/qpid/branches/M2/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/OptOutTestCase.java Fri May  4 07:27:53 2007
@@ -49,4 +49,17 @@
     {
         Assert.fail("One of " + getSender() + " and " + getReceiver() + " opted out of the test.");
     }
+
+    /**
+     * Should provide a translation from the junit method name of a test to its test case name as defined in the
+     * interop testing specification. For example the method "testP2P" might map onto the interop test case name
+     * "TC2_BasicP2P".
+     *
+     * @param methodName The name of the JUnit test method.
+     * @return The name of the corresponding interop test case.
+     */
+    public String getTestCaseNameForTestMethod(String methodName)
+    {
+        return "OptOutTest";
+    }
 }

Modified: incubator/qpid/branches/M2/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/TestClientDetails.java
URL: http://svn.apache.org/viewvc/incubator/qpid/branches/M2/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/TestClientDetails.java?view=diff&rev=535254&r1=535253&r2=535254
==============================================================================
--- incubator/qpid/branches/M2/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/TestClientDetails.java (original)
+++ incubator/qpid/branches/M2/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/TestClientDetails.java Fri May  4 07:27:53 2007
@@ -82,6 +82,6 @@
      */
     public String toString()
     {
-        return "clientName = " + clientName + ", privateControlKey = " + privateControlKey;
+        return "TestClientDetails: [ clientName = " + clientName + ", privateControlKey = " + privateControlKey + " ]";
     }
 }

Added: incubator/qpid/branches/M2/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/testcases/CoordinatingTestCase1DummyRun.java
URL: http://svn.apache.org/viewvc/incubator/qpid/branches/M2/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/testcases/CoordinatingTestCase1DummyRun.java?view=auto&rev=535254
==============================================================================
--- incubator/qpid/branches/M2/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/testcases/CoordinatingTestCase1DummyRun.java (added)
+++ incubator/qpid/branches/M2/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/testcases/CoordinatingTestCase1DummyRun.java Fri May  4 07:27:53 2007
@@ -0,0 +1,66 @@
+package org.apache.qpid.interop.coordinator.testcases;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.jms.Message;
+
+import junit.framework.Assert;
+
+import org.apache.log4j.Logger;
+
+import org.apache.qpid.interop.coordinator.CoordinatingTestCase;
+
+/**
+ * <p><table id="crc"><caption>CRC Card</caption>
+ * <tr><th> Responsibilities <th> Collaborations
+ * <tr><td> Exercises the interop testing framework without actually sending any test messages.
+ *     <td> {@link org.apache.qpid.interop.coordinator.CoordinatingTestCase}
+ * </table>
+ */
+public class CoordinatingTestCase1DummyRun extends CoordinatingTestCase
+{
+    /** Used for debugging. */
+    private static final Logger log = Logger.getLogger(CoordinatingTestCase2BasicP2P.class);
+
+    /**
+     * Creates a new coordinating test case with the specified name.
+     *
+     * @param name The test case name.
+     */
+    public CoordinatingTestCase1DummyRun(String name)
+    {
+        super(name);
+    }
+
+    /**
+     * Performs the basic P2P test case, "Test Case 2" in the specification.
+     */
+    public void testDummyRun() throws Exception
+    {
+        log.debug("public void testDummyRun(): called");
+
+        Map<String, Object> testConfig = new HashMap<String, Object>();
+        testConfig.put("TEST_NAME", "TC1_DummyRun");
+
+        Message[] reports = sequenceTest(testConfig);
+
+        // Compare sender and receiver reports.
+        Assert.assertEquals("Expected to get 2 dummy reports.", 2, reports.length);
+    }
+
+    /**
+     * Should provide a translation from the junit method name of a test to its test case name as defined in the
+     * interop testing specification. For example the method "testP2P" might map onto the interop test case name
+     * "TC2_BasicP2P".
+     *
+     * @param methodName The name of the JUnit test method.
+     * @return The name of the corresponding interop test case.
+     */
+    public String getTestCaseNameForTestMethod(String methodName)
+    {
+        return "TC1_DummyRun";
+    }
+
+}

Modified: incubator/qpid/branches/M2/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/testcases/CoordinatingTestCase2BasicP2P.java
URL: http://svn.apache.org/viewvc/incubator/qpid/branches/M2/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/testcases/CoordinatingTestCase2BasicP2P.java?view=diff&rev=535254&r1=535253&r2=535254
==============================================================================
--- incubator/qpid/branches/M2/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/testcases/CoordinatingTestCase2BasicP2P.java (original)
+++ incubator/qpid/branches/M2/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/testcases/CoordinatingTestCase2BasicP2P.java Fri May  4 07:27:53 2007
@@ -1,11 +1,15 @@
 package org.apache.qpid.interop.coordinator.testcases;
 
+import java.util.HashMap;
+import java.util.Map;
 import java.util.Properties;
 
 import javax.jms.Message;
 
 import junit.framework.Assert;
 
+import org.apache.log4j.Logger;
+
 import org.apache.qpid.interop.coordinator.CoordinatingTestCase;
 
 /**
@@ -16,6 +20,9 @@
  */
 public class CoordinatingTestCase2BasicP2P extends CoordinatingTestCase
 {
+    /** Used for debugging. */
+    private static final Logger log = Logger.getLogger(CoordinatingTestCase2BasicP2P.class);
+
     /**
      * Creates a new coordinating test case with the specified name.
      *
@@ -31,10 +38,12 @@
      */
     public void testBasicP2P() throws Exception
     {
-        Properties testConfig = new Properties();
-        testConfig.setProperty("TEST_CASE", "TC2_BasicP2P");
-        testConfig.setProperty("P2P_QUEUE_AND_KEY_NAME", "tc2queue");
-        testConfig.setProperty("P2P_NUM_MESSAGES", "50");
+        log.debug("public void testBasicP2P(): called");
+
+        Map<String, Object> testConfig = new HashMap<String, Object>();
+        testConfig.put("TEST_NAME", "TC2_BasicP2P");
+        testConfig.put("P2P_QUEUE_AND_KEY_NAME", "tc2queue");
+        testConfig.put("P2P_NUM_MESSAGES", 50);
 
         Message[] reports = sequenceTest(testConfig);
 
@@ -44,5 +53,18 @@
 
         Assert.assertEquals("The requested number of messages were not sent.", 50, messagesSent);
         Assert.assertEquals("Sender and receiver messages sent did not match up.", messagesSent, messagesReceived);
+    }
+
+    /**
+     * Should provide a translation from the junit method name of a test to its test case name as defined in the
+     * interop testing specification. For example the method "testP2P" might map onto the interop test case name
+     * "TC2_BasicP2P".
+     *
+     * @param methodName The name of the JUnit test method.
+     * @return The name of the corresponding interop test case.
+     */
+    public String getTestCaseNameForTestMethod(String methodName)
+    {
+        return "TC2_BasicP2P";
     }
 }

Modified: incubator/qpid/branches/M2/java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/InteropClientTestCase.java
URL: http://svn.apache.org/viewvc/incubator/qpid/branches/M2/java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/InteropClientTestCase.java?view=diff&rev=535254&r1=535253&r2=535254
==============================================================================
--- incubator/qpid/branches/M2/java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/InteropClientTestCase.java (original)
+++ incubator/qpid/branches/M2/java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/InteropClientTestCase.java Fri May  4 07:27:53 2007
@@ -79,8 +79,10 @@
 
     /**
      * Performs the test case actions.
+     *
+     * @throws JMSException Any JMSException resulting from reading the message are allowed to fall through.
      */
-    public void start();
+    public void start() throws JMSException;
 
     /**
      * Gets a report on the actions performed by the test case in its assigned role.

Modified: incubator/qpid/branches/M2/java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/TestClient.java
URL: http://svn.apache.org/viewvc/incubator/qpid/branches/M2/java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/TestClient.java?view=diff&rev=535254&r1=535253&r2=535254
==============================================================================
--- incubator/qpid/branches/M2/java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/TestClient.java (original)
+++ incubator/qpid/branches/M2/java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/TestClient.java Fri May  4 07:27:53 2007
@@ -21,10 +21,7 @@
 package org.apache.qpid.interop.testclient;
 
 import java.io.IOException;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Properties;
+import java.util.*;
 
 import javax.jms.*;
 import javax.naming.Context;
@@ -33,6 +30,8 @@
 
 import org.apache.log4j.Logger;
 
+import org.apache.qpid.interop.testclient.testcases.TestCase1DummyRun;
+import org.apache.qpid.interop.testclient.testcases.TestCase2BasicP2P;
 import org.apache.qpid.util.ClasspathScanner;
 import org.apache.qpid.util.CommandLineParser;
 import org.apache.qpid.util.PropertiesUtils;
@@ -61,41 +60,53 @@
 {
     private static Logger log = Logger.getLogger(TestClient.class);
 
+    public static final String CONNECTION_PROPERTY = "connectionfactory.broker";
+    public static final String CONNECTION_NAME = "broker";
+    public static final String CLIENT_NAME = "java";
+    public static final String DEFAULT_CONNECTION_PROPS_RESOURCE = "org/apache/qpid/interop/connection.properties";
+
     /** Holds the URL of the broker to run the tests on. */
-    String brokerUrl;
+    public static String brokerUrl;
 
     /** Holds the virtual host to run the tests on. If <tt>null</tt>, then the default virtual host is used. */
-    String virtualHost;
+    public static String virtualHost;
 
     /** Holds all the test cases loaded from the classpath. */
     Map<String, InteropClientTestCase> testCases = new HashMap<String, InteropClientTestCase>();
 
     InteropClientTestCase currentTestCase;
 
-    public static final String CONNECTION_PROPERTY = "connectionfactory.broker";
-    public static final String CONNECTION_NAME = "broker";
-    public static final String CLIENT_NAME = "java";
-    public static final String DEFAULT_CONNECTION_PROPS_RESOURCE = "org/apache/qpid/interop/connection.properties";
-
     private MessageProducer producer;
     private Session session;
 
-    public TestClient(String brokerUrl, String virtualHost)
+    private String clientName = CLIENT_NAME;
+
+    /**
+     * Creates a new interop test client, listenting to the specified broker and virtual host, with the specified
+     * client identifying name.
+     *
+     * @param brokerUrl   The url of the broker to connect to.
+     * @param virtualHost The virtual host to conect to.
+     * @param clientName  The client name to use.
+     */
+    public TestClient(String brokerUrl, String virtualHost, String clientName)
     {
         log.debug("public TestClient(String brokerUrl = " + brokerUrl + ", String virtualHost = " + virtualHost
-                  + "): called");
+            + ", String clientName = " + clientName + "): called");
 
         // Retain the connection parameters.
         this.brokerUrl = brokerUrl;
         this.virtualHost = virtualHost;
+        this.clientName = clientName;
     }
 
     /**
      * 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> Mandatory.
-     * <tr><td> -h         <td> The virtual host. <td> Optional.
+     * <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>
      *
@@ -105,11 +116,13 @@
     {
         // Use the command line parser to evaluate the command line.
         CommandLineParser commandLine =
-            new CommandLineParser(new String[][]
-                                  {
-                                      { "b", "The broker URL.", "broker", "false" },
-                                      { "h", "The virtual host to use.", "virtual host", "false" }
-                                  });
+            new CommandLineParser(
+                new String[][]
+                {
+                    { "b", "The broker URL.", "broker", "false" },
+                    { "h", "The virtual host to use.", "virtual host", "false" },
+                    { "n", "The test client name.", "name", "false" }
+                });
 
         // Capture the command line arguments or display errors and correct usage and then exit.
         Properties options = null;
@@ -128,13 +141,14 @@
         // Extract the command line options.
         String brokerUrl = options.getProperty("b");
         String virtualHost = options.getProperty("h");
+        String clientName = options.getProperty("n");
 
         // Add all the trailing command line options (name=value pairs) to system properties. Tests may pick up
         // overridden values from there.
         commandLine.addCommandLineToSysProperties();
 
         // Create a test client and start it running.
-        TestClient client = new TestClient(brokerUrl, virtualHost);
+        TestClient client = new TestClient(brokerUrl, virtualHost, (clientName == null) ? CLIENT_NAME : clientName);
 
         try
         {
@@ -147,13 +161,21 @@
         }
     }
 
+    /**
+     * Starts the interop test client running. This causes it to start listening for incoming test invites.
+     *
+     * @throws JMSException Any underlying JMSExceptions are allowed to fall through.
+     */
     private void start() throws JMSException
     {
         log.debug("private void start(): called");
 
         // Use a class path scanner to find all the interop test case implementations.
         Collection<Class<? extends InteropClientTestCase>> testCaseClasses =
-            ClasspathScanner.getMatches(InteropClientTestCase.class, "^TestCase.*", true);
+            new ArrayList<Class<? extends InteropClientTestCase>>();
+        // ClasspathScanner.getMatches(InteropClientTestCase.class, "^TestCase.*", true);
+        // Hard code the test classes till the classpath scanner is fixed.
+        Collections.addAll(testCaseClasses, new Class[] { TestCase1DummyRun.class, TestCase2BasicP2P.class });
 
         // Create all the test case implementations and index them by the test names.
         for (Class<? extends InteropClientTestCase> nextClass : testCaseClasses)
@@ -181,9 +203,12 @@
         session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
 
         // Set this up to listen for control messages.
-        MessageConsumer consumer = session.createConsumer(session.createTopic("iop.control." + CLIENT_NAME));
+        MessageConsumer consumer = session.createConsumer(session.createTopic("iop.control." + clientName));
         consumer.setMessageListener(this);
 
+        MessageConsumer consumer2 = session.createConsumer(session.createTopic("iop.control"));
+        consumer2.setMessageListener(this);
+
         // Create a producer to send replies with.
         producer = session.createProducer(null);
 
@@ -209,13 +234,13 @@
     public static Connection createConnection(String connectionPropsResource, String brokerUrl, String virtualHost)
     {
         log.debug("public static Connection createConnection(String connectionPropsResource = " + connectionPropsResource
-                  + ", String brokerUrl = " + brokerUrl + ", String virtualHost = " + virtualHost + "): called");
+            + ", String brokerUrl = " + brokerUrl + ", String virtualHost = " + virtualHost + "): called");
 
         try
         {
             Properties connectionProps =
                 PropertiesUtils.getProperties(TestClient.class.getClassLoader().getResourceAsStream(
-                                                  connectionPropsResource));
+                        connectionPropsResource));
 
             if (brokerUrl != null)
             {
@@ -270,6 +295,8 @@
 
                 if (testCaseName != null)
                 {
+                    log.debug("Got an invite to test: " + testCaseName);
+
                     // Check if the requested test case is available.
                     InteropClientTestCase testCase = testCases.get(testCaseName);
 
@@ -282,6 +309,8 @@
                 }
                 else
                 {
+                    log.debug("Got a compulsory invite.");
+
                     enlist = true;
                 }
 
@@ -290,8 +319,8 @@
                     // Reply with the client name in an Enlist message.
                     Message enlistMessage = session.createMessage();
                     enlistMessage.setStringProperty("CONTROL_TYPE", "ENLIST");
-                    enlistMessage.setStringProperty("CLIENT_NAME", CLIENT_NAME);
-                    enlistMessage.setStringProperty("CLIENT_PRIVATE_CONTROL_KEY", "iop.control." + CLIENT_NAME);
+                    enlistMessage.setStringProperty("CLIENT_NAME", clientName);
+                    enlistMessage.setStringProperty("CLIENT_PRIVATE_CONTROL_KEY", "iop.control." + clientName);
                     enlistMessage.setJMSCorrelationID(message.getJMSCorrelationID());
 
                     producer.send(message.getJMSReplyTo(), enlistMessage);
@@ -300,7 +329,10 @@
             else if ("ASSIGN_ROLE".equals(controlType))
             {
                 // Assign the role to the current test case.
-                String roleName = message.getStringProperty("");
+                String roleName = message.getStringProperty("ROLE");
+
+                log.debug("Got a role assignment to role: " + roleName);
+
                 InteropClientTestCase.Roles role = Enum.valueOf(InteropClientTestCase.Roles.class, roleName);
 
                 currentTestCase.assignRole(role, message);
@@ -316,9 +348,15 @@
             {
                 if ("START".equals(controlType))
                 {
+                    log.debug("Got a start notification.");
+
                     // Start the current test case.
                     currentTestCase.start();
                 }
+                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);
@@ -327,10 +365,17 @@
 
                 producer.send(message.getJMSReplyTo(), reportMessage);
             }
+            else if ("TERMINATE".equals(controlType))
+            {
+                System.out.println("Received termination instruction from coordinator.");
+
+                // Is a cleaner shutdown needed?
+                System.exit(0);
+            }
             else
             {
                 // Log a warning about this but otherwise ignore it.
-                log.warn("Got an unknown control message: " + message);
+                log.warn("Got an unknown control message, controlType = " + controlType + ", message = " + message);
             }
         }
         catch (JMSException e)

Modified: incubator/qpid/branches/M2/java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/testcases/TestCase1DummyRun.java
URL: http://svn.apache.org/viewvc/incubator/qpid/branches/M2/java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/testcases/TestCase1DummyRun.java?view=diff&rev=535254&r1=535253&r2=535254
==============================================================================
--- incubator/qpid/branches/M2/java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/testcases/TestCase1DummyRun.java (original)
+++ incubator/qpid/branches/M2/java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/testcases/TestCase1DummyRun.java Fri May  4 07:27:53 2007
@@ -84,6 +84,8 @@
 
     public void onMessage(Message message)
     {
+        log.debug("public void onMessage(Message message = " + message + "): called");
+
         // Ignore any messages.
     }
 }

Modified: incubator/qpid/branches/M2/java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/testcases/TestCase2BasicP2P.java
URL: http://svn.apache.org/viewvc/incubator/qpid/branches/M2/java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/testcases/TestCase2BasicP2P.java?view=diff&rev=535254&r1=535253&r2=535254
==============================================================================
--- incubator/qpid/branches/M2/java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/testcases/TestCase2BasicP2P.java (original)
+++ incubator/qpid/branches/M2/java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/testcases/TestCase2BasicP2P.java Fri May  4 07:27:53 2007
@@ -20,11 +20,12 @@
  */
 package org.apache.qpid.interop.testclient.testcases;
 
-import javax.jms.JMSException;
-import javax.jms.Message;
-import javax.jms.Session;
+import javax.jms.*;
+
+import org.apache.log4j.Logger;
 
 import org.apache.qpid.interop.testclient.InteropClientTestCase;
+import org.apache.qpid.interop.testclient.TestClient;
 
 /**
  * Implements test case 2, basic P2P. Sends/received a specified number of messages to a specified route on the
@@ -41,6 +42,30 @@
  */
 public class TestCase2BasicP2P implements InteropClientTestCase
 {
+    /** Used for debugging. */
+    private static final Logger log = Logger.getLogger(TestCase2BasicP2P.class);
+
+    /** Holds the count of test messages received. */
+    private int messageCount;
+
+    /** The role to be played by the test. */
+    private Roles role;
+
+    /** The number of test messages to send. */
+    private int numMessages;
+
+    /** The routing key to send them to on the default direct exchange. */
+    private Destination sendDestination;
+
+    /** The connection to send the test messages on. */
+    private Connection connection;
+
+    /** The session to send the test messages on. */
+    private Session session;
+
+    /** The producer to send the test messages with. */
+    MessageProducer producer;
+
     /**
      * Should provide the name of the test case that this class implements. The exact names are defined in the
      * interop testing spec.
@@ -49,6 +74,8 @@
      */
     public String getName()
     {
+        log.debug("public String getName(): called");
+
         return "TC2_BasicP2P";
     }
 
@@ -63,6 +90,8 @@
      */
     public boolean acceptInvite(Message inviteMessage) throws JMSException
     {
+        log.debug("public boolean acceptInvite(Message inviteMessage = " + inviteMessage + "): called");
+
         // All invites are acceptable.
         return true;
     }
@@ -79,27 +108,65 @@
      */
     public void assignRole(Roles role, Message assignRoleMessage) throws JMSException
     {
+        log.debug("public void assignRole(Roles role = " + role + ", Message assignRoleMessage = " + assignRoleMessage
+            + "): called");
+
+        // Reset the message count for a new test.
+        messageCount = 0;
+
         // Take note of the role to be played.
+        this.role = role;
+
+        // Create a new connection to pass the test messages on.
+        connection =
+            TestClient.createConnection(TestClient.DEFAULT_CONNECTION_PROPS_RESOURCE, TestClient.brokerUrl,
+                TestClient.virtualHost);
+        session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
 
         // Extract and retain the test parameters.
+        numMessages = assignRoleMessage.getIntProperty("P2P_NUM_MESSAGES");
+        sendDestination = session.createQueue(assignRoleMessage.getStringProperty("P2P_QUEUE_AND_KEY_NAME"));
 
-        // Create a new connection to pass the test messages on.
+        log.debug("numMessages = " + numMessages);
+        log.debug("sendDestination = " + sendDestination);
+        log.debug("role = " + role);
 
-        // Check if the sender role is being assigned, and set up a message producer if so.
+        switch (role)
         {
-        }
+        // Check if the sender role is being assigned, and set up a message producer if so.
+        case SENDER:
+            producer = session.createProducer(sendDestination);
+            break;
+
         // Otherwise the receiver role is being assigned, so set this up to listen for messages.
-        {
+        case RECEIVER:
+            MessageConsumer consumer = session.createConsumer(sendDestination);
+            consumer.setMessageListener(this);
+            break;
         }
+
+        connection.start();
     }
 
     /**
      * Performs the test case actions.
      */
-    public void start()
+    public void start() throws JMSException
     {
+        log.debug("public void start(): called");
+
         // Check that the sender role is being performed.
+        if (role.equals(Roles.SENDER))
         {
+            Message testMessage = session.createTextMessage("test");
+
+            for (int i = 0; i < numMessages; i++)
+            {
+                producer.send(testMessage);
+
+                // Increment the message count.
+                messageCount++;
+            }
         }
     }
 
@@ -114,11 +181,17 @@
      */
     public Message getReport(Session session) throws JMSException
     {
+        log.debug("public Message getReport(Session session): called");
+
         // Close the test connection.
+        connection.close();
 
         // Generate a report message containing the count of the number of messages passed.
+        Message report = session.createMessage();
+        report.setStringProperty("CONTROL_TYPE", "REPORT");
+        report.setIntProperty("MESSAGE_COUNT", messageCount);
 
-        return null;
+        return report;
     }
 
     /**
@@ -128,6 +201,9 @@
      */
     public void onMessage(Message message)
     {
+        log.debug("public void onMessage(Message message = " + message + "): called");
+
         // Increment the message count.
+        messageCount++;
     }
 }

Modified: incubator/qpid/branches/M2/java/integrationtests/src/main/java/org/apache/qpid/util/ConversationFactory.java
URL: http://svn.apache.org/viewvc/incubator/qpid/branches/M2/java/integrationtests/src/main/java/org/apache/qpid/util/ConversationFactory.java?view=diff&rev=535254&r1=535253&r2=535254
==============================================================================
--- incubator/qpid/branches/M2/java/integrationtests/src/main/java/org/apache/qpid/util/ConversationFactory.java (original)
+++ incubator/qpid/branches/M2/java/integrationtests/src/main/java/org/apache/qpid/util/ConversationFactory.java Fri May  4 07:27:53 2007
@@ -23,10 +23,13 @@
 import java.util.*;
 import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicLong;
 
 import javax.jms.*;
 
+import org.apache.log4j.Logger;
+
 /**
  * A conversation helper, uses a message correlation id pattern to match up sent and received messages as a conversation
  * over JMS messaging. Incoming message traffic is divided up by correlation id. Each id has a queue (behaviour dependant
@@ -96,6 +99,9 @@
  */
 public class ConversationFactory
 {
+    /** Used for debugging. */
+    private static final Logger log = Logger.getLogger(ConversationFactory.class);
+
     /** Holds a map from correlation id's to queues. */
     private Map<Long, BlockingQueue<Message>> idsToQueues = new HashMap<Long, BlockingQueue<Message>>();
 
@@ -152,6 +158,9 @@
     public ConversationFactory(Connection connection, Destination receiveDestination,
         Class<? extends BlockingQueue> queueClass) throws JMSException
     {
+        log.debug("public ConversationFactory(Connection connection, Destination receiveDestination = " + receiveDestination
+            + ", Class<? extends BlockingQueue> queueClass = " + queueClass + "): called");
+
         this.connection = connection;
         this.queueClass = queueClass;
 
@@ -173,6 +182,8 @@
      */
     public Conversation startConversation()
     {
+        log.debug("public Conversation startConversation(): called");
+
         Conversation conversation = new Conversation();
         conversation.conversationId = conversationIdGenerator.getAndIncrement();
 
@@ -199,6 +210,8 @@
      */
     public Collection<Message> emptyDeadLetterBox()
     {
+        log.debug("public Collection<Message> emptyDeadLetterBox(): called");
+
         Collection<Message> result = new ArrayList<Message>();
         deadLetterBox.drainTo(result);
 
@@ -246,6 +259,9 @@
          */
         public void send(Destination sendDestination, Message message) throws JMSException
         {
+            log.debug("public void send(Destination sendDestination = " + sendDestination + ", Message message = " + message
+                + "): called");
+
             // Conversation settings = threadLocals.get();
             // long conversationId = conversationId;
             message.setJMSCorrelationID(Long.toString(conversationId));
@@ -287,6 +303,8 @@
          */
         public Message receive() throws JMSException
         {
+            log.debug("public Message receive(): called");
+
             // Conversation settings = threadLocals.get();
             // long conversationId = settings.conversationId;
 
@@ -313,7 +331,8 @@
         /**
          * Gets many messages in an ongoing conversation. If a limit is specified, then once that many messages are
          * received they will be returned. If a timeout is specified, then all messages up to the limit, received within
-         * that timespan will be returned.
+         * that timespan will be returned. At least one of the message count or timeout should be set to a value of
+         * 1 or greater.
          *
          * @param num     The number of messages to receive, or all if this is less than 1.
          * @param timeout The timeout in milliseconds to receive the messages in, or forever if this is less than 1.
@@ -324,12 +343,78 @@
          */
         public Collection<Message> receiveAll(int num, long timeout) throws JMSException
         {
+            log.debug("public Collection<Message> receiveAll(int num = " + num + ", long timeout = " + timeout
+                + "): called");
+
+            // Check that a timeout or message count was set.
+            if ((num < 1) && (timeout < 1))
+            {
+                throw new IllegalArgumentException("At least one of message count (num) or timeout must be set.");
+            }
+
+            // Ensure that the reply queue for this conversation exists.
+            initQueueForId(conversationId);
+            BlockingQueue<Message> queue = idsToQueues.get(conversationId);
+
+            // Used to collect the received messages in.
             Collection<Message> result = new ArrayList<Message>();
 
-            for (int i = 0; i < num; i++)
+            // Used to indicate when the timeout or message count has expired.
+            boolean receiveMore = true;
+
+            int messageCount = 0;
+
+            // Receive messages until the timeout or message count expires.
+            do
             {
-                result.add(receive());
+                try
+                {
+                    Message next = null;
+
+                    // Try to receive the message with a timeout if one has been set.
+                    if (timeout > 0)
+                    {
+                        next = queue.poll(timeout, TimeUnit.MILLISECONDS);
+
+                        // Check if the timeout expired, and stop receiving if so.
+                        if (next == null)
+                        {
+                            receiveMore = false;
+                        }
+                    }
+                    // Receive the message without a timeout.
+                    else
+                    {
+                        next = queue.take();
+                    }
+
+                    // Increment the message count if a message was received.
+                    messageCount += (next != null) ? 1 : 0;
+
+                    // Check if all the requested messages were received, and stop receiving if so.
+                    if ((num > 0) && (messageCount >= num))
+                    {
+                        receiveMore = false;
+                    }
+
+                    // Keep the reply-to destination to send replies to.
+                    sendDestination = (next != null) ? next.getJMSReplyTo() : sendDestination;
+
+                    if (next != null)
+                    {
+                        result.add(next);
+                    }
+                }
+                catch (InterruptedException e)
+                {
+                    // Restore the threads interrupted status.
+                    Thread.currentThread().interrupt();
+
+                    // Stop receiving but return the messages received so far.
+                    receiveMore = false;
+                }
             }
+            while (receiveMore);
 
             return result;
         }
@@ -340,6 +425,8 @@
          */
         public void end()
         {
+            log.debug("public void end(): called");
+
             // Ensure that the thread local for the current thread is cleaned up.
             // Conversation settings = threadLocals.get();
             // long conversationId = settings.conversationId;
@@ -366,6 +453,8 @@
          */
         public void onMessage(Message message)
         {
+            log.debug("public void onMessage(Message message = " + message + "): called");
+
             try
             {
                 Long conversationId = Long.parseLong(message.getJMSCorrelationID());