From b960cd5acbb26aa7b228e234204e4af1092d759a Mon Sep 17 00:00:00 2001 From: Rupert Smith Date: Wed, 25 Jul 2007 13:57:21 +0000 Subject: Refactored packaging of test framework. git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/branches/M2@559458 13f79535-47bb-0310-9956-ffa450edef68 --- .../interop/clienttestcases/TestCase1DummyRun.java | 133 ++++++ .../interop/clienttestcases/TestCase2BasicP2P.java | 207 +++++++++ .../clienttestcases/TestCase3BasicPubSub.java | 237 ++++++++++ .../coordinator/testcases/CircuitTestCase.java | 101 ----- .../testcases/InteropTestCase1DummyRun.java | 84 ---- .../testcases/InteropTestCase2BasicP2P.java | 90 ---- .../testcases/InteropTestCase3BasicPubSub.java | 88 ---- .../qpid/interop/testcases/CircuitTestCase.java | 101 +++++ .../testcases/InteropTestCase1DummyRun.java | 84 ++++ .../testcases/InteropTestCase2BasicP2P.java | 90 ++++ .../testcases/InteropTestCase3BasicPubSub.java | 88 ++++ .../interop/testclient/InteropClientTestCase.java | 101 ----- .../apache/qpid/interop/testclient/TestClient.java | 377 ---------------- .../testclient/testcases/TestCase1DummyRun.java | 133 ------ .../testclient/testcases/TestCase2BasicP2P.java | 207 --------- .../testclient/testcases/TestCase3BasicPubSub.java | 237 ---------- .../qpid/sustained/SustainedClientTestCase.java | 4 +- .../apache/qpid/sustained/SustainedTestCase.java | 7 +- .../distributedtesting/InteropClientTestCase.java | 101 +++++ .../framework/distributedtesting/TestClient.java | 377 ++++++++++++++++ .../org/apache/qpid/util/ClasspathScanner.java | 234 ---------- .../org/apache/qpid/util/ConversationFactory.java | 479 --------------------- 22 files changed, 1423 insertions(+), 2137 deletions(-) create mode 100644 java/integrationtests/src/main/java/org/apache/qpid/interop/clienttestcases/TestCase1DummyRun.java create mode 100644 java/integrationtests/src/main/java/org/apache/qpid/interop/clienttestcases/TestCase2BasicP2P.java create mode 100644 java/integrationtests/src/main/java/org/apache/qpid/interop/clienttestcases/TestCase3BasicPubSub.java delete mode 100644 java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/testcases/CircuitTestCase.java delete mode 100644 java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/testcases/InteropTestCase1DummyRun.java delete mode 100644 java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/testcases/InteropTestCase2BasicP2P.java delete mode 100644 java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/testcases/InteropTestCase3BasicPubSub.java create mode 100644 java/integrationtests/src/main/java/org/apache/qpid/interop/testcases/CircuitTestCase.java create mode 100644 java/integrationtests/src/main/java/org/apache/qpid/interop/testcases/InteropTestCase1DummyRun.java create mode 100644 java/integrationtests/src/main/java/org/apache/qpid/interop/testcases/InteropTestCase2BasicP2P.java create mode 100644 java/integrationtests/src/main/java/org/apache/qpid/interop/testcases/InteropTestCase3BasicPubSub.java delete mode 100644 java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/InteropClientTestCase.java delete mode 100644 java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/TestClient.java delete mode 100644 java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/testcases/TestCase1DummyRun.java delete mode 100644 java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/testcases/TestCase2BasicP2P.java delete mode 100644 java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/testcases/TestCase3BasicPubSub.java create mode 100644 java/integrationtests/src/main/java/org/apache/qpid/test/framework/distributedtesting/InteropClientTestCase.java create mode 100644 java/integrationtests/src/main/java/org/apache/qpid/test/framework/distributedtesting/TestClient.java delete mode 100644 java/integrationtests/src/main/java/org/apache/qpid/util/ClasspathScanner.java delete mode 100644 java/integrationtests/src/main/java/org/apache/qpid/util/ConversationFactory.java (limited to 'java/integrationtests/src') diff --git a/java/integrationtests/src/main/java/org/apache/qpid/interop/clienttestcases/TestCase1DummyRun.java b/java/integrationtests/src/main/java/org/apache/qpid/interop/clienttestcases/TestCase1DummyRun.java new file mode 100644 index 0000000000..b119d13a3d --- /dev/null +++ b/java/integrationtests/src/main/java/org/apache/qpid/interop/clienttestcases/TestCase1DummyRun.java @@ -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.interop.clienttestcases; + +import org.apache.log4j.Logger; + +import org.apache.qpid.test.framework.distributedtesting.InteropClientTestCase; + +import javax.jms.JMSException; +import javax.jms.Message; +import javax.jms.Session; + +/** + * Implements tet case 1, dummy run. This test case sends no test messages, it exists to confirm that the test harness + * is interacting with the coordinator correctly. + * + *

+ *
CRC Card
Responsibilities Collaborations + *
Supply the name of the test case that this implements. + *
Accept/Reject invites based on test parameters. + *
Adapt to assigned roles. + *
Perform test case actions. + *
Generate test reports. + *
+ */ +public class TestCase1DummyRun implements InteropClientTestCase +{ + /** Used for debugging. */ + private static final Logger log = Logger.getLogger(TestCase1DummyRun.class); + + /** + * Should provide the name of the test case that this class implements. The exact names are defined in the + * interop testing spec. + * + * @return The name of the test case that this implements. + */ + public String getName() + { + log.debug("public String getName(): called"); + + return "TC1_DummyRun"; + } + + /** + * Determines whether the test invite that matched this test case is acceptable. + * + * @param inviteMessage The invitation to accept or reject. + * + * @return true to accept the invitation, false to reject it. + * + * @throws JMSException Any JMSException resulting from reading the message are allowed to fall through. + */ + public boolean acceptInvite(Message inviteMessage) throws JMSException + { + log.debug("public boolean acceptInvite(Message inviteMessage): called"); + + // Test parameters don't matter, accept all invites. + return true; + } + + /** + * Assigns the role to be played by this test case. The test parameters are fully specified in the + * assignment message. When this method return the test case will be ready to execute. + * + * @param role The role to be played; sender or receivers. + * @param assignRoleMessage The role assingment message, contains the full test parameters. + * + * @throws JMSException Any JMSException resulting from reading the message are allowed to fall through. + */ + public void assignRole(Roles role, Message assignRoleMessage) throws JMSException + { + log.debug("public void assignRole(Roles role, Message assignRoleMessage): called"); + + // Do nothing, both roles are the same. + } + + /** + * Performs the test case actions. Returning from here, indicates that the sending role has completed its test. + */ + public void start() + { + log.debug("public void start(): called"); + + // Do nothing. + } + + /** + * Gets a report on the actions performed by the test case in its assigned role. + * + * @param session The session to create the report message in. + * + * @return The report message. + * + * @throws JMSException Any JMSExceptions resulting from creating the report are allowed to fall through. + */ + public Message getReport(Session session) throws JMSException + { + log.debug("public Message getReport(Session session): called"); + + // Generate a dummy report, the coordinator expects a report but doesn't care what it is. + return session.createTextMessage("Dummy Run, Ok."); + } + + /** + * Handles incoming test messages. Does nothing. + * + * @param message The incoming test message. + */ + public void onMessage(Message message) + { + log.debug("public void onMessage(Message message = " + message + "): called"); + + // Ignore any messages. + } +} diff --git a/java/integrationtests/src/main/java/org/apache/qpid/interop/clienttestcases/TestCase2BasicP2P.java b/java/integrationtests/src/main/java/org/apache/qpid/interop/clienttestcases/TestCase2BasicP2P.java new file mode 100644 index 0000000000..080bd846ee --- /dev/null +++ b/java/integrationtests/src/main/java/org/apache/qpid/interop/clienttestcases/TestCase2BasicP2P.java @@ -0,0 +1,207 @@ +/* + * + * 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.interop.clienttestcases; + +import org.apache.log4j.Logger; + +import org.apache.qpid.test.framework.distributedtesting.InteropClientTestCase; +import org.apache.qpid.test.framework.distributedtesting.TestClient; +import org.apache.qpid.test.framework.TestUtils; + +import javax.jms.*; + +/** + * Implements test case 2, basic P2P. Sends/received a specified number of messages to a specified route on the + * default direct exchange. Produces reports on the actual number of messages sent/received. + * + *

+ *
CRC Card
Responsibilities Collaborations + *
Supply the name of the test case that this implements. + *
Accept/Reject invites based on test parameters. + *
Adapt to assigned roles. + *
Send required number of test messages. + *
Generate test reports. + *
+ */ +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 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. + * + * @return The name of the test case that this implements. + */ + public String getName() + { + log.debug("public String getName(): called"); + + return "TC2_BasicP2P"; + } + + /** + * Determines whether the test invite that matched this test case is acceptable. + * + * @param inviteMessage The invitation to accept or reject. + * + * @return true to accept the invitation, false to reject it. + * + * @throws JMSException Any JMSException resulting from reading the message are allowed to fall through. + */ + public boolean acceptInvite(Message inviteMessage) throws JMSException + { + log.debug("public boolean acceptInvite(Message inviteMessage = " + inviteMessage + "): called"); + + // All invites are acceptable. + return true; + } + + /** + * Assigns the role to be played by this test case. The test parameters are fully specified in the + * assignment message. When this method return the test case will be ready to execute. + * + * @param role The role to be played; sender or receivers. + * + * @param assignRoleMessage The role assingment message, contains the full test parameters. + * + * @throws JMSException Any JMSException resulting from reading the message are allowed to fall through. + */ + 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 = TestUtils.createConnection(TestClient.testContextProperties); + session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + + // Extract and retain the test parameters. + numMessages = assignRoleMessage.getIntProperty("P2P_NUM_MESSAGES"); + Destination sendDestination = session.createQueue(assignRoleMessage.getStringProperty("P2P_QUEUE_AND_KEY_NAME")); + + log.debug("numMessages = " + numMessages); + log.debug("sendDestination = " + sendDestination); + log.debug("role = " + role); + + 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 receivers 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. Returning from here, indicates that the sending role has completed its test. + * + * @throws JMSException Any JMSException resulting from reading the message are allowed to fall through. + */ + 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++; + } + } + } + + /** + * Gets a report on the actions performed by the test case in its assigned role. + * + * @param session The session to create the report message in. + * + * @return The report message. + * + * @throws JMSException Any JMSExceptions resulting from creating the report are allowed to fall through. + */ + 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 report; + } + + /** + * Counts incoming test messages. + * + * @param message The incoming test message. + */ + public void onMessage(Message message) + { + log.debug("public void onMessage(Message message = " + message + "): called"); + + // Increment the message count. + messageCount++; + } +} diff --git a/java/integrationtests/src/main/java/org/apache/qpid/interop/clienttestcases/TestCase3BasicPubSub.java b/java/integrationtests/src/main/java/org/apache/qpid/interop/clienttestcases/TestCase3BasicPubSub.java new file mode 100644 index 0000000000..a11d045e89 --- /dev/null +++ b/java/integrationtests/src/main/java/org/apache/qpid/interop/clienttestcases/TestCase3BasicPubSub.java @@ -0,0 +1,237 @@ +/* + * + * 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.interop.clienttestcases; + +import org.apache.log4j.Logger; + +import org.apache.qpid.test.framework.distributedtesting.InteropClientTestCase; +import org.apache.qpid.test.framework.distributedtesting.TestClient; +import org.apache.qpid.test.framework.TestUtils; + +import javax.jms.*; + +/** + * Implements test case 3, basic pub/sub. Sends/received a specified number of messages to a specified route on the + * default topic exchange, using the specified number of receivers connections. Produces reports on the actual number of + * messages sent/received. + * + *

+ *
CRC Card
Responsibilities Collaborations + *
Supply the name of the test case that this implements. + *
Accept/Reject invites based on test parameters. + *
Adapt to assigned roles. + *
Send required number of test messages using pub/sub. + *
Generate test reports. + *
+ */ +public class TestCase3BasicPubSub implements InteropClientTestCase +{ + /** Used for debugging. */ + private static final Logger log = Logger.getLogger(TestCase3BasicPubSub.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 connections to send/receive the test messages on. */ + private Connection[] connection; + + /** The sessions to send/receive 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. + * + * @return The name of the test case that this implements. + */ + public String getName() + { + log.debug("public String getName(): called"); + + return "TC3_BasicPubSub"; + } + + /** + * Determines whether the test invite that matched this test case is acceptable. + * + * @param inviteMessage The invitation to accept or reject. + * + * @return true to accept the invitation, false to reject it. + * + * @throws javax.jms.JMSException Any JMSException resulting from reading the message are allowed to fall through. + */ + public boolean acceptInvite(Message inviteMessage) throws JMSException + { + log.debug("public boolean acceptInvite(Message inviteMessage = " + inviteMessage + "): called"); + + // All invites are acceptable. + return true; + } + + /** + * Assigns the role to be played by this test case. The test parameters are fully specified in the + * assignment message. When this method return the test case will be ready to execute. + * + * @param role The role to be played; sender or receivers. + * + * @param assignRoleMessage The role assingment message, contains the full test parameters. + * + * @throws JMSException Any JMSException resulting from reading the message are allowed to fall through. + */ + 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; + + // Extract and retain the test parameters. + numMessages = assignRoleMessage.getIntProperty("PUBSUB_NUM_MESSAGES"); + int numReceivers = assignRoleMessage.getIntProperty("PUBSUB_NUM_RECEIVERS"); + String sendKey = assignRoleMessage.getStringProperty("PUBSUB_KEY"); + + log.debug("numMessages = " + numMessages); + log.debug("numReceivers = " + numReceivers); + log.debug("sendKey = " + sendKey); + log.debug("role = " + role); + + switch (role) + { + // Check if the sender role is being assigned, and set up a single message producer if so. + case SENDER: + // Create a new connection to pass the test messages on. + connection = new Connection[1]; + session = new Session[1]; + + connection[0] = TestUtils.createConnection(TestClient.testContextProperties); + session[0] = connection[0].createSession(false, Session.AUTO_ACKNOWLEDGE); + + // Extract and retain the test parameters. + Destination sendDestination = session[0].createTopic(sendKey); + + producer = session[0].createProducer(sendDestination); + break; + + // Otherwise the receivers role is being assigned, so set this up to listen for messages on the required number + // of receivers connections. + case RECEIVER: + // Create the required number of receivers connections. + connection = new Connection[numReceivers]; + session = new Session[numReceivers]; + + for (int i = 0; i < numReceivers; i++) + { + connection[i] = TestUtils.createConnection(TestClient.testContextProperties); + session[i] = connection[i].createSession(false, Session.AUTO_ACKNOWLEDGE); + + sendDestination = session[i].createTopic(sendKey); + + MessageConsumer consumer = session[i].createConsumer(sendDestination); + consumer.setMessageListener(this); + } + + break; + } + + // Start all the connection dispatcher threads running. + for (Connection conn : connection) + { + conn.start(); + } + } + + /** + * Performs the test case actions. Returning from here, indicates that the sending role has completed its test. + * + * @throws JMSException Any JMSException resulting from reading the message are allowed to fall through. + */ + 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[0].createTextMessage("test"); + + for (int i = 0; i < numMessages; i++) + { + producer.send(testMessage); + + // Increment the message count. + messageCount++; + } + } + } + + /** + * Gets a report on the actions performed by the test case in its assigned role. + * + * @param session The session to create the report message in. + * + * @return The report message. + * + * @throws JMSException Any JMSExceptions resulting from creating the report are allowed to fall through. + */ + public Message getReport(Session session) throws JMSException + { + log.debug("public Message getReport(Session session): called"); + + // Close the test connections. + for (Connection conn : connection) + { + conn.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 report; + } + + /** + * Counts incoming test messages. + * + * @param message The incoming test message. + */ + public void onMessage(Message message) + { + log.debug("public void onMessage(Message message = " + message + "): called"); + + // Increment the message count. + messageCount++; + } +} diff --git a/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/testcases/CircuitTestCase.java b/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/testcases/CircuitTestCase.java deleted file mode 100644 index 81a3e891fd..0000000000 --- a/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/testcases/CircuitTestCase.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * - * 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.interop.coordinator.testcases; - -import org.apache.log4j.Logger; - -import org.apache.qpid.interop.coordinator.sequencers.TestCaseSequencer; -import org.apache.qpid.test.framework.Circuit; -import org.apache.qpid.test.framework.FrameworkBaseCase; -import org.apache.qpid.test.framework.MessagingTestConfigProperties; - -import uk.co.thebadgerset.junit.extensions.util.ParsedProperties; -import uk.co.thebadgerset.junit.extensions.util.TestContextProperties; - -/** - * CircuitTestCase runs a test over a {@link Circuit} controlled by the test parameters. - * - *

- *
CRC Card
Responsibilities Collaborations - *
- *
- * - * @todo When working with test context properties, add overrides to defaults to the singleton instance, but when taking - * a starting point to add specific test case parameters to, take a copy. Use the copy with test case specifics - * to control the test. - */ -public class CircuitTestCase extends FrameworkBaseCase -{ - /** Used for debugging. */ - private static final Logger log = Logger.getLogger(CircuitTestCase.class); - - /** - * Creates a new test case with the specified name. - * - * @param name The test case name. - */ - public CircuitTestCase(String name) - { - super(name); - } - - /** - * Performs the a basic P2P test case. - * - * @throws Exception Any exceptions are allowed to fall through and fail the test. - */ - public void testBasicP2P() throws Exception - { - log.debug("public void testBasicP2P(): called"); - - // Get the test parameters, any overrides on the command line will have been applied. - ParsedProperties testProps = TestContextProperties.getInstance(MessagingTestConfigProperties.defaults); - - // Customize the test parameters. - testProps.setProperty("TEST_NAME", "DEFAULT_CIRCUIT_TEST"); - testProps.setProperty(MessagingTestConfigProperties.SEND_DESTINATION_NAME_ROOT_PROPNAME, "testqueue"); - - // Get the test sequencer to create test circuits and run the standard test procedure through. - TestCaseSequencer sequencer = getTestSequencer(); - - // Send the test messages, and check that there were no errors doing so. - Circuit testCircuit = sequencer.createCircuit(testProps); - sequencer.sequenceTest(testCircuit, assertionList(testCircuit.getPublisher().noExceptionsAssertion()), testProps); - - // Check that all of the message were sent. - // Check that the receiving end got the same number of messages as the publishing end. - } - - /** - * Should provide a translation from the junit method name of a test to its test case name as known to the test - * clients that will run the test. The purpose of this is to convert the JUnit method name into the correct test - * case name to place into the test invite. 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 "DEFAULT_CIRCUIT_TEST"; - } -} diff --git a/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/testcases/InteropTestCase1DummyRun.java b/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/testcases/InteropTestCase1DummyRun.java deleted file mode 100644 index 075d5ecad4..0000000000 --- a/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/testcases/InteropTestCase1DummyRun.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * - * 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.interop.coordinator.testcases; - -import org.apache.log4j.Logger; - -import org.apache.qpid.interop.coordinator.DistributedTestCase; - -import java.util.Properties; - -/** - * Coordinates test case 1, from the interop test specification. This test connects up the sender and receivers roles, - * and gets some dummy test reports from them, in order to check that the test framework itself is operational. - * - *

- *
CRC Card
Responsibilities Collaborations - *
Exercises the interop testing framework without actually sending any test messages. - * {@link org.apache.qpid.interop.coordinator.DistributedTestCase} - *
- */ -public class InteropTestCase1DummyRun extends DistributedTestCase -{ - /** Used for debugging. */ - private static final Logger log = Logger.getLogger(InteropTestCase1DummyRun.class); - - /** - * Creates a new coordinating test case with the specified name. - * - * @param name The test case name. - */ - public InteropTestCase1DummyRun(String name) - { - super(name); - } - - /** - * Performs the basic P2P test case, "Test Case 2" in the specification. - * - * @throws Exception Any exceptions are allowed to fall through and fail the test. - */ - public void testDummyRun() throws Exception - { - log.debug("public void testDummyRun(): called"); - - Properties testConfig = new Properties(); - testConfig.put("TEST_NAME", "TC1_DummyRun"); - - /*Message[] reports =*/ getTestSequencer().sequenceTest(null, null, testConfig); - - // Compare sender and receivers 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"; - } -} diff --git a/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/testcases/InteropTestCase2BasicP2P.java b/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/testcases/InteropTestCase2BasicP2P.java deleted file mode 100644 index 1b75a13712..0000000000 --- a/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/testcases/InteropTestCase2BasicP2P.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * - * 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.interop.coordinator.testcases; - -import org.apache.log4j.Logger; - -import org.apache.qpid.interop.coordinator.DistributedTestCase; - -import java.util.Properties; - -/** - * Implements test case 2, from the interop test specification. This test sets up the TC2_BasicP2P test for 50 - * messages. It checks that the sender and receivers reports both indicate that all the test messages were transmitted - * successfully. - * - *

- *
CRC Card
Responsibilities Collaborations - *
Setup p2p test parameters and compare with test output. {@link DistributedTestCase} - *
- */ -public class InteropTestCase2BasicP2P extends DistributedTestCase -{ - /** Used for debugging. */ - private static final Logger log = Logger.getLogger(InteropTestCase2BasicP2P.class); - - /** - * Creates a new coordinating test case with the specified name. - * - * @param name The test case name. - */ - public InteropTestCase2BasicP2P(String name) - { - super(name); - } - - /** - * Performs the basic P2P test case, "Test Case 2" in the specification. - * - * @throws Exception Any exceptions are allowed to fall through and fail the test. - */ - public void testBasicP2P() throws Exception - { - log.debug("public void testBasicP2P(): called"); - - Properties testConfig = new Properties(); - testConfig.setProperty("TEST_NAME", "TC2_BasicP2P"); - testConfig.setProperty("P2P_QUEUE_AND_KEY_NAME", "tc2queue"); - testConfig.put("P2P_NUM_MESSAGES", 50); - - /*Message[] reports =*/ getTestSequencer().sequenceTest(null, null, testConfig); - - // Compare sender and receivers reports. - /*int messagesSent = reports[0].getIntProperty("MESSAGE_COUNT"); - int messagesReceived = reports[1].getIntProperty("MESSAGE_COUNT"); - - Assert.assertEquals("The requested number of messages were not sent.", 50, messagesSent); - Assert.assertEquals("Sender and receivers 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"; - } -} diff --git a/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/testcases/InteropTestCase3BasicPubSub.java b/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/testcases/InteropTestCase3BasicPubSub.java deleted file mode 100644 index 6d4db4c13c..0000000000 --- a/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/testcases/InteropTestCase3BasicPubSub.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * - * 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.interop.coordinator.testcases; - -import org.apache.log4j.Logger; - -import org.apache.qpid.interop.coordinator.DistributedTestCase; - -import java.util.Properties; - -/** - *

- *
CRC Card
Responsibilities Collaborations - *
Setup pub/sub test parameters and compare with test output. {@link DistributedTestCase} - *
- */ -public class InteropTestCase3BasicPubSub extends DistributedTestCase -{ - /** Used for debugging. */ - private static final Logger log = Logger.getLogger(InteropTestCase3BasicPubSub.class); - - /** - * Creates a new coordinating test case with the specified name. - * - * @param name The test case name. - */ - public InteropTestCase3BasicPubSub(String name) - { - super(name); - } - - /** - * Performs the basic P2P test case, "Test Case 2" in the specification. - * - * @throws Exception Any exceptions are allowed to fall through and fail the test. - */ - public void testBasicPubSub() throws Exception - { - log.debug("public void testBasicPubSub(): called"); - - Properties testConfig = new Properties(); - testConfig.put("TEST_NAME", "TC3_BasicPubSub"); - testConfig.put("PUBSUB_KEY", "tc3route"); - testConfig.put("PUBSUB_NUM_MESSAGES", 10); - testConfig.put("PUBSUB_NUM_RECEIVERS", 5); - - /*Message[] reports =*/ getTestSequencer().sequenceTest(null, null, testConfig); - - // Compare sender and receivers reports. - /*int messagesSent = reports[0].getIntProperty("MESSAGE_COUNT"); - int messagesReceived = reports[1].getIntProperty("MESSAGE_COUNT"); - - Assert.assertEquals("The requested number of messages were not sent.", 10, messagesSent); - Assert.assertEquals("Received messages did not match up to num sent * num receivers.", messagesSent * 5, - 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 "TC3_BasicPubSub"; - } -} diff --git a/java/integrationtests/src/main/java/org/apache/qpid/interop/testcases/CircuitTestCase.java b/java/integrationtests/src/main/java/org/apache/qpid/interop/testcases/CircuitTestCase.java new file mode 100644 index 0000000000..966a545e16 --- /dev/null +++ b/java/integrationtests/src/main/java/org/apache/qpid/interop/testcases/CircuitTestCase.java @@ -0,0 +1,101 @@ +/* + * + * 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.interop.testcases; + +import org.apache.log4j.Logger; + +import org.apache.qpid.test.framework.sequencers.TestCaseSequencer; +import org.apache.qpid.test.framework.Circuit; +import org.apache.qpid.test.framework.FrameworkBaseCase; +import org.apache.qpid.test.framework.MessagingTestConfigProperties; + +import uk.co.thebadgerset.junit.extensions.util.ParsedProperties; +import uk.co.thebadgerset.junit.extensions.util.TestContextProperties; + +/** + * CircuitTestCase runs a test over a {@link Circuit} controlled by the test parameters. + * + *

+ *
CRC Card
Responsibilities Collaborations + *
+ *
+ * + * @todo When working with test context properties, add overrides to defaults to the singleton instance, but when taking + * a starting point to add specific test case parameters to, take a copy. Use the copy with test case specifics + * to control the test. + */ +public class CircuitTestCase extends FrameworkBaseCase +{ + /** Used for debugging. */ + private static final Logger log = Logger.getLogger(CircuitTestCase.class); + + /** + * Creates a new test case with the specified name. + * + * @param name The test case name. + */ + public CircuitTestCase(String name) + { + super(name); + } + + /** + * Performs the a basic P2P test case. + * + * @throws Exception Any exceptions are allowed to fall through and fail the test. + */ + public void testBasicP2P() throws Exception + { + log.debug("public void testBasicP2P(): called"); + + // Get the test parameters, any overrides on the command line will have been applied. + ParsedProperties testProps = TestContextProperties.getInstance(MessagingTestConfigProperties.defaults); + + // Customize the test parameters. + testProps.setProperty("TEST_NAME", "DEFAULT_CIRCUIT_TEST"); + testProps.setProperty(MessagingTestConfigProperties.SEND_DESTINATION_NAME_ROOT_PROPNAME, "testqueue"); + + // Get the test sequencer to create test circuits and run the standard test procedure through. + TestCaseSequencer sequencer = getTestSequencer(); + + // Send the test messages, and check that there were no errors doing so. + Circuit testCircuit = sequencer.createCircuit(testProps); + sequencer.sequenceTest(testCircuit, assertionList(testCircuit.getPublisher().noExceptionsAssertion()), testProps); + + // Check that all of the message were sent. + // Check that the receiving end got the same number of messages as the publishing end. + } + + /** + * Should provide a translation from the junit method name of a test to its test case name as known to the test + * clients that will run the test. The purpose of this is to convert the JUnit method name into the correct test + * case name to place into the test invite. 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 "DEFAULT_CIRCUIT_TEST"; + } +} diff --git a/java/integrationtests/src/main/java/org/apache/qpid/interop/testcases/InteropTestCase1DummyRun.java b/java/integrationtests/src/main/java/org/apache/qpid/interop/testcases/InteropTestCase1DummyRun.java new file mode 100644 index 0000000000..73e08b578e --- /dev/null +++ b/java/integrationtests/src/main/java/org/apache/qpid/interop/testcases/InteropTestCase1DummyRun.java @@ -0,0 +1,84 @@ +/* + * + * 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.interop.testcases; + +import org.apache.log4j.Logger; + +import org.apache.qpid.test.framework.distributedtesting.DistributedTestCase; + +import java.util.Properties; + +/** + * Coordinates test case 1, from the interop test specification. This test connects up the sender and receivers roles, + * and gets some dummy test reports from them, in order to check that the test framework itself is operational. + * + *

+ *
CRC Card
Responsibilities Collaborations + *
Exercises the interop testing framework without actually sending any test messages. + * {@link org.apache.qpid.test.framework.distributedtesting.DistributedTestCase} + *
+ */ +public class InteropTestCase1DummyRun extends DistributedTestCase +{ + /** Used for debugging. */ + private static final Logger log = Logger.getLogger(InteropTestCase1DummyRun.class); + + /** + * Creates a new coordinating test case with the specified name. + * + * @param name The test case name. + */ + public InteropTestCase1DummyRun(String name) + { + super(name); + } + + /** + * Performs the basic P2P test case, "Test Case 2" in the specification. + * + * @throws Exception Any exceptions are allowed to fall through and fail the test. + */ + public void testDummyRun() throws Exception + { + log.debug("public void testDummyRun(): called"); + + Properties testConfig = new Properties(); + testConfig.put("TEST_NAME", "TC1_DummyRun"); + + /*Message[] reports =*/ getTestSequencer().sequenceTest(null, null, testConfig); + + // Compare sender and receivers 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"; + } +} diff --git a/java/integrationtests/src/main/java/org/apache/qpid/interop/testcases/InteropTestCase2BasicP2P.java b/java/integrationtests/src/main/java/org/apache/qpid/interop/testcases/InteropTestCase2BasicP2P.java new file mode 100644 index 0000000000..f77bbf032f --- /dev/null +++ b/java/integrationtests/src/main/java/org/apache/qpid/interop/testcases/InteropTestCase2BasicP2P.java @@ -0,0 +1,90 @@ +/* + * + * 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.interop.testcases; + +import org.apache.log4j.Logger; + +import org.apache.qpid.test.framework.distributedtesting.DistributedTestCase; + +import java.util.Properties; + +/** + * Implements test case 2, from the interop test specification. This test sets up the TC2_BasicP2P test for 50 + * messages. It checks that the sender and receivers reports both indicate that all the test messages were transmitted + * successfully. + * + *

+ *
CRC Card
Responsibilities Collaborations + *
Setup p2p test parameters and compare with test output. {@link DistributedTestCase} + *
+ */ +public class InteropTestCase2BasicP2P extends DistributedTestCase +{ + /** Used for debugging. */ + private static final Logger log = Logger.getLogger(InteropTestCase2BasicP2P.class); + + /** + * Creates a new coordinating test case with the specified name. + * + * @param name The test case name. + */ + public InteropTestCase2BasicP2P(String name) + { + super(name); + } + + /** + * Performs the basic P2P test case, "Test Case 2" in the specification. + * + * @throws Exception Any exceptions are allowed to fall through and fail the test. + */ + public void testBasicP2P() throws Exception + { + log.debug("public void testBasicP2P(): called"); + + Properties testConfig = new Properties(); + testConfig.setProperty("TEST_NAME", "TC2_BasicP2P"); + testConfig.setProperty("P2P_QUEUE_AND_KEY_NAME", "tc2queue"); + testConfig.put("P2P_NUM_MESSAGES", 50); + + /*Message[] reports =*/ getTestSequencer().sequenceTest(null, null, testConfig); + + // Compare sender and receivers reports. + /*int messagesSent = reports[0].getIntProperty("MESSAGE_COUNT"); + int messagesReceived = reports[1].getIntProperty("MESSAGE_COUNT"); + + Assert.assertEquals("The requested number of messages were not sent.", 50, messagesSent); + Assert.assertEquals("Sender and receivers 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"; + } +} diff --git a/java/integrationtests/src/main/java/org/apache/qpid/interop/testcases/InteropTestCase3BasicPubSub.java b/java/integrationtests/src/main/java/org/apache/qpid/interop/testcases/InteropTestCase3BasicPubSub.java new file mode 100644 index 0000000000..ad27ca63bd --- /dev/null +++ b/java/integrationtests/src/main/java/org/apache/qpid/interop/testcases/InteropTestCase3BasicPubSub.java @@ -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.interop.testcases; + +import org.apache.log4j.Logger; + +import org.apache.qpid.test.framework.distributedtesting.DistributedTestCase; + +import java.util.Properties; + +/** + *

+ *
CRC Card
Responsibilities Collaborations + *
Setup pub/sub test parameters and compare with test output. {@link DistributedTestCase} + *
+ */ +public class InteropTestCase3BasicPubSub extends DistributedTestCase +{ + /** Used for debugging. */ + private static final Logger log = Logger.getLogger(InteropTestCase3BasicPubSub.class); + + /** + * Creates a new coordinating test case with the specified name. + * + * @param name The test case name. + */ + public InteropTestCase3BasicPubSub(String name) + { + super(name); + } + + /** + * Performs the basic P2P test case, "Test Case 2" in the specification. + * + * @throws Exception Any exceptions are allowed to fall through and fail the test. + */ + public void testBasicPubSub() throws Exception + { + log.debug("public void testBasicPubSub(): called"); + + Properties testConfig = new Properties(); + testConfig.put("TEST_NAME", "TC3_BasicPubSub"); + testConfig.put("PUBSUB_KEY", "tc3route"); + testConfig.put("PUBSUB_NUM_MESSAGES", 10); + testConfig.put("PUBSUB_NUM_RECEIVERS", 5); + + /*Message[] reports =*/ getTestSequencer().sequenceTest(null, null, testConfig); + + // Compare sender and receivers reports. + /*int messagesSent = reports[0].getIntProperty("MESSAGE_COUNT"); + int messagesReceived = reports[1].getIntProperty("MESSAGE_COUNT"); + + Assert.assertEquals("The requested number of messages were not sent.", 10, messagesSent); + Assert.assertEquals("Received messages did not match up to num sent * num receivers.", messagesSent * 5, + 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 "TC3_BasicPubSub"; + } +} diff --git a/java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/InteropClientTestCase.java b/java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/InteropClientTestCase.java deleted file mode 100644 index 216efd3aff..0000000000 --- a/java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/InteropClientTestCase.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * - * 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.interop.testclient; - -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.MessageListener; -import javax.jms.Session; - -/** - * InteropClientTestCase provides an interface that classes implementing test cases from the interop testing spec - * (http://cwiki.apache.org/confluence/display/qpid/Interop+Testing+Specification) should implement. Implementations - * must be Java beans, that is, to provide a default constructor and to implement the {@link #getName} method. - * - *

- *
CRC Card
Responsibilities - *
Supply the name of the test case that this implements. - *
Accept/Reject invites based on test parameters. - *
Adapt to assigned roles. - *
Perform test case actions. - *
Generate test reports. - *
- */ -public interface InteropClientTestCase extends MessageListener -{ - /** Defines the possible test case roles that an interop test case can take on. */ - public enum Roles - { - /** Specifies the sender role. */ - SENDER, - - /** Specifies the receivers role. */ - RECEIVER - } - - /** - * Should provide the name of the test case that this class implements. The exact names are defined in the - * interop testing spec. - * - * @return The name of the test case that this implements. - */ - public String getName(); - - /** - * Determines whether the test invite that matched this test case is acceptable. - * - * @param inviteMessage The invitation to accept or reject. - * - * @return true to accept the invitation, false to reject it. - * - * @throws JMSException Any JMSException resulting from reading the message are allowed to fall through. - */ - public boolean acceptInvite(Message inviteMessage) throws JMSException; - - /** - * Assigns the role to be played by this test case. The test parameters are fully specified in the - * assignment message. When this method return the test case will be ready to execute. - * - * @param role The role to be played; sender or receivers. - * @param assignRoleMessage The role assingment message, contains the full test parameters. - * - * @throws JMSException Any JMSException resulting from reading the message are allowed to fall through. - */ - public void assignRole(Roles role, Message assignRoleMessage) throws JMSException; - - /** - * Performs the test case actions. Returning from here, indicates that the sending role has completed its test. - * - * @throws JMSException Any JMSException resulting from reading the message are allowed to fall through. - */ - public void start() throws JMSException; - - /** - * Gets a report on the actions performed by the test case in its assigned role. - * - * @param session The session to create the report message in. - * - * @return The report message. - * - * @throws JMSException Any JMSExceptions resulting from creating the report are allowed to fall through. - */ - public Message getReport(Session session) throws JMSException; -} diff --git a/java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/TestClient.java b/java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/TestClient.java deleted file mode 100644 index 26b00aa442..0000000000 --- a/java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/TestClient.java +++ /dev/null @@ -1,377 +0,0 @@ -/* - * - * 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.interop.testclient; - -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.interop.testclient.testcases.TestCase3BasicPubSub; -import org.apache.qpid.sustained.SustainedClientTestCase; -import org.apache.qpid.test.framework.MessagingTestConfigProperties; -import org.apache.qpid.test.framework.TestUtils; - -import uk.co.thebadgerset.junit.extensions.util.ParsedProperties; -import uk.co.thebadgerset.junit.extensions.util.TestContextProperties; - -import javax.jms.*; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -/** - * 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 org.apache.qpid.interop.coordinator.Coordinator}. - * - *

- *
Messages Handled by SustainedTestClient
Message Action - *
Invite(compulsory) Reply with Enlist. - *
Invite(test case) Reply with Enlist if test case available. - *
AssignRole(test case) Reply with Accept Role if matches an enlisted test. Keep test parameters. - *
Start Send test messages defined by test parameters. Send report on messages sent. - *
Status Request Send report on messages received. - *
Terminate Terminate the test client. - *
- * - *

- *
CRC Card
Responsibilities Collaborations - *
Handle all incoming control messages. {@link InteropClientTestCase} - *
Configure and look up test cases by name. {@link InteropClientTestCase} - *
- */ -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 null, 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 testCases = new HashMap(); - - /** Holds the test case currently being run by this client. */ - protected InteropClientTestCase 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 session 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; - - /** - * 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, boolean join) - { - log.debug("public SustainedTestClient(String brokerUrl = " + brokerUrl + ", String virtualHost = " + virtualHost - + ", String clientName = " + clientName + "): called"); - - // Retain the connection parameters. - this.brokerUrl = brokerUrl; - this.virtualHost = virtualHost; - this.clientName = clientName; - this.join = join; - } - - /** - * The entry point for the interop test coordinator. This client accepts the following command line arguments: - * - *

- *
-b The broker URL. Optional. - *
-h The virtual host. Optional. - *
-n The test client name. Optional. - *
name=value Trailing argument define name/value pairs. Added to system properties. Optional. - *
- * - * @param args The command line arguments. - */ - public static void main(String[] args) - { - // 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"); - boolean join = options.getPropertyAsBoolean("j"); - - // Create a test client and start it running. - TestClient client = new TestClient(brokerUrl, virtualHost, (clientName == null) ? CLIENT_NAME : 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> testCaseClasses = - new ArrayList>(); - // ClasspathScanner.getMatches(InteropClientTestCase.class, "^TestCase.*", true); - Collections.addAll(testCaseClasses, TestCase1DummyRun.class, TestCase2BasicP2P.class, TestCase3BasicPubSub.class, - SustainedClientTestCase.class); - - try - { - client.start(testCaseClasses); - } - catch (Exception e) - { - log.error("The test client was unable to start.", e); - System.exit(1); - } - } - - /** - * 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> testCaseClasses) throws JMSException - { - log.debug("private void start(): called"); - - // Create all the test case implementations and index them by the test names. - for (Class nextClass : testCaseClasses) - { - try - { - InteropClientTestCase 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) - { - log.debug("public void onMessage(Message message = " + message + "): called"); - - try - { - String controlType = message.getStringProperty("CONTROL_TYPE"); - String testName = message.getStringProperty("TEST_NAME"); - - log.info("onMessage(Message message = " + message + "): for '" + controlType + "' to '" + 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. - InteropClientTestCase testCase = testCases.get(testName); - - if (testCase != null) - { - // Make the requested test case the current test case. - currentTestCase = testCase; - enlist = true; - } - else - { - log.debug("Received an invite to the test '" + testName + "' but this test is not known."); - } - } - else - { - log.debug("Got a compulsory invite."); - - 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.info("Sending 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); - - InteropClientTestCase.Roles role = Enum.valueOf(InteropClientTestCase.Roles.class, roleName); - - currentTestCase.assignRole(role, message); - - // Reply by accepting the role in an Accept Role message. - Message acceptRoleMessage = session.createMessage(); - acceptRoleMessage.setStringProperty("CONTROL_TYPE", "ACCEPT_ROLE"); - acceptRoleMessage.setJMSCorrelationID(message.getJMSCorrelationID()); - - producer.send(message.getJMSReplyTo(), acceptRoleMessage); - } - else if ("START".equals(controlType) || "STATUS_REQUEST".equals(controlType)) - { - 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); - reportMessage.setStringProperty("CONTROL_TYPE", "REPORT"); - reportMessage.setJMSCorrelationID(message.getJMSCorrelationID()); - - producer.send(message.getJMSReplyTo(), reportMessage); - } - else if ("TERMINATE".equals(controlType)) - { - log.info("Received termination instruction from coordinator."); - - // Is a cleaner shutdown needed? - connection.close(); - System.exit(0); - } - 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("A JMSException occurred whilst handling a message."); - log.debug("Got JMSException whilst handling message: " + message, e); - } - } -} diff --git a/java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/testcases/TestCase1DummyRun.java b/java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/testcases/TestCase1DummyRun.java deleted file mode 100644 index a8edeef80e..0000000000 --- a/java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/testcases/TestCase1DummyRun.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * - * 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.interop.testclient.testcases; - -import org.apache.log4j.Logger; - -import org.apache.qpid.interop.testclient.InteropClientTestCase; - -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.Session; - -/** - * Implements tet case 1, dummy run. This test case sends no test messages, it exists to confirm that the test harness - * is interacting with the coordinator correctly. - * - *

- *
CRC Card
Responsibilities Collaborations - *
Supply the name of the test case that this implements. - *
Accept/Reject invites based on test parameters. - *
Adapt to assigned roles. - *
Perform test case actions. - *
Generate test reports. - *
- */ -public class TestCase1DummyRun implements InteropClientTestCase -{ - /** Used for debugging. */ - private static final Logger log = Logger.getLogger(TestCase1DummyRun.class); - - /** - * Should provide the name of the test case that this class implements. The exact names are defined in the - * interop testing spec. - * - * @return The name of the test case that this implements. - */ - public String getName() - { - log.debug("public String getName(): called"); - - return "TC1_DummyRun"; - } - - /** - * Determines whether the test invite that matched this test case is acceptable. - * - * @param inviteMessage The invitation to accept or reject. - * - * @return true to accept the invitation, false to reject it. - * - * @throws JMSException Any JMSException resulting from reading the message are allowed to fall through. - */ - public boolean acceptInvite(Message inviteMessage) throws JMSException - { - log.debug("public boolean acceptInvite(Message inviteMessage): called"); - - // Test parameters don't matter, accept all invites. - return true; - } - - /** - * Assigns the role to be played by this test case. The test parameters are fully specified in the - * assignment message. When this method return the test case will be ready to execute. - * - * @param role The role to be played; sender or receivers. - * @param assignRoleMessage The role assingment message, contains the full test parameters. - * - * @throws JMSException Any JMSException resulting from reading the message are allowed to fall through. - */ - public void assignRole(Roles role, Message assignRoleMessage) throws JMSException - { - log.debug("public void assignRole(Roles role, Message assignRoleMessage): called"); - - // Do nothing, both roles are the same. - } - - /** - * Performs the test case actions. Returning from here, indicates that the sending role has completed its test. - */ - public void start() - { - log.debug("public void start(): called"); - - // Do nothing. - } - - /** - * Gets a report on the actions performed by the test case in its assigned role. - * - * @param session The session to create the report message in. - * - * @return The report message. - * - * @throws JMSException Any JMSExceptions resulting from creating the report are allowed to fall through. - */ - public Message getReport(Session session) throws JMSException - { - log.debug("public Message getReport(Session session): called"); - - // Generate a dummy report, the coordinator expects a report but doesn't care what it is. - return session.createTextMessage("Dummy Run, Ok."); - } - - /** - * Handles incoming test messages. Does nothing. - * - * @param message The incoming test message. - */ - public void onMessage(Message message) - { - log.debug("public void onMessage(Message message = " + message + "): called"); - - // Ignore any messages. - } -} diff --git a/java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/testcases/TestCase2BasicP2P.java b/java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/testcases/TestCase2BasicP2P.java deleted file mode 100644 index 823ed51596..0000000000 --- a/java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/testcases/TestCase2BasicP2P.java +++ /dev/null @@ -1,207 +0,0 @@ -/* - * - * 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.interop.testclient.testcases; - -import org.apache.log4j.Logger; - -import org.apache.qpid.interop.testclient.InteropClientTestCase; -import org.apache.qpid.interop.testclient.TestClient; -import org.apache.qpid.test.framework.TestUtils; - -import javax.jms.*; - -/** - * Implements test case 2, basic P2P. Sends/received a specified number of messages to a specified route on the - * default direct exchange. Produces reports on the actual number of messages sent/received. - * - *

- *
CRC Card
Responsibilities Collaborations - *
Supply the name of the test case that this implements. - *
Accept/Reject invites based on test parameters. - *
Adapt to assigned roles. - *
Send required number of test messages. - *
Generate test reports. - *
- */ -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 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. - * - * @return The name of the test case that this implements. - */ - public String getName() - { - log.debug("public String getName(): called"); - - return "TC2_BasicP2P"; - } - - /** - * Determines whether the test invite that matched this test case is acceptable. - * - * @param inviteMessage The invitation to accept or reject. - * - * @return true to accept the invitation, false to reject it. - * - * @throws JMSException Any JMSException resulting from reading the message are allowed to fall through. - */ - public boolean acceptInvite(Message inviteMessage) throws JMSException - { - log.debug("public boolean acceptInvite(Message inviteMessage = " + inviteMessage + "): called"); - - // All invites are acceptable. - return true; - } - - /** - * Assigns the role to be played by this test case. The test parameters are fully specified in the - * assignment message. When this method return the test case will be ready to execute. - * - * @param role The role to be played; sender or receivers. - * - * @param assignRoleMessage The role assingment message, contains the full test parameters. - * - * @throws JMSException Any JMSException resulting from reading the message are allowed to fall through. - */ - 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 = TestUtils.createConnection(TestClient.testContextProperties); - session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - - // Extract and retain the test parameters. - numMessages = assignRoleMessage.getIntProperty("P2P_NUM_MESSAGES"); - Destination sendDestination = session.createQueue(assignRoleMessage.getStringProperty("P2P_QUEUE_AND_KEY_NAME")); - - log.debug("numMessages = " + numMessages); - log.debug("sendDestination = " + sendDestination); - log.debug("role = " + role); - - 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 receivers 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. Returning from here, indicates that the sending role has completed its test. - * - * @throws JMSException Any JMSException resulting from reading the message are allowed to fall through. - */ - 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++; - } - } - } - - /** - * Gets a report on the actions performed by the test case in its assigned role. - * - * @param session The session to create the report message in. - * - * @return The report message. - * - * @throws JMSException Any JMSExceptions resulting from creating the report are allowed to fall through. - */ - 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 report; - } - - /** - * Counts incoming test messages. - * - * @param message The incoming test message. - */ - public void onMessage(Message message) - { - log.debug("public void onMessage(Message message = " + message + "): called"); - - // Increment the message count. - messageCount++; - } -} diff --git a/java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/testcases/TestCase3BasicPubSub.java b/java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/testcases/TestCase3BasicPubSub.java deleted file mode 100644 index 4cdb07c546..0000000000 --- a/java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/testcases/TestCase3BasicPubSub.java +++ /dev/null @@ -1,237 +0,0 @@ -/* - * - * 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.interop.testclient.testcases; - -import org.apache.log4j.Logger; - -import org.apache.qpid.interop.testclient.InteropClientTestCase; -import org.apache.qpid.interop.testclient.TestClient; -import org.apache.qpid.test.framework.TestUtils; - -import javax.jms.*; - -/** - * Implements test case 3, basic pub/sub. Sends/received a specified number of messages to a specified route on the - * default topic exchange, using the specified number of receivers connections. Produces reports on the actual number of - * messages sent/received. - * - *

- *
CRC Card
Responsibilities Collaborations - *
Supply the name of the test case that this implements. - *
Accept/Reject invites based on test parameters. - *
Adapt to assigned roles. - *
Send required number of test messages using pub/sub. - *
Generate test reports. - *
- */ -public class TestCase3BasicPubSub implements InteropClientTestCase -{ - /** Used for debugging. */ - private static final Logger log = Logger.getLogger(TestCase3BasicPubSub.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 connections to send/receive the test messages on. */ - private Connection[] connection; - - /** The sessions to send/receive 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. - * - * @return The name of the test case that this implements. - */ - public String getName() - { - log.debug("public String getName(): called"); - - return "TC3_BasicPubSub"; - } - - /** - * Determines whether the test invite that matched this test case is acceptable. - * - * @param inviteMessage The invitation to accept or reject. - * - * @return true to accept the invitation, false to reject it. - * - * @throws javax.jms.JMSException Any JMSException resulting from reading the message are allowed to fall through. - */ - public boolean acceptInvite(Message inviteMessage) throws JMSException - { - log.debug("public boolean acceptInvite(Message inviteMessage = " + inviteMessage + "): called"); - - // All invites are acceptable. - return true; - } - - /** - * Assigns the role to be played by this test case. The test parameters are fully specified in the - * assignment message. When this method return the test case will be ready to execute. - * - * @param role The role to be played; sender or receivers. - * - * @param assignRoleMessage The role assingment message, contains the full test parameters. - * - * @throws JMSException Any JMSException resulting from reading the message are allowed to fall through. - */ - 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; - - // Extract and retain the test parameters. - numMessages = assignRoleMessage.getIntProperty("PUBSUB_NUM_MESSAGES"); - int numReceivers = assignRoleMessage.getIntProperty("PUBSUB_NUM_RECEIVERS"); - String sendKey = assignRoleMessage.getStringProperty("PUBSUB_KEY"); - - log.debug("numMessages = " + numMessages); - log.debug("numReceivers = " + numReceivers); - log.debug("sendKey = " + sendKey); - log.debug("role = " + role); - - switch (role) - { - // Check if the sender role is being assigned, and set up a single message producer if so. - case SENDER: - // Create a new connection to pass the test messages on. - connection = new Connection[1]; - session = new Session[1]; - - connection[0] = TestUtils.createConnection(TestClient.testContextProperties); - session[0] = connection[0].createSession(false, Session.AUTO_ACKNOWLEDGE); - - // Extract and retain the test parameters. - Destination sendDestination = session[0].createTopic(sendKey); - - producer = session[0].createProducer(sendDestination); - break; - - // Otherwise the receivers role is being assigned, so set this up to listen for messages on the required number - // of receivers connections. - case RECEIVER: - // Create the required number of receivers connections. - connection = new Connection[numReceivers]; - session = new Session[numReceivers]; - - for (int i = 0; i < numReceivers; i++) - { - connection[i] = TestUtils.createConnection(TestClient.testContextProperties); - session[i] = connection[i].createSession(false, Session.AUTO_ACKNOWLEDGE); - - sendDestination = session[i].createTopic(sendKey); - - MessageConsumer consumer = session[i].createConsumer(sendDestination); - consumer.setMessageListener(this); - } - - break; - } - - // Start all the connection dispatcher threads running. - for (Connection conn : connection) - { - conn.start(); - } - } - - /** - * Performs the test case actions. Returning from here, indicates that the sending role has completed its test. - * - * @throws JMSException Any JMSException resulting from reading the message are allowed to fall through. - */ - 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[0].createTextMessage("test"); - - for (int i = 0; i < numMessages; i++) - { - producer.send(testMessage); - - // Increment the message count. - messageCount++; - } - } - } - - /** - * Gets a report on the actions performed by the test case in its assigned role. - * - * @param session The session to create the report message in. - * - * @return The report message. - * - * @throws JMSException Any JMSExceptions resulting from creating the report are allowed to fall through. - */ - public Message getReport(Session session) throws JMSException - { - log.debug("public Message getReport(Session session): called"); - - // Close the test connections. - for (Connection conn : connection) - { - conn.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 report; - } - - /** - * Counts incoming test messages. - * - * @param message The incoming test message. - */ - public void onMessage(Message message) - { - log.debug("public void onMessage(Message message = " + message + "): called"); - - // Increment the message count. - messageCount++; - } -} diff --git a/java/integrationtests/src/main/java/org/apache/qpid/sustained/SustainedClientTestCase.java b/java/integrationtests/src/main/java/org/apache/qpid/sustained/SustainedClientTestCase.java index edc6fdba1e..65e05fab4b 100644 --- a/java/integrationtests/src/main/java/org/apache/qpid/sustained/SustainedClientTestCase.java +++ b/java/integrationtests/src/main/java/org/apache/qpid/sustained/SustainedClientTestCase.java @@ -24,8 +24,8 @@ import org.apache.log4j.Logger; import org.apache.qpid.client.AMQNoConsumersException; import org.apache.qpid.client.AMQNoRouteException; -import org.apache.qpid.interop.testclient.TestClient; -import org.apache.qpid.interop.testclient.testcases.TestCase3BasicPubSub; +import org.apache.qpid.test.framework.distributedtesting.TestClient; +import org.apache.qpid.interop.clienttestcases.TestCase3BasicPubSub; import org.apache.qpid.test.framework.TestUtils; import javax.jms.Connection; diff --git a/java/integrationtests/src/main/java/org/apache/qpid/sustained/SustainedTestCase.java b/java/integrationtests/src/main/java/org/apache/qpid/sustained/SustainedTestCase.java index 84852078f0..36f9b4eaf1 100644 --- a/java/integrationtests/src/main/java/org/apache/qpid/sustained/SustainedTestCase.java +++ b/java/integrationtests/src/main/java/org/apache/qpid/sustained/SustainedTestCase.java @@ -23,9 +23,8 @@ package org.apache.qpid.sustained; import org.apache.log4j.Logger; import org.apache.qpid.client.AMQSession; -import org.apache.qpid.interop.coordinator.DistributedTestCase; -import org.apache.qpid.interop.coordinator.DropInTest; -import org.apache.qpid.interop.coordinator.TestClientDetails; +import org.apache.qpid.test.framework.distributedtesting.DistributedTestCase; +import org.apache.qpid.test.framework.DropInTest; import javax.jms.JMSException; import javax.jms.Message; @@ -33,7 +32,7 @@ import javax.jms.Message; import java.util.Properties; /** - * SustainedTestCase is a {@link org.apache.qpid.interop.coordinator.DistributedTestCase} that runs the "Perf_SustainedPubSub" test case. This consists of one + * SustainedTestCase is a {@link org.apache.qpid.test.framework.distributedtesting.DistributedTestCase} that runs the "Perf_SustainedPubSub" test case. This consists of one * test client sending, and several receiving, and attempts to find the highest rate at which messages can be broadcast * to the receivers. It is also a {@link DropInTest} to which more test clients may be added during a test run. * diff --git a/java/integrationtests/src/main/java/org/apache/qpid/test/framework/distributedtesting/InteropClientTestCase.java b/java/integrationtests/src/main/java/org/apache/qpid/test/framework/distributedtesting/InteropClientTestCase.java new file mode 100644 index 0000000000..5e6d61a9e0 --- /dev/null +++ b/java/integrationtests/src/main/java/org/apache/qpid/test/framework/distributedtesting/InteropClientTestCase.java @@ -0,0 +1,101 @@ +/* + * + * 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 javax.jms.JMSException; +import javax.jms.Message; +import javax.jms.MessageListener; +import javax.jms.Session; + +/** + * InteropClientTestCase provides an interface that classes implementing test cases from the interop testing spec + * (http://cwiki.apache.org/confluence/display/qpid/Interop+Testing+Specification) should implement. Implementations + * must be Java beans, that is, to provide a default constructor and to implement the {@link #getName} method. + * + *

+ *
CRC Card
Responsibilities + *
Supply the name of the test case that this implements. + *
Accept/Reject invites based on test parameters. + *
Adapt to assigned roles. + *
Perform test case actions. + *
Generate test reports. + *
+ */ +public interface InteropClientTestCase extends MessageListener +{ + /** Defines the possible test case roles that an interop test case can take on. */ + public enum Roles + { + /** Specifies the sender role. */ + SENDER, + + /** Specifies the receivers role. */ + RECEIVER + } + + /** + * Should provide the name of the test case that this class implements. The exact names are defined in the + * interop testing spec. + * + * @return The name of the test case that this implements. + */ + public String getName(); + + /** + * Determines whether the test invite that matched this test case is acceptable. + * + * @param inviteMessage The invitation to accept or reject. + * + * @return true to accept the invitation, false to reject it. + * + * @throws JMSException Any JMSException resulting from reading the message are allowed to fall through. + */ + public boolean acceptInvite(Message inviteMessage) throws JMSException; + + /** + * Assigns the role to be played by this test case. The test parameters are fully specified in the + * assignment message. When this method return the test case will be ready to execute. + * + * @param role The role to be played; sender or receivers. + * @param assignRoleMessage The role assingment message, contains the full test parameters. + * + * @throws JMSException Any JMSException resulting from reading the message are allowed to fall through. + */ + public void assignRole(Roles role, Message assignRoleMessage) throws JMSException; + + /** + * Performs the test case actions. Returning from here, indicates that the sending role has completed its test. + * + * @throws JMSException Any JMSException resulting from reading the message are allowed to fall through. + */ + public void start() throws JMSException; + + /** + * Gets a report on the actions performed by the test case in its assigned role. + * + * @param session The session to create the report message in. + * + * @return The report message. + * + * @throws JMSException Any JMSExceptions resulting from creating the report are allowed to fall through. + */ + public Message getReport(Session session) throws JMSException; +} diff --git a/java/integrationtests/src/main/java/org/apache/qpid/test/framework/distributedtesting/TestClient.java b/java/integrationtests/src/main/java/org/apache/qpid/test/framework/distributedtesting/TestClient.java new file mode 100644 index 0000000000..12c0d0aa69 --- /dev/null +++ b/java/integrationtests/src/main/java/org/apache/qpid/test/framework/distributedtesting/TestClient.java @@ -0,0 +1,377 @@ +/* + * + * 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.qpid.interop.clienttestcases.TestCase1DummyRun; +import org.apache.qpid.interop.clienttestcases.TestCase2BasicP2P; +import org.apache.qpid.interop.clienttestcases.TestCase3BasicPubSub; +import org.apache.qpid.sustained.SustainedClientTestCase; +import org.apache.qpid.test.framework.MessagingTestConfigProperties; +import org.apache.qpid.test.framework.TestUtils; + +import uk.co.thebadgerset.junit.extensions.util.ParsedProperties; +import uk.co.thebadgerset.junit.extensions.util.TestContextProperties; + +import javax.jms.*; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +/** + * 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 org.apache.qpid.test.framework.distributedtesting.Coordinator}. + * + *

+ *
Messages Handled by SustainedTestClient
Message Action + *
Invite(compulsory) Reply with Enlist. + *
Invite(test case) Reply with Enlist if test case available. + *
AssignRole(test case) Reply with Accept Role if matches an enlisted test. Keep test parameters. + *
Start Send test messages defined by test parameters. Send report on messages sent. + *
Status Request Send report on messages received. + *
Terminate Terminate the test client. + *
+ * + *

+ *
CRC Card
Responsibilities Collaborations + *
Handle all incoming control messages. {@link InteropClientTestCase} + *
Configure and look up test cases by name. {@link InteropClientTestCase} + *
+ */ +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 null, 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 testCases = new HashMap(); + + /** Holds the test case currently being run by this client. */ + protected InteropClientTestCase 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 session 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; + + /** + * 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, boolean join) + { + log.debug("public SustainedTestClient(String brokerUrl = " + brokerUrl + ", String virtualHost = " + virtualHost + + ", String clientName = " + clientName + "): called"); + + // Retain the connection parameters. + this.brokerUrl = brokerUrl; + this.virtualHost = virtualHost; + this.clientName = clientName; + this.join = join; + } + + /** + * The entry point for the interop test coordinator. This client accepts the following command line arguments: + * + *

+ *
-b The broker URL. Optional. + *
-h The virtual host. Optional. + *
-n The test client name. Optional. + *
name=value Trailing argument define name/value pairs. Added to system properties. Optional. + *
+ * + * @param args The command line arguments. + */ + public static void main(String[] args) + { + // 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"); + boolean join = options.getPropertyAsBoolean("j"); + + // Create a test client and start it running. + TestClient client = new TestClient(brokerUrl, virtualHost, (clientName == null) ? CLIENT_NAME : 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> testCaseClasses = + new ArrayList>(); + // ClasspathScanner.getMatches(InteropClientTestCase.class, "^TestCase.*", true); + Collections.addAll(testCaseClasses, TestCase1DummyRun.class, TestCase2BasicP2P.class, TestCase3BasicPubSub.class, + SustainedClientTestCase.class); + + try + { + client.start(testCaseClasses); + } + catch (Exception e) + { + log.error("The test client was unable to start.", e); + System.exit(1); + } + } + + /** + * 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> testCaseClasses) throws JMSException + { + log.debug("private void start(): called"); + + // Create all the test case implementations and index them by the test names. + for (Class nextClass : testCaseClasses) + { + try + { + InteropClientTestCase 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) + { + log.debug("public void onMessage(Message message = " + message + "): called"); + + try + { + String controlType = message.getStringProperty("CONTROL_TYPE"); + String testName = message.getStringProperty("TEST_NAME"); + + log.info("onMessage(Message message = " + message + "): for '" + controlType + "' to '" + 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. + InteropClientTestCase testCase = testCases.get(testName); + + if (testCase != null) + { + // Make the requested test case the current test case. + currentTestCase = testCase; + enlist = true; + } + else + { + log.debug("Received an invite to the test '" + testName + "' but this test is not known."); + } + } + else + { + log.debug("Got a compulsory invite."); + + 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.info("Sending 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); + + InteropClientTestCase.Roles role = Enum.valueOf(InteropClientTestCase.Roles.class, roleName); + + currentTestCase.assignRole(role, message); + + // Reply by accepting the role in an Accept Role message. + Message acceptRoleMessage = session.createMessage(); + acceptRoleMessage.setStringProperty("CONTROL_TYPE", "ACCEPT_ROLE"); + acceptRoleMessage.setJMSCorrelationID(message.getJMSCorrelationID()); + + producer.send(message.getJMSReplyTo(), acceptRoleMessage); + } + else if ("START".equals(controlType) || "STATUS_REQUEST".equals(controlType)) + { + 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); + reportMessage.setStringProperty("CONTROL_TYPE", "REPORT"); + reportMessage.setJMSCorrelationID(message.getJMSCorrelationID()); + + producer.send(message.getJMSReplyTo(), reportMessage); + } + else if ("TERMINATE".equals(controlType)) + { + log.info("Received termination instruction from coordinator."); + + // Is a cleaner shutdown needed? + connection.close(); + System.exit(0); + } + 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("A JMSException occurred whilst handling a message."); + log.debug("Got JMSException whilst handling message: " + message, e); + } + } +} diff --git a/java/integrationtests/src/main/java/org/apache/qpid/util/ClasspathScanner.java b/java/integrationtests/src/main/java/org/apache/qpid/util/ClasspathScanner.java deleted file mode 100644 index bad49060ca..0000000000 --- a/java/integrationtests/src/main/java/org/apache/qpid/util/ClasspathScanner.java +++ /dev/null @@ -1,234 +0,0 @@ -/* - * - * 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.util; - -import java.io.File; -import java.util.*; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.apache.log4j.Logger; - -/** - * An ClasspathScanner scans the classpath for classes that implement an interface or extend a base class and have names - * that match a regular expression. - * - *

In order to test whether a class implements an interface or extends a class, the class must be loaded (unless - * the class files were to be scanned directly). Using this collector can cause problems when it scans the classpath, - * because loading classes will initialize their statics, which in turn may cause undesired side effects. For this - * reason, the collector should always be used with a regular expression, through which the class file names are - * filtered, and only those that pass this filter will be tested. For example, if you define tests in classes that - * end with the keyword "Test" then use the regular expression "Test$" to match this. - * - *

- *
CRC Card
Responsibilities Collaborations - *
Find all classes matching type and name pattern on the classpath. - *
- * - * @todo Add logic to scan jars as well as directories. - */ -public class ClasspathScanner -{ - private static final Logger log = Logger.getLogger(ClasspathScanner.class); - - /** - * Scans the classpath and returns all classes that extend a specified class and match a specified name. - * There is an flag that can be used to indicate that only Java Beans will be matched (that is, only those classes - * that have a default constructor). - * - * @param matchingClass The class or interface to match. - * @param matchingRegexp The regular expression to match against the class name. - * @param beanOnly Flag to indicate that onyl classes with default constructors should be matched. - * - * @return All the classes that match this collector. - */ - public static Collection> getMatches(Class matchingClass, String matchingRegexp, - boolean beanOnly) - { - log.debug("public static Collection> getMatches(Class matchingClass = " + matchingClass - + ", String matchingRegexp = " + matchingRegexp + ", boolean beanOnly = " + beanOnly + "): called"); - - // Build a compiled regular expression from the pattern to match. - Pattern matchPattern = Pattern.compile(matchingRegexp); - - String classPath = System.getProperty("java.class.path"); - Map> result = new HashMap>(); - - log.debug("classPath = " + classPath); - - // Find matching classes starting from all roots in the classpath. - for (String path : splitClassPath(classPath)) - { - gatherFiles(new File(path), "", result, matchPattern, matchingClass); - } - - return result.values(); - } - - /** - * Finds all matching classes rooted at a given location in the file system. If location is a directory it - * is recursively examined. - * - * @param classRoot The root of the current point in the file system being examined. - * @param classFileName The name of the current file or directory to examine. - * @param result The accumulated mapping from class names to classes that match the scan. - * - * @todo Recursion ok as file system depth is not likely to exhaust the stack. Might be better to replace with - * iteration. - */ - private static void gatherFiles(File classRoot, String classFileName, Map> result, - Pattern matchPattern, Class matchClass) - { - log.debug("private static void gatherFiles(File classRoot = " + classRoot + ", String classFileName = " - + classFileName + ", Map> result, Pattern matchPattern = " + matchPattern - + ", Class matchClass = " + matchClass + "): called"); - - File thisRoot = new File(classRoot, classFileName); - - // If the current location is a file, check if it is a matching class. - if (thisRoot.isFile()) - { - // Check that the file has a matching name. - if (matchesName(thisRoot.getName(), matchPattern)) - { - String className = classNameFromFile(thisRoot.getName()); - - // Check that the class has matching type. - try - { - Class candidateClass = Class.forName(className); - - Class matchedClass = matchesClass(candidateClass, matchClass); - - if (matchedClass != null) - { - result.put(className, matchedClass); - } - } - catch (ClassNotFoundException e) - { - // Ignore this. The matching class could not be loaded. - log.debug("Got ClassNotFoundException, ignoring.", e); - } - } - - return; - } - // Otherwise the current location is a directory, so examine all of its contents. - else - { - String[] contents = thisRoot.list(); - - if (contents != null) - { - for (String content : contents) - { - gatherFiles(classRoot, classFileName + File.separatorChar + content, result, matchPattern, matchClass); - } - } - } - } - - /** - * Checks if the specified class file name corresponds to a class with name matching the specified regular expression. - * - * @param classFileName The class file name. - * @param matchPattern The regular expression pattern to match. - * - * @return true if the class name matches, false otherwise. - */ - private static boolean matchesName(String classFileName, Pattern matchPattern) - { - String className = classNameFromFile(classFileName); - Matcher matcher = matchPattern.matcher(className); - - return matcher.matches(); - } - - /** - * Checks if the specified class to compare extends the base class being scanned for. - * - * @param matchingClass The base class to match against. - * @param toMatch The class to match against the base class. - * - * @return The class to check, cast as an instance of the class to match if the class extends the base class, or - * null otherwise. - */ - private static Class matchesClass(Class matchingClass, Class toMatch) - { - try - { - return matchingClass.asSubclass(toMatch); - } - catch (ClassCastException e) - { - return null; - } - } - - /** - * Takes a classpath (which is a series of paths) and splits it into its component paths. - * - * @param classPath The classpath to split. - * - * @return A list of the component paths that make up the class path. - */ - private static List splitClassPath(String classPath) - { - List result = new LinkedList(); - String separator = System.getProperty("path.separator"); - StringTokenizer tokenizer = new StringTokenizer(classPath, separator); - - while (tokenizer.hasMoreTokens()) - { - result.add(tokenizer.nextToken()); - } - - return result; - } - - /** - * Translates from the filename of a class to its fully qualified classname. Files are named using forward slash - * seperators and end in ".class", whereas fully qualified class names use "." sperators and no ".class" ending. - * - * @param classFileName The filename of the class to translate to a class name. - * - * @return The fully qualified class name. - */ - private static String classNameFromFile(String classFileName) - { - log.debug("private static String classNameFromFile(String classFileName = " + classFileName + "): called"); - - // Remove the .class ending. - String s = classFileName.substring(0, classFileName.length() - ".class".length()); - - // Turn / seperators in . seperators. - String s2 = s.replace(File.separatorChar, '.'); - - // Knock off any leading . caused by a leading /. - if (s2.startsWith(".")) - { - return s2.substring(1); - } - - return s2; - } -} diff --git a/java/integrationtests/src/main/java/org/apache/qpid/util/ConversationFactory.java b/java/integrationtests/src/main/java/org/apache/qpid/util/ConversationFactory.java deleted file mode 100644 index 0090bec3d0..0000000000 --- a/java/integrationtests/src/main/java/org/apache/qpid/util/ConversationFactory.java +++ /dev/null @@ -1,479 +0,0 @@ -/* - * - * 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.util; - -import org.apache.log4j.Logger; - -import javax.jms.*; - -import java.util.*; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicLong; - -/** - * 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 - * on the queue implementation). Clients of this de-multiplexer can wait on messages, defined by message correlation ids. - * - *

One use of this is as a conversation synchronizer where multiple threads are carrying out conversations over a - * multiplexed messaging route. This can be usefull, as JMS sessions are not multi-threaded. Setting up the conversation - * with synchronous queues will allow these threads to be written in a synchronous style, but with their execution order - * governed by the asynchronous message flow. For example, something like the following code could run a multi-threaded - * conversation (the conversation methods can be called many times in parallel): - * - *

- * class Initiator
- * {
- * ConversationHelper conversation = new ConversationHelper(connection, null,
- *                                                          java.util.concurrent.LinkedBlockingQueue.class);
- *
- * initiateConversation()
- * {
- *  try {
- *   // Exchange greetings.
- *   conversation.send(sendDestination, conversation.getSession().createTextMessage("Hello."));
- *   Message greeting = conversation.receive();
- *
- *   // Exchange goodbyes.
- *   conversation.send(conversation.getSession().createTextMessage("Goodbye."));
- *   Message goodbye = conversation.receive();
- *  } finally {
- *   conversation.end();
- *  }
- * }
- * }
- *
- * class Responder
- * {
- * ConversationHelper conversation = new ConversationHelper(connection, receiveDestination,
- *                                                          java.util.concurrent.LinkedBlockingQueue.class);
- *
- * respondToConversation()
- * {
- *   try {
- *   // Exchange greetings.
- *   Message greeting = conversation.receive();
- *   conversation.send(conversation.getSession().createTextMessage("Hello."));
- *
- *   // Exchange goodbyes.
- *   Message goodbye = conversation.receive();
- *   conversation.send(conversation.getSession().createTextMessage("Goodbye."));
- *  } finally {
- *   conversation.end();
- *  }
- * }
- * }
- * 
- * - *

Conversation correlation id's are generated on a per thread basis. - * - *

The same session is shared amongst all conversations. Calls to send are therefore synchronized because JMS - * sessions are not multi-threaded. - * - *

- *
CRC Card
Responsibilities Collaborations - *
Associate messages to an ongoing conversation using correlation ids. - *
Auto manage sessions for conversations. - *
Store messages not in a conversation in dead letter box. - *
- */ -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> idsToQueues = new HashMap>(); - - /** Holds the connection over which the conversation is conducted. */ - private Connection connection; - - /** Holds the session over which the conversation is conduxted. */ - private Session session; - - /** The message consumer for incoming messages. */ - MessageConsumer consumer; - - /** The message producer for outgoing messages. */ - MessageProducer producer; - - /** The well-known or temporary destination to receive replies on. */ - Destination receiveDestination; - - /** Holds the queue implementation class for the reply queue. */ - Class queueClass; - - /** Used to hold any replies that are received outside of the context of a conversation. */ - BlockingQueue deadLetterBox = new LinkedBlockingQueue(); - - /* Used to hold conversation state on a per thread basis. */ - /* - ThreadLocal threadLocals = - new ThreadLocal() - { - protected Conversation initialValue() - { - Conversation settings = new Conversation(); - settings.conversationId = conversationIdGenerator.getAndIncrement(); - - return settings; - } - }; - */ - - /** Generates new coversation id's as needed. */ - AtomicLong conversationIdGenerator = new AtomicLong(); - - /** - * Creates a conversation helper on the specified connection with the default sending destination, and listening - * to the specified receiving destination. - * - * @param connection The connection to build the conversation helper on. - * @param receiveDestination The destination to listen to for incoming messages. This may be null to use a temporary - * queue. - * @param queueClass The queue implementation class. - * - * @throws JMSException All underlying JMSExceptions are allowed to fall through. - */ - public ConversationFactory(Connection connection, Destination receiveDestination, - Class queueClass) throws JMSException - { - log.debug("public ConversationFactory(Connection connection, Destination receiveDestination = " + receiveDestination - + ", Class queueClass = " + queueClass + "): called"); - - this.connection = connection; - this.queueClass = queueClass; - - session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - - // Check if a well-known receive destination has been provided, or use a temporary queue if not. - this.receiveDestination = (receiveDestination != null) ? receiveDestination : session.createTemporaryQueue(); - - consumer = session.createConsumer(receiveDestination); - producer = session.createProducer(null); - - consumer.setMessageListener(new Receiver()); - } - - /** - * Creates a new conversation context. - * - * @return A new conversation context. - */ - public Conversation startConversation() - { - log.debug("public Conversation startConversation(): called"); - - Conversation conversation = new Conversation(); - conversation.conversationId = conversationIdGenerator.getAndIncrement(); - - return conversation; - } - - /** - * Ensures that the reply queue for a conversation exists. - * - * @param conversationId The conversation correlation id. - */ - private void initQueueForId(long conversationId) - { - if (!idsToQueues.containsKey(conversationId)) - { - idsToQueues.put(conversationId, ReflectionUtils.newInstance(queueClass)); - } - } - - /** - * Clears the dead letter box, returning all messages that were in it. - * - * @return All messages in the dead letter box. - */ - public Collection emptyDeadLetterBox() - { - log.debug("public Collection emptyDeadLetterBox(): called"); - - Collection result = new ArrayList(); - deadLetterBox.drainTo(result); - - return result; - } - - /** - * Gets the session over which the conversation is conducted. - * - * @return The session over which the conversation is conducted. - */ - public Session getSession() - { - // Conversation settings = threadLocals.get(); - - return session; - } - - /** - * Used to hold a conversation context. This consists of a correlating id for the conversation, and a reply - * destination automatically updated to the last received reply-to destination. - */ - public class Conversation - { - /** Holds the correlation id for the context. */ - long conversationId; - - /** - * Holds the send destination for the context. This will automatically be updated to the most recently received - * reply-to destination. - */ - Destination sendDestination; - - /** - * Sends a message to the default sending location. The correlation id of the message will be assigned by this - * method, overriding any previously set value. - * - * @param sendDestination The destination to send to. This may be null to use the last received reply-to - * destination. - * @param message The message to send. - * - * @throws JMSException All undelying JMSExceptions are allowed to fall through. This will also be thrown if no - * send destination is specified and there is no most recent reply-to destination available - * to use. - */ - 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)); - message.setJMSReplyTo(receiveDestination); - - // Ensure that the reply queue for this conversation exists. - initQueueForId(conversationId); - - // Check if an overriding send to destination has been set or use the last reply-to if not. - Destination sendTo = null; - - if (sendDestination != null) - { - sendTo = sendDestination; - } - else if (sendDestination != null) - { - sendTo = sendDestination; - } - else - { - throw new JMSException("The send destination was specified, and no most recent reply-to available to use."); - } - - // Send the message. - synchronized (this) - { - producer.send(sendTo, message); - } - } - - /** - * Gets the next message in an ongoing conversation. This method may block until such a message is received. - * - * @return The next incoming message in the conversation. - * - * @throws JMSException All undelying JMSExceptions are allowed to fall through. Thrown if the received message - * did not have its reply-to destination set up. - */ - public Message receive() throws JMSException - { - log.debug("public Message receive(): called"); - - // Conversation settings = threadLocals.get(); - // long conversationId = settings.conversationId; - - // Ensure that the reply queue for this conversation exists. - initQueueForId(conversationId); - - BlockingQueue queue = idsToQueues.get(conversationId); - - try - { - Message result = queue.take(); - - // Keep the reply-to destination to send replies to. - sendDestination = result.getJMSReplyTo(); - - return result; - } - catch (InterruptedException e) - { - return null; - } - } - - /** - * 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. 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. - * - * @return All messages received within the count limit and the timeout. - * - * @throws JMSException All undelying JMSExceptions are allowed to fall through. - */ - public Collection receiveAll(int num, long timeout) throws JMSException - { - log.debug("public Collection 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 queue = idsToQueues.get(conversationId); - - // Used to collect the received messages in. - Collection result = new ArrayList(); - - // 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 - { - 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; - } - - /** - * Completes the conversation. Any correlation id's pertaining to the conversation are no longer valid, and any - * incoming messages using them will go to the dead letter box. - */ - 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; - // threadLocals.remove(); - - // Ensure that its queue is removed from the queue map. - BlockingQueue queue = idsToQueues.remove(conversationId); - - // Move any outstanding messages on the threads conversation id into the dead letter box. - queue.drainTo(deadLetterBox); - } - } - - /** - * Implements the message listener for this conversation handler. - */ - protected class Receiver implements MessageListener - { - /** - * Handles all incoming messages in the ongoing conversations. These messages are split up by correaltion id - * and placed into queues. - * - * @param message The incoming message. - */ - public void onMessage(Message message) - { - log.debug("public void onMessage(Message message = " + message + "): called"); - - try - { - Long conversationId = Long.parseLong(message.getJMSCorrelationID()); - - // Find the converstaion queue to place the message on. If there is no conversation for the message id, - // the the dead letter box queue is used. - BlockingQueue queue = idsToQueues.get(conversationId); - queue = (queue == null) ? deadLetterBox : queue; - - queue.put(message); - } - catch (JMSException e) - { - throw new RuntimeException(e); - } - catch (InterruptedException e) - { - throw new RuntimeException(e); - } - } - } -} -- cgit v1.2.1