/*==========================================================================*\
| $Id: AdvancedTimeout.java,v 1.2 2011/06/09 15:35:28 stedwar2 Exp $
|*-------------------------------------------------------------------------*|
| Copyright (C) 2011 Virginia Tech
|
| This file is part of the Student-Library.
|
| The Student-Library is free software; you can redistribute it and/or
| modify it under the terms of the GNU Lesser General Public License as
| published by the Free Software Foundation; either version 3 of the
| License, or (at your option) any later version.
|
| The Student-Library is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
| GNU Lesser General Public License for more details.
|
| You should have received a copy of the GNU Lesser General Public License
| along with the Student-Library; if not, see <http://www.gnu.org/licenses/>.
\*==========================================================================*/
package student.testingsupport.junit4;
import org.junit.internal.runners.statements.FailOnTimeout;
import org.junit.rules.*;
import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.Statement;
//-------------------------------------------------------------------------
/**
* A custom MethodRule, following the example of Timeout, that supports both
* a per-method timeout, and a per-class timeout. The smallest of whichever
* of these remains is used for the next test method.
*
* NOTE: You must declare an instance of this timeout as a static field in
* the test class you want it to apply to.
*
* This class is really just a proof-of-concept class for experimental
* purposes.
*
* @author Craig Estep
* @author Last changed by $Author: stedwar2 $
* @version $Revision: 1.2 $, $Date: 2011/06/09 15:35:28 $
*/
public class AdvancedTimeout
implements MethodRule
{
//~ Instance/static variables .............................................
private int classwide;
private int method;
private static boolean useClasswideTimeout;
private static boolean useMethodTimeout;
private static long beforeTime;
private static long afterTime;
//~ Constructors ..........................................................
// ----------------------------------------------------------
/**
* Creates a new timeout with the specified timeout options. If a value
* entered is not positive, that timeout condition will be ignored. The
* method timeout is a flat number applied to every method. The classwide
* timeout is a countdown that prevents further tests from running once
* the specified limit has expired.
*
* @param classwide controls the timeout for the test class applied to.
* @param method controls timeout on an individual method.
*/
public AdvancedTimeout(int classwide, int method)
{
this.classwide = classwide;
useClasswideTimeout = (classwide > 0);
this.method = method;
useMethodTimeout = (method > 0);
beforeTime = System.currentTimeMillis();
}
//~ Methods ...............................................................
// ----------------------------------------------------------
/**
* Applies the strictest remaining timeout.
*
* @base the statement to apply the timeout to.
*/
public Statement apply(Statement base, FrameworkMethod fm, Object target)
{
if (useClasswideTimeout)
{
afterTime = System.currentTimeMillis();
int diff = (int) (afterTime - beforeTime);
classwide = classwide - diff;
if (useMethodTimeout)
{
return new FailOnTimeout(base, Math.min(classwide, method));
}
else
{
return new FailOnTimeout(base, classwide);
}
}
else
{
if (useMethodTimeout)
{
return new FailOnTimeout(base, method);
}
else
{
return base;
}
}
}
}