All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.thesett.junit.extensions.DurationTestDecorator Maven / Gradle / Ivy

Go to download

JUnit Toolkit enhances JUnit with performance testing, asymptotic behaviour analysis, and concurrency testing.

There is a newer version: 0.9.52
Show newest version
/*
 * Copyright The Sett Ltd, 2005 to 2014.
 *
 * Licensed 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 com.thesett.junit.extensions;

import java.util.Timer;
import java.util.TimerTask;

import junit.framework.Test;
import junit.framework.TestResult;

import org.apache.log4j.Logger;

import com.thesett.common.util.concurrent.ShutdownHookable;

/**
 * A test decorator that runs a test repeatedly until a specified length of time has passed.
 *
 * 

*
CRC Card
Responsibilities Collaborations *
Repeatedly run a test for a fixed length of time. *
* * @author Rupert Smith * @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. */ public class DurationTestDecorator extends WrappedSuiteTestDecorator implements ShutdownHookable { /** Used for logging. */ /*private static final Logger log = Logger.getLogger(DurationTestDecorator.class);*/ /** The test to run. */ private final 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; /** * 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");*/ // 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; } // Work out when the test should end. long now = System.nanoTime(); long end = (duration * 1000000) + now; // 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); } // 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. * *

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. */ final 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(); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy