TimedTest.java :  » Testing » JUnitPerf » com » clarkware » junitperf » Java Open Source

Java Open Source » Testing » JUnitPerf 
JUnitPerf » com » clarkware » junitperf » TimedTest.java
package com.clarkware.junitperf;

import junit.framework.AssertionFailedError;
import junit.framework.Test;
import junit.framework.TestResult;
import junit.extensions.TestDecorator;

/**
 * The <code>TimedTest</code> is a test decorator that 
 * runs a test and measures the elapsed time of the test.
 * <p>
 * A <code>TimedTest</code> is constructed with a specified
 * maximum elapsed time.  By default, a <code>TimedTest</code> 
 * will wait for the completion of its decorated test and
 * then fail if the maximum elapsed time was exceeded.
 * Alternatively, a <code>TimedTest</code> can be constructed 
 * to immediately signal a failure when the maximum elapsed time 
 * of its decorated test is exceeded.  In other words, the 
 * <code>TimedTest</code> will <b>not</b> wait for its decorated 
 * test to run to completion if the maximum elapsed time is 
 * exceeded.
 * </p>
 * <p>
 * For example, to decorate the <code>ExampleTest</code> 
 * as a <code>TimedTest</code> that waits for the 
 * <code>ExampleTest</code> test case to run 
 * to completion and then fails if the maximum elapsed 
 * time of 2 seconds is exceeded, use: 
 * <blockquote>
 * <pre>
 * Test timedTest = new TimedTest(new TestSuite(ExampleTest.class), 2000);
 * </pre>
 * </blockquote> 
 * or, to time a single test method, use: 
 * <blockquote>
 * <pre>
 * Test timedTest = new TimedTest(new ExampleTest("testSomething"), 2000);
 * </pre>
 * </blockquote> 
 * <p>
 * Alternatively, to decorate the <code>ExampleTest.testSomething()</code>
 * test as a <code>TimedTest</code> that fails immediately when
 * the maximum elapsed time of 2 seconds is exceeded, use:
 * <blockquote>
 * <pre>
 * Test timedTest = new TimedTest(new ExampleTest("testSomething"), 2000, false);
 * </pre>
 * </blockquote>
 * </p>
 * 
 * @author <b>Mike Clark</b>
 * @author Clarkware Consulting, Inc.
 * @author Ervin Varga
 */

public class TimedTest extends TestDecorator {

  private final long maxElapsedTime;
  private final boolean waitForCompletion;
  private boolean maxElapsedTimeExceeded;
  private boolean isQuiet;

  /**
   * Constructs a <code>TimedTest</code> to decorate the 
   * specified test with the specified maximum elapsed time.
   * <p>
   * The <code>TimedTest</code> will wait for the completion 
   * of its decorated test and then fail if the maximum elapsed 
   * time was exceeded.
   * 
   * @param test Test to decorate.
   * @param maxElapsedTime Maximum elapsed time (ms).
   */
  public TimedTest(Test test, long maxElapsedTime) {
    this(test, maxElapsedTime, true);
  }
  
  /**
   * Constructs a <code>TimedTest</code> to decorate the 
   * specified test with the specified maximum elapsed time.
   * 
   * @param test Test to decorate.
   * @param maxElapsedTime Maximum elapsed time (ms).
   * @param waitForCompletion <code>true</code> (default) to 
   *        indicate that the <code>TimedTest</code> should wait 
   *        for its decorated test to run to completion and then 
   *        fail if the maximum elapsed time was exceeded; 
   *        <code>false</code> to indicate that the 
   *        <code>TimedTest</code> should immediately signal 
   *        a failure when the maximum elapsed time is exceeded.
   */
  public TimedTest(Test test, long maxElapsedTime, boolean waitForCompletion) {
    super(test);
    this.maxElapsedTime = maxElapsedTime;
    this.waitForCompletion = waitForCompletion;
    maxElapsedTimeExceeded = false;
    isQuiet = false;
  }
  
  /**
   * Disables the output of the test's elapsed time.
   */
  public void setQuiet() {
    isQuiet = true;
  }

  /**
   * Returns the number of tests in this timed test.
   *
   * @return Number of tests.
   */
  public int countTestCases() {
    return super.countTestCases();
  }
  
  /**
   * Determines whether the maximum elapsed time of
   * the test was exceeded.
   *
   * @return <code>true</code> if the max elapsed time
   *         was exceeded; <code>false</code> otherwise.
   */
  public boolean outOfTime() {
    return maxElapsedTimeExceeded;    
  }

  /**
   * Runs the test.
   *
   * @param result Test result.
   */
  public void run(TestResult result) {
    //
    // TODO: May require a strategy pattern
    //       if other algorithms emerge.
    // 
    if (waitForCompletion) {
      runUntilTestCompletion(result);
    } else {
      runUntilTimeExpires(result);
    }
  }
  
  /**
   * Runs the test until test completion and then signals
   * a failure if the maximum elapsed time was exceeded.
   *
   * @param result Test result.
   */
  protected void runUntilTestCompletion(TestResult result) {

    long beginTime = System.currentTimeMillis();

    super.run(result);

    long elapsedTime = getElapsedTime(beginTime);
    printElapsedTime(elapsedTime);

    if (elapsedTime > maxElapsedTime) {  
      maxElapsedTimeExceeded = true;      
      result.addFailure(getTest(),
        new AssertionFailedError("Maximum elapsed time exceeded!" +
          " Expected " + maxElapsedTime + "ms, but was " +
          elapsedTime + "ms."));
            result.endTest(getTest());
    }
  }
  
  /**
   * Runs the test and immediately signals a failure 
   * when the maximum elapsed time is exceeded.
   *
   * @param result Test result.
   */
  protected void runUntilTimeExpires(final TestResult result) {
  
    Thread t = new Thread(new Runnable() {
      public void run() {
        TimedTest.super.run(result);
        
        // IBM's JVM prefers this instead:
        // run(result);
      }
    });

    long beginTime = System.currentTimeMillis();
    
    t.start();

    try {
    
      t.join(maxElapsedTime);
    
    } catch(InterruptedException ignored) {}

    printElapsedTime(getElapsedTime(beginTime));
  
    if (t.isAlive()) {        
      maxElapsedTimeExceeded = true;
      result.addFailure(getTest(),
        new AssertionFailedError("Maximum elapsed time (" + maxElapsedTime + " ms) exceeded!"));
      result.endTest(getTest());
        }  
  }

  protected long getElapsedTime(long beginTime) {
    long endTime = System.currentTimeMillis();
    return endTime - beginTime;
  }
  
  protected void printElapsedTime(long elapsedTime) {
    if (!isQuiet) {
      System.out.println(toString() + ": " + elapsedTime + " ms");
      System.out.flush();
    }
  }
    
  /**
   * Returns the test description.
   *
   * @return Description.
   */
  public String toString() {
    if (waitForCompletion) {
      return "TimedTest (WAITING): " + super.toString();
    } else {
      return "TimedTest (NON-WAITING): " + super.toString();
    }
  }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.