diff options
author | Rajith Muditha Attapattu <rajith@apache.org> | 2011-05-27 15:44:23 +0000 |
---|---|---|
committer | Rajith Muditha Attapattu <rajith@apache.org> | 2011-05-27 15:44:23 +0000 |
commit | 66765100f4257159622cefe57bed50125a5ad017 (patch) | |
tree | a88ee23bb194eb91f0ebb2d9b23ff423e3ea8e37 /java/junit-toolkit/src | |
parent | 1aeaa7b16e5ce54f10c901d75c4d40f9f88b9db6 (diff) | |
parent | 88b98b2f4152ef59a671fad55a0d08338b6b78ca (diff) | |
download | qpid-python-rajith_jms_client.tar.gz |
Creating a branch for experimenting with some ideas for JMS client.rajith_jms_client
git-svn-id: https://svn.apache.org/repos/asf/qpid/branches/rajith_jms_client@1128369 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'java/junit-toolkit/src')
42 files changed, 0 insertions, 8905 deletions
diff --git a/java/junit-toolkit/src/main/org/apache/qpid/junit/concurrency/DefaultThreadFactory.java b/java/junit-toolkit/src/main/org/apache/qpid/junit/concurrency/DefaultThreadFactory.java deleted file mode 100644 index 8fb0a6a90e..0000000000 --- a/java/junit-toolkit/src/main/org/apache/qpid/junit/concurrency/DefaultThreadFactory.java +++ /dev/null @@ -1,48 +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.junit.concurrency; - -import java.util.concurrent.ThreadFactory; - -/** - * Implements a default thread factory. - * - * <p/><table id="crc"><caption>CRC Card</caption> - * <tr><th> Responsibilities <th> Collaborations - * <tr><td> Create default threads with no specialization. - * </table> - * - * @author Rupert Smith - */ -public class DefaultThreadFactory implements ThreadFactory -{ - /** - * Constructs a new <tt>Thread</tt>. - * - * @param r A runnable to be executed by new thread instance. - * - * @return The constructed thread. - */ - public Thread newThread(Runnable r) - { - return new Thread(r); - } -} diff --git a/java/junit-toolkit/src/main/org/apache/qpid/junit/concurrency/PossibleDeadlockException.java b/java/junit-toolkit/src/main/org/apache/qpid/junit/concurrency/PossibleDeadlockException.java deleted file mode 100644 index 3bbfc2d502..0000000000 --- a/java/junit-toolkit/src/main/org/apache/qpid/junit/concurrency/PossibleDeadlockException.java +++ /dev/null @@ -1,46 +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.junit.concurrency; - -/** - * PossibleDeadlockException is used to signal that two test threads being executed by a {@link ThreadTestCoordinator} - * may be in a state of deadlock because they are mutually blocking each other or one is waiting on the other and the - * other has been blocked elsewhere for longer than a specified timeout. - * - * <p/><table id="crc"><caption>CRC Card</caption> - * <tr><th> Responsibilities <th> Collaborations - * <tr><td> Signal a possible state of deadlock between coordinated test threads. - * </table> - * - * @author Rupert Smith - */ -public class PossibleDeadlockException extends RuntimeException -{ - /** - * Create a new possible deadlock execption. - * - * @param message The exception message. - */ - public PossibleDeadlockException(String message) - { - super(message); - } -} diff --git a/java/junit-toolkit/src/main/org/apache/qpid/junit/concurrency/TestRunnable.java b/java/junit-toolkit/src/main/org/apache/qpid/junit/concurrency/TestRunnable.java deleted file mode 100644 index 02e776a4ea..0000000000 --- a/java/junit-toolkit/src/main/org/apache/qpid/junit/concurrency/TestRunnable.java +++ /dev/null @@ -1,239 +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.junit.concurrency; - -/** - * TestRunnable is an extension of java.util.Runnable that adds some features to make it easier to coordinate the - * activities of threads in such a way as to expose bugs in multi threaded code. - * - * <p/>Sometimes several threads will run in a particular order so that a bug is not revealed. Other times the ordering - * of the threads will expose a bug. Such bugs can be hard to replicate as the exact execution ordering of threads is not - * usually controlled. This class adds some methods that allow threads to synchronize other threads, either allowing them - * to run, or waiting for them to allow this thread to run. It also provides convenience methods to gather error messages - * and exceptions from threads, which will often be reported in unit testing code. - * - * <p/>Coordination between threads is handled by the {@link ThreadTestCoordinator}. It is called through the convenience - * methods {@link #allow} and {@link #waitFor}. Threads to be coordinated must be set up with the coordinator and assigned - * integer ids. It is then possible to call the coordinator with an array of thread ids requesting that those threads - * be allowed to continue, or to wait until one of them allows this thread to continue. The otherwise non-deterministic - * execution order of threads can be controlled into a carefully determined sequence using these methods in order - * to reproduce race conditions, dead locks, live locks, dirty reads, phantom reads, non repeatable reads and so on. - * - * <p/>When waiting for another thread to give a signal to continue it is sometimes the case that the other thread has - * become blocked by the code under test. For example in testing for a dirty read (for example in database code), - * thread 1 lets thread 2 perform a write but not commit it, then thread 2 lets thread 1 run and attempt to perform a - * dirty read on its uncommitted write. Transaction synchronization code being tested against the possibility of a dirty - * write may make use of snapshots in which case both threads should be able to read and write without blocking. It may - * make use of explicit keys in which case thread 2 may become blocked on its write attempt because thread 1 holds a - * read lock and it must wait until thread 1 completes its transaction before it can acquire this lock. The - * {@link #waitFor} method accepts a boolean parameter to indicate that threads being blocked (other than on the - * coordinator) can be interpreted the same as if the thread explicitly allows the thread calling waitFor to continue. - * Using this technique a dirty read test could be written that works against either the snapshot or the locking - * implementation, allowing both approaches to pass the test yet arranging for multiple threads to run against the - * implementation in such a way that a potential dirty read bug is exposed. - * - * <p/><table id="crc"><caption>CRC Card</caption> - * <tr><th> Responsibilities <th> Collaborations - * <tr><td> Wait for another thread to allow this one to continue. - * <tr><td> Allow another thread to continue. - * <tr><td> Accumulate error messages. - * <tr><td> Record exceptions from thread run. - * <tr><td> Maintain link to thread coordinator. - * <tr><td> Explicitly mark a thread with an integer id. - * <tr><td> Maintian a flag to indicate whether or not this thread is waiting on the coordinator. - * </table> - * - * @todo The allow then waitFor operations are very often used as a pair. So create a method allowAndWait that combines - * them into a single method call. - * - * @author Rupert Smith - */ -public abstract class TestRunnable implements Runnable -{ - /** Holds a reference to the thread coordinator. */ - private ThreadTestCoordinator coordinator; - - /** Holds the explicit integer id of this thread. */ - private int id; - - /** Used to indicate that this thread is waiting on the coordinator and not elsewhere. */ - private boolean waitingOnCoordinator = false; - - /** Used to accumulate error messsages. */ - private String errorMessage = ""; - - /** Holds the Java thread object that this is running under. */ - private Thread thisThread; - - /** Used to hold any exceptions resulting from the run method. */ - private Exception runException = null; - - /** - * Implementations override this to perform coordinated thread sequencing. - * - * @throws Exception Any exception raised by the implementation will be caught by the default {@link #run()} - * implementation for later querying by the {@link #getException()} method. - */ - public abstract void runWithExceptions() throws Exception; - - /** - * Provides a default implementation of the run method that allows exceptions to be thrown and keeps a record - * of those exceptions. Defers to the {@link #runWithExceptions()} method to provide the thread body implementation - * and catches any exceptions thrown by it. - */ - public void run() - { - try - { - runWithExceptions(); - } - catch (Exception e) - { - this.runException = e; - } - } - - /** - * Attempt to consume an allow event from one of the specified threads and blocks until such an event occurrs. - * - * @param threads The set of threads that can allow this one to continue. - * @param otherWaitIsAllow If set to <tt>true</tt> if the threads being waited on are blocked other than on - * the coordinator itself then this is to be interpreted as allowing this thread to - * continue. - * - * @return If the <tt>otherWaitIsAllow</tt> flag is set, then <tt>true</tt> is returned when the thread being waited on is found - * to be blocked outside of the thread test coordinator. <tt>false</tt> under all other conditions. - */ - protected boolean waitFor(int[] threads, boolean otherWaitIsAllow) - { - return coordinator.consumeAllowEvent(threads, otherWaitIsAllow, id, this); - } - - /** - * Produces allow events on each of the specified threads. - * - * @param threads The set of threads that are to be allowed to continue. - */ - protected void allow(int[] threads) - { - coordinator.produceAllowEvents(threads, id, this); - } - - /** - * Keeps the error message for later reporting by the coordinator. - * - * @param message The error message to keep. - */ - protected void addErrorMessage(String message) - { - errorMessage += message; - } - - /** - * Sets the coordinator for this thread. - * - * @param coordinator The coordinator for this thread. - */ - void setCoordinator(ThreadTestCoordinator coordinator) - { - this.coordinator = coordinator; - } - - /** - * Reports whether or not this thread is waiting on the coordinator. - * - * @return <tt>If this thread is waiting on the coordinator. - */ - boolean isWaitingOnCoordinator() - { - return waitingOnCoordinator; - } - - /** - * Sets the value of the waiting on coordinator flag. - * - * @param waiting The value of the waiting on coordinator flag. - */ - void setWaitingOnCoordinator(boolean waiting) - { - waitingOnCoordinator = waiting; - } - - /** - * Sets up the explicit int id for this thread. - * - * @param id The integer id. - */ - void setId(int id) - { - this.id = id; - } - - /** - * Reports any accumulated error messages. - * - * @return Any accumulated error messages. - */ - String getErrorMessage() - { - return errorMessage; - } - - /** - * Reports any exception thrown by the {@link #runWithExceptions} method. - * - * @return Any exception thrown by the {@link #runWithExceptions} method. - */ - Exception getException() - { - return runException; - } - - /** - * Sets the Java thread under which this runs. - * - * @param thread The Java thread under which this runs. - */ - void setThread(Thread thread) - { - thisThread = thread; - } - - /** - * Gets the Java thread under which this runs. - * - * @return The Java thread under which this runs. - */ - Thread getThread() - { - return thisThread; - } - - /** - * Provides a string summary of this test threads status. - * - * @return Summarizes this threads status. - */ - public String toString() - { - return "id = " + id + ", waitingOnCoordinator = " + waitingOnCoordinator; - } -} diff --git a/java/junit-toolkit/src/main/org/apache/qpid/junit/concurrency/ThreadTestCoordinator.java b/java/junit-toolkit/src/main/org/apache/qpid/junit/concurrency/ThreadTestCoordinator.java deleted file mode 100644 index 3cf8543656..0000000000 --- a/java/junit-toolkit/src/main/org/apache/qpid/junit/concurrency/ThreadTestCoordinator.java +++ /dev/null @@ -1,486 +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.junit.concurrency; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.concurrent.ThreadFactory; - -/** - * ThreadTestCoordinator provides an array of binary latches that allows threads to wait for other threads or to send - * them a signal that allows them to continue running or to wait for another thread to signal them. The binary latch - * array is always a square array, allowing one latch from and to every thread. Upon accepting an allow signal from one - * sender the latches for all senders for a are cleared. This class is always used in conjunction with - * {@link TestRunnable} for writing concurrent test code that coordinates multi-threaded activity in order to reproduce - * concurrency bugs. - * - * <p/><table id="crc"><caption>CRC Card</caption> - * <tr><th> Responsibilities <th> Collaborations - * <tr><td> Accept test threads to coordinate. - * <tr><td> Allow test threads to send 'allow to continue' signals. - * <tr><td> Allow test threads to wait on this coordinator for 'allow to continue' signals. - * <tr><td> Report error messages from test threads. - * <tr><td> Report exceptions from test threads. - * <tr><td> Provide method to wait until all test threads have completed. - * </table> - * - * @todo This code was hacked together as a bit of an experiment, because I wasn't sure if this idea would work. It has - * proved extremely usefull. Some documentation for this needs to be written to explain it better. - * - * @todo Consider how deadlock detection will be handled. If all threads are blocking on the coordinator, waiting for - * each other, they are deadlocked and there is something wrong with the test code that put them in that - * situation. If they are all blocked elsewhere, they may be deadlocked, or could just be waiting on some - * external event. A timeout should be used. Timeout is already implemented, just need to sanity check how - * this is working and document it. - * - * @todo Consider how livelock detection could be implemented? LockFree data structures might cause live locks. I - * guess a longish timeout is the only thing that can be done for that. - * - * @todo Only course grained synchronous at the method class level can be obtained. This is because test code can - * only insert synchronization points between method calls it makes. So this code will not be usefull for - * checking sequences of events within methods, unless the code under test is explicitly instrumented for it. - * It might be possible to instrument code by using labels, and then use the debugger/profiler interface to - * put breakpoints on the labels and use them as synchronization points. Not perfect, but at the unused labels - * can be left in the code, without altering its behaviour. - * - * @author Rupert Smith - */ -public class ThreadTestCoordinator -{ - /** Used for logging. */ - private static final Logger log = LoggerFactory.getLogger(ThreadTestCoordinator.class); - - /** Keeps track of the test threads by their ids. */ - private TestRunnable[] testThreads; // = new TestRunnable[2]; - - /** An explicit thread monitor for the coordinator. Threads wait on the coordinator whilst waiting for events. */ - private final Object coordinatorLock = new Object(); - - /** A set of monitors for each test thread. */ - private Object[] locks; - - /** The binary latch array, this is always a square array allowing one event from and to every thread. */ - private boolean[][] allowEvents; - - /** Keeps track of the number of threads being coordinated. */ - private int threadCount = 0; - - /** Accumulates any exceptions resulting from the threads run methods. */ - private Collection<Exception> exceptions = new ArrayList<Exception>(); - - /** - * Holds the deadlock timeout after which threads are given a runtime exception to signal that a potential - * deadlock may be happening. - */ - private long deadlockTimeout = 1000 * 1000000; - - /** Holds the factory to create test thread with. */ - private ThreadFactory threadFactory; - - /** - * Creates a new test thread coordinator. The number of threads to run must be specified here. - * - * @param numThreads The number of threads to run. - */ - public ThreadTestCoordinator(int numThreads) - { - this.threadCount = numThreads; - - // Create an array big enough to hold all the test threads. - testThreads = new TestRunnable[threadCount]; - - // Use the default thread factory, as none specified. - threadFactory = new DefaultThreadFactory(); - } - - /** - * Creates a new test thread coordinator with a specific thread factory. The number of threads to run must be - * specified here. - * - * @param numThreads The number of threads to run. - * @param threadFactory The factory to use to create the test threads. - */ - public ThreadTestCoordinator(int numThreads, ThreadFactory threadFactory) - { - this.threadCount = numThreads; - - // Create an array big enough to hold all the test threads. - testThreads = new TestRunnable[threadCount]; - - // Use the specified thread factory. - this.threadFactory = threadFactory; - } - - /** - * Adds a thread to this coordinator and assigns an id to it. The ids must be numbered sequentially from 0 and - * it is up to the caller to do this. - * - * @param runnable The test thread. - * @param id The explicit id to assign to the test thread. - */ - public void addTestThread(TestRunnable runnable, int id) - { - testThreads[id] = runnable; - runnable.setCoordinator(this); - runnable.setId(id); - } - - /** - * Starts all the coordinated threads running. - */ - public void run() - { - // Create the monitors for each thread. - locks = new Object[threadCount]; - - // Create an appropriately sized event queue to allow one event from and to each thread. - allowEvents = new boolean[threadCount][threadCount]; - - // Initialize the monitors and clear the event queues. - for (int i = 0; i < locks.length; i++) - { - locks[i] = new Object(); - - for (int j = 0; j < locks.length; j++) - { - allowEvents[i][j] = false; - } - } - - // Start all the threads running. - for (TestRunnable nextRunnable : testThreads) - { - // Create a Java thread for the test thread. - Thread newThread = threadFactory.newThread(nextRunnable); - nextRunnable.setThread(newThread); - - // Start it running. - newThread.start(); - } - } - - /** - * Waits until all the test threads have completed and returns any accumulated error messages from them. Any - * exceptions thrown by their run methods are also kept at this point. - * - * @return The accumulated error messages from all the threads concatenated together. - */ - public String joinAndRetrieveMessages() - { - // Create an empty error message. - String errorMessage = ""; - - // Join all the test threads. - for (TestRunnable r : testThreads) - { - Thread t = r.getThread(); - - try - { - t.join(); - } - catch (InterruptedException e) - { } - - // Add any accumulated error messages to the return value. - errorMessage += r.getErrorMessage(); - - // Keep any exceptions resulting from the threads run method. - Exception e = r.getException(); - - if (e != null) - { - exceptions.add(e); - } - } - - return errorMessage; - } - - /** - * Reports any accumulated exceptions from the test threads run methods. This method must be called after - * {@link #joinAndRetrieveMessages}. - * - * @return Any accumulated exceptions from the test threads run methods. This method must be called after - */ - public Collection<Exception> getExceptions() - { - return exceptions; - } - - /** - * Sets a timeout to break out of potential deadlocks. If all threads are waiting for other threads to send - * them continue events for longer than this timeout then the threads are all terminated. - * - * @param millis The minimum time to allow to pass before breaking out of any potential deadlocks. - * - * @todo This has not been implemented yet. If a potential deadlock happens then the joinAndRetrieveMessages - * method should throw a PotentialDeadlockException. - */ - public void setDeadlockTimeout(long millis) - { - deadlockTimeout = millis * 1000000; - } - - /** - * Creates a set of 'allow to continue' events on the event queues of the specified threads. - * - * @param threads The set of threads to allow to continue. - * @param callerId The explicit id of the calling test thread. - * @param caller The calling test thread. - */ - void produceAllowEvents(int[] threads, int callerId, TestRunnable caller) - { - // Generate some debugging messages. Very usefull to know how thread synchronization is progressing. - String message = "Thread " + callerId + " is allowing threads [ "; - - for (int j = 0; j < threads.length; j++) - { - message += threads[j] + ((j < (threads.length - 1)) ? ", " : ""); - } - - message += " ] to continue."; - log.debug(message); - - // For each allow event, synchronize on the threads lock then set the event flag to true. - for (int id : threads) - { - // Set the waiting on coordinator flag to true in case the coordinator tries to test this thread for - // being blocked at this time. - caller.setWaitingOnCoordinator(true); - - synchronized (locks[id]) - { - // Release the wating on coordinator flag now that this thread is running again. - caller.setWaitingOnCoordinator(false); - - // Send the allow to continue event to the receiving thread. - allowEvents[id][callerId] = true; - } - } - - // Wake up any threads waiting on the coordinator lock to recheck their event queues. - // Set the waiting on coordinator flag to true in case the coordinator tries to test this thread for - // being blocked at this time. - caller.setWaitingOnCoordinator(true); - - synchronized (coordinatorLock) - { - // Release the wating on coordinator flag now that this thread is running again. - caller.setWaitingOnCoordinator(false); - coordinatorLock.notifyAll(); - } - } - - /** - * Consumes an 'allow to continue' from one of the specified threads or waits until one is available or in some - * cases if one of the specified threads is blocked elsewhere to accept that as an 'allow to continue' event. - * - * @param threads The set of threads to accept an allow to continue event from. - * @param otherWaitIsAllow Whether or not to accept threads being blocked elsewhere as permission to continue. - * @param callerId The explicit id of the calling test thread. - * @param caller The calling test thread. - * - * @return If the <tt>otherWaitIsAllow</tt> flag is set, then <tt>true</tt> is returned when the thread being waited on is found - * to be blocked outside of the thread test coordinator. <tt>false</tt> under all other conditions. - */ - boolean consumeAllowEvent(int[] threads, boolean otherWaitIsAllow, int callerId, TestRunnable caller) - { - // Generate some debugging messages. Very usefull to know how thread synchronization is progressing. - String message = "Thread " + callerId + " is requesting threads [ "; - - // Record the time at which this method was called. Will be used for breaking out of potential deadlocks. - long startTime = System.nanoTime(); - - for (int j = 0; j < threads.length; j++) - { - message += threads[j] + ((j < (threads.length - 1)) ? ", " : ""); - } - - message += " ] to allow it to continue."; - log.debug(message); - - // Loop until an allow to continue event is received. - while (true) - { - // Look at all the allowing thread to see if one has created an event for consumption. - for (int allowerId : threads) - { - // Get the threads lock for the event to consume. - // Set the waiting on coordinator flag to true in case the coordinator tries to test this thread for - // being blocked at this time. - caller.setWaitingOnCoordinator(true); - - synchronized (locks[callerId]) - { - // Release the wating on coordinator flag now that this thread is running again. - caller.setWaitingOnCoordinator(false); - - // Check if there is an event on the queue from the allowing thread to this one. - if (allowEvents[callerId][allowerId]) - { - log.debug("Found an allow event, thread " + allowerId + ", is allowing thread " + callerId - + ", to continue."); - - // Consume all the allow events for this thread. - /*for (int i = 0; i < allowEvents[callerId].length; i++) - { - allowEvents[callerId][i] = false; - }*/ - - // Consume just the event from the allower to the consumer, leaving other pending allow events alone. - allowEvents[callerId][allowerId] = false; - - return false; - } - } - } - - // If waiting elsewhere is to be interpreted as an 'allow to continue' event, then look at the thread status - // for the threads being waited on to see if any are blocked on other resources. - if (otherWaitIsAllow) - { - log.debug("Other wait is to be interpreted as an allow event."); - - // Look at all the potential allower threads. - for (int allowerId : threads) - { - // Get the Java thread state for the allowing thread. - Thread threadToTest = testThreads[allowerId].getThread(); - Thread.State state = threadToTest.getState(); - - // Check if the thread is blocked and so a potential candidate for releasing this one. - if ((state == Thread.State.BLOCKED) || (state == Thread.State.WAITING) - || (state == Thread.State.TIMED_WAITING)) - { - log.debug("Found an allower thread, id = " + allowerId + ", that is blocked or wating."); - - // Check that the allower thread is not waiting on the coordinator lock or any of the - // individual thread locks. It must be waiting or blocked on another monitor. - TestRunnable allowingRunnable = testThreads[allowerId]; - boolean isWaitingOnCoordinator = allowingRunnable.isWaitingOnCoordinator(); - - if (!isWaitingOnCoordinator) - { - log.debug("The allower thread, id = " + allowerId - + ", is blocked or waiting other than on the coordinator."); - - // Get the threads lock for the event to consume. - caller.setWaitingOnCoordinator(true); - - synchronized (locks[callerId]) - { - caller.setWaitingOnCoordinator(false); - - // Consume all the allow events for this thread. - for (int i = 0; i < allowEvents[callerId].length; i++) - { - allowEvents[callerId][i] = false; - } - - return true; - } - } - else - { - log.debug("The waiting allower thread, " + allowerId - + ", is waiting on the coordinator so does not allow thread " + callerId + " to continue."); - } - } - } - } - - // Keep waiting until an 'allow to continue' event can be consumed. - try - { - // Set the waiting on coordinator flag to true in case the coordinator tries to test this thread for - // being blocked at this time. - caller.setWaitingOnCoordinator(true); - - synchronized (coordinatorLock) - { - // Release the wating on coordinator flag now that this thread is running again. - caller.setWaitingOnCoordinator(false); - - log.debug("Thread " + callerId + " is waiting on coordinator lock for more allow events."); - - // Set the waiting on coordinator flag to true in case the coordinator tries to test this thread for - // being blocked at this time. - caller.setWaitingOnCoordinator(true); - coordinatorLock.wait(10); - } - } - catch (InterruptedException e) - { } - - // Release the waiting on coordinator flag now that this thread is running again. - caller.setWaitingOnCoordinator(false); - - // Check if this thread has been waiting for longer than the deadlock timeout and raise a possible - // deadlock exception if so. - long waitTime = System.nanoTime() - startTime; - log.debug("Thread " + callerId + " has been waiting for " + (waitTime / 1000000) + " milliseconds."); - - if (waitTime > deadlockTimeout) - { - // Throw a possible deadlock exception. - throw new PossibleDeadlockException("Possible deadlock due to timeout with state:\n" + this); - } - - log.debug("Thread " + callerId + " has woken up, was waiting for more allow events to become available."); - } - } - - /** - * Pretty prints the state of the thread test coordinator, for debugging purposes. - * - * @return Pretty printed state of the thread test coordinator. - */ - public String toString() - { - String result = "["; - - for (int i = 0; i < allowEvents.length; i++) - { - for (int j = 0; j < allowEvents[i].length; j++) - { - result += allowEvents[i][j]; - - result += (j < (allowEvents[i].length - 1)) ? ", " : ""; - } - - result += (i < (allowEvents.length - 1)) ? ",\n " : ""; - } - - result += "]"; - - for (int i = 0; i < testThreads.length; i++) - { - result += "thread[" + i + "] = " + testThreads[i].toString(); - } - - return result; - } - -} diff --git a/java/junit-toolkit/src/main/org/apache/qpid/junit/concurrency/ThreadTestExample.java b/java/junit-toolkit/src/main/org/apache/qpid/junit/concurrency/ThreadTestExample.java deleted file mode 100644 index b9865f2e22..0000000000 --- a/java/junit-toolkit/src/main/org/apache/qpid/junit/concurrency/ThreadTestExample.java +++ /dev/null @@ -1,145 +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.junit.concurrency; - -import org.apache.log4j.Logger; - -/** - * An example to illustrate the use of the {@link ThreadTestCoordinator} and {@link TestRunnable}s. - * - * <p/><table id="crc"><caption>CRC Card</caption> - * <tr><th> Responsibilities <th> Collaborations - * <tr><td> Demo multi-threaded testing. - * </table> - * - * @author Rupert Smith - */ -public class ThreadTestExample -{ - /** Used for logging. */ - private static final Logger log = Logger.getLogger(ThreadTestExample.class); - - /** Test thread 1. */ - TestRunnable testThread1 = - new TestRunnable() - { - public void runWithExceptions() throws Exception - { - log.debug("public void run(): called"); - log.info("in testThread0, block 1"); - - // Wait for t2 to allow t1 to continue. - allow(new int[] { 1 }); - waitFor(new int[] { 1 }, false); - - log.info("in testThread0, block 2"); - - // Wait for t2 to allow t1 to continue. T2 is allowed to be blocked elsewhere than giving explicit - // permission to allow t1 to continue. - allow(new int[] { 1 }); - waitFor(new int[] { 1 }, true); - - log.info("in testThread0, block 3"); - - // Release thread 2 from waiting on the shared lock. - synchronized (sharedLock) - { - sharedLock.notifyAll(); - } - - allow(new int[] { 1 }); - } - }; - - /** A shared lock between the test threads. */ - final Object sharedLock = new Object(); - - /** Test thread 2. */ - TestRunnable testThread2 = - new TestRunnable() - { - public void runWithExceptions() throws Exception - { - log.debug("public void run(): called"); - log.info("in testThread1, block 1"); - - // Wait for t1 to allow t2 to continue. - allow(new int[] { 0 }); - waitFor(new int[] { 0 }, false); - - log.info("in testThread1, block 2"); - - // Wait on another resource. T1 should accept this as permission to continue. - try - { - synchronized (sharedLock) - { - log.debug("in testThread1, waiting on shared lock."); - sharedLock.wait(); - } - } - catch (InterruptedException e) - { - // Bail-out with a runtime if this happens. - throw new RuntimeException("Interrupted whilst waiting for shared lock.", e); - } - - log.info("in testThread1, finished waiting on shared lock."); - - // allow(new int[] { 0 }); - - // Wait for t1 to allow t2 to continue. - waitFor(new int[] { 0 }, false); - - log.info("in testThread1, block 3"); - - allow(new int[] { 0 }); - } - }; - - /** - * Executes the test threads with coordination. - * - * @param args Ignored. - */ - public void main(String[] args) - { - ThreadTestCoordinator tt = new ThreadTestCoordinator(2); - - tt.addTestThread(testThread1, 0); - tt.addTestThread(testThread2, 1); - tt.setDeadlockTimeout(500); - tt.run(); - - String errorMessage = tt.joinAndRetrieveMessages(); - - // Print any error messages or exceptions. - log.info(errorMessage); - - if (!tt.getExceptions().isEmpty()) - { - for (Exception e : tt.getExceptions()) - { - log.warn("Exception thrown during test thread: ", e); - } - } - } -} diff --git a/java/junit-toolkit/src/main/org/apache/qpid/junit/concurrency/package.html b/java/junit-toolkit/src/main/org/apache/qpid/junit/concurrency/package.html deleted file mode 100644 index 904fd0fd05..0000000000 --- a/java/junit-toolkit/src/main/org/apache/qpid/junit/concurrency/package.html +++ /dev/null @@ -1,28 +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. - ---> - -<html> -<body> -Contains code to assist in testing concurrency issues using coordinated threads to present code under test with -oportunities to expose concurrency bugs. Some example concurrency bugs that may be tested using these techniques are -race conditions, dead locks, live locks, dirty reads, phantom reads, non repeatable reads and so on. -</body> -</html> diff --git a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/AsymptoticTestCase.java b/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/AsymptoticTestCase.java deleted file mode 100644 index 58a7f60f3c..0000000000 --- a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/AsymptoticTestCase.java +++ /dev/null @@ -1,303 +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.junit.extensions; - -import junit.framework.TestCase; - -import org.apache.log4j.Logger; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; - -/** - * AsymptoticTestCase is an extension of TestCase for writing unit tests to analyze asymptotic time and space behaviour. - * - * <p>ParameterizedTestCases allow tests to be defined which have test methods that take a single int argument. Normal - * JUnit test methods do not take any arguments. This int argument can be interpreted in any way by the test but it is - * intended to denote the 'size' of the test to be run. For example, when testing the performance of a data structure - * for different numbers of data elements held in the data structure the int parameter should be interpreted as the - * number of elements. Test timings for different numbers of elements can then be captured and the asymptotic behaviour - * of the data structure with respect to time analyzed. Any non-parameterized tests defined in extensions of this class - * will also be run. - * - * <p>TestCases derived from this class may also define tear down methods to clean up their memory usage. This is - * intended to be used in conjunction with memory listeners that report the amount of memory a test uses. The idea is - * to write a test that allocates memory in the main test method in such a way that it leaves that memory still - * allocated at the end of the test. The amount of memory used can then be measured before calling the tear down method - * to clean it up. In the data structure example above, a test will allocate as many elements as are requested by the - * int parameter and deallocate them in the tear down method. In this way memory readings for different numbers of - * elements can be captured and the asymptotic behaviour of the data structure with respect to space analyzed. - * - * <p><table id="crc"><caption>CRC Card</caption> - * <tr><th> Responsibilities <th> Collaborations - * <tr><td> Store the current int parameter value. <td> {@link TKTestResult} and see {@link AsymptoticTestDecorator} too. - * <tr><td> Invoke parameterized test methods. - * </table> - * - * @todo If possible try to move the code that invokes the test and setup/teardown methods into {@link TKTestResult} or - * {@link AsymptoticTestDecorator} rather than this class. This would mean that tests don't have to extend this - * class to do time and space performance analysis, these methods could be added to any JUnit TestCase class - * instead. This would be an improvement because existing unit tests wouldn't have to extend a different class to - * work with this extension, and also tests that extend other junit extension classes could have parameterized - * and tear down methods too. - * - * @author Rupert Smith - */ -public class AsymptoticTestCase extends TestCase implements InstrumentedTest -{ - /** Used for logging. */ - private static final Logger log = Logger.getLogger(AsymptoticTestCase.class); - - /** The name of the test case. */ - private String testCaseName; - - /** Thread local for holding measurements on a per thread basis. */ - ThreadLocal<TestMeasurements> threadLocalMeasurement = - new ThreadLocal<TestMeasurements>() - { - /** - * Sets up a default set test measurements (zeroed, apart from the size param which defaults to 1). - * - * @return A set of default test measurements. - */ - protected synchronized TestMeasurements initialValue() - { - return new TestMeasurements(); - } - }; - - /** - * Constructs a test case with the given name. - * - * @param name The name of the test. - */ - public AsymptoticTestCase(String name) - { - super(name); - - log.debug("public AsymptoticTestCase(String " + name + "): called"); - testCaseName = name; - } - - /** - * Gets the current value of the integer parameter to be passed to the parameterized test. - * - * @return The current value of the integer parameter. - */ - public int getN() - { - log.debug("public int getN(): called"); - int n = threadLocalMeasurement.get().n; - - log.debug("return: " + n); - - return n; - } - - /** - * Sets the current value of the integer parameter to be passed to the parameterized test. - * - * @param n The new current value of the integer parameter. - */ - public void setN(int n) - { - log.debug("public void setN(int " + n + "): called"); - threadLocalMeasurement.get().n = n; - } - - /** - * Reports how long the test took to run. - * - * @return The time in milliseconds that the test took to run. - */ - public long getTestTime() - { - log.debug("public long getTestTime(): called"); - long startTime = threadLocalMeasurement.get().startTime; - long endTime = threadLocalMeasurement.get().endTime; - long testTime = endTime - startTime; - - log.debug("return: " + testTime); - - return testTime; - } - - /** - * Reports the memory usage at the start of the test. - * - * @return The memory usage at the start of the test. - */ - public long getTestStartMemory() - { - // log.debug("public long getTestStartMemory(): called"); - long startMem = threadLocalMeasurement.get().startMem; - - // log.debug("return: " + startMem); - - return startMem; - } - - /** - * Reports the memory usage at the end of the test. - * - * @return The memory usage at the end of the test. - */ - public long getTestEndMemory() - { - // log.debug("public long getTestEndMemory(): called"); - long endMem = threadLocalMeasurement.get().endMem; - - // log.debug("return: " + endMem); - return endMem; - } - - /** - * Resets the instrumentation values to zero, and nulls any references to held measurements so that the memory - * can be reclaimed. - */ - public void reset() - { - log.debug("public void reset(): called"); - threadLocalMeasurement.remove(); - } - - /** - * Runs the test method for this test case. - * - * @throws Throwable Any Throwables from the test methods invoked are allowed to fall through. - */ - protected void runTest() throws Throwable - { - log.debug("protected void runTest(): called"); - - // Check that a test name has been set. This is used to define which method to run. - assertNotNull(testCaseName); - log.debug("testCaseName = " + testCaseName); - - // Try to get the method with matching name. - Method runMethod = null; - boolean isParameterized = false; - - // Check if a parameterized test method is available. - try - { - // Use getMethod to get all public inherited methods. getDeclaredMethods returns all - // methods of this class but excludes the inherited ones. - runMethod = getClass().getMethod(testCaseName, int.class); - isParameterized = true; - } - catch (NoSuchMethodException e) - { - // log.debug("Parameterized method \"" + testCaseName + "\" not found."); - // Set run method to null (it already will be but...) to indicate that no parameterized method - // version could be found. - runMethod = null; - } - - // If no parameterized method is available, try and get the unparameterized method. - if (runMethod == null) - { - try - { - runMethod = getClass().getMethod(testCaseName); - isParameterized = false; - - } - catch (NoSuchMethodException e) - { - fail("Method \"" + testCaseName + "\" not found."); - } - } - - // Check that the method is publicly accessable. - if (!Modifier.isPublic(runMethod.getModifiers())) - { - fail("Method \"" + testCaseName + "\" should be public."); - } - - // Try to execute the method, passing it the current int parameter value. Allow any invocation exceptions or - // resulting exceptions from the method to fall through. - try - { - Integer paramN = getN(); - log.debug("paramN = " + paramN); - - // Calculate parameters for parameterized tests so new does not get called during memory measurement. - Object[] params = new Object[] { paramN }; - - // Take the test start memory and start time. - threadLocalMeasurement.get().startMem = 0; // SizeOf.getUsedMemory(); - - threadLocalMeasurement.get().startTime = System.nanoTime(); - - if (isParameterized) - { - runMethod.invoke(this, params); - } - else - { - runMethod.invoke(this); - } - } - catch (InvocationTargetException e) - { - e.fillInStackTrace(); - throw e.getTargetException(); - } - catch (IllegalAccessException e) - { - e.fillInStackTrace(); - throw e; - } - finally - { - // Take the test end memory and end time and calculate how long it took to run. - long endTime = System.nanoTime(); - threadLocalMeasurement.get().endTime = endTime; - log.debug("startTime = " + threadLocalMeasurement.get().startTime + ", endTime = " + endTime + ", testTime = " - + getTestTime()); - - threadLocalMeasurement.get().endMem = 0; // SizeOf.getUsedMemory(); - } - } - - /** - * The test parameters, encapsulated as a unit for attaching on a per thread basis. - */ - private static class TestMeasurements - { - /** Holds the current value of the integer parameter to run tests on. */ - public int n = 1; - - /** Holds the test start memory. */ - public long startTime = 0; - - /** Holds the test end memory. */ - public long endTime = 0; - - /** Holds the test start memory. */ - public long startMem = 0; - - /** Holds the test end memory. */ - public long endMem = 0; - } -} diff --git a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/AsymptoticTestDecorator.java b/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/AsymptoticTestDecorator.java deleted file mode 100644 index 8869d25be3..0000000000 --- a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/AsymptoticTestDecorator.java +++ /dev/null @@ -1,173 +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.junit.extensions; - -import junit.framework.TestResult; - -import org.apache.log4j.Logger; - -import org.apache.qpid.junit.extensions.util.MathUtils; - -/** - * A Decorator that runs a test repeatedly on an increasing int parameter, or for a fixed number of repeats. If both - * a set of integer parameters and a repeat count are specified, then each test is run for the repeat count at each - * integer parameter. - * - * <p><table id="crc"><caption>CRC Card</caption> - * <tr><th> Responsibilities <th> Collaborations - * <tr><td> Repeat a test for each of a set of integer parameters. <td> {@link TKTestResult} - * <tr><td> Repeat a test multiple times. - * <tr><td> - * </table> - * - * @author Rupert Smith - */ -public class AsymptoticTestDecorator extends WrappedSuiteTestDecorator -{ - /** Used for logging. */ - private static final Logger log = Logger.getLogger(AsymptoticTestDecorator.class); - - /** The int size parameters to run the test with. */ - private int[] params; - - /** The number of times the whole test should be repeated. */ - private int repeat; - - /** - * Creates an asymptotic test decorator that wraps a test with repeats and a set of integer 'size' paramters - * to call the test with. - * - * @param test The test to wrap. - * @param params The integer 'size' parameters. - * @param repeat The number of times to repeat the test. - */ - public AsymptoticTestDecorator(WrappedSuiteTestDecorator test, int[] params, int repeat) - { - super(test); - - log.debug("public AsymptoticTestDecorator(Test \"" + test + "\", int[] " - + ((params == null) ? null : MathUtils.printArray(params)) + ", int " + repeat + "): called"); - - this.params = params; - this.repeat = repeat; - } - - /** - * Creates a new AsymptoticTestDecorator object. - * - * @param test The test to decorate. - * @param start The starting asymptotic integer parameter value. - * @param end The ending asymptotic integer parameter value. - * @param step The increment size to move from the start to end values by. - * @param repeat The number of times to repeat the test at each step of the cycle. - */ - public AsymptoticTestDecorator(WrappedSuiteTestDecorator test, int start, int end, int step, int repeat) - { - super(test); - - if (start < 0) - { - throw new IllegalArgumentException("Start must be >= 0"); - } - - if (end < start) - { - throw new IllegalArgumentException("End must be >= start"); - } - - if (step < 1) - { - throw new IllegalArgumentException("Step must be >= 1"); - } - - if (repeat < 1) - { - throw new IllegalArgumentException("Repeat must be >= 1"); - } - - // Generate the sequence. - params = new int[((end - start) / step) + 1]; - int i = 0; - for (int n = start; n <= end; n += step) - { - params[i++] = n; - } - - this.repeat = repeat; - } - - /** - * Runs the test repeatedly for each value of the int parameter specified and for the correct number of test - * repeats. - * - * @param result The test result object that the tests will indicate their results to. This is also used - * to pass the int parameter from this class to the decorated test class. - */ - public void run(TestResult result) - { - log.debug("public void run(TestResult result): called"); - - if (!(result instanceof TKTestResult)) - { - throw new IllegalArgumentException("AsymptoticTestDecorator only works with TKTestResult"); - } - - // Cast the test result into a TKTestResult to place the current parameter into. - TKTestResult tkResult = (TKTestResult) result; - - log.debug("params = " + ((params == null) ? null : MathUtils.printArray(params))); - log.debug("repeat = " + repeat); - - if(params != null) - { - for (int n : params) - { - for (int j = 0; j < repeat; j++) - { - log.debug("n = " + n); - - // Set the integer parameter in the TKTestResult to be passed to the tests. - tkResult.setN(n); - - if (tkResult.shouldStop()) - { - log.debug("tkResult.shouldStop = " + true); - - break; - } - - log.debug("Calling super#run"); - super.run(tkResult); - } - } - } - } - - /** - * Prints out the name of this test with the string "(parameterized)" appended onto it for debugging purposes. - * - * @return The name of this test with the string "(parameterized)" appended onto it. - */ - public String toString() - { - return super.toString() + "(parameterized)"; - } -} diff --git a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/BaseThrottle.java b/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/BaseThrottle.java deleted file mode 100644 index 61d5746421..0000000000 --- a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/BaseThrottle.java +++ /dev/null @@ -1,98 +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.junit.extensions; - -/** - * Provides a base implementation of the non-waiting throttle checking method, using the system nano timer. - * - * <p/><table id="crc"><caption>CRC Card</caption> - * <tr><th> Responsibilities <th> Collaborations - * <tr><td> Check against a throttle speed without waiting. - * </table> - * - * @author Rupert Smith - */ -public abstract class BaseThrottle implements Throttle -{ - /** Holds the length of a single cycle in nano seconds. */ - protected long cycleTimeNanos; - - /** Holds the time of the last succesfull call to the check method. */ - private long lastCheckTimeNanos; - - /** Flag used to detect the first call to the {@link #checkThrottle()} method. */ - boolean firstCheckCall = true; - - /** - * Flag used to detect the first call to the {@link #throttle()} method. Zero or negative start time cannot be - * relied on to detect this as System.nanoTime can return zero or negative values. - */ - boolean firstCall = true; - - /** - * Specifies the throttling rate in operations per second. This must be called with with a value, the inverse - * of which is a measurement in nano seconds, such that the number of nano seconds do not overflow a long integer. - * The value must also be larger than zero. - * - * @param hertz The throttling rate in cycles per second. - */ - public void setRate(float hertz) - { - // Check that the argument is above zero. - if (hertz <= 0.0f) - { - throw new IllegalArgumentException("The throttle rate must be above zero."); - } - - // Calculate the cycle time. - cycleTimeNanos = (long) (1000000000f / hertz); - - // Reset the first pass flag. - firstCall = false; - firstCheckCall = false; - } - - /** - * Checks but does not enforce the throttle rate. When this method is called, it checks if a length of time greater - * than that equal to the inverse of the throttling rate has passed since it was last called and returned <tt>true</tt> - * - * @return <tt>true</tt> if a length of time greater than that equal to the inverse of the throttling rate has - * passed since this method was last called and returned <tt>true</tt>, <tt>false</tt> otherwise. The very - * first time this method is called on a throttle, it returns <tt>true</tt> as the base case to the above - * self-referential definition. - */ - public boolean checkThrottle() - { - long now = System.nanoTime(); - - if ((now > (cycleTimeNanos + lastCheckTimeNanos)) || firstCheckCall) - { - firstCheckCall = false; - lastCheckTimeNanos = now; - - return true; - } - else - { - return false; - } - } -} diff --git a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/BatchedThrottle.java b/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/BatchedThrottle.java deleted file mode 100644 index 241e7aa2b7..0000000000 --- a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/BatchedThrottle.java +++ /dev/null @@ -1,94 +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.junit.extensions; - -/** - * BatchedThrottle is a {@link SleepThrottle} that uses batching to achieve much higher throttling rates than a sleep - * throttle can. Sleep throttle has difficulties once the rate gets above a few hundred hertz, because the JVM cannot - * generate timed pauses that are that short. BatchedThrottle gets around this by only inserting pauses once every so - * many calls to the {@link #throttle()} method, and using a sleep throttle run at a lower rate. The rate for the sleep - * throttle is chosen so that it remains under 100hz. The final throttling rate of this throttle is equal to the batch - * size times the rate of the underlying sleep throttle. - * - * <p/>The batching calculation involves taking the log to the base 100 of the desired rate and rounding this to - * an integer. The batch size is always an exact power of 100 because of the rounding. The rate for an underlying - * sleep throttle is then chosen appropriately. - * - * <p/>In practice, the accuracy of a BacthedThrottle skews off but can sometimes even be reasonable up to ten thousand - * hertz compared with 100 Hz for a {@link SleepThrottle}. - * - * <p><table id="crc"><caption>CRC Card</caption> - * <tr><th> Responsibilities <th> Collaborations - * <tr><td> Accept throttling rate in operations per second. - * <tr><td> Inject short pauses, occasionaly, to fill out processing cycles to a specified rate. - * <tr><td> Check against a throttle speed without waiting. - * </table> - * - * @todo Should always round the log base 100 down to the nearest integer? - * - * @author Rupert Smith - */ -public class BatchedThrottle extends BaseThrottle -{ - /** Holds the batch size. */ - int batchSize; - - /** The call count within the current batch. */ - long callCount; - - /** Holds a sleep throttle configured to run at the batched rate. */ - private Throttle batchRateThrottle = new SleepThrottle(); - - /** - * Specifies the throttling rate in operations per second. - * - * @param hertz The throttling rate in cycles per second. - */ - public void setRate(float hertz) - { - // Pass the rate unaltered down to the base implementation, for the check method. - super.setRate(hertz); - - // Log base 10 over 2 is used here to get a feel for what power of 100 the total rate is. - // As the total rate goes up the powers of 100 the batch size goes up by powers of 100 to keep the - // throttle rate in the range 1 to 100. - int x = (int) (Math.log10(hertz) / 2); - batchSize = (int) Math.pow(100, x); - float throttleRate = hertz / batchSize; - - // Reset the call count. - callCount = 0; - - // Set the sleep throttle wrapped implementation at a rate within its abilities. - batchRateThrottle.setRate(throttleRate); - } - - /** - * Throttle calls to this method to the rate specified by the {@link #setRate(float)} method. - */ - public void throttle() - { - if ((callCount++ % batchSize) == 0) - { - batchRateThrottle.throttle(); - } - } -} diff --git a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/DurationTestDecorator.java b/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/DurationTestDecorator.java deleted file mode 100644 index e99fcce752..0000000000 --- a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/DurationTestDecorator.java +++ /dev/null @@ -1,205 +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.junit.extensions; - -import junit.framework.Test; -import junit.framework.TestResult; - -import org.apache.log4j.Logger; - -import java.util.Timer; -import java.util.TimerTask; - -/** - * A test decorator that runs a test repeatedly until a specified length of time has passed. - * - * <p/><table id="crc"><caption>CRC Card</caption> - * <tr><th> Responsibilities <th> Collaborations - * <tr><td> Repeatedly run a test for a fixed length of time. - * </table> - * - * @todo The count of the number of tests run is an important number to keep. Also num passed/error/failed is also - * important to record. What to do with these numbers? They are already logged to the test listeners. - * - * @todo The duration test runner wraps on top of size, repeat or thread wrappers, need a way for it to tell - * TKTestResult when the duration is up, so that it can terminate any repeats in progress. It should end - * as soon as possible once the test method exits. - * - * @author Rupert Smith - */ -public class DurationTestDecorator extends WrappedSuiteTestDecorator implements ShutdownHookable -{ - /** Used for logging. */ - private static final Logger log = Logger.getLogger(DurationTestDecorator.class); - - /** The test to run. */ - private Test test; - - /** The length of time to run the test for. */ - private long duration; - - /** Flag set by the shutdown hook. This decorator will not start any new tests when this is set. */ - private boolean shutdown = false; - - /** - * Creates an active test with default multiplier (1). - * - * @param test The target test. - */ - public DurationTestDecorator(WrappedSuiteTestDecorator test) - { - super(test); - this.test = test; - } - - /** - * Creates active test with default multiplier (1). - * - * @param test The target test. - * @param duration The duration in milliseconds. - */ - public DurationTestDecorator(WrappedSuiteTestDecorator test, long duration) - { - super(test); - - // log.debug("public DurationTestDecorator(Test \"" + test + "\", long " + duration + "): called"); - - this.test = test; - this.duration = duration; - } - - /** - * Runs the test repeatedly for the fixed duration. - * - * @param testResult The the results object to monitor the test results with. - */ - public void run(TestResult testResult) - { - log.debug("public void run(TestResult testResult): called"); - -// Removing the durationTimer as this addition prevents this TestDecorator being wrapped with a Scaled Test Decorator. - // This change will cause the tests to run for at least the specified duration - // If we need the test to stop much closer to the specified duration then we need to - // ensure that the solution doesn't prevent this Decorator being wrapped with other Decorators. - -// // Cast the test result to expose it as a TKTestResult if the test is running under the TKTestRunner. -// TKTestResult tkTestResult = null; -// -// if (testResult instanceof TKTestResult) -// { -// tkTestResult = (TKTestResult) testResult; -// } -// -// // If running under the TKTestRunner, set up a timer to notify the test framework when the test reaches its -// // completion time. -// Timer durationTimer = null; -// -// if (tkTestResult != null) -// { -// log.debug("Creating duration timer."); -// -// durationTimer = new Timer(); -// durationTimer.schedule(new DurationTimerTask((TKTestResult) testResult), duration); -// } - - - // Work out when the test should end. - long now = System.nanoTime(); - long end = (duration * 1000000) + now; - - // Run the test until the duration times out or the shutdown flag is set. The test method may not exit until - // interrupted in some cases, in which case the timer will do the interrupting. - while ((now < end) && !shutdown) - { - test.run(testResult); - - now = System.nanoTime(); - } - -// // Clean up any timer that was used. -// if (durationTimer != null) -// { -// log.debug("Cancelling duration timer."); -// -// durationTimer.cancel(); -// } - } - - /** - * Supplies the shutdown hook. This shutdown hook does not call {@link TKTestResult#shutdownNow()} because the - * {@link ScaledTestDecorator} already takes care of that. - * - * @return The shut down hook. - */ - public Thread getShutdownHook() - { - return new Thread(new Runnable() - { - public void run() - { - // log.debug("DurationTestDecorator::ShutdownHook: called"); - - // Set the shutdown flag so that no new tests are started. - shutdown = true; - } - }); - } - -// /** -// * DurationTimerTask is a timer task that is configured, upon expiry of its timer, to invoke -// * {@link TKTestResult#shutdownNow()}, for the test result object on which it is set. It also sets -// * the {@link DurationTestDecorator#shutdown} flag to indicate that no new tests should be run. -// * -// * <p/>The test loop implemented by DurationTestDecorator checks that the duration has not expired, on each -// * test case that it runs. However, it is possible to write test cases that never return until explicitly -// * interrupted by the test framework. This timer task exists to notify the test framework -// */ -// private class DurationTimerTask extends TimerTask -// { -// /** Used for debugging purposes. */ -// private final Logger log = Logger.getLogger(DurationTimerTask.class); -// -// /** Holds the test result for the test to which a duration limit is being applied. */ -// TKTestResult testResult; -// -// /** -// * Creates a duration limit timer which will notify the specified test result when the duration has -// * expired. -// * -// * @param testResult The test result to notify upon expiry of the test duration. -// */ -// public DurationTimerTask(TKTestResult testResult) -// { -// this.testResult = testResult; -// } -// -// /** -// * The action to be performed by this timer task. -// */ -// public void run() -// { -// log.debug("public void run(): called"); -// -// shutdown = true; -// testResult.shutdownNow(); -// } -// } -} diff --git a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/InstrumentedTest.java b/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/InstrumentedTest.java deleted file mode 100644 index 0804757dce..0000000000 --- a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/InstrumentedTest.java +++ /dev/null @@ -1,66 +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.junit.extensions; - -import junit.framework.Test; - -/** - * An InstrumentedTest is one which can supply some additional instrumentation on top of the pass/fail/error behaviour - * of normal junit tests. Tests implementing this interface must additionally supply information about how long they - * took to run and how much memory they used. - * - * <p><table id="crc"><caption>CRC Card</caption> - * <tr><th> Responsibilities - * <tr><td> Report test run time. - * <tr><td> Report test memory usage. - * </table> - * - * @author Rupert Smith - */ -public interface InstrumentedTest extends Test -{ - /** - * Reports how long the test took to run. - * - * @return The time in milliseconds that the test took to run. - */ - public long getTestTime(); - - /** - * Reports the memory usage at the start of the test. - * - * @return The memory usage at the start of the test. - */ - public long getTestStartMemory(); - - /** - * Reports the memory usage at the end of the test. - * - * @return The memory usage at the end of the test. - */ - public long getTestEndMemory(); - - /** - * Resets the instrumentation values to zero, and nulls any references to held measurements so that the memory - * can be reclaimed. - */ - public void reset(); -} diff --git a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/NullResultPrinter.java b/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/NullResultPrinter.java deleted file mode 100644 index 6727f6f152..0000000000 --- a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/NullResultPrinter.java +++ /dev/null @@ -1,92 +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.junit.extensions; - -import junit.framework.AssertionFailedError; -import junit.framework.Test; - -import junit.textui.ResultPrinter; - -import java.io.PrintStream; - -/** - * A ResultPrinter that prints nothing. This exists, in order to provide a replacement to JUnit's ResultPrinter, which - * is refered to directly by JUnit code, rather that as an abstracted TestListener. JUnit's text ui TestRunner must - * have a ResultPrinter. This provides an implementation of it that prints nothing, so that a better mechanism can - * be used for providing feedback to the console instead. - * - * <p/><table id="crc"><caption>CRC Card</caption> - * <tr><th> Responsibilities <th> Collaborations - * <tr><td> - * </table> - * - * @todo See todo in TKTestRunner about completely replacing the test ui runner. Doing things like this in order to - * extend JUnit is not nice, and there needs to be a better way to do it. Delete this class and use a listener - * instead. - * - * @author Rupert Smith - */ -public class NullResultPrinter extends ResultPrinter -{ - /** - * Builds a fake ResultPrinter that prints nothing. - * - * @param writer The writer to send output to. - */ - public NullResultPrinter(PrintStream writer) - { - super(writer); - } - - /** - * Does nothing. - * - * @param test Ignored. - * @param t Ignored. - */ - public void addError(Test test, Throwable t) - { } - - /** - * Does nothing. - * - * @param test Ignored. - * @param t Ignored. - */ - public void addFailure(Test test, AssertionFailedError t) - { } - - /** - * Does nothing. - * - * @param test Ignored. - */ - public void endTest(Test test) - { } - - /** - * Does nothing. - * - * @param test Ignored. - */ - public void startTest(Test test) - { } -} diff --git a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/ParameterVariationTestDecorator.java b/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/ParameterVariationTestDecorator.java deleted file mode 100644 index 7da4667928..0000000000 --- a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/ParameterVariationTestDecorator.java +++ /dev/null @@ -1,175 +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.junit.extensions; - -import junit.framework.TestResult; - -import org.apache.log4j.Logger; - -import org.apache.qpid.junit.extensions.util.MathUtils; - -/** - * ParameterVariationTestDecorator is a test decorator that runs a test repeatedly under all permutations of its - * test parameters. - * - * a set of integer parameters and a repeat count are specified, then each test is run for the repeat count at each - * integer parameter. - * - * <p><table id="crc"><caption>CRC Card</caption> - * <tr><th> Responsibilities <th> Collaborations - * <tr><td> Repeat a test for each of a set of integer parameters. <td> {@link org.apache.qpid.junit.extensions.TKTestResult} - * <tr><td> Repeat a test multiple times. - * <tr><td> - * </table> - * - * @author Rupert Smith - */ -public class ParameterVariationTestDecorator extends WrappedSuiteTestDecorator -{ - /** Used for logging. */ - private static final Logger log = Logger.getLogger(ParameterVariationTestDecorator.class); - - /** The int size parameters to run the test with. */ - private int[] params; - - /** The number of times the whole test should be repeated. */ - private int repeat; - - /** - * Creates an asymptotic test decorator that wraps a test with repeats and a set of integer 'size' paramters - * to call the test with. - * - * @param test The test to wrap. - * @param params The integer 'size' parameters. - * @param repeat The number of times to repeat the test. - */ - public ParameterVariationTestDecorator(WrappedSuiteTestDecorator test, int[] params, int repeat) - { - super(test); - - log.debug("public AsymptoticTestDecorator(Test \"" + test + "\", int[] " - + ((params == null) ? null : MathUtils.printArray(params)) + ", int " + repeat + "): called"); - - this.params = params; - this.repeat = repeat; - } - - /** - * Creates a new AsymptoticTestDecorator object. - * - * @param test The test to decorate. - * @param start The starting asymptotic integer parameter value. - * @param end The ending asymptotic integer parameter value. - * @param step The increment size to move from the start to end values by. - * @param repeat The number of times to repeat the test at each step of the cycle. - */ - public ParameterVariationTestDecorator(WrappedSuiteTestDecorator test, int start, int end, int step, int repeat) - { - super(test); - - if (start < 0) - { - throw new IllegalArgumentException("Start must be >= 0"); - } - - if (end < start) - { - throw new IllegalArgumentException("End must be >= start"); - } - - if (step < 1) - { - throw new IllegalArgumentException("Step must be >= 1"); - } - - if (repeat < 1) - { - throw new IllegalArgumentException("Repeat must be >= 1"); - } - - // Generate the sequence. - params = new int[((end - start) / step) + 1]; - int i = 0; - for (int n = start; n <= end; n += step) - { - params[i++] = n; - } - - this.repeat = repeat; - } - - /** - * Runs the test repeatedly for each value of the int parameter specified and for the correct number of test - * repeats. - * - * @param result The test result object that the tests will indicate their results to. This is also used - * to pass the int parameter from this class to the decorated test class. - */ - public void run(TestResult result) - { - log.debug("public void run(TestResult result): called"); - - if (!(result instanceof TKTestResult)) - { - throw new IllegalArgumentException("AsymptoticTestDecorator only works with TKTestResult"); - } - - // Cast the test result into a TKTestResult to place the current parameter into. - TKTestResult tkResult = (TKTestResult) result; - - log.debug("params = " + ((params == null) ? null : MathUtils.printArray(params))); - log.debug("repeat = " + repeat); - - if(params != null) - { - for (int n : params) - { - for (int j = 0; j < repeat; j++) - { - log.debug("n = " + n); - - // Set the integer parameter in the TKTestResult to be passed to the tests. - tkResult.setN(n); - - if (tkResult.shouldStop()) - { - log.debug("tkResult.shouldStop = " + true); - - break; - } - - log.debug("Calling super#run"); - super.run(tkResult); - } - } - } - } - - /** - * Prints out the name of this test with the string "(parameterized)" appended onto it for debugging purposes. - * - * @return The name of this test with the string "(parameterized)" appended onto it. - */ - public String toString() - { - return super.toString() + "(parameterized)"; - } -} diff --git a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/ScaledTestDecorator.java b/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/ScaledTestDecorator.java deleted file mode 100644 index 93e2a3c855..0000000000 --- a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/ScaledTestDecorator.java +++ /dev/null @@ -1,391 +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.junit.extensions; - -import junit.framework.Test; -import junit.framework.TestResult; - -import java.util.concurrent.BrokenBarrierException; -import java.util.concurrent.CyclicBarrier; - -/** - * A test decorator that runs a test many times simultaneously in many threads. - * - * <p><table id="crc"><caption>CRC Card</caption> - * <tr><th> Responsibilities <th> Collaborations - * <tr><td> Clone a test run into many threads and run them simultaneously. - * <tr><td> Inform the test results of the start and end of each concurrent test batch. <td> {@link TKTestResult} - * <tr><td> Inform the test results of the concurrency level. <td> {@link TKTestResult} - * </table> - * - * @author Rupert Smith - */ -public class ScaledTestDecorator extends WrappedSuiteTestDecorator implements ShutdownHookable // TestDecorator -{ - /** Used for logging. */ - // private static final Logger log = Logger.getLogger(ScaledTestDecorator.class); - - /** Determines how long to wait for tests to cleanly exit on shutdown. */ - private static final long SHUTDOWN_PAUSE = 3000; - - /** - * The stress levels or numbers of simultaneous threads to run the test in. The test is repeated at each of - * the concurrency levels specified here. Defaults to 1 thread. - */ - private int[] threads = new int[] { 1 }; - - /** Used to hold the number of tests currently being run in parallel. */ - private int concurrencyLevel; - - /** The test to run. */ - private WrappedSuiteTestDecorator test; - - /** - * Used to hold the current {@link TKTestResult} for the tests currently being run. This is made available so that - * the shutdown hook can ask it to cleanly end the current tests in the event of a shutdown. - */ - private TKTestResult currentTestResult; - - /** Flag set by the shutdown hook. This decorator will not start any new tests when this is set. */ - private boolean shutdown = false; - - /** - * Creates an active test with default multiplier (1). - * - * @param test The target test. - */ - public ScaledTestDecorator(WrappedSuiteTestDecorator test) - { - super(test); - this.test = test; - } - - /** - * Creates a concurrently scaled test with the specified number of threads. - * - * @param test The target test. - * @param numThreads The stress level. - */ - public ScaledTestDecorator(WrappedSuiteTestDecorator test, int numThreads) - { - this(test, new int[] { numThreads }); - } - - /** - * Creates a concurrently scaled test with the specified thread levels, the test is repeated at each level. - * - * @param test The target test. - * @param threads The concurrency levels. - */ - public ScaledTestDecorator(WrappedSuiteTestDecorator test, int[] threads) - { - super(test); - - /*log.debug("public ScaledTestDecorator(WrappedSuiteTestDecorator test = \"" + test + "\", int[] threads = " - + MathUtils.printArray(threads) + "): called");*/ - - this.test = test; - this.threads = threads; - } - - /** - * Runs the test simultaneously in at the specified concurrency levels. - * - * @param testResult The results object to monitor the test results with. - */ - public void run(TestResult testResult) - { - // log.debug("public void run(TestResult testResult = " + testResult + "): called"); - - // Loop through all of the specified concurrent levels for the test, provided shutdown has not been called. - for (int i = 0; (i < threads.length) && !shutdown; i++) - { - // Get the number of threads for this run. - int numThreads = threads[i]; - - // Create test thread handlers for all the threads. - TestThreadHandler[] threadHandlers = new TestThreadHandler[numThreads]; - - // Create a cyclic barrier for the test threads to synch their setups and teardowns on. - CyclicBarrier barrier = new CyclicBarrier(numThreads); - - // Set up the test thread handlers to output results to the same test results object. - for (int j = 0; j < numThreads; j++) - { - threadHandlers[j] = new TestThreadHandler(testResult, test, barrier); - } - - // Ensure the concurrency level statistic is set up correctly. - concurrencyLevel = numThreads; - - // Begin batch. - if (testResult instanceof TKTestResult) - { - TKTestResult tkResult = (TKTestResult) testResult; - // tkResult.notifyStartBatch(); - tkResult.setConcurrencyLevel(numThreads); - - // Set the test result for the currently running tests, so that the shutdown hook can call it if necessary. - currentTestResult = tkResult; - } - - // Run all the tests and wait for them all to finish. - executeAndWaitForRunnables(threadHandlers); - - // Clear the test result for the currently running tests. - currentTestResult = null; - - // End batch. - if (testResult instanceof TKTestResult) - { - TKTestResult tkResult = (TKTestResult) testResult; - tkResult.notifyEndBatch(); - } - - // Clear up all the test threads, they hold references to their associated TestResult object and Test object, - // which may prevent them from being garbage collected as the TestResult and Test objects are long lived. - for (int j = 0; j < numThreads; j++) - { - threadHandlers[j].testResult = null; - threadHandlers[j].test = null; - threadHandlers[j] = null; - } - } - } - - /** - * Reports the number of tests that the scaled decorator is currently running concurrently. - * - * @return The number of tests that the scaled decorator is currently running concurrently. - */ - public int getConcurrencyLevel() - { - return concurrencyLevel; - } - - /** - * Executes all of the specifed runnable using the thread pool and waits for them all to complete. - * - * @param runnables The set of runnables to execute concurrently. - */ - private void executeAndWaitForRunnables(Runnable[] runnables) - { - int numThreads = runnables.length; - - // Used to keep track of the test threads in order to know when they have all completed. - Thread[] threads = new Thread[numThreads]; - - // Create all the test threads. - for (int j = 0; j < numThreads; j++) - { - threads[j] = new Thread(runnables[j]); - } - - // Start all the test threads. - for (int j = 0; j < numThreads; j++) - { - threads[j].start(); - } - - // Wait for all the test threads to complete. - for (int j = 0; j < numThreads; j++) - { - try - { - threads[j].join(); - } - catch (InterruptedException e) - { - // Restore the interrupted state of the thread. - Thread.currentThread().interrupt(); - } - } - } - - /** - * Supplies the shut-down hook. - * - * @return The shut-down hook. - */ - public Thread getShutdownHook() - { - return new Thread(new Runnable() - { - public void run() - { - // log.debug("ScaledTestDecorator::ShutdownHook: called"); - - // Set the shutdown flag so that no new tests are started. - shutdown = true; - - // Check if tests are currently running, and ask them to complete as soon as possible. Allow - // a short pause for this to happen. - TKTestResult testResult = currentTestResult; - - if (testResult != null) - { - // log.debug("There is a test result currently running tests, asking it to terminate ASAP."); - testResult.shutdownNow(); - - try - { - Thread.sleep(SHUTDOWN_PAUSE); - } - catch (InterruptedException e) - { - // Restore the interrupted state of the thread. - Thread.currentThread().interrupt(); - } - } - } - }); - } - - /** - * Prints a string summarizing this test decorator, mainly for debugging purposes. - * - * @return String representation for debugging purposes. - */ - public String toString() - { - return "ScaledTestDecorator: [ test = " + test + ", concurrencyLevel = " + concurrencyLevel + " ]"; - } - - /** - * TestThreadHandler is a runnable used to execute a test in. This is static to avoid implicit 'this' reference to - * the longer lived ScaledTestDecorator class. The scaled test decorator may execute many repeats but creates fresh - * handlers for each one. It re-uses the threads in a pool but does not re-use these handlers. - */ - private static class TestThreadHandler implements Runnable - { - /** The test result object for the test to be run with. */ - TestResult testResult; - - /** The test to run. */ - WrappedSuiteTestDecorator test; - - /** Holds the cyclic barrier to synchronize on the end of the setups and before the tear downs. */ - CyclicBarrier barrier; - - /** - * Creates a new TestThreadHandler object. - * - * @param testResult The test result object for the test to be run with. - * @param test The test to run in a sperate thread. - * @param barrier The barrier implementation to use to synchronize per-thread setup completion and test - * completion before moving on through the setup, test, teardown phases. The barrier should - * be configured for the number of test threads. - */ - TestThreadHandler(TestResult testResult, WrappedSuiteTestDecorator test, CyclicBarrier barrier) - { - this.testResult = testResult; - this.test = test; - this.barrier = barrier; - } - - /** - * Runs the test associated with this pool. - */ - public void run() - { - try - { - // Call setup on all underlying tests in the suite that are thread aware. - for (Test childTest : test.getAllUnderlyingTests()) - { - // Check that the test is concurrency aware, so provides a setup method to call. - if (childTest instanceof TestThreadAware) - { - // Call the tests per thread setup. - TestThreadAware setupTest = (TestThreadAware) childTest; - setupTest.threadSetUp(); - } - } - - // Wait until all test threads have completed their setups. - barrier.await(); - - - // Call setup on all underlying tests in the suite that are thread aware. - for (Test childTest : test.getAllUnderlyingTests()) - { - // Check that the test is concurrency aware, so provides a setup method to call. - if (childTest instanceof TestThreadAware) - { - // Call the tests post thread setup. - TestThreadAware setupTest = (TestThreadAware) childTest; - setupTest.postThreadSetUp(); - } - } - - // Wait until all test threads have completed their prefill. - barrier.await(); - - // Start timing the test batch, only after thread setups have completed. - if (testResult instanceof TKTestResult) - { - ((TKTestResult) testResult).notifyStartBatch(); - } - - // Run the tests. - test.run(testResult); - - // Wait unitl all test threads have completed their tests. - barrier.await(); - - // Call tear down on all underlying tests in the suite that are thread aware. - for (Test childTest : test.getAllUnderlyingTests()) - { - // Check that the test is concurrency aware, so provides a teardown method to call. - if (childTest instanceof TestThreadAware) - { - // Call the tests per thread tear down. - TestThreadAware setupTest = (TestThreadAware) childTest; - setupTest.threadTearDown(); - } - } - } - catch (InterruptedException e) - { - // Restore the interrupted state of the thread. - Thread.currentThread().interrupt(); - } - catch (BrokenBarrierException e) - { - // Set the interrupted state on the thread. The BrokenBarrierException may be caused where one thread - // waiting for the barrier is interrupted, causing the remaining threads correctly waiting on the - // barrier to fail. This condition is expected during test interruptions, and the response to it is to - // interrupt all the other threads running in the same scaled test. - Thread.currentThread().interrupt(); - } - } - - /** - * Prints the name of the test for debugging purposes. - * - * @return The name of the test. - */ - public String toString() - { - return "ScaledTestDecorator: [test = \"" + test + "\"]"; - } - } -} diff --git a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/SetupTaskAware.java b/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/SetupTaskAware.java deleted file mode 100644 index e462145d7d..0000000000 --- a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/SetupTaskAware.java +++ /dev/null @@ -1,55 +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.junit.extensions; - -/** - * SetupTaskAware is an interface that tests that can accept injectable setup tasks may implement. Typically this - * is used by configurable decorator stack to inject setup tasks into tests. It is then up to the test case to run - * the tasks in the setup or threadSetup methods as it chooses. - * - * <p/>Set up tasks should be chained so that they are executed in the order that they are applied. Tear down tasks - * should be chained so that they are executed in the reverse order to which they are applied. That way the set up and - * tear down tasks act as a 'task' stack, with nested setups and tear downs. - * - * <p/><table id="crc"><caption>CRC Card</caption> - * <tr><th> Responsibilities. - * <tr><td> Handle injection of set up tasks. - * <tr><td> Handle injection of tear down tasks. - * </table> - * - * @author Rupert Smith - */ -public interface SetupTaskAware -{ - /** - * Adds the specified task to the tests setup. - * - * @param task The task to add to the tests setup. - */ - public void chainSetupTask(Runnable task); - - /** - * Adds the specified task to the tests tear down. - * - * @param task The task to add to the tests tear down. - */ - public void chainTearDownTask(Runnable task); -} diff --git a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/SetupTaskHandler.java b/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/SetupTaskHandler.java deleted file mode 100644 index b91ce41ad3..0000000000 --- a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/SetupTaskHandler.java +++ /dev/null @@ -1,92 +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.junit.extensions; - -import org.apache.qpid.junit.extensions.util.StackQueue; - -import java.util.LinkedList; -import java.util.Queue; - -/** - * SetupTaskHandler implements a task stack. It can be used, by delegation, as a base implementation for tests that want - * to have configurable setup/teardown task stacks. Typically it is up to the test implementation to decide whether the - * stack is executed in the setup/teardown methods or in the threadSetup/threadTeaddown methods. - * - * <p/><table id="crc"><caption>CRC Card</caption> - * <tr><th> Responsibilities <th> Collaborations - * <tr><td> Handle injection of set up tasks. - * <tr><td> Handle injection of tear down tasks. - * <tr><td> Run set up tasks in chain order. - * <tr><td> Run tear down tasks in reverse chain order. - * </table> - * - * @author Rupert Smith - */ -public class SetupTaskHandler implements SetupTaskAware -{ - /** Holds the set up tasks. */ - Queue<Runnable> setups = new LinkedList<Runnable>(); - - /** Holds the tear down tasks. */ - Queue<Runnable> teardowns = new StackQueue<Runnable>(); - - /** - * Adds the specified task to the tests setup. - * - * @param task The task to add to the tests setup. - */ - public void chainSetupTask(Runnable task) - { - setups.offer(task); - } - - /** - * Adds the specified task to the tests tear down. - * - * @param task The task to add to the tests tear down. - */ - public void chainTearDownTask(Runnable task) - { - teardowns.offer(task); - } - - /** - * Runs the set up tasks in the order that they way chained. - */ - public void runSetupTasks() - { - while (!setups.isEmpty()) - { - setups.remove().run(); - } - } - - /** - * Runs the tear down tasks in the reverse of the order in which they were chained. - */ - public void runTearDownTasks() - { - while (!teardowns.isEmpty()) - { - teardowns.remove().run(); - } - } -} diff --git a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/ShutdownHookable.java b/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/ShutdownHookable.java deleted file mode 100644 index dc6aa3c291..0000000000 --- a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/ShutdownHookable.java +++ /dev/null @@ -1,42 +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.junit.extensions; - -/** - * Defines an interface that classes which supply shutdown hooks implement. Code that creates these classes can check - * if they supply a shutdown hook and register these hooks when the obejct are created. - * - * <p><table id="crc"><caption>CRC Card</caption> - * <tr><th> Responsibilities - * <tr><td> Supply a shutdown hook. - * </table> - * - * @author Rupert Smith - */ -public interface ShutdownHookable -{ - /** - * Supplies the shutdown hook. - * - * @return The shut down hook. - */ - public Thread getShutdownHook(); -} diff --git a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/SleepThrottle.java b/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/SleepThrottle.java deleted file mode 100644 index 2dc4c0e272..0000000000 --- a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/SleepThrottle.java +++ /dev/null @@ -1,81 +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.junit.extensions; - -/** - * SleepThrottle is a Throttle implementation that generates short pauses using the thread sleep methods. As the pauses - * get shorter, this technique gets more innacurate. In practice, around 100 Hz is the cap rate for accuracy. - * - * <p/><table id="crc"><caption>CRC Card</caption> - * <tr><th> Responsibilities <th> Collaborations - * <tr><td> Accept throttling rate in operations per second. - * <tr><td> Inject short pauses to fill out processing cycles to a specified rate. - * <tr><td> Check against a throttle speed without waiting. - * </table> - * - * @author Rupert Smith - */ -public class SleepThrottle extends BaseThrottle implements Throttle -{ - /** Holds the time of the last call to the throttle method in nano seconds. */ - private long lastTimeNanos; - - /** - * This method can only be called at the rate set by the {@link #setRate} method, if it is called faster than this - * it will inject short pauses to restrict the call rate to that rate. - */ - public void throttle() - { - // Get the current time in nanos. - long currentTimeNanos = System.nanoTime(); - - // Don't introduce any pause on the first call. - if (!firstCall) - { - // Check if there is any time left in the cycle since the last call to this method and introduce a short pause - // to fill that time if there is. - long remainingTimeNanos = cycleTimeNanos - (currentTimeNanos - lastTimeNanos); - - if (remainingTimeNanos > 0) - { - long milliPause = remainingTimeNanos / 1000000; - int nanoPause = (int) (remainingTimeNanos % 1000000); - - try - { - Thread.sleep(milliPause, nanoPause); - } - catch (InterruptedException e) - { - // Restore the interrupted thread, in-case the caller is checking for it. - Thread.currentThread().interrupt(); - } - } - } - else - { - firstCall = false; - } - - // Update the last time stamp. - lastTimeNanos = System.nanoTime(); - } -} diff --git a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/TKTestResult.java b/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/TKTestResult.java deleted file mode 100644 index 5ce56a690e..0000000000 --- a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/TKTestResult.java +++ /dev/null @@ -1,654 +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.junit.extensions; - -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestResult; - -import org.apache.log4j.Logger; - -import org.apache.qpid.junit.extensions.listeners.TKTestListener; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Properties; - -/** - * TKTestResult extends TestResult in order to calculate test timings, to pass the variable integer parameter for - * parameterized test cases to those test cases and to introduce an optional delay before test starts. Interested - * {@link TKTestListener}s may be attached to this and will be informed of all relevant test statistics. - * - * <p><table id="crc"><caption>CRC Card</caption> - * <tr><th> Responsibilities <th> Collaborations - * <tr><td> Calculate test timings. - * <tr><td> Inform timing listeners of timings. - * <tr><td> Inform memory listeners of memory readings. - * <tr><td> Inform parameters listeners of parameters. - * <tr><td> Pass the integer parameter to parameterized test cases. - * <tr><td> Provide verbose test information on test start and end. - * </table> - * - * @todo Move the verbose test information on test start/end into a test listener instead. It confuses the intention - * of this class. Could also move the delay into a listener but that seems less appropriate as it would be a - * side-effecting listener. Delay and timing calculation are fundamental enough to this class. - * - * @todo The need for this class to act as a place-holder for the integer parameter for parameterized test cases is - * because this behaviour has been factored out into a test decorator class, see {@link AsymptoticTestDecorator}. - * The {@link AsymptoticTestDecorator#run} method takes a TestResult as an argument and cannot easily get to the - * {@link AsymptoticTestCase} class other than through this class. The option of using this class as a place hold - * for this value was chosen. Alternatively this class could provide a method for decorators to access the - * underlying test case through and then leave the setting of this parameter to the decorator which is a more - * natural home for this behaviour. It would also provide a more general framework for decorators. - * - * @todo The memory usage may need to be moved in closer to the test method invocation so that as little code as possible - * exists between it and the test or the results may be obscured. In fact it certainly does as the teardown method - * is getting called first. Wouldn't be a bad idea to move the timing code in closer too. - * - * @todo Get rid of the delay logic. Will be replaced by throttle control. - * - * @author Rupert Smith - */ -public class TKTestResult extends TestResult -{ - /** Used for logging. */ - private static final Logger log = Logger.getLogger(TKTestResult.class); - - /** The delay between two tests. */ - private int delay = 0; - - /** - * This flag indicates that the #completeTest method of the timing controller has been called. Once this has - * been called once, the end test event for the whole test method should be ignored because tests have taken - * charge of outputing their own timings. - */ - private boolean completeTestUsed = false; - - /** - * Thread locals to hold test start time for non-instrumented tests. (Instrumented tests hold their own - * measurement data). - */ - // private Hashtable threadStartTimeMap = new Hashtable(); - private ThreadLocal<ThreadLocalSettings> threadLocals = new ThreadLocal<ThreadLocalSettings>(); - - /** Used to hold the current integer parameter to pass to parameterized tests. This defaults to 1. */ - private int n = 1; - - /** The timing listeners. */ - private Collection<TKTestListener> tkListeners; - - /** The test case name. */ - private String testCaseName; - - /** Used to hold the current concurrency level, set by the {@link ScaledTestDecorator}. */ - private int concurrencyLevel = 1; - - /** Flag used to indicate that this test result should attempt to complete its current tests as soon as possible. */ - private boolean shutdownNow = false; - - /** Holds the parametes that the test is run with. */ - private Properties testParameters; - - /** - * Creates a new TKTestResult object. - * - * @param delay A delay in milliseconds to introduce before every test start. - * @param testCaseName The name of the test case that this is the TestResult object for. - */ - public TKTestResult(int delay, String testCaseName) - { - super(); - - /*log.debug("public TKTestResult(PrintStream writer, int " + delay + ", boolean " + verbose + ", String " - + testCaseName + "): called");*/ - - // Keep all the parameters that this is created with. - this.delay = delay; - this.testCaseName = testCaseName; - } - - /** - * Callback method use to inform this test result that a test will be started. Waits for the configured delay time - * if one has been set, starts the timer, then delegates to the super class implementation. - * - * @param test The test to be started. - */ - public void startTest(Test test) - { - // log.debug("public void startTest(Test test): called"); - - // If a delay time has been specified then wait for that length of time. - if (this.delay > 0) - { - try - { - Thread.sleep(delay); - } - catch (InterruptedException e) - { - // Ignore, but restore the interrupted flag. - Thread.currentThread().interrupt(); - } - } - - // Create the thread local settings for the test. - ThreadLocalSettings threadLocalSettings = new ThreadLocalSettings(); - threadLocals.set(threadLocalSettings); - - // Record the test start time against this thread for calculating the test timing. (Consider using ThreadLocal - // instead?) - Long startTime = System.nanoTime(); - threadLocalSettings.startTime = startTime; - // log.debug("startTime = " + startTime); - - // Check if the test is timing controller aware, in which case set up a new timing controller and hold it - // in the thread local settings. - if (test instanceof TimingControllerAware) - { - TimingControllerAware controllerAware = (TimingControllerAware) test; - TimingControllerImpl controller = - new TimingControllerImpl(this, test, startTime, Thread.currentThread().getId()); - controllerAware.setTimingController(controller); - - threadLocalSettings.timingController = controller; - } - - // Delegate to the super method to notify test event listeners. - super.startTest(test); - } - - /** - * Callback method use to inform this result that a test was completed. This calculates how long the test took - * to run, then delegates to the super class implementation. - * - * @param test The test that has ended. - */ - public void endTest(Test test) - { - // log.debug("public void endTest(Test test): called"); - - long runTime = 0; - - // Recover the thread local settings. - ThreadLocalSettings threadLocalSettings = threadLocals.get(); - - // Check if the test is an instrumented test and get the timing information from the instrumentation as this - // will be more accurate. - if (test instanceof InstrumentedTest) - { - InstrumentedTest iTest = (InstrumentedTest) test; - - // Calculate the test run time. - runTime = iTest.getTestTime(); - // log.debug("runTime = " + runTime); - - // Calculate the test memory usage. - long startMem = iTest.getTestStartMemory(); - long endMem = iTest.getTestEndMemory(); - - // log.debug("startMem = " + startMem); - // log.debug("endMem = " + endMem); - - // Inform any memory listeners of the test memory. - if (tkListeners != null) - { - for (TKTestListener memoryListener : tkListeners) - { - memoryListener.memoryUsed(test, startMem, endMem, null); - } - } - } - else - { - // Calculate the test run time. - long endTime = System.nanoTime(); - Long startTime = threadLocalSettings.startTime; - runTime = endTime - startTime; - // log.debug("runTime = " + runTime); - - threadLocals.remove(); - } - - // Output end test stats. This is only done when the tests have not used the timing controller to output - // mutiple timings. - if (!completeTestUsed) - { - // Check if the test is an asymptotic test case and get its int parameter if so. - if (test instanceof AsymptoticTestCase) - { - AsymptoticTestCase pTest = (AsymptoticTestCase) test; - - // Set the parameter. - int paramValue = pTest.getN(); - - // Inform any parameter listeners of the test parameter. - if (tkListeners != null) - { - for (TKTestListener parameterListener : tkListeners) - { - parameterListener.parameterValue(test, paramValue, null); - } - } - } - - // Inform any timing listeners of the test timing and concurrency level. - if (tkListeners != null) - { - for (TKTestListener tkListener : tkListeners) - { - TKTestListener next = tkListener; - - next.timing(test, runTime, null); - next.concurrencyLevel(test, concurrencyLevel, null); - } - } - - // Call the super method to notify test event listeners of the end event. - super.endTest(test); - } - } - - /** - * Gets the integer parameter to pass to parameterized test cases. - * - * @return The value of the integer parameter. - */ - public int getN() - { - return n; - } - - /** - * Sets the integer parameter to pass to parameterized test cases. - * - * @param n The new value of the integer parameter. - */ - public void setN(int n) - { - // log.debug("public void setN(int " + n + "): called"); - - this.n = n; - } - - /** - * Adds a timing listener to pass all timing events to. - * - * @param listener The timing listener to register. - */ - public void addTKTestListener(TKTestListener listener) - { - // Create the collection to hold the timing listeners if it does not already exist. - if (tkListeners == null) - { - tkListeners = new ArrayList<TKTestListener>(); - } - - // Keep the new timing listener. - tkListeners.add(listener); - } - - /** - * Called by the test runner to notify this that a new test batch is being begun. This method forwards this - * notification to all batch listeners. - */ - public void notifyStartBatch() - { - if (tkListeners != null) - { - for (TKTestListener batchListener : tkListeners) - { - batchListener.startBatch(); - } - } - } - - /** - * Called by the test runner to notify this that the current test batch has been ended. This method forwards this - * notification to all batch listener. - */ - public void notifyEndBatch() - { - // log.debug("public void notifyEndBatch(): called"); - - if (tkListeners != null) - { - for (TKTestListener batchListener : tkListeners) - { - batchListener.endBatch(testParameters); - } - } - } - - /** - * Called by the test runner to notify this of the properties that the test is using. - * - * @param properties The tests set/read properties. - */ - public void notifyTestProperties(Properties properties) - { - // log.debug("public void notifyTestProperties(Properties properties): called"); - - this.testParameters = properties; - - /* - if (tkListeners != null) - { - for (TKTestListener batchListener : tkListeners) - { - batchListener.properties(properties); - } - } - */ - } - - /** - * Intercepts the execution of a test case to pass the variable integer parameter to a test if it is a parameterized - * test case. - * - * @param test The test to run. - */ - protected void run(final TestCase test) - { - // log.debug("protected void run(final TestCase test): called"); - - // Check if the test case is a parameterized test and set its integer parameter if so. - if (test instanceof AsymptoticTestCase) - { - AsymptoticTestCase pTest = (AsymptoticTestCase) test; - - // Set up the integer parameter. - pTest.setN(n); - } - - // Delegate to the super method to run the test. - super.run(test); - } - - /** - * Helper method that generats a String of verbose information about a test. This includes the thread name, test - * class name and test method name. - * - * @param test The test to generate the info string for. - * - * @return Returns a string with the thread name, test class name and test method name. - */ - protected String getTestInfo(Test test) - { - // log.debug("protected String getTestInfo(Test test): called"); - - return "[" + Thread.currentThread().getName() + "@" + test.getClass().getName() + "." - + ((test instanceof TestCase) ? ((TestCase) test).getName() : "") + "]"; - } - - /** - * Sets the concurrency level to pass into the test result. - * - * @param concurrencyLevel The concurrency level the tests are running out. - */ - public void setConcurrencyLevel(int concurrencyLevel) - { - this.concurrencyLevel = concurrencyLevel; - } - - /** - * Tells this test result that it should stop running tests. Once this method has been called this test result - * will not start any new tests, and any tests that use the timing controller will be passed interrupted exceptions, - * to indicate that they should end immediately. Usually the caller of this method will introduce a short wait - * to allow an opporunity for running tests to complete, before forcing the shutdown of the JVM. - */ - public void shutdownNow() - { - log.debug("public void shutdownNow(): called on " + this); - - shutdownNow = true; - } - - /** - * Prints a string summary of this class, mainly for debugging purposes. - * - * @return A string summary of this class, mainly for debugging purposes. - */ - public String toString() - { - return "TKTestResult@" + Integer.toString(hashCode(), 16) + ": [ testCaseName = " + testCaseName + ", n = " + n - + ", tkListeners = " + tkListeners + " ]"; - } - - /** - * Holds things that need to be kept on a per thread basis for each test invocation, such as the test start - * time and its timing controller. - */ - private static class ThreadLocalSettings - { - /** Holds the test start time. */ - Long startTime; - - /** Holds the test threads timing controller. */ - TimingController timingController; - } - - /** - * Provides an implementation of the {@link TimingController} interface that timing aware tests can use to call - * back to reset timers, and register additional test timings. - */ - private static class TimingControllerImpl implements TimingController - { - /** Holds an explicit reference to the test TKTestResult that created this. */ - TKTestResult testResult; - - /** Holds a reference to the test that this is the timing controller for. */ - Test test; - - /** Holds the start time for this timing controller. This gets reset to now on each completed test. */ - long startTime; - - /** - * Holds the thread id of the thread that started the test, so that this controller may be called from other - * threads but still identify itself correctly to {@link TKTestListener}s as being associated with the - * thread that called the test method. - */ - long threadId; - - /** - * Creates a timing controller on a specified TKTestResult and a test. - * - * @param testResult The TKTestResult that this controller interacts with. - * @param test The test that this is the timing controller for. - * @param startTime The test start time in nanoseconds. - * @param threadId The thread id of the thread that is calling the test method. - */ - public TimingControllerImpl(TKTestResult testResult, Test test, long startTime, long threadId) - { - this.testResult = testResult; - this.test = test; - this.startTime = startTime; - this.threadId = threadId; - } - - /** - * Gets the timing controller associated with the current test thread. Tests that use timing controller should - * always get the timing controller from this method in the same thread that called the setUp, tearDown or test - * method. The controller returned by this method may be called from any thread because it remembers the thread - * id of the original test thread. - * - * @return The timing controller associated with the current test thread. - */ - public TimingController getControllerForCurrentThread() - { - // Recover the thread local settings and extract the timing controller from them. - ThreadLocalSettings threadLocalSettings = testResult.threadLocals.get(); - - return threadLocalSettings.timingController; - } - - /** - * Not implemented yet. - * - * @return Nothing. - */ - public long suspend() - { - throw new RuntimeException("Method not implemented."); - } - - /** - * Not implemented yet. - * - * @return Nothing. - */ - public long resume() - { - throw new RuntimeException("Method not implemented."); - } - - /** - * Resets the timer start time to now. - * - * @return The new value of the start time. - */ - public long restart() - { - startTime = System.nanoTime(); - - return startTime; - } - - /** - * Register an additional pass/fail for the current test. The test result is assumed to apply to a test of - * 'size' parmeter 1. Use the {@link #completeTest(boolean, int)} method to register timings with parameters. - * - * @param testPassed Whether or not this timing is for a test pass or fail. - * - * @throws InterruptedException If the test runner decides that testing should stop it throws this exception to - * indicate to the test method that it should stop immediately. - */ - public void completeTest(boolean testPassed) throws InterruptedException - { - completeTest(testPassed, 1); - } - - /** - * Register an additional pass/fail for the current test. The test result is applies to a test of the specified - * 'size' parmeter. - * - * @param testPassed Whether or not this timing is for a test pass or fail. - * @param param The test parameter size for parameterized tests. - * - * @throws InterruptedException If the test runner decides that testing should stop it throws this exception to - * indicate to the test method that it should stop immediately. - */ - public void completeTest(boolean testPassed, int param) throws InterruptedException - { - completeTest(testPassed, param, null, null); - } - - /** - * Register an additional pass/fail for the current test. The test result is applies to a test of the specified - * 'size' parmeter and allows the caller to sepecify the timing to log. - * - * @param testPassed Whether or not this timing is for a test pass or fail. - * @param param The test parameter size for parameterized tests. - * @param timeNanos The time in nano-seconds to log the test result with. - * - * A null value for timeNanos is a request to this method that it should - * calculate the time for the given test run. - * - * @throws InterruptedException If the test runner decides that testing should stop it throws this exception to - * indicate to the test method that it should stop immediately. - */ - public void completeTest(boolean testPassed, int param, Long timeNanos) throws InterruptedException - { - completeTest(testPassed, param, timeNanos, null); - } - - /** - * Register an additional pass/fail for the current test. The test result is applies to a test of the specified - * 'size' parmeter and allows the caller to sepecify the timing to log. - * - * @param testPassed Whether or not this timing is for a test pass or fail. - * @param param The test parameter size for parameterized tests. - * @param timeNanos The time in nano seconds to log the test result with. - * - * A null value for timeNanos is a request to this method that it should - * calculate the time for the given test run. - * A null value for timeNanos2 means this test does not provide a second - * timing value so a '-' is printed in the log. - * - * - * @throws InterruptedException If the test runner decides that testing should stop it throws this exception to - * indicate to the test method that it should stop immediately. - */ - public void completeTest(boolean testPassed, int param, Long timeNanos, Long time2Nanos) throws InterruptedException - { - log.debug("public void completeTest(boolean testPassed, int param, long timeNanos): called"); - log.debug("testResult = " + testResult); - - /*log.debug("public long completeTest(boolean testPassed = " + testPassed + ", int param = " + param - + "): called");*/ - - // Calculate the test run time. - long endTime = System.nanoTime(); - long runTime = endTime - startTime; - startTime = endTime; - - // - if (timeNanos != null) - { - runTime = timeNanos; - } - - // Tell the test result that completeTest has been used, so to not register end test events for the whole - // test method. - testResult.completeTestUsed = true; - - // Inform any timing listeners of the test timings and parameters and send an end test notification using - // the thread id of the thread that started the test. - if (testResult.tkListeners != null) - { - for (TKTestListener listener : testResult.tkListeners) - { - listener.reset(test, threadId); - listener.timing(test, runTime, threadId); - listener.timing2(test, time2Nanos, threadId); - listener.parameterValue(test, param, threadId); - listener.concurrencyLevel(test, testResult.concurrencyLevel, threadId); - - if (!testPassed) - { - listener.addFailure(test, null, threadId); - } - - listener.endTest(test, threadId); - } - } - - // log.debug("testResult.shutdownNow = " + testResult.shutdownNow); - - // Check if the test runner has been asked to shutdown and raise an interuppted exception if so. - if (testResult.shutdownNow) - { - // log.debug("The shutdown flag is set."); - - throw new InterruptedException("Attempting clean shutdown by suspending current test."); - } - } - } -} diff --git a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/TKTestRunner.java b/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/TKTestRunner.java deleted file mode 100644 index 671d33feed..0000000000 --- a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/TKTestRunner.java +++ /dev/null @@ -1,694 +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.junit.extensions; - -import junit.framework.Test; -import junit.framework.TestResult; -import junit.framework.TestSuite; - -import org.apache.log4j.Logger; - -import org.apache.qpid.junit.extensions.listeners.CSVTestListener; -import org.apache.qpid.junit.extensions.listeners.ConsoleTestListener; -import org.apache.qpid.junit.extensions.listeners.XMLTestListener; -import org.apache.qpid.junit.extensions.util.CommandLineParser; -import org.apache.qpid.junit.extensions.util.MathUtils; -import org.apache.qpid.junit.extensions.util.ParsedProperties; -import org.apache.qpid.junit.extensions.util.TestContextProperties; - -import java.io.*; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.LinkedList; -import java.util.List; - -/** - * TKTestRunner extends {@link junit.textui.TestRunner} with the ability to run tests multiple times, to execute a test - * simultaneously using many threads, to put a delay between test runs and adds support for tests that take integer - * parameters that can be 'stepped' through on multiple test runs. These features can be accessed by using this class - * as an entry point and passing command line arguments to specify which features to use: - * - * <pre> - * -w ms The number of milliseconds between invocations of test cases. - * -c pattern The number of tests to run concurrently. - * -r num The number of times to repeat each test. - * -d duration The length of time to run the tests for. - * -t name The name of the test case to execute. - * -s pattern The size parameter to run tests with. - * -o dir The name of the directory to output test timings to. - * --csv Output test results in CSV format. - * --xml Output test results in XML format. - * </pre> - * - * <p/>This command line may also have trailing 'name=value' parameters added to it. All of these values are added - * to the test context properties and passed to the test, which can access them by name. - * - * <p/>The pattern arguments are of the form [lowest(: ...)(: highest)](:sample=s)(:exp), where round brackets - * enclose optional values. Using this pattern form it is possible to specify a single value, a range of values divided - * into s samples, a range of values divided into s samples but distributed exponentially, or a fixed set of samples. - * - * <p/>The duration arguments are of the form (dD)(hH)(mM)(sS), where round brackets enclose optional values. At least - * one of the optional values must be present. - * - * <p/>When specifying optional test parameters on the command line, in 'name=value' format, it is also possible to use - * the format 'name=[value1:value2:value3:...]', to specify multiple values for a parameter. All permutations of all - * parameters with multiple values will be created and tested. If the values are numerical, it is also possible to use - * the sequence generation patterns instead of fully specifying all of the values. - * - * <p/>Here are some examples: - * - * <p/><table> - * <tr><td><pre> -c [10:20:30:40:50] </pre><td> Runs the test with 10,20,...,50 threads. - * <tr><td><pre> -s [1:100]:samples=10 </pre> - * <td> Runs the test with ten different size parameters evenly spaced between 1 and 100. - * <tr><td><pre> -s [1:1000000]:samples=10:exp </pre> - * <td> Runs the test with ten different size parameters exponentially spaced between 1 and 1000000. - * <tr><td><pre> -r 10 </pre><td> Runs each test ten times. - * <tr><td><pre> -d 10H </pre><td> Runs the test repeatedly for 10 hours. - * <tr><td><pre> -d 1M, -r 10 </pre> - * <td> Runs the test repeatedly for 1 minute but only takes a timing sample every 10 test runs. - * <tr><td><pre> -r 10, -c [1:5:10:50], -s [100:1000:10000] </pre> - * <td> Runs 12 test cycles (4 concurrency samples * 3 size sample), with 10 repeats each. In total the test - * will be run 199 times (3 + 15 + 30 + 150) - * <tr><td><pre> cache=true </pre><td> Passes the 'cache' parameter with value 'true' to the test. - * <tr><td><pre> cache=[true:false] </pre><td> Runs the test with the 'cache' parameter set to 'true' and 'false'. - * <tr><td><pre> cacheSize=[1000:1000000],samples=4,exp </pre> - * <td> Runs the test with the 'cache' parameter set to a series of exponentially increasing sizes. - * </table> - * - * <p><table id="crc"><caption>CRC Card</caption> - * <tr><th> Responsibilities <th> Collaborations - * <tr><td> Create the test configuration specified by the command line parameters. - * </table> - * - * @todo Verify that the output directory exists or can be created. - * - * @todo Verify that the specific named test case to execute exists. - * - * @todo Drop the delay parameter as it is being replaced by throttling. - * - * @todo Completely replace the test ui test runner, instead of having TKTestRunner inherit from it, its just not - * good code to extend. - * - * @author Rupert Smith - */ -public class TKTestRunner extends TestRunnerImprovedErrorHandling -{ - /** Used for debugging. */ - private static final Logger log = Logger.getLogger(TKTestRunner.class); - - /** Used for displaying information on the console. */ - // private static final Logger console = Logger.getLogger("CONSOLE." + TKTestRunner.class.getName()); - - /** Used for generating the timestamp when naming output files. */ - protected static final DateFormat TIME_STAMP_FORMAT = new SimpleDateFormat("yyyy-MM-dd-HH.mm.ss"); - - /** Number of times to rerun the test. */ - protected Integer repetitions = 1; - - /** The length of time to run the tests for. */ - protected Long duration; - - /** Number of threads running the tests. */ - protected int[] threads; - - /** Delay in ms to wait between two test cases. */ - protected int delay = 0; - - /** The parameter values to pass to parameterized tests. */ - protected int[] params; - - /** Name of the single test case to execute. */ - protected String testCaseName = null; - - /** Name of the test class. */ - protected String testClassName = null; - - /** Name of the test run. */ - protected String testRunName = null; - - /** Directory to output XML reports into, if specified. */ - protected String reportDir = null; - - /** Flag that indicates the CSV results listener should be used to output results. */ - protected boolean csvResults; - - /** Flag that indiciates the XML results listener should be used to output results. */ - protected boolean xmlResults; - - /** - * Holds the name of the class of the test currently being run. Ideally passed into the {@link #createTestResult} - * method, but as the signature is already fixed for this, the current value gets pushed here as a member variable. - */ - protected String currentTestClassName; - - /** Holds the test results object, which is reponsible for instrumenting tests/threads to record results. */ - protected TKTestResult result; - - /** Holds a list of factories for instantiating optional user specified test decorators. */ - protected List<TestDecoratorFactory> decoratorFactories; - - /** - * Constructs a TKTestRunner using System.out for all the output. - * - * @param repetitions The number of times to repeat the test, or test batch size. - * @param duration The length of time to run the tests for. -1 means no duration has been set. - * @param threads The concurrency levels to ramp up to. - * @param delay A delay in milliseconds between test runs. - * @param params The sets of 'size' parameters to pass to test. - * @param testCaseName The name of the test case to run. - * @param reportDir The directory to output the test results to. - * @param runName The name of the test run; used to name the output file. - * @param csvResults <tt>true</tt> if the CSV results listener should be attached. - * @param xmlResults <tt>true</tt> if the XML results listener should be attached. - * @param decoratorFactories List of factories for user specified decorators. - */ - public TKTestRunner(Integer repetitions, Long duration, int[] threads, int delay, int[] params, String testCaseName, - String reportDir, String runName, boolean csvResults, boolean xmlResults, - List<TestDecoratorFactory> decoratorFactories) - { - super(new NullResultPrinter(System.out)); - - log.debug("public TKTestRunner(): called"); - - // Keep all the test parameters. - this.repetitions = repetitions; - this.duration = duration; - this.threads = threads; - this.delay = delay; - this.params = params; - this.testCaseName = testCaseName; - this.reportDir = reportDir; - this.testRunName = runName; - this.csvResults = csvResults; - this.xmlResults = xmlResults; - this.decoratorFactories = decoratorFactories; - } - - /** - * The entry point for the toolkit test runner. - * - * @param args The command line arguments. - */ - public static void main(String[] args) - { - // Use the command line parser to evaluate the command line. - CommandLineParser commandLine = - new CommandLineParser( - new String[][] - { - { "w", "The number of milliseconds between invocations of test cases.", "ms", "false" }, - { "c", "The number of tests to run concurrently.", "num", "false", MathUtils.SEQUENCE_REGEXP }, - { "r", "The number of times to repeat each test.", "num", "false" }, - { "d", "The length of time to run the tests for.", "duration", "false", MathUtils.DURATION_REGEXP }, - { "f", "The maximum rate to call the tests at.", "frequency", "false", "^([1-9][0-9]*)/([1-9][0-9]*)$" }, - { "s", "The size parameter to run tests with.", "size", "false", MathUtils.SEQUENCE_REGEXP }, - { "t", "The name of the test case to execute.", "name", "false" }, - { "o", "The name of the directory to output test timings to.", "dir", "false" }, - { "n", "A name for this test run, used to name the output file.", "name", "true" }, - { - "X:decorators", "A list of additional test decorators to wrap the tests in.", - "\"class.name[:class.name]*\"", "false" - }, - { "1", "Test class.", "class", "true" }, - { "-csv", "Output test results in CSV format.", null, "false" }, - { "-xml", "Output test results in XML format.", null, "false" } - }); - - // Capture the command line arguments or display errors and correct usage and then exit. - ParsedProperties options = null; - - try - { - options = new ParsedProperties(commandLine.parseCommandLine(args)); - } - catch (IllegalArgumentException e) - { - System.out.println(commandLine.getErrors()); - System.out.println(commandLine.getUsage()); - System.exit(FAILURE_EXIT); - } - - // Extract the command line options. - Integer delay = options.getPropertyAsInteger("w"); - String threadsString = options.getProperty("c"); - Integer repetitions = options.getPropertyAsInteger("r"); - String durationString = options.getProperty("d"); - String paramsString = options.getProperty("s"); - String testCaseName = options.getProperty("t"); - String reportDir = options.getProperty("o"); - String testRunName = options.getProperty("n"); - String decorators = options.getProperty("X:decorators"); - String testClassName = options.getProperty("1"); - boolean csvResults = options.getPropertyAsBoolean("-csv"); - boolean xmlResults = options.getPropertyAsBoolean("-xml"); - - int[] threads = (threadsString == null) ? null : MathUtils.parseSequence(threadsString); - int[] params = (paramsString == null) ? null : MathUtils.parseSequence(paramsString); - Long duration = (durationString == null) ? null : MathUtils.parseDuration(durationString); - - // The test run name defaults to the test class name unless a value was specified for it. - testRunName = (testRunName == null) ? testClassName : testRunName; - - // Add all the command line options and trailing settings to test context properties. Tests may pick up - // overridden values from there, and these values will be logged in the test results, for analysis and - // to make tests repeatable. - commandLine.addTrailingPairsToProperties(TestContextProperties.getInstance()); - commandLine.addOptionsToProperties(TestContextProperties.getInstance()); - - // Create and start the test runner. - try - { - // Create a list of test decorator factories for use specified decorators to be applied. - List<TestDecoratorFactory> decoratorFactories = parseDecorators(decorators); - - TKTestRunner testRunner = - new TKTestRunner(repetitions, duration, threads, (delay == null) ? 0 : delay, params, testCaseName, - reportDir, testRunName, csvResults, xmlResults, decoratorFactories); - - TestResult testResult = testRunner.start(testClassName); - - if (!testResult.wasSuccessful()) - { - System.exit(FAILURE_EXIT); - } - } - catch (Exception e) - { - System.err.println(e.getMessage()); - e.printStackTrace(new PrintStream(System.err)); - System.exit(EXCEPTION_EXIT); - } - } - - /** - * Parses a list of test decorators, in the form "class.name[:class.name]*", and creates factories for those - * TestDecorator classes , and returns a list of the factories. This list of factories will be in the same - * order as specified in the string. The factories can be used to succesively wrap tests in layers of - * decorators, as decorators themselves implement the 'Test' interface. - * - * <p/>If the string fails to parse, or if any of the decorators specified in it are cannot be loaded, or are not - * TestDecorators, a runtime exception with a suitable error message will be thrown. The factories themselves - * throw runtimes if the constructor method calls on the decorators fail. - * - * @param decorators The decorators list to be parsed. - * - * @return A list of instantiated decorators. - */ - protected static List<TestDecoratorFactory> parseDecorators(String decorators) - { - List<TestDecoratorFactory> result = new LinkedList<TestDecoratorFactory>(); - String toParse = decorators; - - // Check that the decorators string is not null or empty, returning an empty list of decorator factories it - // it is. - if ((decorators == null) || "".equals(decorators)) - { - return result; - } - - // Strip any leading and trailing quotes from the string. - if (toParse.charAt(0) == '\"') - { - toParse = toParse.substring(1, toParse.length() - 1); - } - - if (toParse.charAt(toParse.length() - 1) == '\"') - { - toParse = toParse.substring(0, toParse.length() - 2); - } - - // Instantiate all decorators. - for (String decoratorClassName : toParse.split(":")) - { - try - { - Class decoratorClass = Class.forName(decoratorClassName); - final Constructor decoratorConstructor = decoratorClass.getConstructor(WrappedSuiteTestDecorator.class); - - // Check that the decorator is an instance of WrappedSuiteTestDecorator. - if (!WrappedSuiteTestDecorator.class.isAssignableFrom(decoratorClass)) - { - throw new RuntimeException("The decorator class " + decoratorClassName - + " is not a sub-class of WrappedSuiteTestDecorator, which it needs to be."); - } - - result.add(new TestDecoratorFactory() - { - public WrappedSuiteTestDecorator decorateTest(Test test) - { - try - { - return (WrappedSuiteTestDecorator) decoratorConstructor.newInstance(test); - } - catch (InstantiationException e) - { - throw new RuntimeException( - "The decorator class " + decoratorConstructor.getDeclaringClass().getName() - + " cannot be instantiated.", e); - } - catch (IllegalAccessException e) - { - throw new RuntimeException( - "The decorator class " + decoratorConstructor.getDeclaringClass().getName() - + " does not have a publicly accessable constructor.", e); - } - catch (InvocationTargetException e) - { - throw new RuntimeException( - "The decorator class " + decoratorConstructor.getDeclaringClass().getName() - + " cannot be invoked.", e); - } - } - }); - } - catch (ClassNotFoundException e) - { - throw new RuntimeException("The decorator class " + decoratorClassName + " could not be found.", e); - } - catch (NoSuchMethodException e) - { - throw new RuntimeException("The decorator class " + decoratorClassName - + " does not have a constructor that accepts a single 'WrappedSuiteTestDecorator' argument.", e); - } - } - - return result; - } - - /** - * TestDecoratorFactory is a factory for creating test decorators from tests. - */ - protected interface TestDecoratorFactory - { - /** - * Decorates the specified test with a new decorator. - * - * @param test The test to decorate. - * - * @return The decorated test. - */ - public WrappedSuiteTestDecorator decorateTest(Test test); - } - - /** - * Runs a test or suite of tests, using the super class implemenation. This method wraps the test to be run - * in any test decorators needed to add in the configured toolkits enhanced junit functionality. - * - * @param test The test to run. - * @param wait Undocumented. Nothing in the JUnit javadocs to say what this is for. - * - * @return The results of the test run. - */ - public TestResult doRun(Test test, boolean wait) - { - log.debug("public TestResult doRun(Test \"" + test + "\", boolean " + wait + "): called"); - - // Wrap the tests in decorators for duration, scaling, repetition, parameterization etc. - WrappedSuiteTestDecorator targetTest = decorateTests(test); - - // Delegate to the super method to run the decorated tests. - log.debug("About to call super.doRun"); - - TestResult result = super.doRun(targetTest, wait); - log.debug("super.doRun returned."); - - /*if (result instanceof TKTestResult) - { - TKTestResult tkResult = (TKTestResult) result; - - tkResult.notifyEndBatch(); - }*/ - - return result; - } - - /** - * Applies test decorators to the tests for parameterization, duration, scaling and repetition. - * - * @param test The test to decorat. - * - * @return The decorated test. - */ - protected WrappedSuiteTestDecorator decorateTests(Test test) - { - log.debug("params = " + ((params == null) ? null : MathUtils.printArray(params))); - log.debug("repetitions = " + repetitions); - log.debug("threads = " + ((threads == null) ? null : MathUtils.printArray(threads))); - log.debug("duration = " + duration); - - // Wrap all tests in the test suite with WrappedSuiteTestDecorators. This is quite ugly and a bit baffling, - // but the reason it is done is because the JUnit implementation of TestDecorator has some bugs in it. - WrappedSuiteTestDecorator targetTest = null; - - if (test instanceof TestSuite) - { - log.debug("targetTest is a TestSuite"); - - TestSuite suite = (TestSuite) test; - - int numTests = suite.countTestCases(); - log.debug("There are " + numTests + " in the suite."); - - for (int i = 0; i < numTests; i++) - { - Test nextTest = suite.testAt(i); - log.debug("suite.testAt(" + i + ") = " + nextTest); - - if (nextTest instanceof TimingControllerAware) - { - log.debug("nextTest is TimingControllerAware"); - } - - if (nextTest instanceof TestThreadAware) - { - log.debug("nextTest is TestThreadAware"); - } - } - - targetTest = new WrappedSuiteTestDecorator(suite); - log.debug("Wrapped with a WrappedSuiteTestDecorator."); - } - // If the test has already been wrapped, no need to do it again. - else if (test instanceof WrappedSuiteTestDecorator) - { - targetTest = (WrappedSuiteTestDecorator) test; - } - - // If size parameter values have been set, then wrap the test in an asymptotic test decorator. - if (params != null) - { - targetTest = new AsymptoticTestDecorator(targetTest, params, (repetitions == null) ? 1 : repetitions); - log.debug("Wrapped with asymptotic test decorator."); - log.debug("targetTest = " + targetTest); - } - - // If no size parameters are set but the repitions parameter is, then wrap the test in an asymptotic test decorator. - else if ((repetitions != null) && (repetitions > 1)) - { - targetTest = new AsymptoticTestDecorator(targetTest, new int[] { 1 }, repetitions); - log.debug("Wrapped with asymptotic test decorator."); - log.debug("targetTest = " + targetTest); - } - - // Apply any optional user specified decorators. - targetTest = applyOptionalUserDecorators(targetTest); - - // If a test run duration has been set then wrap the test in a duration test decorator. This will wrap on - // top of size, repeat or concurrency wrappings already applied. - if (duration != null) - { - DurationTestDecorator durationTest = new DurationTestDecorator(targetTest, duration); - targetTest = durationTest; - - log.debug("Wrapped with duration test decorator."); - log.debug("targetTest = " + targetTest); - - registerShutdownHook(durationTest); - } - - // ParameterVariationTestDecorator... - - // If a test thread concurrency level is set then wrap the test in a scaled test decorator. This will wrap on - // top of size scaling or repetition wrappings. - ScaledTestDecorator scaledDecorator; - - if ((threads != null) && ((threads.length > 1) || (MathUtils.maxInArray(threads) > 1))) - { - scaledDecorator = new ScaledTestDecorator(targetTest, threads); - targetTest = scaledDecorator; - log.debug("Wrapped with scaled test decorator."); - log.debug("targetTest = " + targetTest); - } - else - { - scaledDecorator = new ScaledTestDecorator(targetTest, new int[] { 1 }); - targetTest = scaledDecorator; - log.debug("Wrapped with scaled test decorator with default of 1 thread."); - log.debug("targetTest = " + targetTest); - } - - // Register the scaled test decorators shutdown hook. - registerShutdownHook(scaledDecorator); - - return targetTest; - } - - /** - * If there were any user specified test decorators on the command line, this method instantiates them and wraps - * the test in them, from inner-most to outer-most in the order in which the decorators were supplied on the - * command line. - * - * @param targetTest The test to wrap. - * - * @return A wrapped test. - */ - protected WrappedSuiteTestDecorator applyOptionalUserDecorators(WrappedSuiteTestDecorator targetTest) - { - // If there are user defined test decorators apply them in order now. - for (TestDecoratorFactory factory : decoratorFactories) - { - targetTest = factory.decorateTest(targetTest); - } - - return targetTest; - } - - /** - * Creates the TestResult object to be used for test runs. See {@link TKTestResult} for more information and the - * enhanced test result class that this uses. - * - * @return An instance of the enhanced test result object, {@link TKTestResult}. - */ - protected TestResult createTestResult() - { - log.debug("protected TestResult createTestResult(): called"); - - TKTestResult result = new TKTestResult(delay, testCaseName); - - // Check if a directory to output reports to has been specified and attach test listeners if so. - if (reportDir != null) - { - // Create the report directory if it does not already exist. - File reportDirFile = new File(reportDir); - - if (!reportDirFile.exists()) - { - reportDirFile.mkdir(); - } - - // Create the results file (make the name of this configurable as a command line parameter). - Writer timingsWriter; - - // Always set up a console feedback listener. - ConsoleTestListener feedbackListener = new ConsoleTestListener(); - result.addListener(feedbackListener); - result.addTKTestListener(feedbackListener); - - // Set up an XML results listener to output the timings to the results file, if requested on the command line. - if (xmlResults) - { - try - { - File timingsFile = new File(reportDirFile, "TEST-" + currentTestClassName + ".xml"); - timingsWriter = new BufferedWriter(new FileWriter(timingsFile), 20000); - } - catch (IOException e) - { - throw new RuntimeException("Unable to create the log file to write test results to: " + e, e); - } - - XMLTestListener listener = new XMLTestListener(timingsWriter, currentTestClassName); - result.addListener(listener); - result.addTKTestListener(listener); - - registerShutdownHook(listener); - } - - // Set up an CSV results listener to output the timings to the results file, if requested on the command line. - if (csvResults) - { - try - { - File timingsFile = - new File(reportDirFile, testRunName + "-" + TIME_STAMP_FORMAT.format(new Date()) + "-timings.csv"); - timingsWriter = new BufferedWriter(new FileWriter(timingsFile), 20000); - } - catch (IOException e) - { - throw new RuntimeException("Unable to create the log file to write test results to: " + e, e); - } - - CSVTestListener listener = new CSVTestListener(timingsWriter); - result.addListener(listener); - result.addTKTestListener(listener); - - // Register the results listeners shutdown hook to flush its data if the test framework is shutdown - // prematurely. - registerShutdownHook(listener); - } - - // Register the results listeners shutdown hook to flush its data if the test framework is shutdown - // prematurely. - // registerShutdownHook(listener); - - // Record the start time of the batch. - // result.notifyStartBatch(); - - // At this point in time the test class has been instantiated, giving it an opportunity to read its parameters. - // Inform any test listers of the test properties. - result.notifyTestProperties(TestContextProperties.getAccessedProps()); - } - - return result; - } - - /** - * Registers the shutdown hook of a {@link ShutdownHookable}. - * - * @param hookable The hookable to register. - */ - protected void registerShutdownHook(ShutdownHookable hookable) - { - Runtime.getRuntime().addShutdownHook(hookable.getShutdownHook()); - } - - /** - * Initializes the test runner with the provided command line arguments and and starts the test run. - * - * @param testClassName The fully qualified name of the test class to run. - * - * @return The test results. - * - * @throws Exception Any exceptions from running the tests are allowed to fall through. - */ - protected TestResult start(String testClassName) throws Exception - { - // Record the current test class, so that the test results can be output to a file incorporating this name. - this.currentTestClassName = testClassName; - - // Delegate to the super method to run the tests. - return super.start(new String[] { testClassName }); - } -} diff --git a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/TestRunnerImprovedErrorHandling.java b/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/TestRunnerImprovedErrorHandling.java deleted file mode 100644 index c68405bd06..0000000000 --- a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/TestRunnerImprovedErrorHandling.java +++ /dev/null @@ -1,131 +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.junit.extensions; - -import junit.framework.Test; -import junit.framework.TestResult; - -import junit.runner.Version; - -import junit.textui.ResultPrinter; -import junit.textui.TestRunner; - -import org.apache.log4j.Logger; - -import java.io.PrintStream; - -/** - * The {@link junit.textui.TestRunner} does not provide very good error handling. It does not wrap exceptions and - * does not print out stack traces, losing valuable error tracing information. This class overrides methods in it - * in order to improve their error handling. The {@link TKTestRunner} is then built on top of this. - * - * <p/><table id="crc"><caption>CRC Card</caption> - * <tr><th> Responsibilities <th> Collaborations - * </table> - * - * @author Rupert Smith - */ -public class TestRunnerImprovedErrorHandling extends TestRunner -{ - /** Used for logging. */ - Logger log = Logger.getLogger(TestRunnerImprovedErrorHandling.class); - - /** - * Delegates to the super constructor. - */ - public TestRunnerImprovedErrorHandling() - { - super(); - } - - /** - * Delegates to the super constructor. - * - * @param printStream The location to write test results to. - */ - public TestRunnerImprovedErrorHandling(PrintStream printStream) - { - super(printStream); - } - - /** - * Delegates to the super constructor. - * - * @param resultPrinter The location to write test results to. - */ - public TestRunnerImprovedErrorHandling(ResultPrinter resultPrinter) - { - super(resultPrinter); - } - - /** - * Starts a test run. Analyzes the command line arguments - * and runs the given test suite. - * - * @param args The command line arguments. - * - * @return The test results. - * - * @throws Exception Any exceptions falling through the tests are wrapped in Exception and rethrown. - */ - public TestResult start(String[] args) throws Exception - { - String testCase = ""; - boolean wait = false; - - for (int i = 0; i < args.length; i++) - { - if (args[i].equals("-wait")) - { - wait = true; - } - else if (args[i].equals("-c")) - { - testCase = extractClassName(args[++i]); - } - else if (args[i].equals("-v")) - { - System.err.println("JUnit " + Version.id() + " by Kent Beck and Erich Gamma"); - } - else - { - testCase = args[i]; - } - } - - if (testCase.equals("")) - { - throw new Exception("Usage: TestRunner [-wait] testCaseName, where name is the name of the TestCase class"); - } - - try - { - Test suite = getTest(testCase); - - return doRun(suite, wait); - } - catch (Exception e) - { - log.warn("Got exception whilst creating and running test suite.", e); - throw new Exception("Could not create and run the test suite.", e); - } - } -} diff --git a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/TestThreadAware.java b/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/TestThreadAware.java deleted file mode 100644 index 94dcf5499b..0000000000 --- a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/TestThreadAware.java +++ /dev/null @@ -1,54 +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.junit.extensions; - -/** - * This interface can be implemented by tests that want to know if they are being run concurrently. It provides - * lifecycle notification events to tell the test implementation when test threads are being created and destroyed. - * This can assist tests in creating and destroying resources that exist over the life of a test thread. A single - * test thread can excute the same test many times, and often it is convenient to keep resources, for example network - * connections, open over many test calls. - * - * <p/><table id="crc"><caption>CRC Card</caption> - * <tr><th> Responsibilities - * <tr><td> Set up per thread test fixtures. - * <tr><td> Clean up per thread test fixtures. - * </table> - * - * @author Rupert Smith - */ -public interface TestThreadAware -{ - /** - * Called when a test thread is created. - */ - public void threadSetUp(); - - /** - * Called after all threads have completed their setup. - */ - public void postThreadSetUp(); - - /** - * Called when a test thread is destroyed. - */ - public void threadTearDown(); -} diff --git a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/Throttle.java b/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/Throttle.java deleted file mode 100644 index 1ea8e8e2be..0000000000 --- a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/Throttle.java +++ /dev/null @@ -1,73 +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.junit.extensions; - -/** - * Throttle is an interface that supplies a {@link #throttle} method, that can only be called at the rate specified - * in a call to the {@link #setRate} method. This can be used to restict processing to run at a certain number - * of operations per second. - * - * <p/>Throttle also supplies a method to check the throttle rate, without waiting. This could be used to update a user - * interface every time an event occurs, but only up to a maximum rate. For example, as elements are added to a list, - * a count of elements is updated for the user to see, but only up to a maximum rate of ten updates a second, as updating - * faster than that slows the processing of element-by-element additions to the list unnecessarily. - * - * <p/><table id="crc"><caption>CRC Card</caption> - * <tr><th> Responsibilities - * <tr><td> Accept throttling rate in operations per second. - * <tr><td> Inject short pauses to fill-out processing cycles to a specified rate. - * <tr><td> Check against a throttle speed without waiting. - * </table> - * - * @author Rupert Smith - */ -public interface Throttle -{ - /** - * Specifies the throttling rate in operations per second. This must be called with with a value, the inverse - * of which is a measurement in nano seconds, such that the number of nano seconds do not overflow a long integer. - * The value must also be larger than zero. - * - * @param hertz The throttling rate in cycles per second. - */ - public void setRate(float hertz); - - /** - * This method can only be called at the rate set by the {@link #setRate} method, if it is called faster than this - * it will inject short pauses to restrict the call rate to that rate. - * - * <p/>If the thread executing this method is interrupted, it must ensure that the threads interrupt thread - * remains set upon exit from the method. This method does not expose InterruptedException, to indicate interruption - * of the throttle during a timed wait. It may be changed so that it does. - */ - public void throttle(); - - /** - * Checks but does not enforce the throttle rate. When this method is called, it checks if a length of time greater - * than that equal to the inverse of the throttling rate has passed since it was last called and returned <tt>true</tt> - * - * @return <tt>true</tt> if a length of time greater than that equal to the inverse of the throttling rate has - * passed since this method was last called and returned <tt>true</tt>, <tt>false</tt> otherwise. The very - * first time this method is called on a throttle, it returns <tt>true</tt> as the base case to the above - * self-referential definition. - */ - public boolean checkThrottle(); -} diff --git a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/TimingController.java b/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/TimingController.java deleted file mode 100644 index 27e43a10a4..0000000000 --- a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/TimingController.java +++ /dev/null @@ -1,198 +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.junit.extensions; - -/** - * A TimingController is a interface that a test that is aware of the fact that it is being timed can use to manage - * the timer. Using this interface tests can suspend and resume test timers. This is usefull if you want to exclude - * some expensive preparation from being timed as part of a test. In general when timing tests to measure the - * performance of code, you should try to set up data in the #setUp where possible, or as static members in the test - * class. This is not always convenient, this interface gives you a way to suspend and resume, or event completely - * restart test timers, to get accurate measurements. - * - * <p/>The interface can also be used to register multiple test pass/fails and timings from a single test method. - * In some cases it is easier to write tests in this way. For example a concurrent and asynchronous test may make - * many asynchronous requests and then wait for replies to all its requests. Writing such a test with one send/reply - * per test method and trying to scale up using many threads will quickly run into limitations if more than about - * 100 asynchronous calls need to be made at once. A better way to write such a test is as a single method that sends - * many (perhaps thousands or millions) and waits for replies in two threads, one for send, one for replies. It can - * then log pass/fails and timings on each individual reply as they come back in, even though the test has been written - * to send thousands of requests per test method in order to do volume testing. - * - * <p/>If when the {@link #completeTest(boolean)} is called, the test runner decides that testing should stop (perhaps - * because a duration test has expired), it throws an InterruptedException to indicate that the test method should stop - * immediately. The test method can do this by allowing this exception to fall through, if no other clean-up handling - * is necessary, or it can simply return as soon as it possibly can. The test runner will still call the tearDown - * method in the usual way when this happens. - * - * <p/>Below are some examples of how this can be used. Not how checking that the timing controller is really available - * rather than assuming it is, means that the test can run as an ordinary JUnit test under the default test runners. In - * general code should be written to take advantage of the extended capabilities of junit toolkit, without assuming they - * are going to be run under its test runner. - * - * <pre> - * public class MyTest extends TestCase implements TimingControllerAware { - * ... - * - * timingUtils = this.getTimingController(); - * - * // Do expensive data preparation here... - * - * if (timingUtils != null) - * timingUtils.restart(); - * </pre> - * - * <pre> - * public class MyTest extends TestCase implements TimingControllerAware { - * ... - * - * public void myVolumeTest(int size) { - * - * timingUtils = this.getTimingController(); - * - * boolean stopNow = false; - * - * // In Sender thread. - * for(int i = 0; !stopNow && i < size; i++) - * // Send request i. - * ... - * - * // In Receiver thread. - * onReceive(Object o) { - * try { - * // Check o is as expected. - * if (....) - * { - * if (timingUtils != null) - * timingUtils.completeTest(true); - * } - * else - * { - * if (timingUtils != null) - * timingUtils.completeTest(false); - * } - * } catch (InterruptedException e) { - * stopNow = true; - * return; - * } - * } - * </pre> - * - * <p><table id="crc"><caption>CRC Card</caption> - * <tr><th> Responsibilities - * <tr><td> Allow test timers to be suspended, restarted or reset. - * <tr><td> Allow tests to register multiple pass/fails and timings. - * </table> - * - * @author Rupert Smith - */ -public interface TimingController -{ - /** - * Gets the timing controller associated with the current test thread. Tests that use timing controller should - * always get the timing controller from this method in the same thread that called the setUp, tearDown or test - * method. The controller returned by this method may be called from any thread because it remembers the thread - * id of the original test thread. - * - * @return The timing controller associated with the current test thread. - */ - public TimingController getControllerForCurrentThread(); - - /** - * Suspends the test timer. - * - * @return The current time in nanoseconds. - */ - public long suspend(); - - /** - * Allows the test timer to continue running after a suspend. - * - * @return The current time in nanoseconds. - */ - public long resume(); - - /** - * Completely restarts the test timer from zero. - * - * @return The current time in nanoseconds. - */ - public long restart(); - - /** - * Register an additional pass/fail for the current test. The test result is assumed to apply to a test of - * 'size' parmeter 1. Use the {@link #completeTest(boolean, int)} method to register timings with parameters. - * - * @param testPassed Whether or not this timing is for a test pass or fail. - * - * @throws InterruptedException If the test runner decides that testing should stop it throws this exception to - * indicate to the test method that it should stop immediately. - */ - public void completeTest(boolean testPassed) throws InterruptedException; - - /** - * Register an additional pass/fail for the current test. The test result is applies to a test of the specified - * 'size' parmeter. - * - * @param testPassed Whether or not this timing is for a test pass or fail. - * @param param The test parameter size for parameterized tests. - * - * @throws InterruptedException If the test runner decides that testing should stop it throws this exception to - * indicate to the test method that it should stop immediately. - */ - public void completeTest(boolean testPassed, int param) throws InterruptedException; - - /** - * Register an additional pass/fail for the current test. The test result is applies to a test of the specified - * 'size' parmeter and allows the caller to sepecify the timing to log. - * - * @param testPassed Whether or not this timing is for a test pass or fail. - * @param param The test parameter size for parameterized tests. - * @param timeNanos The time in nano seconds to log the test result with. - * - * A null value for timeNanos is a request to this method that it should - * calculate the time for the given test run. - * - * - * @throws InterruptedException If the test runner decides that testing should stop it throws this exception to - * indicate to the test method that it should stop immediately. - */ - public void completeTest(boolean testPassed, int param, Long timeNanos) throws InterruptedException; - - /** - * Register an additional pass/fail for the current test. The test result is applies to a test of the specified - * 'size' parmeter and allows the caller to sepecify the timing to log. - * - * @param testPassed Whether or not this timing is for a test pass or fail. - * @param param The test parameter size for parameterized tests. - * @param timeNanos The time in nano seconds to log the test result with. - * - * A null value for timeNanos is a request to this method that it should - * calculate the time for the given test run. - * A null value for timeNanos2 means this test does not provide a second - * timing value so a '-' is printed in the log. - * - * - * @throws InterruptedException If the test runner decides that testing should stop it throws this exception to - * indicate to the test method that it should stop immediately. - */ - public void completeTest(boolean testPassed, int param, Long timeNanos, Long time2Nanos) throws InterruptedException; -} diff --git a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/TimingControllerAware.java b/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/TimingControllerAware.java deleted file mode 100644 index 11db87e073..0000000000 --- a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/TimingControllerAware.java +++ /dev/null @@ -1,43 +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.junit.extensions; - -/** - * TimingControllerAware is an interface that tests that manipulate the timing controller should implement. It enables - * the TK test runner to set the test up with a handle on the timing controller which the test can use to call back - * to the test runner to manage the timers. - * - * <p><table id="crc"><caption>CRC Card</caption> - * <tr><th> Responsibilities - * <tr><td> Provide timing controller insertion point for tests. - * </table> - * - * @author Rupert Smith - */ -public interface TimingControllerAware -{ - /** - * Used by test runners that can supply a {@link TimingController} to set the controller on an aware test. - * - * @param controller The timing controller. - */ - public void setTimingController(TimingController controller); -} diff --git a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/WrappedSuiteTestDecorator.java b/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/WrappedSuiteTestDecorator.java deleted file mode 100644 index d5690fc24a..0000000000 --- a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/WrappedSuiteTestDecorator.java +++ /dev/null @@ -1,134 +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.junit.extensions; - -import junit.extensions.TestDecorator; - -import junit.framework.Test; -import junit.framework.TestSuite; - -import org.apache.log4j.Logger; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -/** - * WrappedSuiteTestDecorator is a test decorator that wraps a test suite, or another wrapped suite, but provides the - * same functionality for the {@link junit.extensions.TestDecorator#countTestCases()} and {@link TestSuite#testAt(int)} - * methods as the underlying suite. It returns the values that these methods provide, to enable classes using decorated - * tests to drill down to the underlying tests in the suite. That is to say that it indexes and reports the number of - * distinct tests in the suite, not the number of test runs that would result from, for example, wrapping the suite in a - * repeating decorator. - * - * <p><table id="crc"><caption>CRC Card</caption> - * <tr><th> Responsibilities - * <tr><td> Provide access to the underlying tests in a suite. - * </table> - * - * @author Rupert Smith - */ -public class WrappedSuiteTestDecorator extends TestDecorator -{ - /** Used for logging. */ - private static Logger log = Logger.getLogger(WrappedSuiteTestDecorator.class); - - /** Holds the test suite that this supplies access to. */ - protected Test suite; - - /** - * Creates a wrappred suite test decorator from a test suite. - * - * @param suite The test suite. - */ - public WrappedSuiteTestDecorator(TestSuite suite) - { - super(suite); - this.suite = suite; - } - - /** - * Creates a wrapped suite test decorator from another one. - * - * @param suite The test suite. - */ - public WrappedSuiteTestDecorator(WrappedSuiteTestDecorator suite) - { - super(suite); - this.suite = suite; - } - - /** - * Returns the test count of the wrapped suite. - * - * @return The test count of the wrapped suite. - */ - public int countTestCases() - { - return suite.countTestCases(); - } - - /** - * Gets the ith test from the test suite. - * - * @param i The index of the test within the suite to get. - * - * @return The test with the specified index. - */ - public Test testAt(int i) - { - log.debug("public Test testAt(int i = " + i + "): called"); - - if (suite instanceof WrappedSuiteTestDecorator) - { - return ((WrappedSuiteTestDecorator) suite).testAt(i); - } - else if (suite instanceof TestSuite) - { - return ((TestSuite) suite).testAt(i); - } - - // This should never happen. - return null; - } - - /** - * Gets all the tests from the underlying test suite. - * - * @return All the tests from the underlying test suite. - */ - public Collection<Test> getAllUnderlyingTests() - { - log.debug("public Collection<Test> getAllUnderlyingTests(): called"); - - List<Test> tests = new ArrayList<Test>(); - - int numTests = countTestCases(); - log.debug("numTests = " + numTests); - - for (int i = 0; i < numTests; i++) - { - tests.add(testAt(i)); - } - - return tests; - } -} diff --git a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/listeners/CSVTestListener.java b/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/listeners/CSVTestListener.java deleted file mode 100644 index 40841189a3..0000000000 --- a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/listeners/CSVTestListener.java +++ /dev/null @@ -1,572 +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.junit.extensions.listeners; - -import junit.framework.AssertionFailedError; -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestListener; - -import org.apache.log4j.Logger; - -import org.apache.qpid.junit.extensions.ShutdownHookable; -import org.apache.qpid.junit.extensions.util.TestContextProperties; - -import java.io.IOException; -import java.io.Writer; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.Properties; -import java.util.Set; -import java.util.TreeSet; - -/** - * CSVTestListener is both a test listener, a timings listener, a memory listener and a parameter listener. It listens for test completion events and - * then writes out all the data that it has listened to into a '.csv' (comma seperated values) file. - * - * <p><table id="crc"><caption>CRC Card</caption> - * <tr><th> Responsibilities <th> Collaborations - * <tr><td> Listen to test events; start, end, fail, error. - * <tr><td> Listen to test timings. - * <tr><td> Listen to test memory usage. - * <tr><td> Listen to parameterized test parameters. - * <tr><td> Output all test data to a CSV file. - * </table> - * - * @author Rupert Smith - * - * @todo Write an XML output class. Write a transform to convert it into an HTML page with timings as graphs. - */ -public class CSVTestListener implements TestListener, TKTestListener, ShutdownHookable -{ - /** Used for logging. */ - private static final Logger log = Logger.getLogger(CSVTestListener.class); - - /** The timings file writer. */ - private Writer timingsWriter; - - /** - * Map for holding results on a per thread basis as they come in. A ThreadLocal is not used as sometimes an - * explicit thread id must be used, where notifications come from different threads than the ones that called - * the test method. - */ - Map<Long, TestResult> threadLocalResults = Collections.synchronizedMap(new HashMap<Long, TestResult>()); - - /** Used to record the start time of a complete test run, for outputing statistics at the end of the test run. */ - private long batchStartTime; - - /** Used to record the number of errors accross a complete test run. */ - private int numError; - - /** Used to record the number of failures accross a complete test run. */ - private int numFailed; - - /** Used to record the number of passes accross a complete test run. */ - private int numPassed; - - /** Used to record the total tests run accross a complete test run. Always equal to passes + errors + fails. */ - private int totalTests; - - /** Used to recrod the current concurrency level for the test batch. */ - private int concurrencyLevel; - - /** - * Used to record the total 'size' of the tests run, this is the number run times the average value of the test - * size parameters. - */ - private int totalSize; - - /** - * Used to record the summation of all of the individual test timings. Note that total time and summed time - * are unlikely to be in agreement, exception for a single threaded test (with no setup time). Total time is - * the time taken to run all the tests, summed time is the added up time that each individual test took. So if - * two tests run in parallel and take one second each, total time will be one seconds, summed time will be two - * seconds. - */ - private long summedTime; - - /** - * Used to record the summation of all of the second test timing information. - * One use of the second timing would be to provide latency as well as test timing. - */ - private long summedTime2; - - /** Flag to indicate when batch has been started but not ended to ensure end batch stats are output only once. */ - private boolean batchStarted = false; - - /** - * Creates a new CSVTestListener object. - * - * @param writer A writer where this CSV listener should write out its output to. - */ - public CSVTestListener(Writer writer) - { - // log.debug("public CSVTestListener(Writer writer): called"); - - // Keep the writer. - this.timingsWriter = writer; - } - - /** - * Resets the test results to the default state of time zero, memory usage zero, test passed. - * - * @param test The test to resest any results for. - * @param threadId Optional thread id if not calling from thread that started the test method. May be null. - */ - public void reset(Test test, Long threadId) - { - // log.debug("public void reset(Test test = \"" + test + "\", Long threadId = " + threadId + "): called"); - - TestResult r = - (threadId == null) ? threadLocalResults.get(Thread.currentThread().getId()) : threadLocalResults.get(threadId); - - r.testTime = 0L; - r.testTime2 = null; - r.testStartMem = 0L; - r.testEndMem = 0L; - r.testState = "Pass"; - r.testParam = 0; - } - - /** - * Called when a test results in an error. - * - * @param test The test which is in error. - * @param t Any Throwable raised by the test in error. - */ - public void addError(Test test, Throwable t) - { - // log.debug("public void addError(Test test, Throwable t): called"); - - TestResult r = threadLocalResults.get(Thread.currentThread().getId()); - r.testState = "Error"; - } - - /** - * Called when a test results in a failure. - * - * @param test The test which failed. - * @param t The AssertionFailedError that encapsulates the test failure. - */ - public void addFailure(Test test, AssertionFailedError t) - { - // log.debug("public void addFailure(Test \"" + test + "\", AssertionFailedError t): called"); - - TestResult r = threadLocalResults.get(Thread.currentThread().getId()); - r.testState = "Failure"; - } - - /** - * Called when a test completes to mark it as a test fail. This method should be used when registering a - * failure from a different thread than the one that started the test. - * - * @param test The test which failed. - * @param e The assertion that failed the test. - * @param threadId Optional thread id if not calling from thread that started the test method. May be null. - */ - public void addFailure(Test test, AssertionFailedError e, Long threadId) - { - // log.debug("public void addFailure(Test test = \"" + test + "\", AssertionFailedError e, Long threadId = " + threadId - // + "): called"); - - TestResult r = - (threadId == null) ? threadLocalResults.get(Thread.currentThread().getId()) : threadLocalResults.get(threadId); - - r.testState = "Failure"; - } - - /** - * Called when a test completes. Success, failure and errors. - * - * @param test The test which completed. - */ - public void endTest(Test test) - { - // log.debug("public void endTest(Test \"" + test + "\"): called"); - - TestResult r = threadLocalResults.get(Thread.currentThread().getId()); - - writeTestResults(r, test); - - // Clear all the test results for the thread. - threadLocalResults.remove(Thread.currentThread().getId()); - } - - /** - * Called when a test starts. - * - * @param test The test wich has started. - */ - public void startTest(Test test) - { - // log.debug("public void startTest(Test \"" + test + "\"): called"); - - // Initialize the thread local test results. - threadLocalResults.put(Thread.currentThread().getId(), new TestResult()); - } - - /** - * Should be called every time a test completes with the run time of that test. - * - * @param test The name of the test. - * @param nanos The run time of the test in nanoseconds. - * @param threadId Optional thread id if not calling from thread that started the test method. May be null. - */ - public void timing(Test test, long nanos, Long threadId) - { - // log.debug("public void timing(String \"" + test + "\", long " + nanos + "): called"); - - TestResult r = - (threadId == null) ? threadLocalResults.get(Thread.currentThread().getId()) : threadLocalResults.get(threadId); - - r.testTime = nanos; - summedTime += nanos; - } - - /** - * Optionally called every time a test completes with the second timing test. - * - * @param test The name of the test. - * @param nanos The second timing information of the test in nanoseconds. - * @param threadId Optional thread id if not calling from thread that started the test method. May be null. - */ - public void timing2(Test test, Long nanos, Long threadId) - { - TestResult r = - (threadId == null) ? threadLocalResults.get(Thread.currentThread().getId()) : threadLocalResults.get(threadId); - - - if (nanos != null) - { - r.testTime2 = nanos; - summedTime2 += nanos; - } - } - - /** - * Should be called every time a test completed with the amount of memory used before and after the test was run. - * - * @param test The test which memory was measured for. - * @param memStart The total JVM memory used before the test was run. - * @param memEnd The total JVM memory used after the test was run. - * @param threadId Optional thread id if not calling from thread that started the test method. May be null. - */ - public void memoryUsed(Test test, long memStart, long memEnd, Long threadId) - { - // log.debug("public void memoryUsed(Test \"" + test + "\", long " + memStart + ", long " + memEnd + ", Long " - // + threadId + "): called"); - - TestResult r = - (threadId == null) ? threadLocalResults.get(Thread.currentThread().getId()) : threadLocalResults.get(threadId); - - r.testStartMem = memStart; - r.testEndMem = memEnd; - } - - /** - * Should be called every time a parameterized test completed with the int value of its test parameter. - * - * @param test The test which memory was measured for. - * @param parameter The int parameter value. - * @param threadId Optional thread id if not calling from thread that started the test method. May be null. - */ - public void parameterValue(Test test, int parameter, Long threadId) - { - // log.debug("public void parameterValue(Test test = \"" + test + "\", int parameter = " + parameter + "): called"); - - TestResult r = - (threadId == null) ? threadLocalResults.get(Thread.currentThread().getId()) : threadLocalResults.get(threadId); - - r.testParam = parameter; - totalSize += parameter; - } - - /** - * Should be called every time a test completes with the current number of test threads running. This should not - * change within a test batch, therefore it is safe to take this as a batch level property value too. - * - * @param test The test for which the measurement is being generated. - * @param threads The number of tests being run concurrently. - * @param threadId Optional thread id if not calling from thread that started the test method. May be null. - */ - public void concurrencyLevel(Test test, int threads, Long threadId) - { - // log.debug("public void concurrencyLevel(Test test = \"" + test + "\", int threads = " + threads + "): called"); - - TestResult r = - (threadId == null) ? threadLocalResults.get(Thread.currentThread().getId()) : threadLocalResults.get(threadId); - - r.testConcurrency = threads; - concurrencyLevel = threads; - - } - - /** - * Called when a test completes. Success, failure and errors. This method should be used when registering an - * end test from a different thread than the one that started the test. - * - * @param test The test which completed. - * @param threadId Optional thread id if not calling from thread that started the test method. May be null. - */ - public void endTest(Test test, Long threadId) - { - // log.debug("public void endTest(Test test = \"" + test + "\", Long threadId " + threadId + "): called"); - - TestResult r = - (threadId == null) ? threadLocalResults.get(Thread.currentThread().getId()) : threadLocalResults.get(threadId); - - writeTestResults(r, test); - } - - /** - * Takes a time stamp for the beginning of the batch and resets stats counted for the batch. - */ - public synchronized void startBatch() - { - numError = 0; - numFailed = 0; - numPassed = 0; - totalTests = 0; - totalSize = 0; - batchStartTime = System.nanoTime(); - summedTime = 0; - summedTime2 = 0; - batchStarted = true; - - // Write out the column headers for the batch. - writeColumnHeaders(); - } - - /** - * Takes a time stamp for the end of the batch to calculate the total run time. - * Write this and other stats out to the tail of the csv file. - * - * @param parameters The optional test parameters, may be null. - */ - public synchronized void endBatch(Properties parameters) - { - boolean noParams = (parameters == null) || (parameters.size() == 0); - - // Check that a batch has been started but not ended. - if (batchStarted) - { - long batchEndTime = System.nanoTime(); - float totalTimeMillis = ((float) (batchEndTime - batchStartTime)) / 1000000f; - float summedTimeMillis = ((float) summedTime) / 1000000f; - float summedTime2Millis = ((float) summedTime2) / 1000000f; - - - // Write the stats for the batch out. - try - { - synchronized (this.getClass()) - { - timingsWriter.write("Total Tests:, " + totalTests + ", "); - timingsWriter.write("Total Passed:, " + numPassed + ", "); - timingsWriter.write("Total Failed:, " + numFailed + ", "); - timingsWriter.write("Total Error:, " + numError + ", "); - timingsWriter.write("Total Size:, " + totalSize + ", "); - timingsWriter.write("Summed Time:, " + summedTimeMillis + ", "); - timingsWriter.write("Summed Custom Time:, " + summedTime2Millis + ", "); - timingsWriter.write("Concurrency Level:, " + concurrencyLevel + ", "); - timingsWriter.write("Total Time:, " + totalTimeMillis + ", "); - timingsWriter.write("Average Custom Time:, " + ((summedTime2Millis/ (float) totalTests)) + ", "); - timingsWriter.write("Test Throughput:, " + (((float) totalTests) / totalTimeMillis) + ", "); - timingsWriter.write("Test * Size Throughput:, " + (((float) totalSize) / totalTimeMillis) - + (noParams ? "\n\n" : ", ")); - - // Write out the test parameters if there are any specified. - if (!noParams) - { - properties(parameters); - } - - timingsWriter.flush(); - } - } - catch (IOException e) - { - throw new RuntimeException("Unable to write out end batch statistics: " + e, e); - } - } - - // Reset the batch started flag to ensure stats are only output once. - batchStarted = false; - } - - /** - * Notifies listeners of the tests read/set properties. - * - * @param properties The tests read/set properties. - */ - public void properties(Properties properties) - { - // log.debug("public void properties(Properties properties): called"); - - // Write the properties out to the results file. - try - { - synchronized (this.getClass()) - { - Set keySet = new TreeSet(properties.keySet()); - - // timingsWriter.write("\n"); - - for (Object key : keySet) - { - timingsWriter.write(key + " = , " + properties.getProperty((String) key) + ", "); - } - - timingsWriter.write("\n\n"); - // timingsWriter.flush(); - } - } - catch (IOException e) - { - throw new RuntimeException("Unable to write out test parameters: " + e, e); - } - - // Write out the column headers after the properties. - // writeColumnHeaders(); - } - - /** - * Writes out and flushes the column headers for raw test data. - */ - private void writeColumnHeaders() - { - // Write the column headers for the CSV file. Any IO exceptions are ignored. - try - { - timingsWriter.write("Class, "); - timingsWriter.write("Method, "); - timingsWriter.write("Thread, "); - timingsWriter.write("Test Outcome, "); - timingsWriter.write("Time (milliseconds), "); - timingsWriter.write("Custom Time (milliseconds), "); - timingsWriter.write("Memory Used (bytes), "); - timingsWriter.write("Concurrency level, "); - timingsWriter.write("Test Size\n"); - - timingsWriter.flush(); - } - catch (IOException e) - { - throw new RuntimeException("Unable to write out column headers: " + e, e); - } - } - - /** - * Writes out the test results for the specified test. This outputs a single line of results to the csv file. - * - * @param r The test results to write out. - * @param test The test to write them out for. - */ - private void writeTestResults(TestResult r, Test test) - { - // Update the running stats for this batch. - if ("Error".equals(r.testState)) - { - numError++; - } - else if ("Failure".equals(r.testState)) - { - numFailed++; - } - else if ("Pass".equals(r.testState)) - { - numPassed++; - } - - totalTests++; - - // Write the test name and thread information plus all instrumenation a line of the CSV ouput. Any IO - // exceptions are ignored. - try - { - synchronized (this.getClass()) - { - timingsWriter.write(test.getClass().getName() + ", "); - timingsWriter.write(((test instanceof TestCase) ? ((TestCase) test).getName() : "") + ", "); - timingsWriter.write(Thread.currentThread().getName() + ", "); - timingsWriter.write(r.testState + ", "); - timingsWriter.write((((float) r.testTime) / 1000000f) + ", "); - - timingsWriter.write(r.testTime2 == null ? "- , " : - (((float) r.testTime2) / 1000000f) + ", "); - timingsWriter.write((r.testEndMem - r.testStartMem) + ", "); - timingsWriter.write(r.testConcurrency + ", "); - timingsWriter.write(r.testParam + "\n"); - } - } - catch (IOException e) - { - throw new RuntimeException("Unable to write out test results: " + e, e); - } - } - - /** - * Supplies the shutdown hook. This attempts to flush the results in the event of the test runner being prematurely - * suspended before the end of the current test batch. - * - * @return The shut down hook. - */ - public Thread getShutdownHook() - { - return new Thread(new Runnable() - { - public void run() - { - log.debug("CSVTestListener::ShutdownHook: called"); - - // Complete the current test batch stats. - endBatch(TestContextProperties.getInstance()); - } - }); - } - - /** Captures test results packaged into a single object, so that it can be set up as a thread local. */ - private static class TestResult - { - /** Used to hold the test timing. */ - public long testTime; - - /** Use to hold the second timing information. */ - public Long testTime2; - - /** Used to hold the test start memory usage. */ - public long testStartMem; - - /** Used to hold the test end memory usage. */ - public long testEndMem; - - /** Used to hold the test pass/fail/error state. */ - public String testState = "Pass"; - - /** Used to hold the test parameter value. */ - public int testParam; - - /** Used to hold the concurrency level under which the test was run. */ - public int testConcurrency; - - } -} diff --git a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/listeners/ConsoleTestListener.java b/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/listeners/ConsoleTestListener.java deleted file mode 100644 index 276fec328e..0000000000 --- a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/listeners/ConsoleTestListener.java +++ /dev/null @@ -1,274 +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.junit.extensions.listeners; - -import junit.framework.AssertionFailedError; -import junit.framework.Test; -import junit.framework.TestListener; - -import org.apache.qpid.junit.extensions.SleepThrottle; -import org.apache.qpid.junit.extensions.Throttle; - -import java.util.Properties; - -/** - * ConsoleTestListener provides feedback to the console, as test timings are taken, by drawing a '.', or an 'E', or an - * 'F', for each test that passes, is in error or fails. It does this for every test result registered with the framework, - * not just on the completion of each test method as the JUnit one does. It also uses a throttle to cap the rate of - * dot drawing, as exessively high rates can degrade test performance without providing much usefull feedback to the user. - * Unlike the JUnit dot drawing feedback, this one will correctly wrap lines when tests are run concurrently (the - * rate capping ensures that this does not become a hot-spot for thread contention). - * - * <p/>Where rate capping causes the conflation of multiple requested dots into a single dot, the dot that is actually - * drawn will be the worst result within the conflation period, that is, error is worse than fail which is worse than pass. - * - * <p/><table id="crc"><caption>CRC Card</caption> - * <tr><th> Responsibilities <th> Collaborations - * <tr><td> Draw dots as each test result completes, at a capped rate. - * </table> - * - * @author Rupert Smith - */ -public class ConsoleTestListener implements TestListener, TKTestListener -{ - /** Used to indicate a test pass. */ - private static final int PASS = 1; - - /** Used to indicate a test failure. */ - private static final int FAIL = 2; - - /** Used to indicate a test error. */ - private static final int ERROR = 3; - - /** Defines the maximum number of columns of dots to print. */ - private static final int MAX_COLUMNS = 80; - - /** Used to throttle the dot writing rate. */ - Throttle throttle; - - /** Tracks the worst test result so far, when the throttled print method must conflate results due to throttling. */ - private int conflatedResult = 0; - - /** Tracks the column count as dots are printed, so that newlines can be inserted at the right margin. */ - private int columnCount = 0; - - /** Used as a monitor on the print method criticial section, to ensure that line ends always happen in the right place. */ - private final Object printMonitor = new Object(); - - /** - * Creates a dot drawing feedback test listener, set by default to 80 columns at 80 dots per second capped rate. - */ - public ConsoleTestListener() - { - throttle = new SleepThrottle(); - throttle.setRate(80f); - } - - /** - * Prints dots at a capped rate, conflating the requested type of dot to draw if this method is called at a rate - * higher than the capped rate. The conflation works by always printing the worst result that occurs within the - * conflation period, that is, error is worse than fail which is worse than a pass. - * - * @param result The type of dot to draw, {@link #PASS}, {@link #FAIL} or {@link #ERROR}. - */ - private void throttledPrint(int result) - { - conflatedResult = (result > conflatedResult) ? result : conflatedResult; - - if (throttle.checkThrottle()) - { - synchronized (printMonitor) - { - switch (conflatedResult) - { - default: - case PASS: - System.out.print('.'); - break; - - case FAIL: - System.out.print('F'); - break; - - case ERROR: - System.out.print('E'); - break; - } - - columnCount = (columnCount >= MAX_COLUMNS) ? 0 : (columnCount + 1); - - if (columnCount == 0) - { - System.out.print('\n'); - } - - conflatedResult = 0; - } - } - } - - /** - * An error occurred. - * - * @param test The test in error. Ignored. - * @param t The error that the test threw. Ignored. - */ - public void addError(Test test, Throwable t) - { - throttledPrint(ERROR); - } - - /** - * A failure occurred. - * - * @param test The test that failed. Ignored. - * @param t The assertion failure that the test threw. Ignored. - */ - public void addFailure(Test test, AssertionFailedError t) - { - throttledPrint(FAIL); - } - - /** - * A test ended. - * - * @param test The test that ended. Ignored. - */ - public void endTest(Test test) - { - throttledPrint(PASS); - } - - /** - * A test started. - * - * @param test The test that started. Ignored. - */ - public void startTest(Test test) - { } - - /** - * Resets the test results to the default state of time zero, memory usage zero, parameter zero, test passed. - * - * @param test The test to resest any results for. - * @param threadId Optional thread id if not calling from thread that started the test method. May be null. - */ - public void reset(Test test, Long threadId) - { } - - /** - * Should be called every time a test completes with the run time of that test. - * - * @param test The name of the test. - * @param nanos The run time of the test in nanoseconds. - * @param threadId Optional thread id if not calling from thread that started the test method. May be null. - */ - public void timing(Test test, long nanos, Long threadId) - { } - - /** - * Optionally called every time a test completes with the second timing test. - * - * @param test The name of the test. - * @param nanos The second timing information of the test in nanoseconds. - * @param threadId Optional thread id if not calling from thread that started the test method. May be null. - */ - public void timing2(Test test, Long nanos, Long threadId) - { } - - /** - * Should be called every time a test completed with the amount of memory used before and after the test was run. - * - * @param test The test which memory was measured for. - * @param memStart The total JVM memory used before the test was run. - * @param memEnd The total JVM memory used after the test was run. - * @param threadId Optional thread id if not calling from thread that started the test method. May be null. - */ - public void memoryUsed(Test test, long memStart, long memEnd, Long threadId) - { } - - /** - * Should be called every time a parameterized test completed with the int value of its test parameter. - * - * @param test The test which memory was measured for. - * @param parameter The int parameter value. - * @param threadId Optional thread id if not calling from thread that started the test method. May be null. - */ - public void parameterValue(Test test, int parameter, Long threadId) - { } - - /** - * Should be called every time a test completes with the current number of test threads running. - * - * @param test The test for which the measurement is being generated. - * @param threads The number of tests being run concurrently. - * @param threadId Optional thread id if not calling from thread that started the test method. May be null. - */ - public void concurrencyLevel(Test test, int threads, Long threadId) - { } - - /** - * Called when a test completes. Success, failure and errors. This method should be used when registering an - * end test from a different thread than the one that started the test. - * - * @param test The test which completed. - * @param threadId Optional thread id if not calling from thread that started the test method. May be null. - */ - public void endTest(Test test, Long threadId) - { - throttledPrint(PASS); - } - - /** - * Called when a test completes to mark it as a test fail. This method should be used when registering a - * failure from a different thread than the one that started the test. - * - * @param test The test which failed. - * @param e The assertion that failed the test. - * @param threadId Optional thread id if not calling from thread that started the test method. May be null. - */ - public void addFailure(Test test, AssertionFailedError e, Long threadId) - { - throttledPrint(FAIL); - } - - /** - * Notifies listeners of the start of a complete run of tests. - */ - public void startBatch() - { } - - /** - * Notifies listeners of the end of a complete run of tests. - * - * @param parameters The optional test parameters to log out with the batch results. - */ - public void endBatch(Properties parameters) - { } - - /** - * Notifies listeners of the tests read/set properties. - * - * @param properties The tests read/set properties. - */ - public void properties(Properties properties) - { } -} diff --git a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/listeners/TKTestListener.java b/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/listeners/TKTestListener.java deleted file mode 100644 index 63b042db10..0000000000 --- a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/listeners/TKTestListener.java +++ /dev/null @@ -1,142 +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.junit.extensions.listeners; - -import junit.framework.AssertionFailedError; -import junit.framework.Test; -import junit.framework.TestListener; - -import java.util.Properties; - -/** - * TKTestListener is a listener interface for listeners that want to be informed of the run times of tests, the memory - * usage of tests, the 'size' parameters of parameterized tests and the begin and end events of complete test runs. - * {@link org.apache.qpid.junit.extensions.TKTestResult} is an example of a test result class that listeners - * interested in these events can be attached to. - * - * The {@link #timing(junit.framework.Test, long, Long)}, {@link #memoryUsed(junit.framework.Test, long, long, Long)}, - * {@link #parameterValue(junit.framework.Test, int, Long)} and {@link #endTest(junit.framework.Test, Long)} methods - * all accept on optional thread id parameter. - * - * <p><table id="crc"><caption>CRC Card</caption> - * <tr><th> Responsibilities - * <tr><td> Listen to test timings. - * <tr><td> Listen to test memory usages. - * <tr><td> Listen to parameterized test parameters. - * </table> - * - * @author Rupert Smith - */ -public interface TKTestListener extends TestListener -{ - /** - * Resets the test results to the default state of time zero, memory usage zero, parameter zero, test passed. - * - * @param test The test to resest any results for. - * @param threadId Optional thread id if not calling from thread that started the test method. May be null. - */ - public void reset(Test test, Long threadId); - - /** - * Should be called every time a test completes with the run time of that test. - * - * @param test The name of the test. - * @param nanos The run time of the test in nanoseconds. - * @param threadId Optional thread id if not calling from thread that started the test method. May be null. - */ - public void timing(Test test, long nanos, Long threadId); - - - /** - * Optionally called every time a test completes with the second timing test. - * - * @param test The name of the test. - * @param nanos The second timing information of the test in nanoseconds. - * @param threadId Optional thread id if not calling from thread that started the test method. May be null. - */ - public void timing2(Test test, Long nanos, Long threadId); - - /** - * Should be called every time a test completed with the amount of memory used before and after the test was run. - * - * @param test The test which memory was measured for. - * @param memStart The total JVM memory used before the test was run. - * @param memEnd The total JVM memory used after the test was run. - * @param threadId Optional thread id if not calling from thread that started the test method. May be null. - */ - public void memoryUsed(Test test, long memStart, long memEnd, Long threadId); - - /** - * Should be called every time a parameterized test completed with the int value of its test parameter. - * - * @param test The test which memory was measured for. - * @param parameter The int parameter value. - * @param threadId Optional thread id if not calling from thread that started the test method. May be null. - */ - public void parameterValue(Test test, int parameter, Long threadId); - - /** - * Should be called every time a test completes with the current number of test threads running. - * - * @param test The test for which the measurement is being generated. - * @param threads The number of tests being run concurrently. - * @param threadId Optional thread id if not calling from thread that started the test method. May be null. - */ - public void concurrencyLevel(Test test, int threads, Long threadId); - - /** - * Called when a test completes. Success, failure and errors. This method should be used when registering an - * end test from a different thread than the one that started the test. - * - * @param test The test which completed. - * @param threadId Optional thread id if not calling from thread that started the test method. May be null. - */ - public void endTest(Test test, Long threadId); - - /** - * Called when a test completes to mark it as a test fail. This method should be used when registering a - * failure from a different thread than the one that started the test. - * - * @param test The test which failed. - * @param e The assertion that failed the test. - * @param threadId Optional thread id if not calling from thread that started the test method. May be null. - */ - public void addFailure(Test test, AssertionFailedError e, Long threadId); - - /** - * Notifies listeners of the start of a complete run of tests. - */ - public void startBatch(); - - /** - * Notifies listeners of the end of a complete run of tests. - * - * @param parameters The optional test parameters to log out with the batch results. - */ - public void endBatch(Properties parameters); - - /** - * Notifies listeners of the tests read/set properties. - * - * @param properties The tests read/set properties. - */ - public void properties(Properties properties); -} diff --git a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/listeners/XMLTestListener.java b/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/listeners/XMLTestListener.java deleted file mode 100644 index ac875f89cf..0000000000 --- a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/listeners/XMLTestListener.java +++ /dev/null @@ -1,410 +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.junit.extensions.listeners; - -import junit.framework.AssertionFailedError; -import junit.framework.Test; -import junit.framework.TestCase; - -import org.apache.log4j.Logger; - -import org.apache.qpid.junit.extensions.ShutdownHookable; - -import java.io.IOException; -import java.io.PrintWriter; -import java.io.Writer; -import java.util.*; - -/** - * Listens for test results for a named test and outputs these in the standard JUnit XML format to the specified - * writer. - * - * <p/>The API for this listener accepts notifications about different aspects of a tests results through different - * methods, so some assumption needs to be made as to which test result a notification refers to. For example - * {@link #startTest} will be called, then possibly {@link #timing} will be called, even though the test instance is - * passed in both cases, it is not enough to distinguish a particular run of the test, as the test case instance may - * be being shared between multiple threads, or being run a repeated number of times, and can therfore be re-used - * between calls. The listeners make the assumption that, for every test, a unique thread will call {@link #startTest} - * and {@link #endTest} to delimit each test. All calls to set test parameters, timings, state and so on, will occur - * between the start and end and will be given with the same thread id as the start and end, so the thread id provides - * a unqiue value to identify a particular test run against. - * - * <p><table id="crc"><caption>CRC Card</caption> - * <tr><th> Responsibilities <th> Collaborations - * <tr><td> Listen to test lifecycle notifications. - * <tr><td> Listen to test errors and failures. - * <tr><td> Listen to test timings. - * <tr><td> Listen to test memory usages. - * <tr><td> Listen to parameterized test parameters. - * <tr><th> Responsibilities - * </table> - * - * @todo Merge this class with CSV test listener, making the collection of results common to both, and only factoring - * out the results printing code into sub-classes. Provide a simple XML results formatter with the same format as - * the ant XML formatter, and a more structured one for outputing results with timings and summaries from - * performance tests. - * - * @author Rupert Smith - */ -public class XMLTestListener implements TKTestListener, ShutdownHookable -{ - /** Used for debugging. */ - private static final Logger log = Logger.getLogger(XMLTestListener.class); - - /** The results file writer. */ - protected Writer writer; - - /** Holds the results for individual tests. */ - // protected Map<Result, Result> results = new LinkedHashMap<Result, Result>(); - // protected List<Result> results = new ArrayList<Result>(); - - /** - * Map for holding results on a per thread basis as they come in. A ThreadLocal is not used as sometimes an - * explicit thread id must be used, where notifications come from different threads than the ones that called - * the test method. - */ - Map<Long, Result> threadLocalResults = Collections.synchronizedMap(new LinkedHashMap<Long, Result>()); - - /** - * Holds results for tests that have ended. Transferring these results here from the per-thread results map, means - * that the thread id is freed for the thread to generate more results. - */ - List<Result> results = new ArrayList<Result>(); - - /** Holds the overall error count. */ - protected int errors = 0; - - /** Holds the overall failure count. */ - protected int failures = 0; - - /** Holds the overall tests run count. */ - protected int runs = 0; - - /** Holds the name of the class that tests are being run for. */ - String testClassName; - - /** - * Creates a new XML results output listener that writes to the specified location. - * - * @param writer The location to write results to. - * @param testClassName The name of the test class to include in the test results. - */ - public XMLTestListener(Writer writer, String testClassName) - { - log.debug("public XMLTestListener(Writer writer, String testClassName = " + testClassName + "): called"); - - this.writer = writer; - this.testClassName = testClassName; - } - - /** - * Resets the test results to the default state of time zero, memory usage zero, parameter zero, test passed. - * - * @param test The test to resest any results for. - * @param threadId Optional thread id if not calling from thread that started the test method. May be null. - */ - public void reset(Test test, Long threadId) - { - log.debug("public void reset(Test test = " + test + ", Long threadId = " + threadId + "): called"); - - XMLTestListener.Result r = - (threadId == null) ? threadLocalResults.get(Thread.currentThread().getId()) : threadLocalResults.get(threadId); - - r.error = null; - r.failure = null; - - } - - /** - * Notification that a test started. - * - * @param test The test that started. - */ - public void startTest(Test test) - { - log.debug("public void startTest(Test test = " + test + "): called"); - - Result newResult = new Result(test.getClass().getName(), ((TestCase) test).getName()); - - // Initialize the thread local test results. - threadLocalResults.put(Thread.currentThread().getId(), newResult); - runs++; - } - - /** - * Should be called every time a test completes with the run time of that test. - * - * @param test The name of the test. - * @param nanos The run time of the test in nanoseconds. - * @param threadId Optional thread id if not calling from thread that started the test method. May be null. - */ - public void timing(Test test, long nanos, Long threadId) - { } - - /** - * Optionally called every time a test completes with the second timing test. - * - * @param test The name of the test. - * @param nanos The second timing information of the test in nanoseconds. - * @param threadId Optional thread id if not calling from thread that started the test method. May be null. - */ - public void timing2(Test test, Long nanos, Long threadId) - { } - - /** - * Should be called every time a test completed with the amount of memory used before and after the test was run. - * - * @param test The test which memory was measured for. - * @param memStart The total JVM memory used before the test was run. - * @param memEnd The total JVM memory used after the test was run. - * @param threadId Optional thread id if not calling from thread that started the test method. May be null. - */ - public void memoryUsed(Test test, long memStart, long memEnd, Long threadId) - { } - - /** - * Should be called every time a parameterized test completed with the int value of its test parameter. - * - * @param test The test which memory was measured for. - * @param parameter The int parameter value. - * @param threadId Optional thread id if not calling from thread that started the test method. May be null. - */ - public void parameterValue(Test test, int parameter, Long threadId) - { } - - /** - * Should be called every time a test completes with the current number of test threads running. - * - * @param test The test for which the measurement is being generated. - * @param threads The number of tests being run concurrently. - * @param threadId Optional thread id if not calling from thread that started the test method. May be null. - */ - public void concurrencyLevel(Test test, int threads, Long threadId) - { } - - /** - * Notifies listeners of the tests read/set properties. - * - * @param properties The tests read/set properties. - */ - public void properties(Properties properties) - { } - - /** - * Notification that a test ended. - * - * @param test The test that ended. - */ - public void endTest(Test test) - { - log.debug("public void endTest(Test test = " + test + "): called"); - - // Move complete test results into the completed tests list. - Result r = threadLocalResults.get(Thread.currentThread().getId()); - results.add(r); - - // Clear all the test results for the thread. - threadLocalResults.remove(Thread.currentThread().getId()); - } - - /** - * Called when a test completes. Success, failure and errors. This method should be used when registering an - * end test from a different thread than the one that started the test. - * - * @param test The test which completed. - * @param threadId Optional thread id if not calling from thread that started the test method. May be null. - */ - public void endTest(Test test, Long threadId) - { - log.debug("public void endTest(Test test = " + test + ", Long threadId = " + threadId + "): called"); - - // Move complete test results into the completed tests list. - Result r = - (threadId == null) ? threadLocalResults.get(Thread.currentThread().getId()) : threadLocalResults.get(threadId); - results.add(r); - - // Clear all the test results for the thread. - threadLocalResults.remove(Thread.currentThread().getId()); - } - - /** - * An error occurred. - * - * @param test The test in which the error occurred. - * @param t The throwable that resulted from the error. - */ - public void addError(Test test, Throwable t) - { - log.debug("public void addError(Test test = " + test + ", Throwable t = " + t + "): called"); - - Result r = threadLocalResults.get(Thread.currentThread().getId()); - r.error = t; - errors++; - } - - /** - * A failure occurred. - * - * @param test The test in which the failure occurred. - * @param t The JUnit assertions that led to the failure. - */ - public void addFailure(Test test, AssertionFailedError t) - { - log.debug("public void addFailure(Test test = " + test + ", AssertionFailedError t = " + t + "): called"); - - Result r = threadLocalResults.get(Thread.currentThread().getId()); - r.failure = t; - failures++; - } - - /** - * Called when a test completes to mark it as a test fail. This method should be used when registering a - * failure from a different thread than the one that started the test. - * - * @param test The test which failed. - * @param e The assertion that failed the test. - * @param threadId Optional thread id if not calling from thread that started the test method. May be null. - */ - public void addFailure(Test test, AssertionFailedError e, Long threadId) - { - log.debug("public void addFailure(Test test, AssertionFailedError e, Long threadId): called"); - - Result r = - (threadId == null) ? threadLocalResults.get(Thread.currentThread().getId()) : threadLocalResults.get(threadId); - r.failure = e; - failures++; - } - - /** - * Notifies listeners of the start of a complete run of tests. - */ - public void startBatch() - { - log.debug("public void startBatch(): called"); - - // Reset all results counts. - threadLocalResults = Collections.synchronizedMap(new HashMap<Long, Result>()); - errors = 0; - failures = 0; - runs = 0; - - // Write out the file header. - try - { - writer.write("<?xml version=\"1.0\" ?>\n"); - } - catch (IOException e) - { - throw new RuntimeException("Unable to write the test results.", e); - } - } - - /** - * Notifies listeners of the end of a complete run of tests. - * - * @param parameters The optional test parameters to log out with the batch results. - */ - public void endBatch(Properties parameters) - { - log.debug("public void endBatch(Properties parameters = " + parameters + "): called"); - - // Write out the results. - try - { - // writer.write("<?xml version=\"1.0\" ?>\n"); - writer.write("<testsuite errors=\"" + errors + "\" failures=\"" + failures + "\" tests=\"" + runs + "\" name=\"" - + testClassName + "\">\n"); - - for (Result result : results) - { - writer.write(" <testcase classname=\"" + result.testClass + "\" name=\"" + result.testName + "\">\n"); - - if (result.error != null) - { - writer.write(" <error type=\"" + result.error.getClass() + "\">"); - result.error.printStackTrace(new PrintWriter(writer)); - writer.write(" </error>"); - } - else if (result.failure != null) - { - writer.write(" <failure type=\"" + result.failure.getClass() + "\">"); - result.failure.printStackTrace(new PrintWriter(writer)); - writer.write(" </failure>"); - } - - writer.write(" </testcase>\n"); - } - - writer.write("</testsuite>\n"); - writer.flush(); - } - catch (IOException e) - { - throw new RuntimeException("Unable to write the test results.", e); - } - } - - /** - * Supplies the shutdown hook. - * - * @return The shut down hook. - */ - public Thread getShutdownHook() - { - return new Thread(new Runnable() - { - public void run() - { - log.debug("XMLTestListener::ShutdownHook: called"); - } - }); - } - - /** - * Used to capture the results of a particular test run. - */ - protected static class Result - { - /** Holds the name of the test class. */ - public String testClass; - - /** Holds the name of the test method. */ - public String testName; - - /** Holds the exception that caused error in this test. */ - public Throwable error; - - /** Holds the assertion exception that caused failure in this test. */ - public AssertionFailedError failure; - - /** - * Creates a placeholder for the results of a test. - * - * @param testClass The test class. - * @param testName The name of the test that was run. - */ - public Result(String testClass, String testName) - { - this.testClass = testClass; - this.testName = testName; - } - } -} diff --git a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/listeners/package.html b/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/listeners/package.html deleted file mode 100644 index 15acc02ab1..0000000000 --- a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/listeners/package.html +++ /dev/null @@ -1,27 +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. - ---> - -<html> -<body> -Listners for test statistics are defined in this package. At the moment there is only one listener which writes all test -statistics out to a CSV (comma seperated values) file which can be loaded by most spread sheets. -</body> -</html> diff --git a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/package.html b/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/package.html deleted file mode 100644 index 4cab8d936a..0000000000 --- a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/package.html +++ /dev/null @@ -1,33 +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. - ---> - -<html> -<body> -Basic JUnit is enahanced with test runners to run tests repeatedly, simultaneously in many threads and with increasing -test sizes for asymptotic performance measurements. There are features to measure the time and amount of memory that -tests use as well as to record the asymptotic test size parameters. There are some utilities to write these test -statistics to various file formats too and these can be found in the listeners package. - -</p>The main test runner class is TKTestRunner which can be called with command line parameters to specify how tests -should be run. - -</body> -</html> diff --git a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/util/CommandLineParser.java b/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/util/CommandLineParser.java deleted file mode 100644 index f158090e96..0000000000 --- a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/util/CommandLineParser.java +++ /dev/null @@ -1,787 +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.junit.extensions.util; - -import java.text.CharacterIterator; -import java.text.StringCharacterIterator; -import java.util.*; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * CommandLineParser provides a utility for specifying the format of a command line and parsing command lines to ensure - * that they fit their specified format. A command line is made up of flags and options, both may be refered to as - * options. A flag is an option that does not take an argument (specifying it means it has the value 'true' and not - * specifying it means it has the value 'false'). Options must take arguments but they can be set up with defaults so - * that they take a default value when not set. Options may be mandatory in wich case it is an error not to specify - * them on the command line. Flags are never mandatory because they are implicitly set to false when not specified. - * - * <p/>Some examples command line are: - * - * <ul> - * <li>This one has two options that expect arguments: - * <pre> - * cruisecontrol -configfile cruisecontrol.xml -port 9000 - * </pre> - * <li>This has one no-arg flag and two 'free' arguments: - * <pre> - * zip -r project.zip project/* - * </pre> - * <li>This one concatenates multiple flags into a single block with only one '-': - * <pre> - * jar -tvf mytar.tar - * </pre> - * - * <p/>The parsing rules are: - * - * <ol> - * <li>Flags may be combined after a single '-' because they never take arguments. Normally such flags are single letter - * flags but this is only a convention and not enforced. Flags of more than one letter are usually specified on their own. - * <li>Options expecting arguments must always be on their own. - * <li>The argument to an option may be seperated from it by whitespace or appended directly onto the option. - * <li>The argument to an option may never begin with a '-' character. - * <li>All other arguments not beginning with a '-' character are free arguments that do not belong to any option. - * <li>The second or later of a set of duplicate or repeated flags override earlier ones. - * <li>Options are matched up to the shortest matching option. This is because of the possibility of having no space - * between an option and its argument. This rules out the possibility of using two options where one is an opening - * substring of the other. For example, the options "foo" and "foobar" cannot be used on the same command line because - * it is not possible to distinguish the argument "-foobar" from being the "foobar" option or the "foo" option with - * the "bar" argument. - * </ol> - * - * <p/>By default, unknown options are simply ignored if specified on the command line. This behaviour may be changed - * so that the parser reports all unknowns as errors by using the {@link #setErrorsOnUnknowns} method. - * - * <p><table id="crc"><caption>CRC Card</caption> - * <tr><th> Responsibilities <th> Collaborations - * <tr><td> Accept a command line specification. - * <tr><td> Parse a command line into properties, validating it against its specification. - * <tr><td> Report all errors between a command line and its specification. - * <tr><td> Provide a formatted usage string for a command line. - * <tr><td> Provide a formatted options in force string for a command line. - * <tr><td> Allow errors on unknowns behaviour to be turned on or off. - * </table> - * - * @author Rupert Smith - */ -public class CommandLineParser -{ - /** - * Holds a mapping from command line option names to detailed information about those options. - * Use of a tree map ensures that the options are easy to print in alphabetical order as a usage string. - * An alternative might be to use a LinkedHashMap to print them in the order they are specified. - */ - private Map<String, CommandLineOption> optionMap = new TreeMap<String, CommandLineOption>(); - - /** Holds a list of parsing errors. */ - private List<String> parsingErrors = new ArrayList<String>(); - - /** Holds the regular head matcher to match command line options with. */ - private Matcher optionMatcher = null; - - /** Holds the parsed command line properties after parsing. */ - private Properties parsedProperties = null; - - /** Holds any trailing name=value pairs specified in the free arguments. */ - private Properties trailingProperties = null; - - /** Flag used to indicate that errors should be created for unknown options. False by default. */ - private boolean errorsOnUnknowns = false; - - /** - * Creates a command line options parser from a command line specification. This is passed to this constructor - * as an array of arrays of strings. Each array of strings specifies the command line for a single option. A static - * array may therefore easily be used to configure the command line parser in a single method call with an easily - * readable format. - * - * <p/>Each array of strings must be 2, 3, 4 or 5 elements long. If any of the last three elements are missing they - * are assumed to be null. The elements specify the following parameters: - * <ol> - * <li>The name of the option without the leading '-'. For example, "file". To specify the format of the 'free' - * arguments use the option names "1", "2", ... and so on. - * <li>The option comment. A line of text describing the usage of the option. For example, "The file to be processed." - * <li>The options argument. This is a very short description of the argument to the option, often a single word - * or a reminder as to the arguments format. When this element is null the option is a flag and does not - * accept any arguments. For example, "filename" or "(unix | windows)" or null. The actual text specified - * is only used to print in the usage message to remind the user of the usage of the option. - * <li>The mandatory flag. When set to "true" an option must always be specified. Any other value, including null, - * means that the option is mandatory. Flags are always mandatory (see class javadoc for explanation of why) so - * this is ignored for flags. - * <li>A regular head describing the format that the argument must take. Ignored if null. - * </ol> - * <p/>An example call to this constructor is: - * - * <pre> - * CommandLineParser commandLine = new CommandLineParser( - * new String[][] {{"file", "The file to be processed. ", "filename", "true"}, - * {"dir", "Directory to store results in. Current dir used if not set.", "out dir"}, - * {"os", "Operating system EOL format to use.", "(windows | unix)", null, "windows\|unix"}, - * {"v", "Verbose mode. Prints information about the processing as it goes."}, - * {"1", "The processing command to run.", "command", "true", "add\|remove\|list"}}); - * </pre> - * - * @param config The configuration as an array of arrays of strings. - */ - public CommandLineParser(String[][] config) - { - // Loop through all the command line option specifications creating details for each in the options map. - for (String[] nextOptionSpec : config) - { - addOption(nextOptionSpec[0], nextOptionSpec[1], (nextOptionSpec.length > 2) ? nextOptionSpec[2] : null, - (nextOptionSpec.length > 3) && ("true".equals(nextOptionSpec[3])), - (nextOptionSpec.length > 4) ? nextOptionSpec[4] : null); - } - } - - /** - * Extracts all name=value pairs from the command line, sets them all as system properties and also returns - * a map of properties containing them. - * - * @param args The command line. - * @param commandLine The command line parser. - * @param properties The properties object to inject all parsed properties into (optional may be <tt>null</tt>). - * - * @return A set of properties containing all name=value pairs from the command line. - */ - public static Properties processCommandLine(String[] args, CommandLineParser commandLine, Properties properties) - { - // Capture the command line arguments or display errors and correct usage and then exit. - Properties options = null; - - try - { - options = commandLine.parseCommandLine(args); - - // Add all the command line options and trailing settings to properties if the optional properties object - // to copy them into has been set. - if (properties != null) - { - commandLine.addTrailingPairsToProperties(properties); - commandLine.addOptionsToProperties(properties); - } - } - catch (IllegalArgumentException e) - { - System.out.println(commandLine.getErrors()); - System.out.println(commandLine.getUsage()); - System.exit(1); - } - - return options; - } - - /** - * Lists all the parsing errors from the most recent parsing in a string. - * - * @return All the parsing errors from the most recent parsing. - */ - public String getErrors() - { - // Return the empty string if there are no errors. - if (parsingErrors.isEmpty()) - { - return ""; - } - - // Concatenate all the parsing errors together. - String result = ""; - - for (String s : parsingErrors) - { - result += s; - } - - return result; - } - - /** - * Lists the properties set from the most recent parsing or an empty string if no parsing has been done yet. - * - * @return The properties set from the most recent parsing or an empty string if no parsing has been done yet. - */ - public String getOptionsInForce() - { - // Check if there are no properties to report and return and empty string if so. - if (parsedProperties == null) - { - return ""; - } - - // List all the properties. - String result = "Options in force:\n"; - - for (Map.Entry<Object, Object> property : parsedProperties.entrySet()) - { - result += property.getKey() + " = " + property.getValue() + "\n"; - } - - return result; - } - - /** - * Generates a usage string consisting of the name of each option and each options argument description and - * comment. - * - * @return A usage string for all the options. - */ - public String getUsage() - { - String result = "Options:\n"; - - int optionWidth = 0; - int argumentWidth = 0; - - // Calculate the column widths required for aligned layout. - for (CommandLineOption optionInfo : optionMap.values()) - { - int oWidth = optionInfo.option.length(); - int aWidth = (optionInfo.argument != null) ? (optionInfo.argument.length()) : 0; - - optionWidth = (oWidth > optionWidth) ? oWidth : optionWidth; - argumentWidth = (aWidth > argumentWidth) ? aWidth : argumentWidth; - } - - // Print usage on each of the command line options. - for (CommandLineOption optionInfo : optionMap.values()) - { - String argString = ((optionInfo.argument != null) ? (optionInfo.argument) : ""); - String optionString = optionInfo.option; - - argString = rightPad(argString, " ", argumentWidth); - optionString = rightPad(optionString, " ", optionWidth); - - result += "-" + optionString + " " + argString + " " + optionInfo.comment + "\n"; - } - - return result; - } - - /** - * Right pads a string with a given string to a given size. This method will repeat the padder string as many - * times as is necessary until the exact specified size is reached. If the specified size is less than the size - * of the original string then the original string is returned unchanged. - * - * <pre> - * Example1 - original string "cat", padder string "white", size 8 gives "catwhite". - * Example2 - original string "cat", padder string "white", size 15 gives "catwhitewhitewh". - * Example3 - original string "cat", padder string "white", size 2 gives "cat". - * </pre> - * - * @param stringToPad The original string. - * @param padder The string to pad onto the original string. - * @param size The required size of the new string. - * - * @return The newly padded string. - */ - public static String rightPad(String stringToPad, String padder, int size) - { - if (padder.length() == 0) - { - return stringToPad; - } - - StringBuffer strb = new StringBuffer(stringToPad); - StringCharacterIterator sci = new StringCharacterIterator(padder); - - while (strb.length() < size) - { - for (char ch = sci.first(); ch != CharacterIterator.DONE; ch = sci.next()) - { - if (strb.length() < size) - { - strb.append(String.valueOf(ch)); - } - } - } - - return strb.toString(); - } - - /** - * Control the behaviour of the errors on unkowns reporting. When turned on this reports all unkowns options - * as errors. When turned off, all unknowns are simply ignored. - * - * @param errors The setting of the errors on unkown flag. True to turn it on. - */ - public void setErrorsOnUnknowns(boolean errors) - { - errorsOnUnknowns = errors; - } - - /** - * Parses a set of command line arguments into a set of properties, keyed by the argument flag. The free arguments - * are keyed by integers as strings starting at "1" and then "2", ... and so on. - * - * <p/>See the class level comment for a description of the parsing rules. - * - * @param args The command line arguments. - * - * @return The arguments as a set of properties. - * - * @throws IllegalArgumentException If the command line cannot be parsed against its specification. If this exception - * is thrown a call to {@link #getErrors} will provide a diagnostic of the command - * line errors. - */ - public Properties parseCommandLine(String[] args) throws IllegalArgumentException - { - Properties options = new Properties(); - - // Used to keep count of the current 'free' argument. - int free = 1; - - // Used to indicate that the most recently parsed option is expecting arguments. - boolean expectingArgs = false; - - // The option that is expecting arguments from the next element of the command line. - String optionExpectingArgs = null; - - // Used to indicate that the most recently parsed option is a duplicate and should be ignored. - // boolean ignore = false; - - // Create the regular head matcher for the command line options. - String regexp = "^("; - int optionsAdded = 0; - - for (Iterator<String> i = optionMap.keySet().iterator(); i.hasNext();) - { - String nextOption = i.next(); - - // Check that the option is not a free argument definition. - boolean notFree = false; - - try - { - Integer.parseInt(nextOption); - } - catch (NumberFormatException e) - { - notFree = true; - } - - // Add the option to the regular head matcher if it is not a free argument definition. - if (notFree) - { - regexp += nextOption + (i.hasNext() ? "|" : ""); - optionsAdded++; - } - } - - // There has to be more that one option in the regular head or else the compiler complains that the close - // cannot be nullable if the '?' token is used to make the matched option string optional. - regexp += ")" + ((optionsAdded > 0) ? "?" : "") + "(.*)"; - Pattern pattern = Pattern.compile(regexp); - - // Loop through all the command line arguments. - for (String arg1 : args) - { - // Check if the next command line argument begins with a '-' character and is therefore the start of - // an option. - if (arg1.startsWith("-")) - { - // Extract the value of the option without the leading '-'. - String arg = arg1.substring(1); - - // Match up to the longest matching option. - optionMatcher = pattern.matcher(arg); - optionMatcher.matches(); - - String matchedOption = optionMatcher.group(1); - - // Match any argument directly appended onto the longest matching option. - String matchedArg = optionMatcher.group(2); - - // Check that a known option was matched. - if ((matchedOption != null) && !"".equals(matchedOption)) - { - // Get the command line option information for the matched option. - CommandLineOption optionInfo = optionMap.get(matchedOption); - - // Check if this option is expecting arguments. - if (optionInfo.expectsArgs) - { - // The option is expecting arguments so swallow the next command line argument as an - // argument to this option. - expectingArgs = true; - optionExpectingArgs = matchedOption; - - // In the mean time set this options argument to the empty string in case no argument is ever - // supplied. - // options.put(matchedOption, ""); - } - - // Check if the option was matched on its own and is a flag in which case set that flag. - if ("".equals(matchedArg) && !optionInfo.expectsArgs) - { - options.put(matchedOption, "true"); - } - // The option was matched as a substring with its argument appended to it or is a flag that is - // condensed together with other flags. - else if (!"".equals(matchedArg)) - { - // Check if the option is a flag and therefore is allowed to be condensed together - // with other flags. - if (!optionInfo.expectsArgs) - { - // Set the first matched flag. - options.put(matchedOption, "true"); - - // Repeat the longest matching process on the remainder but ensure that the remainder - // consists only of flags as only flags may be condensed together in this fashion. - do - { - // Match the remainder against the options. - optionMatcher = pattern.matcher(matchedArg); - optionMatcher.matches(); - - matchedOption = optionMatcher.group(1); - matchedArg = optionMatcher.group(2); - - // Check that an option was matched. - if (matchedOption != null) - { - // Get the command line option information for the next matched option. - optionInfo = optionMap.get(matchedOption); - - // Ensure that the next option is a flag or raise an error if not. - if (optionInfo.expectsArgs) - { - parsingErrors.add("Option " + matchedOption + " cannot be combined with flags.\n"); - } - - options.put(matchedOption, "true"); - } - // The remainder could not be matched against a flag it is either an unknown flag - // or an illegal argument to a flag. - else - { - parsingErrors.add("Illegal argument to a flag in the option " + arg + "\n"); - - break; - } - } - // Continue until the remainder of the argument has all been matched with flags. - while (!"".equals(matchedArg)); - } - // The option is expecting an argument, so store the unmatched portion against it - // as its argument. - else - { - // Check the arguments format is correct against any specified format. - checkArgumentFormat(optionInfo, matchedArg); - - // Store the argument against its option (regardless of its format). - options.put(matchedOption, matchedArg); - - // The argument to this flag has already been supplied to it. Do not swallow the - // next command line argument as an argument to this flag. - expectingArgs = false; - } - } - } - else // No matching option was found. - { - // Add this to the list of parsing errors if errors on unkowns is being used. - if (errorsOnUnknowns) - { - parsingErrors.add("Option " + matchedOption + " is not a recognized option.\n"); - } - } - } - // The command line argument did not being with a '-' so it is an argument to the previous flag or it - // is a free argument. - else - { - // Check if a previous flag is expecting to swallow this next argument as its argument. - if (expectingArgs) - { - // Get the option info for the option waiting for arguments. - CommandLineOption optionInfo = optionMap.get(optionExpectingArgs); - - // Check the arguments format is correct against any specified format. - checkArgumentFormat(optionInfo, arg1); - - // Store the argument against its option (regardless of its format). - options.put(optionExpectingArgs, arg1); - - // Clear the expecting args flag now that the argument has been swallowed. - expectingArgs = false; - optionExpectingArgs = null; - } - // This command line option is not an argument to any option. Add it to the set of 'free' options. - else - { - // Get the option info for the free option, if there is any. - CommandLineOption optionInfo = optionMap.get(Integer.toString(free)); - - if (optionInfo != null) - { - // Check the arguments format is correct against any specified format. - checkArgumentFormat(optionInfo, arg1); - } - - // Add to the list of free options. - options.put(Integer.toString(free), arg1); - - // Move on to the next free argument. - free++; - } - } - } - - // Scan through all the specified options to check that all mandatory options have been set and that all flags - // that were not set are set to false in the set of properties. - for (CommandLineOption optionInfo : optionMap.values()) - { - // Check if this is a flag. - if (!optionInfo.expectsArgs) - { - // Check if the flag is not set in the properties and set it to false if so. - if (!options.containsKey(optionInfo.option)) - { - options.put(optionInfo.option, "false"); - } - } - // Check if this is a mandatory option and was not set. - else if (optionInfo.mandatory && !options.containsKey(optionInfo.option)) - { - // Create an error for the missing option. - parsingErrors.add("Option " + optionInfo.option + " is mandatory but not was not specified.\n"); - } - } - - // Check if there were any errors. - if (!parsingErrors.isEmpty()) - { - // Throw an illegal argument exception to signify that there were parsing errors. - throw new IllegalArgumentException(); - } - - // Convert any name/value pairs in the free arguments into properties in the parsed options. - trailingProperties = takeFreeArgsAsProperties(options, 1); - - parsedProperties = options; - - return options; - } - - /** - * If a command line has been parsed, calling this method sets all of its free arguments that were name=value pairs - * on the specified properties. - * - * @param properties The property set to add the name=value pairs to. - */ - public void addTrailingPairsToProperties(Properties properties) - { - if (trailingProperties != null) - { - for (Object propKey : trailingProperties.keySet()) - { - String name = (String) propKey; - String value = trailingProperties.getProperty(name); - - properties.setProperty(name, value); - } - } - } - - /** - * If a command line has been parsed, calling this method sets all of its options that were set to the specified - * properties. - * - * @param properties The property set to the options to. - */ - public void addOptionsToProperties(Properties properties) - { - if (parsedProperties != null) - { - for (Object propKey : parsedProperties.keySet()) - { - String name = (String) propKey; - String value = parsedProperties.getProperty(name); - - // This filters out all trailing items. - if (!name.matches("^[0-9]+$")) - { - properties.setProperty(name, value); - } - } - } - } - - /** - * Resets this command line parser after it has been used to parse a command line. This method will only need - * to be called to use this parser a second time which is not likely seeing as a command line is usually only - * specified once. However, it is exposed as a public method for the rare case where this may be done. - * - * <p/>Cleans the internal state of this parser, removing all stored errors and information about the options in - * force. - */ - public void reset() - { - parsingErrors = new ArrayList<String>(); - parsedProperties = null; - } - - /** - * Adds the option to list of available command line options. - * - * @param option The option to add as an available command line option. - * @param comment A comment for the option. - * @param argument The text that appears after the option in the usage string. - * @param mandatory When true, indicates that this option is mandatory. - * @param formatRegexp The format that the argument must take, defined as a regular head. - */ - protected void addOption(String option, String comment, String argument, boolean mandatory, String formatRegexp) - { - // Check if usage text has been set in which case this option is expecting arguments. - boolean expectsArgs = (!((argument == null) || argument.equals(""))); - - // Add the option to the map of command line options. - CommandLineOption opt = new CommandLineOption(option, expectsArgs, comment, argument, mandatory, formatRegexp); - optionMap.put(option, opt); - } - - /** - * Converts the free arguments into property declarations. After parsing the command line the free arguments - * are numbered from 1, such that the parsed properties contain values for the keys "1", "2", ... This method - * converts any free arguments declared using the 'name=value' syntax into properties with key 'name', value - * 'value'. - * - * <p/>For example the comand line: - * <pre> - * ... debug=true - * </pre> - * - * <p/>After parsing has properties: - * <pre>[[1, debug=true]]</pre> - * - * <p/>After applying this method the properties are: - * <pre>[[1, debug=true], [debug, true]]</pre> - * - * @param properties The parsed command line properties. - * @param from The free argument index to convert to properties from. - * - * @return The parsed command line properties, with free argument name value pairs too. - */ - private Properties takeFreeArgsAsProperties(Properties properties, int from) - { - Properties result = new Properties(); - - for (int i = from; true; i++) - { - String nextFreeArg = properties.getProperty(Integer.toString(i)); - - // Terminate the loop once all free arguments have been consumed. - if (nextFreeArg == null) - { - break; - } - - // Split it on the =, strip any whitespace and set it as a system property. - String[] nameValuePair = nextFreeArg.split("="); - - if (nameValuePair.length == 2) - { - result.setProperty(nameValuePair[0], nameValuePair[1]); - } - } - - return result; - } - - /** - * Checks the format of an argument to an option against its specified regular head format if one has - * been set. Any errors are added to the list of parsing errors. - * - * @param optionInfo The command line option information for the option which is havings its argument checked. - * @param matchedArg The string argument to the option. - */ - private void checkArgumentFormat(CommandLineOption optionInfo, String matchedArg) - { - // Check if this option enforces a format for its argument. - if (optionInfo.argumentFormatRegexp != null) - { - Pattern pattern = Pattern.compile(optionInfo.argumentFormatRegexp); - Matcher argumentMatcher = pattern.matcher(matchedArg); - - // Check if the argument does not meet its required format. - if (!argumentMatcher.matches()) - { - // Create an error for this badly formed argument. - parsingErrors.add("The argument to option " + optionInfo.option + " does not meet its required format.\n"); - } - } - } - - /** - * Holds information about a command line options. This includes what its name is, whether or not it is a flag, - * whether or not it is mandatory, what its user comment is, what its argument reminder text is and what its - * regular head format is. - * - * <p><table id="crc"><caption>CRC Card</caption> - * <tr><th> Responsibilities <th> Collaborations - * <tr><td> Hold details of a command line option. - * </table> - * - * @author Rupert Smith - */ - protected class CommandLineOption - { - /** Holds the text for the flag to match this argument with. */ - public String option = null; - - /** Holds a string describing how to use this command line argument. */ - public String argument = null; - - /** Flag that determines whether or not this command line argument can take arguments. */ - public boolean expectsArgs = false; - - /** Holds a short comment describing what this command line argument is for. */ - public String comment = null; - - /** Flag that determines whether or not this is an mandatory command line argument. */ - public boolean mandatory = false; - - /** A regular head describing what format the argument to this option muist have. */ - public String argumentFormatRegexp = null; - - /** - * Create a command line option object that holds specific information about a command line option. - * - * @param option The text that matches the option. - * @param expectsArgs Whether or not the option expects arguments. It is a flag if this is false. - * @param comment A comment explaining how to use this option. - * @param argument A short reminder of the format of the argument to this option/ - * @param mandatory Set to true if this option is mandatory. - * @param formatRegexp The regular head that the argument to this option must meet to be valid. - */ - public CommandLineOption(String option, boolean expectsArgs, String comment, String argument, boolean mandatory, - String formatRegexp) - { - this.option = option; - this.expectsArgs = expectsArgs; - this.comment = comment; - this.argument = argument; - this.mandatory = mandatory; - this.argumentFormatRegexp = formatRegexp; - } - } -} diff --git a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/util/ContextualProperties.java b/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/util/ContextualProperties.java deleted file mode 100644 index 14de96d165..0000000000 --- a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/util/ContextualProperties.java +++ /dev/null @@ -1,494 +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.junit.extensions.util; - -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; -import java.util.Properties; - -/** - * ContextualProperties is an extension of {@link java.util.Properties} that automatically selects properties based on an - * environment parameter (defined by the system property {@link #ENV_SYS_PROPERTY}), the name of a class, plus a modifier - * (which can be used to name a method of a class) and a property key. It also supports the definition of arrays of - * property values using indexes. The properties are searched in the following order until a match is found: - * - * <ol> - * <li>environment + class name with package name + modifier + key - * <li>environment + class name with package name + key - * <li>environment + key - * <li>class name with package name + modifier + key - * <li>class name with package name + key - * <li>key - * </ol> - * - * <p>To create arrays of property values add index numbers onto the end of the property keys. An array of string values - * will be created with the elements of the array set to the value of the property at the matching index. Ideally the - * index values will be contiguous, starting at 0. This does not need to be the case however. If an array definition - * begins at index n, and ends at index m, Then an array big enough to hold m + 1 elements will be created and populated - * with values from n to m. Values before n and any missing values between n and m will be null in the array. - * - * <p>To give an example, suppose you have two different environments 'DEVELOPMENT' and 'PRODUCTION' and they each need - * the same properties but set to different values for each environment and some properties the same in both, you could - * create a properties file like: - * - * <p><code> - * # Project configuration properties file.<br/> - * <br/> - * # These properties are environment specific.<br/> - * DEVELOPMENT.debug=true<br/> - * PRODUCTION.debug=false<br/> - * <br/> - * # Always debug MyClass in all environments but not the myMethod method.<br/> - * MyClass.debug=true<br/> - * MyClass.myMethod.debug=false<br/> - * <br/> - * # Set up an array of my ten favourite animals. Leave elements 3 to 8 as null as I haven't decided on them yet.<br/> - * animals.0=cat<br/> - * animals.1=dog<br/> - * animals.2=elephant<br/> - * animals.9=lion<br/> - * <br/> - * # This is a default value that will be used when the environment is not known.<br/> - * debug=false<br/> - * </code> - * - * <p>The most specific definition of a property is searched for first moving out to the most general. This allows - * general property defaults to be set and then overiden for specific uses by some classes and modifiers. - * - * <p>A ContextualProperties object can be loaded in the same way as a java.utils.Properties. A recommended way to do - * this that does not assume that the properties file is a file (it could be in a jar) is to load the properties from the - * url for the resource lookup up on the classpath: - * - * <p><code> - * Properties configProperties = new ContextualProperties();<br/> - * configProperties.load(this.getClass().getClassLoader().getResourceAsStream("config.properties"));<br/> - * </code> - * - * <p>EnvironmentProperties will load the 'DEVELOPMENT.debug' property or 'PROUCTION.debug' property based on the setting - * of the system environment property. If a matching property for the environment cannot be found then the simple property - * name without the environment pre-pended onto it will be used instead. This 'use of default environments' behaviour is - * turned on initially but it can be disabled by calling the {@link #useDefaultEnvironments} method. - * - * <p>When a property matching a key cannot be found then the property accessor methods will always return null. If a - * default value for a property exists but the 'use of default environments' behavious prevents it being used then the - * accessor methods will return null. - * - * <p><table id="crc"><caption>CRC Card</caption> - * <tr><th> Responsibilities <th> Collaborations - * <tr><td> Automatically select properties dependant on environment, class name and modifier as well as property key. - * <tr><td> Convert indexed properties into arrays. - * </table> - * - * @author Rupert Smith - */ -public class ContextualProperties extends ParsedProperties -{ - /** The name of the system property that is used to define the environment. */ - public static final String ENV_SYS_PROPERTY = "environment"; - - /** - * <p>Holds the iteration count down order. - * - * <p>If e = 4, b = 2, m = 1 then the iteration order or i is 7,6,4 and then if using environment defaults 3,2,0 - * where the accessor key is: - * (i & e != 0 ? environment : "") + (i & b != 0 ? base : "") + (1 + m != 0 ? modifier : "") + key - * - * <p>In other words the presence or otherwise of the three least significant bits when counting down from 7 - * specifies which of the environment, base and modifier are to be included in the key where the environment, base - * and modifier stand for the bits in positions 2, 1 and 0. The numbers 5 and 1 are missed out of the count because - * they stand for the case where the modifier is used without the base which is not done. - */ - private static final int[] ORDER = new int[] { 7, 6, 4, 3, 2, 0 }; - - /** - * Defines the point in the iteration count order below which the 'use environment defaults' feature is being used. - */ - private static final int ENVIRONMENT_DEFAULTS_CUTOFF = 4; - - /** Defines the bit representation for the environment in the key ordering. See {@link #ORDER}. */ - private static final int E = 4; - - /** Defines the bit representation for the base in the key ordering. See {@link #ORDER}. */ - private static final int B = 2; - - /** Defines the bit representation for the modifier in the key ordering. See {@link #ORDER}. */ - private static final int M = 1; - - /** Used to hold the value of the environment system property. */ - private String environment; - - /** Used to indicate that the 'use of defaults' behaviour should be used. */ - private boolean useDefaults = true; - - /** Used to hold all the array properties. This is a mapping from property names to ArrayLists of Strings. */ - protected Map arrayProperties = new HashMap(); - - /** - * Default constructor that builds a ContextualProperties that uses environment defaults. - */ - public ContextualProperties() - { - super(); - - // Keep the value of the system environment property. - environment = System.getProperty(ENV_SYS_PROPERTY); - } - - /** - * Creates a ContextualProperties that uses environment defaults and is initialized with the specified properties. - * - * @param props The properties to initialize this with. - */ - public ContextualProperties(Properties props) - { - super(props); - - // Keep the value of the system environment property. - environment = System.getProperty(ENV_SYS_PROPERTY); - - // Extract any array properties as arrays. - createArrayProperties(); - } - - /** - * Parses an input stream as properties. - * - * @param inStream The input stream to read the properties from. - * - * @exception IOException If there is an IO error during reading from the input stream. - */ - public void load(InputStream inStream) throws IOException - { - super.load(inStream); - - // Extract any array properties as arrays. - createArrayProperties(); - } - - /** - * Tells this environment aware properties object whether it should use default environment properties without a - * pre-pended environment when a property for the current environment cannot be found. - * - * @param flag True to use defaults, false to not use defaults. - */ - public void useDefaultEnvironments(boolean flag) - { - useDefaults = flag; - } - - /** - * Looks up a property value relative to the environment, callers class and method. The default environment will be - * checked for a matching property if defaults are being used. In order to work out the callers class and method this - * method throws an exception and then searches one level up its stack frames. - * - * @param key The property key. - * - * @return The value of this property searching from the most specific definition (environment, class, method, key) - * to the most general (key only), unless use of default environments is turned off in which case the most general - * proeprty searched is (environment, key). - */ - public String getProperty(String key) - { - // Try to get the callers class name and method name by examing the stack. - String className = null; - String methodName = null; - - // Java 1.4 onwards only. - /*try - { - throw new Exception(); - } - catch (Exception e) - { - StackTraceElement[] stack = e.getStackTrace(); - - // Check that the stack trace contains at least two elements, one for this method and one for the caller. - if (stack.length >= 2) - { - className = stack[1].getClassName(); - methodName = stack[1].getMethodName(); - } - }*/ - - // Java 1.5 onwards only. - StackTraceElement[] stack = Thread.currentThread().getStackTrace(); - - // Check that the stack trace contains at least two elements, one for this method and one for the caller. - if (stack.length >= 2) - { - className = stack[1].getClassName(); - methodName = stack[1].getMethodName(); - } - - // Java 1.3 and before? Not sure, some horrible thing that parses the text spat out by printStackTrace? - - return getProperty(className, methodName, key); - } - - /** - * Looks up a property value relative to the environment, base class and modifier. The default environment will be - * checked for a matching property if defaults are being used. - * - * @param base An object of the class to retrieve properties relative to. - * @param modifier The modifier (which may stand for a method of the class). - * @param key The property key. - * - * @return The value of this property searching from the most specific definition (environment, class, modifier, key) - * to the most general (key only), unless use of default environments is turned off in which case the most general - * property searched is (environment, key). - */ - public String getProperty(Object base, String modifier, String key) - { - return getProperty(base.getClass().getName(), modifier, key); - } - - /** - * Looks up a property value relative to the environment, base class and modifier. The default environment will be - * checked for a matching property if defaults are being used. - * - * @param base The name of the class to retrieve properties relative to. - * @param modifier The modifier (which may stand for a method of the class). - * @param key The property key. - * - * @return The value of this property searching from the most specific definition (environment, class, modifier, key) - * to the most general (key only), unless use of default environments is turned off in which case the most general - * property searched is (environment, key). - */ - public String getProperty(String base, String modifier, String key) - { - String result = null; - - // Loop over the key orderings, from the most specific to the most general, until a matching value is found. - for (Iterator i = getKeyIterator(base, modifier, key); i.hasNext();) - { - String nextKey = (String) i.next(); - - result = super.getProperty(nextKey); - - if (result != null) - { - break; - } - } - - return result; - } - - /** - * Looks up an array property value relative to the environment, callers class and method. The default environment - * will be checked for a matching array property if defaults are being used. In order to work out the callers class - * and method this method throws an exception and then searches one level up its stack frames. - * - * @param key The property key. - * - * @return The array value of this indexed property searching from the most specific definition (environment, class, - * method, key) to the most general (key only), unless use of default environments is turned off in which - * case the most general proeprty searched is (environment, key). - */ - public String[] getProperties(String key) - { - // Try to get the callers class name and method name by throwing an exception an searching the stack frames. - String className = null; - String methodName = null; - - /* Java 1.4 onwards only. - try { - throw new Exception(); - } catch (Exception e) { - StackTraceElement[] stack = e.getStackTrace(); - // Check that the stack trace contains at least two elements, one for this method and one for the caller. - if (stack.length >= 2) { - className = stack[1].getClassName(); - methodName = stack[1].getMethodName(); - } - }*/ - return getProperties(className, methodName, key); - } - - /** - * Looks up an array property value relative to the environment, base class and modifier. The default environment will - * be checked for a matching array property if defaults are being used. - * - * @param base An object of the class to retrieve properties relative to. - * @param modifier The modifier (which may stand for a method of the class). - * @param key The property key. - * - * @return The array value of this indexed property searching from the most specific definition (environment, class, - * modifier, key) to the most general (key only), unless use of default environments is turned off in which - * case the most general proeprty searched is (environment, key). - */ - public String[] getProperties(Object base, String modifier, String key) - { - return getProperties(base.getClass().getName(), modifier, key); - } - - /** - * Looks up an array property value relative to the environment, base class and modifier. The default environment will - * be checked for a matching array property if defaults are being used. - * - * @param base The name of the class to retrieve properties relative to. - * @param modifier The modifier (which may stand for a method of the class). - * @param key The property key. - * - * @return The array value of this indexed property searching from the most specific definition (environment, class, - * modifier, key) to the most general (key only), unless use of default environments is turned off in which - * case the most general property searched is (environment, key). - */ - public String[] getProperties(String base, String modifier, String key) - { - String[] result = null; - - // Loop over the key orderings, from the most specific to the most general, until a matching value is found. - for (Iterator i = getKeyIterator(base, modifier, key); i.hasNext();) - { - String nextKey = (String) i.next(); - ArrayList arrayList = (ArrayList) arrayProperties.get(nextKey); - - if (arrayList != null) - { - result = (String[]) arrayList.toArray(new String[] {}); - - break; - } - } - - return result; - } - - /** - * For a given environment, base, modifier and key and setting of the use of default environments feature this - * generates an iterator that walks over the order in which to try and access properties. - * - * <p>See the {@link #ORDER} constant for an explanation of how the key ordering is generated. - * - * @param base The name of the class to retrieve properties relative to. - * @param modifier The modifier (which may stand for a method of the class). - * @param key The property key. - * - * @return An Iterator over String keys defining the order in which properties should be accessed. - */ - protected Iterator getKeyIterator(final String base, final String modifier, final String key) - { - return new Iterator() - { - // The key ordering count always begins at the start of the ORDER array. - private int i = 0; - - public boolean hasNext() - { - return (useDefaults ? ((i < ORDER.length) && (ORDER[i] > ENVIRONMENT_DEFAULTS_CUTOFF)) - : (i < ORDER.length)); - } - - public Object next() - { - // Check that there is a next element and return null if not. - if (!hasNext()) - { - return null; - } - - // Get the next ordering count. - int o = ORDER[i]; - - // Do bit matching on the count to choose which elements to include in the key. - String result = - (((o & E) != 0) ? (environment + ".") : "") + (((o & B) != 0) ? (base + ".") : "") - + (((o & M) != 0) ? (modifier + ".") : "") + key; - - // Increment the iterator to get the next key on the next call. - i++; - - return result; - } - - public void remove() - { - // This method is not supported. - throw new UnsupportedOperationException("remove() is not supported on this key order iterator as " - + "the ordering cannot be changed"); - } - }; - } - - /** - * Scans all the properties in the parent Properties object and creates arrays for any array property definitions. - * - * <p>Array properties are defined with indexes. For example: - * - * <p><code> - * property.1=one<br/> - * property.2=two<br/> - * property.3=three<br/> - * </code> - * - * <p>Note that these properties will be stored as the 'empty string' or "" property array. - * - * <p><code> - * .1=one<br/> - * 2=two<br/> - * </code> - */ - protected void createArrayProperties() - { - // Scan through all defined properties. - for (Object o : keySet()) - { - String key = (String) o; - String value = super.getProperty(key); - - // Split the property key into everything before the last '.' and after it. - int lastDotIndex = key.lastIndexOf('.'); - String keyEnding = key.substring(lastDotIndex + 1, key.length()); - String keyStart = key.substring(0, (lastDotIndex == -1) ? 0 : lastDotIndex); - - // Check if the property key ends in an integer, in which case it is an array property. - int index = 0; - - try - { - index = Integer.parseInt(keyEnding); - } - // The ending is not an integer so its not an array. - catch (NumberFormatException e) - { - // Scan the next property. - continue; - } - - // Check if an array property already exists for this base name and create one if not. - ArrayList propArray = (ArrayList) arrayProperties.get(keyStart); - - if (propArray == null) - { - propArray = new ArrayList(); - arrayProperties.put(keyStart, propArray); - } - - // Add the new property value to the array property for the index. - propArray.set(index, value); - } - } -} diff --git a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/util/MathUtils.java b/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/util/MathUtils.java deleted file mode 100644 index 7c803294f4..0000000000 --- a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/util/MathUtils.java +++ /dev/null @@ -1,428 +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.junit.extensions.util; - -import java.util.ArrayList; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * Mathematical support methods for the toolkit. Caculating averages, variances, min/max for test latencies and - * generating linear/exponential sequences for test size/concurrency ramping up. - * - * <p/>The sequence specifications are of the form [lowest(, ...)(, highest)](,sample=s)(,exp), where round brackets - * enclose optional values. Using this pattern form it is possible to specify a single value, a range of values divided - * into s samples, a range of values divided into s samples but distributed exponentially, or a fixed set of samples. - * - * <p/>The duration arguments are of the form (dD)(hH)(mM)(sS), where round brackets enclose optional values. At least - * one of the optional values must be present. - * - * <p/><table id="crc"><caption>CRC Card</caption> - * <tr><th> Responsibilities <th> Collaborations - * <tr><td> Generate a sequene of integers from a sequence specification. - * <tr><td> Parse an encoded duration into milliseconds. - * </table> - * - * @author Rupert Smith - */ -public class MathUtils -{ - /** Used for debugging. */ - // private static final Logger log = Logger.getLogger(MathUtils.class); - - /** The sequence defintion matching regular expression. */ - public static final String SEQUENCE_REGEXP = "^(\\[[0-9:]+\\])(:samples=[0-9]+)?(:exp)?$"; - - /** The regular expression that matches sequence definitions. */ - private static final Pattern SEQUENCE_PATTERN = Pattern.compile(SEQUENCE_REGEXP); - - /** The duration definition matching regular expression. */ - public static final String DURATION_REGEXP = "^(\\d+D)?(\\d+H)?(\\d+M)?(\\d+S)?$"; - - /** The regular expression that matches the duration expression. */ - public static final Pattern DURATION_PATTERN = Pattern.compile(DURATION_REGEXP); - - /** For matching name=value pairs. */ - public static final String NAME_VALUE_REGEXP = "^\\w+=\\w+$"; - - /** For matching name=[value1: value2: ...] variations. */ - public static final String NAME_VALUE_VARIATION_REGEXP = "^\\w+=\\[[\\w:]+\\]$"; - - /** For matching name=[n: ... :m](:sample=s)(:exp) sequences. */ - public static final String NAME_VALUE_SEQUENCE_REGEXP = "^\\w+=(\\[[0-9:]+\\])(:samples=[0-9]+)?(:exp)?$"; - - /** The regular expression that matches name=value pairs and variations. */ - public static final Pattern NAME_VALUE_PATTERN = - Pattern.compile("(" + NAME_VALUE_REGEXP + ")|(" + NAME_VALUE_VARIATION_REGEXP + ")|(" + NAME_VALUE_SEQUENCE_REGEXP - + ")"); - - /** - * Runs a quick test of the sequence generation methods to confirm that they work as expected. - * - * @param args The command line parameters. - */ - public static void main(String[] args) - { - // Use the command line parser to evaluate the command line. - CommandLineParser commandLine = - new CommandLineParser( - new String[][] - { - { "s", "The sequence definition.", "[m:...:n](:sample=s)(:exp)", "true", MathUtils.SEQUENCE_REGEXP }, - { "d", "The duration definition.", "dDhHmMsS", "false", MathUtils.DURATION_REGEXP } - }); - - // Capture the command line arguments or display errors and correct usage and then exit. - ParsedProperties options = null; - - try - { - options = new ParsedProperties(commandLine.parseCommandLine(args)); - } - catch (IllegalArgumentException e) - { - System.out.println(commandLine.getErrors()); - System.out.println(commandLine.getUsage()); - System.exit(-1); - } - - // Extract the command line options. - String sequence = options.getProperty("s"); - String durationString = options.getProperty("d"); - - System.out.println("Sequence is: " + printArray(parseSequence(sequence))); - - if (durationString != null) - { - System.out.println("Duration is: " + parseDuration(durationString)); - } - } - - /** - * Given a start and end and a number of steps this method generates a sequence of evenly spaced integer - * values, starting at the start (inclusive) and finishing at the end (inclusive) with the specified number - * of values in the sequence. The sequence returned may contain less than the specified number where the integer - * range between start and end is too small to contain that many. - * - * <p/>As the results are integers, they will not be perfectly evenly spaced but a best-fit. - * - * @param start The sequence start. - * @param end The sequence end. - * @param steps The number of steps. - * - * @return The sequence. - */ - public static int[] generateSequence(int start, int end, int steps) - { - // Check that there are at least two steps. - if (steps < 2) - { - throw new IllegalArgumentException("There must be at least 2 steps."); - } - - ArrayList<Integer> result = new ArrayList<Integer>(); - - // Calculate the sequence using floating point, then round into the results. - double fStart = start; - double fEnd = end; - double fCurrent = start; - - for (int i = 0; i < steps; i++) - { - fCurrent = (((fEnd - fStart) / (steps - 1)) * i) + fStart; - - roundAndAdd(result, fCurrent); - } - - // Return the results after converting to a primitive array. - return intListToPrimitiveArray(result); - } - - /** - * Given a start and end and a number of steps this method generates a sequence of expontentially spaced integer - * values, starting at the start (inclusive) and finishing at the end (inclusive) with the specified number - * of values in the sequence. An exponentially spaced sequence is one where the ratio between any two consecutive - * numbers in the sequence remains constant. The sequence returned may contain less than the specified number where - * the difference between two consecutive values is too small (this is more likely at the start of the sequence, - * where the values are closer together). - * - * <p/>As the results are integers, they will not be perfectly exponentially spaced but a best-fit. - * - * @param start The sequence start. - * @param end The sequence end. - * @param steps The number of steps. - * - * @return The sequence. - */ - public static int[] generateExpSequence(int start, int end, int steps) - { - // Check that there are at least two steps. - if (steps < 2) - { - throw new IllegalArgumentException("There must be at least 2 steps."); - } - - ArrayList<Integer> result = new ArrayList<Integer>(); - - // Calculate the sequence using floating point, then round into the results. - double fStart = start; - double fEnd = end; - // float fCurrent = start; - double diff = fEnd - fStart; - double factor = java.lang.Math.pow(diff, (1.0f / (steps - 1))); - - for (int i = 0; i < steps; i++) - { - // This is a cheat to get the end exactly on and lose the accumulated rounding error. - if (i == (steps - 1)) - { - result.add(end); - } - else - { - roundAndAdd(result, fStart - 1.0f + java.lang.Math.pow(factor, i)); - } - } - - // Return the results after converting to a primitive array. - return intListToPrimitiveArray(result); - } - - /** - * Parses a string defintion of a sequence into an int array containing the sequence. The definition will conform - * to the regular expression: "^(\[[0-9,]+\])(,samples=[0-9]+)?(,exp)?$". This splits it into three parts, - * an array of integers, the optional sample count and the optional exponential flag. - * - * @param sequenceDef The sequence definition. - * - * @return The sequence as a fully expanded int array. - */ - public static int[] parseSequence(String sequenceDef) - { - // Match the sequence definition against the regular expression for sequences. - Matcher matcher = SEQUENCE_PATTERN.matcher(sequenceDef); - - // Check that the argument is of the right format accepted by this method. - if (!matcher.matches()) - { - throw new IllegalArgumentException("The sequence definition is not in the correct format."); - } - - // Get the total number of matching groups to see if either of the optional samples or exponential flag - // goups were set. - int numGroups = matcher.groupCount(); - - // Split the array of integers on commas. - String intArrayString = matcher.group(1); - - String[] intSplits = intArrayString.split("[:\\[\\]]"); - - int[] sequence = new int[intSplits.length - 1]; - - for (int i = 1; i < intSplits.length; i++) - { - sequence[i - 1] = Integer.parseInt(intSplits[i]); - } - - // Check for the optional samples count. - int samples = 0; - - if ((numGroups > 1) && (matcher.group(2) != null)) - { - String samplesGroup = matcher.group(2); - - String samplesString = samplesGroup.substring(",samples=".length()); - samples = Integer.parseInt(samplesString); - } - - // Check for the optional exponential flag. - boolean expFlag = false; - - if ((numGroups > 2) && (matcher.group(3) != null)) - { - expFlag = true; - } - - // If there is a sample count and 2 or more sequence values defined, then generate the sequence from the first - // and last sequence values. - if ((samples != 0) && (sequence.length >= 2)) - { - int start = sequence[0]; - int end = sequence[sequence.length - 1]; - - if (!expFlag) - { - sequence = generateSequence(start, end, samples); - } - else - { - sequence = generateExpSequence(start, end, samples); - } - } - - return sequence; - } - - /** - * Parses a duration defined as a string, giving a duration in days, hours, minutes and seconds into a number - * of milliseconds equal to that duration. - * - * @param duration The duration definition string. - * - * @return The duration in millliseconds. - */ - public static long parseDuration(String duration) - { - // Match the duration against the regular expression. - Matcher matcher = DURATION_PATTERN.matcher(duration); - - // Check that the argument is of the right format accepted by this method. - if (!matcher.matches()) - { - throw new IllegalArgumentException("The duration definition is not in the correct format."); - } - - // This accumulates the duration. - long result = 0; - - int numGroups = matcher.groupCount(); - - // Extract the days. - if (numGroups >= 1) - { - String daysString = matcher.group(1); - result += - (daysString == null) - ? 0 : (Long.parseLong(daysString.substring(0, daysString.length() - 1)) * 24 * 60 * 60 * 1000); - } - - // Extract the hours. - if (numGroups >= 2) - { - String hoursString = matcher.group(2); - result += - (hoursString == null) ? 0 - : (Long.parseLong(hoursString.substring(0, hoursString.length() - 1)) * 60 * 60 * 1000); - } - - // Extract the minutes. - if (numGroups >= 3) - { - String minutesString = matcher.group(3); - result += - (minutesString == null) - ? 0 : (Long.parseLong(minutesString.substring(0, minutesString.length() - 1)) * 60 * 1000); - } - - // Extract the seconds. - if (numGroups >= 4) - { - String secondsString = matcher.group(4); - result += - (secondsString == null) ? 0 : (Long.parseLong(secondsString.substring(0, secondsString.length() - 1)) * 1000); - } - - return result; - } - - /** - * Pretty prints an array of ints as a string. - * - * @param array The array to pretty print. - * - * @return The pretty printed string. - */ - public static String printArray(int[] array) - { - String result = "["; - for (int i = 0; i < array.length; i++) - { - result += array[i]; - result += (i < (array.length - 1)) ? ", " : ""; - } - - result += "]"; - - return result; - } - - /** - * Returns the maximum value in an array of integers. - * - * @param values The array to find the amx in. - * - * @return The max value. - */ - public static int maxInArray(int[] values) - { - if ((values == null) || (values.length == 0)) - { - throw new IllegalArgumentException("Cannot find the max of a null or empty array."); - } - - int max = values[0]; - - for (int value : values) - { - max = (max < value) ? value : max; - } - - return max; - } - - /** - * The #toArray methods of collections cannot be used with primitive arrays. This loops over and array list - * of Integers and outputs and array of int. - * - * @param result The array of Integers to convert. - * - * @return An array of int. - */ - private static int[] intListToPrimitiveArray(ArrayList<Integer> result) - { - int[] resultArray = new int[result.size()]; - int index = 0; - for (int r : result) - { - resultArray[index] = result.get(index); - index++; - } - - return resultArray; - } - - /** - * Rounds the specified floating point value to the nearest integer and adds it to the specified list of - * integers, provided it is not already in the list. - * - * @param result The list of integers to add to. - * @param value The new candidate to round and add to the list. - */ - private static void roundAndAdd(ArrayList<Integer> result, double value) - { - int roundedValue = (int) Math.round(value); - - if (!result.contains(roundedValue)) - { - result.add(roundedValue); - } - } -} diff --git a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/util/ParsedProperties.java b/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/util/ParsedProperties.java deleted file mode 100644 index 1cc6757675..0000000000 --- a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/util/ParsedProperties.java +++ /dev/null @@ -1,390 +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.junit.extensions.util; - -import java.util.Properties; - -/** - * ParsedProperties extends the basic Properties class with methods to extract properties, not as strings but as strings - * parsed into basic types. - * - * <p/><table id="crc"><caption>CRC Card</caption> - * <tr><th> Responsibilities <th> Collaborations - * </table> - * - * @author Rupert Smith - */ -public class ParsedProperties extends Properties -{ - /** - * Creates an empty ParsedProperties. - */ - public ParsedProperties() - { - super(); - } - - /** - * Creates a ParsedProperties initialized with the specified properties. - * - * @param props The properties to initialize this with. - */ - public ParsedProperties(Properties props) - { - super(props); - } - - /** - * Helper method for setting system properties to defaults when they are not already set. - * - * @param propname The name of the system property to set. - * @param value The value to set it to. - * - * @return The value of the property after this method call. - */ - public static boolean setSysPropertyIfNull(String propname, boolean value) - { - return Boolean.parseBoolean(setSysPropertyIfNull(propname, Boolean.toString(value))); - } - - /** - * Helper method for setting system properties to defaults when they are not already set. - * - * @param propname The name of the system property to set. - * @param value The value to set it to. - * - * @return The value of the property after this method call. - */ - public static short setSysPropertyIfNull(String propname, short value) - { - return Short.parseShort(setSysPropertyIfNull(propname, Short.toString(value))); - } - - /** - * Helper method for setting system properties to defaults when they are not already set. - * - * @param propname The name of the system property to set. - * @param value The value to set it to. - * - * @return The value of the property after this method call. - */ - public static int setSysPropertyIfNull(String propname, int value) - { - return Integer.parseInt(setSysPropertyIfNull(propname, Integer.toString(value))); - } - - /** - * Helper method for setting system properties to defaults when they are not already set. - * - * @param propname The name of the system property to set. - * @param value The value to set it to. - * - * @return The value of the property after this method call. - */ - public static long setSysPropertyIfNull(String propname, long value) - { - return Long.parseLong(setSysPropertyIfNull(propname, Long.toString(value))); - } - - /** - * Helper method for setting system properties to defaults when they are not already set. - * - * @param propname The name of the system property to set. - * @param value The value to set it to. - * - * @return The value of the property after this method call. - */ - public static float setSysPropertyIfNull(String propname, float value) - { - return Float.parseFloat(setSysPropertyIfNull(propname, Float.toString(value))); - } - - /** - * Helper method for setting system properties to defaults when they are not already set. - * - * @param propname The name of the system property to set. - * @param value The value to set it to. - * - * @return The value of the property after this method call. - */ - public static double setSysPropertyIfNull(String propname, double value) - { - return Double.parseDouble(setSysPropertyIfNull(propname, Double.toString(value))); - } - - /** - * Helper method for setting system properties to defaults when they are not already set. - * - * @param propname The name of the system property to set. - * @param value The value to set it to. - * - * @return The value of the system property after this method call. - */ - public static String setSysPropertyIfNull(String propname, String value) - { - String property = System.getProperty(propname); - - if (property == null) - { - System.setProperty(propname, value); - - return value; - } - else - { - return property; - } - } - - /** - * Helper method for setting properties to defaults when they are not already set. - * - * @param propname The name of the system property to set. - * @param value The value to set it to. - * - * @return The value of the property after this method call. - */ - public boolean setPropertyIfNull(String propname, boolean value) - { - return Boolean.parseBoolean(setPropertyIfNull(propname, Boolean.toString(value))); - } - - /** - * Helper method for setting properties to defaults when they are not already set. - * - * @param propname The name of the system property to set. - * @param value The value to set it to. - * - * @return The value of the property after this method call. - */ - public short setPropertyIfNull(String propname, short value) - { - return Short.parseShort(setPropertyIfNull(propname, Short.toString(value))); - } - - /** - * Helper method for setting properties to defaults when they are not already set. - * - * @param propname The name of the system property to set. - * @param value The value to set it to. - * - * @return The value of the property after this method call. - */ - public int setPropertyIfNull(String propname, int value) - { - return Integer.parseInt(setPropertyIfNull(propname, Integer.toString(value))); - } - - /** - * Helper method for setting properties to defaults when they are not already set. - * - * @param propname The name of the system property to set. - * @param value The value to set it to. - * - * @return The value of the property after this method call. - */ - public long setPropertyIfNull(String propname, long value) - { - return Long.parseLong(setPropertyIfNull(propname, Long.toString(value))); - } - - /** - * Helper method for setting properties to defaults when they are not already set. - * - * @param propname The name of the system property to set. - * @param value The value to set it to. - * - * @return The value of the property after this method call. - */ - public float setPropertyIfNull(String propname, float value) - { - return Float.parseFloat(setPropertyIfNull(propname, Float.toString(value))); - } - - /** - * Helper method for setting properties to defaults when they are not already set. - * - * @param propname The name of the system property to set. - * @param value The value to set it to. - * - * @return The value of the property after this method call. - */ - public double setPropertyIfNull(String propname, double value) - { - return Double.parseDouble(setPropertyIfNull(propname, Double.toString(value))); - } - - /** - * Helper method for setting properties to defaults when they are not already set. - * - * @param propname The name of the system property to set. - * @param value The value to set it to. - * - * @return The value of the property after this method call. - */ - public String setPropertyIfNull(String propname, String value) - { - String property = super.getProperty(propname); - - if (property == null) - { - super.setProperty(propname, value); - - return value; - } - else - { - return property; - } - } - - /** - * Helper method for setting properties. - * - * @param propname The name of the system property to set. - * @param value The value to set it to. - * - * @return The value of the property after this method call. - */ - public boolean setProperty(String propname, boolean value) - { - setProperty(propname, Boolean.toString(value)); - - return value; - } - - /** - * Helper method for setting properties. - * - * @param propname The name of the system property to set. - * @param value The value to set it to. - * - * @return The value of the property after this method call. - */ - public short setProperty(String propname, short value) - { - setProperty(propname, Short.toString(value)); - - return value; - } - - /** - * Helper method for setting properties. - * - * @param propname The name of the system property to set. - * @param value The value to set it to. - * - * @return The value of the property after this method call. - */ - public int setProperty(String propname, int value) - { - setProperty(propname, Integer.toString(value)); - - return value; - } - - /** - * Helper method for setting properties. - * - * @param propname The name of the system property to set. - * @param value The value to set it to. - * - * @return The value of the property after this method call. - */ - public long setProperty(String propname, long value) - { - setProperty(propname, Long.toString(value)); - - return value; - } - - /** - * Helper method for setting properties. - * - * @param propname The name of the system property to set. - * @param value The value to set it to. - * - * @return The value of the property after this method call. - */ - public float setProperty(String propname, float value) - { - setProperty(propname, Float.toString(value)); - - return value; - } - - /** - * Helper method for setting properties. - * - * @param propname The name of the system property to set. - * @param value The value to set it to. - * - * @return The value of the property after this method call. - */ - public double setProperty(String propname, double value) - { - setProperty(propname, Double.toString(value)); - - return value; - } - - /** - * Parses a property as a boolean. - * - * @param propName The property. - * - * @return The property as a boolean, or false if it does not exist. - */ - public boolean getPropertyAsBoolean(String propName) - { - String prop = getProperty(propName); - - return (prop != null) && Boolean.parseBoolean(prop); - } - - /** - * Parses a property as an integer. - * - * @param propName The property. - * - * @return The property as a integer, or null if it does not exist. - */ - public Integer getPropertyAsInteger(String propName) - { - String prop = getProperty(propName); - - return (prop != null) ? new Integer(prop) : null; - } - - /** - * Parses a property as a long. - * - * @param propName The property. - * - * @return The property as a long, or null if it does not exist. - */ - public Long getPropertyAsLong(String propName) - { - String prop = getProperty(propName); - - return (prop != null) ? new Long(prop) : null; - } -} diff --git a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/util/SizeOf.java b/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/util/SizeOf.java deleted file mode 100644 index ecc08770a9..0000000000 --- a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/util/SizeOf.java +++ /dev/null @@ -1,94 +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.junit.extensions.util; - -/** - * SizeOf provides a static method that does its best to return an accurate measure of the total amount of memory used by - * the virtual machine. This is calculated as the total memory available to the VM minus the actual amount used by it. - * Before this measurement is taken the garbage collector is run many times until the used memory calculation stabilizes. - * Generally, this trick works quite well to provide an accurate reading, however, it cannot be relied upon to be totally - * accurate. It is also quite slow. - * - * <p><table id="crc"><caption>CRC Card</caption> - * <tr><th> Responsibilities <th> Collaborations - * <tr><td> Calculate total memory used. - * </table> - * - * @author Rupert Smith - */ -public class SizeOf -{ - /** Holds a reference to the runtime object. */ - private static final Runtime RUNTIME = Runtime.getRuntime(); - - /** - * Makes 4 calls the {@link #runGCTillStable} method. - */ - public static void runGCTillStableSeveralTimes() - { - // It helps to call Runtime.gc() using several method calls. - for (int r = 0; r < 4; ++r) - { - runGCTillStable(); - } - } - - /** - * Runs the garbage collector until the used memory reading stabilizes. It may run the garbage collector up - * to 500 times. - */ - public static void runGCTillStable() - { - long usedMem1 = usedMemory(), usedMem2 = Long.MAX_VALUE; - - for (int i = 0; (usedMem1 < usedMem2) && (i < 500); ++i) - { - RUNTIME.runFinalization(); - RUNTIME.gc(); - Thread.currentThread().yield(); - - usedMem2 = usedMem1; - usedMem1 = usedMemory(); - } - } - - /** - * Runs the garbage collector until the used memory stabilizes and then measures it. - * - * @return The amount of memory used by the virtual machine. - */ - public static long getUsedMemory() - { - runGCTillStableSeveralTimes(); - - return usedMemory(); - } - - /** - * Returns the amount of memory used by subtracting the free memory from the total available memory. - * - * @return The amount of memory used. - */ - private static long usedMemory() - { - return RUNTIME.totalMemory() - RUNTIME.freeMemory(); - } -} diff --git a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/util/StackQueue.java b/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/util/StackQueue.java deleted file mode 100644 index acc1e2c218..0000000000 --- a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/util/StackQueue.java +++ /dev/null @@ -1,131 +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.junit.extensions.util; - -import java.util.EmptyStackException; -import java.util.NoSuchElementException; -import java.util.Queue; -import java.util.Stack; - -/** - * The Stack class in java.util (most unhelpfully) does not implement the Queue interface. This is an adaption of that - * class as a queue. - * - * <p><table id="crc"><caption>CRC Card</caption> - * <tr><th> Responsibilities <th> Collaborations - * <tr><td> Turn a stack into a queue. - * </table> - * - * @todo Need to override the add method, and iterator and consider other methods too. They work like LIFO but - * really wany FIFO behaviour accross the whole data structure. - * - * @author Rupert Smith - */ -public class StackQueue<E> extends Stack<E> implements Queue<E> -{ - /** - * Retrieves, but does not remove, the head of this queue. - * - * @return The element at the top of the stack. - */ - public E element() - { - try - { - return super.peek(); - } - catch (EmptyStackException e) - { - NoSuchElementException t = new NoSuchElementException(); - t.initCause(e); - throw t; - } - } - - /** - * Inserts the specified element into this queue, if possible. - * - * @param o The data element to push onto the stack. - * - * @return True if it was added to the stack, false otherwise (this implementation always returns true). - */ - public boolean offer(E o) - { - push(o); - - return true; - } - - /** - * Retrieves, but does not remove, the head of this queue, returning null if this queue is empty. - * - * @return The top element from the stack, or null if the stack is empty. - */ - public E peek() - { - try - { - return super.peek(); - } - catch (EmptyStackException e) - { - return null; - } - } - - /** - * Retrieves and removes the head of this queue, or null if this queue is empty. - * - * @return The top element from the stack, or null if the stack is empty. - */ - public E poll() - { - try - { - return super.pop(); - } - catch (EmptyStackException e) - { - return null; - } - } - - /** - * Retrieves and removes the head of this queue. - * - * @return The top element from the stack, or null if the stack is empty. - * - * @throws NoSuchElementException If the stack is empty so no element can be removed from it. - */ - public E remove() - { - try - { - return super.pop(); - } - catch (EmptyStackException e) - { - NoSuchElementException t = new NoSuchElementException(); - t.initCause(e); - throw t; - } - } -} diff --git a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/util/TestContextProperties.java b/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/util/TestContextProperties.java deleted file mode 100644 index d402077963..0000000000 --- a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/util/TestContextProperties.java +++ /dev/null @@ -1,202 +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.junit.extensions.util; - -import java.util.Properties; - -/** - * TestContextProperties is an extension of {@link ParsedProperties} that keeps track of property key/value pairs - * that are used by tests being run under the {@link org.apache.qpid.junit.extensions.TKTestRunner}. To keep the - * test runner notified of configurable test parameters, tests should establish their required property values by - * initiliazing fields or statics or in the constructor, through this class. The tk test runner automatically places - * any additional properties specified on the command line into the this class, and these are held statically. - * - * <p/>Here is an example: - * - * <pre> - * public class MyTestClass extends TestCase { - * ParsedProperties testProps = TestContextProperties.getInstance(); - * private int testParam = testProps.setPropertyIfNull("testParam", 1); - * ... - * </pre> - * - * <p/>This has the effect of setting up the field testParam with the default value of 1, unless it is overridden - * by values passed to the tk test runner. It also notifies the tk test runner of the name and value of the test - * parameter actually used for the test, so that this can be logged in the test output file. - * - * <p/><table id="crc"><caption>CRC Card</caption> - * <tr><th> Responsibilities <th> Collaborations - * <tr><td> Log all name/value pairs read or written. - * </table> - * - * @author Rupert Smith - */ -public class TestContextProperties extends ParsedProperties -{ - /** Used for debugging. */ - // Logger log = Logger.getLogger(TestContextProperties.class); - - /** Holds all properties set or read through this property extension class. */ - private Properties accessedProps = new Properties(); - - /** The singleton instance of the test context properties. */ - private static TestContextProperties singleton = null; - - /** - * Default constructor that builds a ContextualProperties that uses environment defaults. - */ - private TestContextProperties() - { - super(); - } - - /** - * Gets the singleton instance of the test context properties. - * - * @return The singleton instance of the test context properties. - */ - public static synchronized ParsedProperties getInstance() - { - if (singleton == null) - { - singleton = new TestContextProperties(); - } - - return singleton; - } - - /** - * Gets the singleton instance of the test context properties, applying a specified set of default properties to - * it, if they are not already set. - * - * @param defaults The defaults to apply for properties not already set. - * - * @return The singleton instance of the test context properties. - */ - public static synchronized ParsedProperties getInstance(Properties defaults) - { - ParsedProperties props = getInstance(); - - for (Object key : defaults.keySet()) - { - String stringKey = (String) key; - String value = defaults.getProperty(stringKey); - - props.setPropertyIfNull(stringKey, value); - } - - return props; - } - - /* - * Creates a ContextualProperties that uses environment defaults and is initialized with the specified properties. - * - * @param props The properties to initialize this with. - */ - /*public TestContextProperties(Properties props) - { - super(); - }*/ - - /** - * Gets all of the properties (with their most recent values) that have been set or read through this class. - * - * @return All of the properties accessed through this class. - */ - public static Properties getAccessedProps() - { - return (singleton == null) ? new Properties() : singleton; - // return accessedProps; - } - - /** - * Looks up a property value relative to the environment, callers class and method. The default environment will be - * checked for a matching property if defaults are being used. The property key/value pair is remembered and made - * available to {@link org.apache.qpid.junit.extensions.TKTestRunner}. - * - * @param key The property key. - * - * @return The value of this property searching from the most specific definition (environment, class, method, key) - * to the most general (key only), unless use of default environments is turned off in which case the most general - * proeprty searched is (environment, key). - */ - public String getProperty(String key) - { - // log.debug("public String getProperty(String key = " + key + "): called"); - - String value = super.getProperty(key); - - if (value != null) - { - accessedProps.setProperty(key, value); - } - - // log.debug("value = " + value); - - return value; - } - - /** - * Calls the <tt>Hashtable</tt> method <code>put</code>. Provided for parallelism with the <tt>getProperty</tt> - * method. Enforces use of strings for property keys and values. The value returned is the result of the - * <tt>Hashtable</tt> call to <code>put</code>. The property key/value pair is remembered and made - * available to {@link org.apache.qpid.junit.extensions.TKTestRunner}. - * - * @param key The key to be placed into this property list. - * @param value The value corresponding to <tt>key</tt>. - * - * @return The previous value of the specified key in this property list, or <code>null</code> if it did not have one. - */ - public synchronized Object setProperty(String key, String value) - { - // log.debug("public synchronized Object setProperty(String key = " + key + ", String value = " + value + "): called"); - - Object result = super.setProperty(key, value); - accessedProps.setProperty(key, value); - - return result; - } - - /** - * Helper method for setting properties to defaults when they are not already set. The property key/value pair is - * remembered and made available to {@link org.apache.qpid.junit.extensions.TKTestRunner}. - * - * @param key The name of the system property to set. - * @param value The value to set it to. - * - * @return The value of the property, which will be the value passed in if it was null, or the existing value otherwise. - */ - public String setPropertyIfNull(String key, String value) - { - // log.debug("public String setPropertyIfNull(String key = " + key + ", String value = " + value + "): called"); - - String result = super.setPropertyIfNull(key, value); - - if (value != null) - { - accessedProps.setProperty(key, result); - } - - // log.debug("result = " + result); - - return result; - } -} diff --git a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/util/TestUtils.java b/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/util/TestUtils.java deleted file mode 100644 index 553a41ecae..0000000000 --- a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/util/TestUtils.java +++ /dev/null @@ -1,54 +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.junit.extensions.util; - -/** - * Provides commonly used functions that aid testing. - * - * <p/><table id="crc"><caption>CRC Card</caption> - * <tr><th> Responsibilities <th> Collaborations - * <tr><td> Provide a short pause. - * </table> - * - * @author Rupert Smith - */ -public class TestUtils -{ - /** - * Injects a short pause. The pause may not complete its full length, if the thread is interrupted when waiting. - * In most cases, this will not happen and this method is a vry adequate pause implementation, without the - * need to handle interrupted exceptions. - * - * @param millis The length of the pause in milliseconds. - */ - public static void pause(long millis) - { - try - { - Thread.sleep(millis); - } - catch (InterruptedException e) - { - // Clear the flag and ignore. - Thread.interrupted(); - } - } -} diff --git a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/util/package.html b/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/util/package.html deleted file mode 100644 index f39b892e2d..0000000000 --- a/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/util/package.html +++ /dev/null @@ -1,27 +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. - ---> - -<html> -<body> -Provides some helper classes. ContextualProperties allows a hierarchy of properties to be used in properties file with -default overrides. SizeOf takes memeory measurements by stabilizing the garbage collector. -</body> -</html> |