}
long timeoutMillis = timeout * timeoutUnitMultiplier;
//set up the application to run in a separate thread
Parallel applicationRun = newParallel(timeoutMillis);
//with a worker which we can use to manage it
WorkerAnt worker = new WorkerAnt(applicationRun, null);
if (application != null) {
applicationRun.addTask(application);
}
//The test run consists of the block followed by the tests.
long testRunTimeout = 0;
Sequential testRun = new Sequential();
bind(testRun);
if (block != null) {
//waitfor is not a task, it needs to be adapted
TaskAdapter ta = new TaskAdapter(block);
ta.bindToOwner(this);
validateTask(ta, "block");
testRun.addTask(ta);
//add the block time to the total test run timeout
testRunTimeout = block.calculateMaxWaitMillis();
}
//add the tests and more delay
if (tests != null) {
testRun.addTask(tests);
testRunTimeout += timeoutMillis;
}
//add the reporting and more delay
if (reporting != null) {
testRun.addTask(reporting);
testRunTimeout += timeoutMillis;
}
//wrap this in a parallel purely to set up timeouts for the
//test run
timedTests = newParallel(testRunTimeout, testRun);
try {
//run any setup task
if (setup != null) {
Parallel setupRun = newParallel(timeoutMillis, setup);
setupRun.execute();
}
//start the worker thread and leave it running
worker.start();
//start the probe+test sequence
timedTests.execute();
} catch (BuildException e) {
//Record the exception and continue
testException = e;
} finally {
//teardown always runs; its faults are filed away
if (teardown != null) {
try {
Parallel teardownRun = newParallel(timeoutMillis, teardown);
teardownRun.execute();
} catch (BuildException e) {
teardownException = e;
}
}
}