package qat.gui;
/**
*
* @author webhiker
* @version 2.3, 17 June 1999
*/
import java.io.File;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import qat.common.ProtocolConstants;
import qat.common.Resources;
import qat.parser.GenericTestFinder;
import qat.parser.ParserInterface;
import qat.parser.TestFinderInterface;
/**
* This object is resposible for running a single or multiple tests.
* It is implemented as a Thread to allow interuption of a running task.
* If the test run is interrupted, the currently executing test must exit before
* the stop is completed.
*
* @author webhiker
* @version %W %E
*/
public class TestRunner extends Thread {
private boolean running, evaluationMode;
private List<TestSpecification> runList; // this is a list of QAT files to be run
private QAT parent; // handle on the parent so we can paint update info for tree & status
private TestSpecification test; // this is the handle for each test as it is run
private int runProgress;
private Date startTime, endTime;
private String rootDirectory;
public TestRunner(QAT p) {
parent = p;
runList = new ArrayList<TestSpecification>();
startTime = new Date(0);
endTime = new Date(0);
setEvaluationMode(false);
}
public void setProjectRoot(String rootDirectory) {
this.rootDirectory = rootDirectory;
}
public void run() {
// check only once instance is running at a time
if (running) {
return;
}
else {
running = true;
}
// set up the status bar, and intialize all the counters
parent.setStatusGaugeMax(runList.size());
// clear status of all the selected tests
setStatus(runList,ProtocolConstants.NOTRUN,false);
parent.updateStatus(Resources.getString("startingRun"),runList,0);
startTime = new Date();
endTime = startTime;
TestFinderInterface testFinder = new GenericTestFinder(parent.getProperties());
testFinder.setProjectRoot(rootDirectory);
ParserInterface parser;
for(int i = 0; ((i < runList.size())&&(running)); i++) {
runProgress = i;
test = (TestSpecification)runList.get(i);
parser = testFinder.getParser(new File(test.getTestSpecPath()));
if (parser==null) {
System.out.println("No test finder registered for "+test.getTestSpecPath());
}
else {
parser.prepare(parent.getProjectResultsDirectory());
parser.setStatusLabel(parent.getParserStatusLabel());
test.clearTraceFiles(parent.getProjectResultsDirectory());
test.setStatus(ProtocolConstants.RUNNING);
parent.updateTest(test,inEvaluationMode());
if (inEvaluationMode()) {
parent.updateStatus(Resources.getString("startParse")+" "+test.getTestName(),1);
test.parseTest(parent.getProjectResultsDirectory(),
parent.getProperties(),
parser);
}
else {
parent.updateStatus(Resources.getString("running")+" "+test.getTestName(),1);
test.runTest(parent.getProjectResultsDirectory(),
parent.getProperties(),
parser);
}
endTime = new Date();
parent.updateTest(test,inEvaluationMode());
parser.finish();
}
}
if (running) {
parent.updateStatus(Resources.getString("done"),0);
}
else {
setStatus(runList,ProtocolConstants.UNRESOLVED,true);
parent.updateStatus(Resources.getString("interrupted"),0);
}
running = false;
runList.clear();
}
/**
* Sets all the tests to the specified status. If interrupted is true, only tests with status=NOTRUN will
* be set to this status.
*/
private void setStatus(List<TestSpecification> list, int status, boolean interrupted) {
for(int i = 0; i < runList.size(); i++) {
test = (TestSpecification)runList.get(i);
if (interrupted) {
if (test.getStatus()==ProtocolConstants.NOTRUN)
test.setStatus(status);
}
else {
test.setStatus(status);
}
}
}
/**
* Returns the number of tests from this run which have
* already completed.
*/
public int getRunProgress() {
return runProgress+1;
}
/**
* Returns the total number of tests selected for this run, or
* returns zero if no tests are running.
*/
public int getRunTotal() {
return runList.size();
}
public boolean isRunning() {
return running;
}
public String getRemainingTime() {
int totalNoTests = getRunTotal();
int alreadyRunTests = runProgress;
int testsRemaining = (totalNoTests - alreadyRunTests);
if (testsRemaining<2)
testsRemaining = 0;
long timePerTest;
if (alreadyRunTests>0) {
timePerTest = (endTime.getTime()-startTime.getTime()) / alreadyRunTests;
}
else {
timePerTest = 0;
}
long timeLeft = timePerTest * (testsRemaining);
return getTimeString(new Date(timeLeft));
}
public String getElapsedTime() {
return getTimeString(new Date(endTime.getTime()-startTime.getTime()));
}
public static String getTimeString(Date d) {
Calendar c = new GregorianCalendar();
c.setTime(d);
return Integer.toString(c.get(Calendar.HOUR_OF_DAY)-1)+"h "+
Integer.toString(c.get(Calendar.MINUTE))+"m "+
Integer.toString(c.get(Calendar.SECOND))+"s";
}
public void setRunList(List<TestSpecification> runList2) {
runList = runList2;
}
public void interrupt() {
running = false;
if (runList!=null)
runList.clear();
if (test!=null) {
test.interrupt();
parent.updateTest(test,inEvaluationMode());
}
}
public boolean inEvaluationMode() {
return evaluationMode;
}
public void setEvaluationMode(boolean m) {
evaluationMode = m;
}
}