summaryrefslogtreecommitdiff
path: root/qpid/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/DurationTestDecorator.java
diff options
context:
space:
mode:
Diffstat (limited to 'qpid/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/DurationTestDecorator.java')
-rw-r--r--qpid/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/DurationTestDecorator.java205
1 files changed, 205 insertions, 0 deletions
diff --git a/qpid/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/DurationTestDecorator.java b/qpid/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/DurationTestDecorator.java
new file mode 100644
index 0000000000..e99fcce752
--- /dev/null
+++ b/qpid/java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/DurationTestDecorator.java
@@ -0,0 +1,205 @@
+/*
+ *
+ * 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();
+// }
+// }
+}