diff options
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.java | 205 |
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(); +// } +// } +} |