public void processFileList()

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();
    }