diff options
Diffstat (limited to 'qpid/java/systests/src/main/java/org/apache/qpid/test/framework/distributedtesting/DistributedTestDecorator.java')
-rw-r--r-- | qpid/java/systests/src/main/java/org/apache/qpid/test/framework/distributedtesting/DistributedTestDecorator.java | 166 |
1 files changed, 166 insertions, 0 deletions
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/distributedtesting/DistributedTestDecorator.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/distributedtesting/DistributedTestDecorator.java new file mode 100644 index 0000000000..bdcfc996d6 --- /dev/null +++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/distributedtesting/DistributedTestDecorator.java @@ -0,0 +1,166 @@ +/* + * + * 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 junit.framework.TestResult; + +import org.apache.log4j.Logger; + +import org.apache.qpid.test.framework.FrameworkBaseCase; +import org.apache.qpid.test.framework.TestClientDetails; +import org.apache.qpid.test.framework.sequencers.CircuitFactory; +import org.apache.qpid.test.utils.ConversationFactory; + +import org.apache.qpid.junit.extensions.WrappedSuiteTestDecorator; + +import javax.jms.Connection; +import javax.jms.Destination; +import javax.jms.JMSException; +import javax.jms.Message; + +import java.util.*; + +/** + * DistributedTestDecorator is a base class for writing test decorators that invite test clients to participate in + * distributed test cases. It provides a helper method, {@link #signupClients}, that broadcasts an invitation and + * returns the set of test clients that are available to particiapte in the test. + * + * <p/>When used to wrap a {@link FrameworkBaseCase} test, it replaces the default {@link CircuitFactory} implementations + * with a suitable circuit factory for distributed tests. Concrete implementations can use this to configure the sending + * and receiving roles on the test. + * + * <p><table id="crc"><caption>CRC Card</caption> + * <tr><th> Responsibilities <th> Collaborations + * <tr><td> Broadcast test invitations and collect enlists. <td> {@link ConversationFactory}. + * </table> + */ +public abstract class DistributedTestDecorator extends WrappedSuiteTestDecorator +{ + /** Used for debugging. */ + private static final Logger log = Logger.getLogger(DistributedTestDecorator.class); + + /** Holds the contact information for all test clients that are available and that may take part in the test. */ + Set<TestClientDetails> allClients; + + /** Holds the conversation helper for the control level conversation for coordinating the test through. */ + ConversationFactory conversationFactory; + + /** Holds the connection that the control conversation is held over. */ + Connection connection; + + /** Holds the underlying test suite that this decorator wraps. */ + WrappedSuiteTestDecorator testSuite; + + /** Holds the control topic, on which test invitations are broadcast. */ + protected Destination controlTopic; + + /** + * Creates a wrapped suite test decorator from another one. + * + * @param suite The test suite. + * @param availableClients The list of all clients that responded to the compulsory invite. + * @param controlConversation The conversation helper for the control level, test coordination conversation. + * @param controlConnection The connection that the coordination messages are sent over. + */ + public DistributedTestDecorator(WrappedSuiteTestDecorator suite, Set<TestClientDetails> availableClients, + ConversationFactory controlConversation, Connection controlConnection) + { + super(suite); + + log.debug("public DistributedTestDecorator(WrappedSuiteTestDecorator suite, Set<TestClientDetails> allClients = " + + availableClients + ", ConversationHelper controlConversation = " + controlConversation + "): called"); + + testSuite = suite; + allClients = availableClients; + conversationFactory = controlConversation; + connection = controlConnection; + + // Set up the test control topic. + try + { + controlTopic = conversationFactory.getSession().createTopic("iop.control"); + } + catch (JMSException e) + { + throw new RuntimeException("Unable to create the coordinating control topic to broadcast test invites on.", e); + } + } + + /** + * Should run all of the tests in the wrapped test suite. + * + * @param testResult The the results object to monitor the test results with. + */ + public abstract void run(TestResult testResult); + + /** + * Should provide the distributed test sequencer to pass to {@link org.apache.qpid.test.framework.FrameworkBaseCase} + * tests. + * + * @return A distributed test sequencer. + */ + public abstract CircuitFactory getTestSequencer(); + + /** + * Broadcasts an invitation to participate in a coordinating test case to find out what clients are available to + * run the test case. + * + * @param coordTest The coordinating test case to broadcast an inviate for. + * + * @return A set of test clients that accepted the invitation. + */ + protected Set<TestClientDetails> signupClients(FrameworkBaseCase coordTest) + { + // Broadcast the invitation to find out what clients are available to test. + Set<TestClientDetails> enlists; + try + { + Message invite = conversationFactory.getSession().createMessage(); + + ConversationFactory.Conversation conversation = conversationFactory.startConversation(); + + invite.setStringProperty("CONTROL_TYPE", "INVITE"); + invite.setStringProperty("TEST_NAME", coordTest.getTestCaseNameForTestMethod(coordTest.getName())); + + conversation.send(controlTopic, invite); + + // Wait for a short time, to give test clients an opportunity to reply to the invitation. + Collection<Message> replies = conversation.receiveAll(allClients.size(), 500); + enlists = Coordinator.extractEnlists(replies); + } + catch (JMSException e) + { + throw new RuntimeException("There was a JMSException during the invite/enlist conversation.", e); + } + + return enlists; + } + + /** + * Prints a string summarizing this test decorator, mainly for debugging purposes. + * + * @return String representation for debugging purposes. + */ + public String toString() + { + return "DistributedTestDecorator: [ testSuite = " + testSuite + " ]"; + } +} |