in java/src/org/apache/qetest/xsl/ThreadedTestletDriver.java [102:250]
public void processFileList(Vector datalets, String desc)
{
// Validate arguments - must have at least two files to test
if ((null == datalets) || (datalets.size() < 2))
{
// Bad arguments, report it as an error
// Note: normally, this should never happen, since
// this class normally validates these arguments
// before calling us
reporter.checkErr("Testlet or datalets are null/less than 2, nothing to test!");
return;
}
// Put everything else into a testCase
// This is not necessary, but feels a lot nicer to
// break up large test sets
reporter.testCaseInit(desc);
// Now just go through the list and process each set
int numDatalets = datalets.size();
reporter.logInfoMsg("processFileList() with " + numDatalets
+ " potential tests");
// Take the first Datalet and create a Templates from it;
// this is going to be shared by all other threads/testlets
StylesheetDatalet firstDatalet = (StylesheetDatalet)datalets.elementAt(0);
TransformWrapper transformWrapper = null;
// Create a TransformWrapper of appropriate flavor
try
{
transformWrapper = TransformWrapperFactory.newWrapper(firstDatalet.flavor);
transformWrapper.newProcessor(null);
reporter.logMsg(Logger.INFOMSG, "Created transformWrapper, about to process shared: " + firstDatalet.inputName);
transformWrapper.buildStylesheet(firstDatalet.inputName);
}
catch (Throwable t)
{
reporter.logThrowable(Logger.ERRORMSG, t, "Creating transformWrapper: newWrapper/newProcessor threw");
reporter.checkErr("Creating transformWrapper: newWrapper/newProcessor threw: " + t.toString());
return;
}
// Create a ThreadedStylesheetDatalet for shared use
ThreadedStylesheetDatalet sharedDatalet = new ThreadedStylesheetDatalet();
// Copy all other info over
sharedDatalet.inputName = firstDatalet.inputName;
sharedDatalet.outputName = firstDatalet.outputName;
sharedDatalet.goldName = firstDatalet.goldName;
sharedDatalet.transformWrapper = transformWrapper;
sharedDatalet.setDescription(firstDatalet.getDescription());
// Prepare array to store all datalets for later joining
// Note: store all but first datalet, which is used as
// the common shared stylesheet/Templates
ThreadedTestletInfo[] testletThreads = new ThreadedTestletInfo[numDatalets - 1];
// Iterate over every OTHER datalet and test it
for (int ctr = 1; ctr < numDatalets; ctr++)
{
try
{
// Create ThreadedStylesheetDatalets from the common
// one we already have and each of the normal
// StylesheetDatalets that we were handed
ThreadedStylesheetTestlet testlet = getTestlet(ctr);
testlet.sharedDatalet = sharedDatalet;
testlet.setDefaultDatalet((StylesheetDatalet)datalets.elementAt(ctr));
testlet.threadIdentifier = ctr;
// Save a copy of each datalet for later joining
// Note off-by-one necessary for arrays
testletThreads[ctr - 1] = new ThreadedTestletInfo(testlet, new Thread(testlet));
//@todo (optional) start this testlet - should allow
// user to start sequentially or all at once later
((testletThreads[ctr - 1]).thread).start();
reporter.logMsg(Logger.INFOMSG, "Started testlet(" + ctr + ")");
// Continue looping and creating each Testlet
}
catch (Throwable t)
{
// Log any exceptions as fails and keep going
//@todo improve the below to output more useful info
reporter.checkFail("Datalet num " + ctr + " threw: " + t.toString());
reporter.logThrowable(Logger.ERRORMSG, t, "Datalet threw");
}
} // of while...
// We now wait for every thread to finish, and only then
// will we write a final report and finish the test
//@todo probably an easier way; for now, just join the last one
reporter.logMsg(Logger.STATUSMSG, "Driver Attempting-to-Join last thread");
long maxWaitMillis = 100000; // Wait at most xxxx milliseconds
// Try waiting for the last thread several times
testletThreads[testletThreads.length - 1].waitForComplete
(reporter, maxWaitMillis, 10);
reporter.logMsg(Logger.TRACEMSG, "Driver Apparently-Joined last thread");
// Also join all other threads
for (int i = 0; i < (testletThreads.length - 1); i++)
{
// Only wait a little while for these
testletThreads[i].waitForComplete(reporter, maxWaitMillis, 2);
}
reporter.logMsg(Logger.INFOMSG, "Driver Apparently-joined all threads");
// Log results from all threads
for (int i = 0; i < testletThreads.length; i++)
{
switch (testletThreads[i].result)
{
case Logger.PASS_RESULT:
if (testletThreads[i].complete)
{
reporter.checkPass("Thread(" + i + ") " + testletThreads[i].lastStatus);
}
else
{
reporter.checkPass("Thread(" + i + ") " + testletThreads[i].lastStatus);
//@todo What kind of status do we do here?
// In theory the testlet successfully ran
// transforms and checked results, but
// for some reason we don't think the
// thread completed properly/in time
reporter.checkErr("Thread(" + i + ") NOT COMPLETE! " + testletThreads[i].lastStatus);
}
break;
case Logger.FAIL_RESULT:
reporter.checkFail("Thread(" + i + ") " + testletThreads[i].lastStatus);
break;
case Logger.AMBG_RESULT:
reporter.checkAmbiguous("Thread(" + i + ") " + testletThreads[i].lastStatus);
break;
case Logger.ERRR_RESULT:
reporter.checkErr("Thread(" + i + ") " + testletThreads[i].lastStatus);
break;
case Logger.INCP_RESULT:
reporter.checkErr("Thread(" + i + ") INCP! " + testletThreads[i].lastStatus);
break;
default:
reporter.checkErr("Thread(" + i + ") BAD RESULT! " + testletThreads[i].lastStatus);
break;
}
//@todo optimizaion: null out vars for gc?
// or should we do this earlier?
testletThreads[i].thread = null;
testletThreads[i].testlet = null;
}
reporter.testCaseClose();
}