curcuru     00/12/05 11:16:26

  Modified:    test/java build.xml
               test/java/src/org/apache/qetest ConsoleLogger.java
  Added:       test     Harness.properties runharness.bat
               test/java/src/org/apache/qetest/xsl XSLTestHarness.java
  Log:
  New harness for running multiple API tests in order
  
  Revision  Changes    Path
  1.1                  xml-xalan/test/Harness.properties
  
  Index: Harness.properties
  ===================================================================
  # Special property file to run most TRAX API tests with XSLTestHarness
  # You can use various API tests with this properties file
  # Most (but not all) of the same options are shared with ConformanceTest
  
  #---- Choose tests: which tests should we run
  # Semicolon delimited list of tests, either FQCNs or just 
  #   package.ClassName assuming org.apache.qetest. will be prepended
  
tests=trax.TransformerAPITest;trax.TemplatesAPITest;trax.TransformerFactoryAPITest;trax.dom.DOMSourceAPITest;trax.dom.DOMResultAPITest;trax.stream.StreamSourceAPITest;trax.stream.StreamResultAPITest;trax.ExamplesTest
  
  #---- Choose locations: where to find files, where to log to
  # testDir is where root of test xml/xsl files are
  inputDir=tests\\api
  
  # goldDir is where the 'gold' files to check against live
  goldDir=tests\\api-gold
  
  # outDir is where we put the actual output files and any logs or error dumps
  outputDir=results-api
  
  # Harness test output will be saved in this file; 
  #   individual test output will be in the outputDir
  #   in separate files per testfile
  logFile=results-api\\Harness.xml
  
  #---- Choose output: How much/what kinds of info should we log
  # Choose output: How much logging info is saved: between 0 (very little) and 
99 (lots)
  loggingLevel=99
  
  # If we should save performance-oriented info in the logfile
  perfLogging=true
  
  # Set debug for advanced debugging of the tests themselves
  #debug=true
  
  
  
  1.1                  xml-xalan/test/runharness.bat
  
  Index: runharness.bat
  ===================================================================
  @echo off
  @goto start
  @REM  Name:   harness.bat
  @REM  Author: [EMAIL PROTECTED]
  
  :start
  set END_PKG=xsl
  @echo Harness Wrapper using 'xsl.XSLTestHarness Harness.properties'
  @echo Running multiple tests= from Harness.properties now...
  call runtest.bat XSLTestHarness Harness.properties %2 %3 %4 %5 %6 %7 %8 %9
  set END_PKG=
  :end
  
  
  
  1.8       +7 -0      xml-xalan/test/java/build.xml
  
  Index: build.xml
  ===================================================================
  RCS file: /home/cvs/xml-xalan/test/java/build.xml,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- build.xml 2000/11/16 02:46:46     1.7
  +++ build.xml 2000/12/05 19:16:08     1.8
  @@ -91,7 +91,12 @@
                  destdir="${build.dir}" 
                  includes="ProcessorWrapper.java"
                  debug="${debug}" />
  +    <!-- Sun testing: add
  +               excludes="XHTComparator.java,XHTFileCheckService.java"
  +         to the below javac element 
  +         -sc 17-Nov-00  -->
           <javac srcdir="${test.dir}/xsl" 
  +               excludes="XHTComparator.java,XHTFileCheckService.java"
                  destdir="${build.dir}" 
                  debug="${debug}" />
       </target>
  @@ -162,6 +167,8 @@
       <!-- Note: temporarily add the Xalan-J 1.x version of stylebook to 
classpath 
            this needs more work, since we can build docs with either Xalan 1 
or 2, 
            but the matching version of stylebook needs to go with the 
xalan.jar -->
  +    <echo message="java.class.path = ${java.class.path}" />
  +    <echo message="xalan.xdocs = ${xalan.xdocs}/stylebook-1.0-b2.jar" />
       <java fork="yes" classname="${doc.generator}"> 
           <classpath>
               <pathelement location="${xalan.xdocs}/stylebook-1.0-b2.jar" />
  
  
  
  1.4       +10 -2     
xml-xalan/test/java/src/org/apache/qetest/ConsoleLogger.java
  
  Index: ConsoleLogger.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/test/java/src/org/apache/qetest/ConsoleLogger.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- ConsoleLogger.java        2000/12/05 18:43:28     1.3
  +++ ConsoleLogger.java        2000/12/05 19:16:12     1.4
  @@ -71,7 +71,7 @@
   /**
    * Logger that prints human-readable output to System.out.
    * @author [EMAIL PROTECTED]
  - * @version $Id: ConsoleLogger.java,v 1.3 2000/12/05 18:43:28 curcuru Exp $
  + * @version $Id: ConsoleLogger.java,v 1.4 2000/12/05 19:16:12 curcuru Exp $
    */
   public class ConsoleLogger implements Logger
   {
  @@ -350,6 +350,13 @@
       public void logElement(int level, String element, Hashtable attrs,
                              Object msg)
       {
  +        if ((element == null)
  +           || (attrs == null))
  +        {
  +            // Bail if either element name or attr list is null
  +            // Note: we should really handle this case more elegantly
  +            return;
  +        }
   
           indent();
           outStream.println(sIndent + element);
  @@ -365,7 +372,8 @@
           }
   
           outdent();
  -        outStream.println(sIndent + msg.toString());
  +        if (msg != null)
  +            outStream.println(sIndent + msg.toString());
           outdent();
       }
   
  
  
  
  1.1                  
xml-xalan/test/java/src/org/apache/qetest/xsl/XSLTestHarness.java
  
  Index: XSLTestHarness.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 2000 The Apache Software Foundation.  All rights 
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer. 
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:  
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xalan" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written 
   *    permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 2000, Lotus
   * Development Corporation., http://www.lotus.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  /*
   *
   * XSLTestHarness.java
   *
   */
  package org.apache.qetest.xsl;
  import org.apache.qetest.*;
  
  import java.io.File;
  import java.io.FileInputStream;
  import java.io.IOException;
  import java.io.PrintWriter;
  import java.io.StringWriter;
  
  import java.util.Hashtable;
  import java.util.Properties;
  import java.util.StringTokenizer;
  
  //-------------------------------------------------------------------------
  
  /**
   * Utility to run multiple XSLProcessorTestBase objects in a row.  
   * <p>Generally run from the command line and passed a list 
   * of tests to execute, the XSLTestHarness will run each test in 
   * order, saving the results of each test for reporting later.</p>
   * <p>User must have supplied minimal legal properties in the input 
   * Properties file: outputDir, inputDir, logFile, and tests.</p>
   * @todo update to accept per-test.properties and pass'em thru
   * @todo update to check for similarly named tests (in different pkgs)
   * @todo update TestReporter et al to better cover case when 
   *        user doesn't call testCaseClose (where do results go?)
   * @todo report on memory usage, etc.
   * @author [EMAIL PROTECTED]
   * @version $Id: XSLTestHarness.java,v 1.1 2000/12/05 19:16:22 curcuru Exp $
   */
  public class XSLTestHarness
  {
  
  /**
   * Convenience method to print out usage information.
   * @return String denoting usage suitable for printing
   */
      public String usage()
      {
          XSLProcessorTestBase tmp = new XSLProcessorTestBase();
          return ("XSLTestHarness - execute multiple Tests in sequence and log 
results:\n"
                  + "    Usage: java XSLTestHarness properties.prop\n"
                  + "    Reads in all options from a Properties file\n"
                  + "    -tests" + OPT_TESTS + "  <semicolon;delimited;list;of 
FQCNs tests to run>\n"
                  + "    Most other options are identical to 
XSLProcessorTestBase:\n"
                  + tmp.usage()
                  );
      }
  
      /** 
       * Various property names we're expecting.  
       * <ul>
       * <li>tests=TestOne;TestTwo;TestThree - semicolon-delimited list of 
       * TestClassNames to execute, in order; assumes all are in the 
       * org.apache.qetest. as base package currently (subject to change)</li>
       * <li>logFile=LogFileName - name of output XML file to store harness 
       * log data in (passed to Reporter; constant in 
XSLProcessorTestBase.java)</li>
       * <li>inputDir=path\\to\\tests - where the tests should find data</li>
       * <li>outputDir=path\\to\\output - where the tests should send output 
and results</li>
       * <li>goldDir=path\\to\\golds - where the tests should find gold 
files</li>
       * <li>loggingLevel=50 - how much output tests should produce</li>
       * <li>resultsViewer=Filename.xsl - reference to results processing 
stylesheet file</li>
       * <li>Any other options are passed as-is to individual tests</li>
       * </ul>
       * <p>Currently each test has it's own logFile in the outputDir, 
       * named after the test.</p>
       */
  
      /**
       * Parameter: semicolong delimited list of FQCN's of test names.
       * <p>Default: none - this parameter is required.  If the name 
       * is not package-complete, the harness may attempt to 'guess'
       * the correct package underneath org.apache.qetest.</p>
       */
      public static final String OPT_TESTS = "tests";
  
      /** Delimiter for OPT_TESTS.  */
      public static final String TESTS_DELIMITER = ";";
  
      /** 
       * We prepend the default package if any test name does not 
       * have a '.' in it.  
       * This is part of our 'guess' at the appropriate packagename.
       * <b>WARNING!</b> Subject to change!
       */
      public static final String DEFAULT_PACKAGE = "org.apache.qetest.";
  
      /** Separator character for package.ClassName.  */
      public static final String DOT = ".";
  
      /** Default extension for logFiles.  */
      public static final String LOG_EXTENSION = ".xml";
  
      /**
       * Generic Properties block for storing initialization info.
       * All startup options get stored in here for later use, both by
       * the test itself and by any Reporters we use.
       */
      protected Properties harnessProps;
  
      /** Our Reporter, who we tell all our secrets to.  */
      protected Reporter reporter;
  
  
      /**
       * Setup any options and construct a list of tests to execute.  
       * <p>Accesses our class variables harnessProps and debug.  
       * Must not use Reporter, since it hasn't been created yet.</p>
       * @param args array of command line arguments
       * @return array of testClassNames to execute; null if error
       */
      protected String[] doTestHarnessInit(String args[])
      {
          // Harness loads all info from one properties file
          String propFileName = args[0];
          harnessProps = new Properties();
          try
          {
              // Load named file into our properties block
              FileInputStream fIS = new FileInputStream(propFileName);
              harnessProps.load(fIS);
          } 
          catch (IOException ioe)
          {
              System.err.println("ERROR! loading properties file failed: " + 
propFileName);
              ioe.printStackTrace();
              return null;
          }
  
          // Grab the list of tests, which is specific only to the harness
          String testNames = harnessProps.getProperty(OPT_TESTS);
          if ((testNames == null) || (testNames.length() == 0))
          {
              System.err.println("ERROR! No tests(1) were supplied in the 
properties file!");
              return null;
          }
  
          // Split up the list of names
          StringTokenizer st = new StringTokenizer(testNames, TESTS_DELIMITER);
          int testCount = st.countTokens();
          if (testCount == 0)
          {
              System.err.println("ERROR! No tests(2) were supplied in the 
properties file!");
              return null;
          }
          String tests[] = new String[testCount];
          for (int i = 0; st.hasMoreTokens(); i++)
          {
              String s = st.nextToken();
              // @todo use some intelligent way to prepend the 'right' 
              //  package name on the front: we might have tests in 
              //  various subpackages under org.apache.qetest: in .xsl; 
              //  in .trax; in .xalanj1; etc.
              // HACK: if it doesn't start with org, then prepend the 
              //  default package - otherwise assume it's FQCN
              //  thus 'trax.TransformerAPITest' becomes
              //  'org.apache.qetest.trax.TransformerAPITest'
              if (s.startsWith("org"))
              {   
                  // Assume user specified complete package.ClassName
                  tests[i] = s;
              }
              else
              {
                  // Assume user specified (just ClassName or 
                  //  subpackage.Classname) under org.apache.qetest.
                  tests[i] = DEFAULT_PACKAGE + s;
              }
          }
          // Munge the inputDir and goldDir each to be fully qualified for all 
tests
          //      This is necessary since they may be specified as relative 
          //      directories, but we reset the user.dir for each test
          String tempS = harnessProps.getProperty(FileBasedTest.OPT_INPUTDIR);
          File tempF = new File(tempS);
          if (tempF.exists())
          {
              // HACKout what happens if we don't do this?
              // HACKout harnessProps.put(FileBasedTest.OPT_INPUTDIR, 
tempF.getAbsolutePath());
          }
          else
          {
              System.err.println("ERROR! " + FileBasedTest.OPT_INPUTDIR + " 
property does not exist! " + tempS);
              return null;
          }
          tempS = harnessProps.getProperty(FileBasedTest.OPT_GOLDDIR);
          tempF = new File(tempS);
          if (tempF.exists())
          {
              // HACKout what happens if we don't do this?
              // HACKout harnessProps.put(FileBasedTest.OPT_GOLDDIR, 
tempF.getAbsolutePath());
          }
          else
          {
              System.err.println("WARNING! " + FileBasedTest.OPT_GOLDDIR + " 
property does not exist! " + tempS);
          }
  
          return tests;
      }
  
      /**
       * Go run the available tests!  
       * <p>This is sort-of the equivalent of runTest() in a Test 
       * object.  Each test is run in order, and is the equivalent 
       * of a testCase for the Harness.  The Harness records a master 
       * log file, and each test puts its results in it's own log file.</p>
       */
      protected boolean runHarness(String testList[])
      {
          // Report that we've begun testing
          // Note that we're hackishly re-using the 'test' metaphor 
          //      on a grand scale here, where each of the harness'
          //      testCases corresponds to one entire Test
          reporter.testFileInit("XSLTestHarness", "Harness executing " + 
testList.length + " tests");
          logHarnessProps();
  
          // Note 'passCount' is poorly named: a test may fail but 
          //  may still return true from runTest. You really have to 
          //  look at the result files to see real test status
          int passCount = 0;
          int nonPassCount = 0;
          // Run each test in order!
          for (int testIdx = 0; testIdx < testList.length; testIdx++)
          {
              boolean testStat = false;
              try
              {
                  // This method logs out status to our log file, as well 
                  //      as initializing and running the test
                  testStat = runOneTest(testList[testIdx], harnessProps);
              }
              catch (Throwable t)
              {
                  // Catch everything, log it, and move on
                  reporter.checkErr("Test " + testList[testIdx] + " threw: " + 
t.toString());
                  reporter.logThrowable(reporter.ERRORMSG, t, "Test " 
                                        + testList[testIdx] + " threw: " + 
t.toString());
              }
              finally
              {
                  if (testStat)
                      passCount++;
                  else
                      nonPassCount++;
              }
          }
          // Below line is not a 'check': each runOneTest call logs it's own 
status
          // Only for information; remember that the runTest status is not the 
pass/fail of the test!
          reporter.logCriticalMsg("All tests complete, testStatOK:" + passCount 
+ " testStatNOTOK:" + nonPassCount);
  
          // Close out our reporter and report pass only if all tests passed
          reporter.testFileClose();
          if ((passCount < 0) && (nonPassCount == 0))
              return true;
          else
              return false;
      }
  
  
      /**
       * Run a single XSLProcessorTestBase and report it's results.  
       * <p>Uses our class field reporter to dump our results to, also 
       * creates a separate reporter for the test to use.</p>
       * <p>See the code for the specific initialization we custom-craft for 
       * each individual test.  Basically we clone our harnessProps, update the 
       * logFile and outputDir per test, and create a testReporter, then use 
these 
       * to initialize the test before we call runTest on it.</p>
       * @param testName FQCN of the test to execute; must be instanceof 
XSLProcessorTestBase
       * @param hProps property block to use as initializer
       * @return the pass/fail return from runTest(), which is not necessarily 
       *         the same as what we're going to log as the test's result
       */
      protected boolean runOneTest(String testName, Properties hProps)
      {
          // Report on what we're about to do
          reporter.testCaseInit("runOneTest:" + testName);
  
          // Validate our basic arguments
          if ((testName == null) || (testName.length() == 0) || (hProps == 
null))
          {
              reporter.checkErr("runOneTest called with bad arguments!");
              reporter.testCaseClose();
              return false;
          }
  
          // Calculate just the ClassName of the test for later use as the 
logFile name
          String bareClassName = null;
          StringTokenizer st = new StringTokenizer(testName, ".");
          for (bareClassName = st.nextToken(); st.hasMoreTokens(); 
bareClassName = st.nextToken())
          { /* empty loop body */
          }
  
          // Validate that the output directory exists for the test to put it's 
results in
          String testOutDir = hProps.getProperty(FileBasedTest.OPT_OUTPUTDIR);
          if ((testOutDir == null) || (testOutDir.length() == 0))
          {
              // Default to current dir plus the bareClassName if not set
              testOutDir = new String("." + File.separator + bareClassName);
          }
          else
          {
              // Append the bareClassName so different tests don't clobber each 
other
              testOutDir += File.separator + bareClassName;
          }
          File oDir = new File(testOutDir);
          if (!oDir.exists())
          {
              if (!oDir.mkdirs())
              {
                  // Report this but keep going anyway
                  reporter.logErrorMsg("Could not create testOutDir: " + 
testOutDir);
              }
          }
          // no longer needed
          oDir = null;
  
          // Validate we can instantiate the test object itself
          reporter.logTraceMsg("About to newInstance(" + testName + ")");
          XSLProcessorTestBase test = null;
          try
          {
              Class testClass = Class.forName(testName);
              test = (XSLProcessorTestBase)testClass.newInstance();
          }
          catch (Exception e1)
          {
              reporter.checkErr("Could not create test, threw: " + 
e1.toString());
              reporter.logThrowable(reporter.ERRORMSG, e1, "Could not create 
test, threw");
              reporter.testCaseClose();
              return false;
          }
  
          // Create a properties block for the test and pre-fill it with custom 
info
          //      Start with the harness' properties, and then replace certain 
values
          Properties testProps = (Properties)hProps.clone();
          testProps.put(FileBasedTest.OPT_OUTPUTDIR, testOutDir);
          testProps.put(Logger.OPT_LOGFILE, testOutDir + LOG_EXTENSION);
  
          // Disable the ConsoleReporter for the *individual* tests, it's too 
confusing
          testProps.put("noDefaultReporter", "true");
          reporter.logHashtable(reporter.STATUSMSG, testProps, "testProps 
before test creation");
  
          // Initialize the test with the properties we created
          test.setProperties(testProps);
          boolean testInit = test.initializeFromProperties(testProps);
          reporter.logInfoMsg("Test(" + testName + 
").initializeFromProperties() = " + testInit);
  
          // -----------------
          // Execute the test!
          // -----------------
          boolean runTestStat = test.runTest(testProps);
  
          // Report where the test stored it's results - future use 
          //  by multiViewResults.xsl or some other rolledup report
          Hashtable h = new Hashtable(1);
          h.put("fileRef", (String)testProps.get(Logger.OPT_LOGFILE));
          reporter.logElement(reporter.WARNINGMSG, "resultsfile", h, null);
  
          // Call worker method to actually calculate the result and call 
check*()        
          logTestResult(bareClassName, 
test.getReporter().getCurrentFileResult(), 
                        runTestStat, test.getAbortTest());
  
          // Cleanup local variables and garbage collect, in case tests don't
          //      release all resources or something
          testProps = null;
          test = null;
          logMemory();    // Side effect: System.gc()
          
          reporter.testCaseClose();
          return runTestStat;
      }
  
  
      /**
       * Convenience method to report the result of a single test.  
       * <p>Depending on the test's return value, it's currentFileResult, 
       * and if it was ever aborted, we call check to our reporter to log 
it.</p>
       * @param testName basic name of the test
       * @param testResult result of whole test file
       * @param testStat return value from test.runTest()
       * @param testAborted if the test was aborted at all
       */
      protected void logTestResult(String testName, int testResult, boolean 
testStat, boolean testAborted)
      {
          // Report the 'rolled-up' results of the test, combining each of the 
above data
          switch (testResult)
          {
              case reporter.INCP_RESULT:
                  // There is no 'checkIncomplete' method, so simply avoid 
calling check at all
                  reporter.logErrorMsg(testName + ".runTest() returned 
INCP_RESULT!");
                  break;
              case reporter.PASS_RESULT:
                  // Only report a pass if it returned true and didn't abort
                  if (testStat && (!testAborted))
                  {
                      reporter.checkPass(testName + ".runTest()");
                  }
                  else
                  {
                      // Assume something went wrong and call it an ERRR
                      reporter.checkErr(testName + ".runTest()");
                  }
                  break;
              case reporter.AMBG_RESULT:
                  reporter.checkAmbiguous(testName + ".runTest()");
                  break;
              case reporter.FAIL_RESULT:
                  reporter.checkFail(testName + ".runTest()");
                  break;
              case reporter.ERRR_RESULT:
                  reporter.checkErr(testName + ".runTest()");
                  break;
              default:
                  // Assume something went wrong
                  //  (always 'err' on the safe side, ha, ha)
                  reporter.checkErr(testName + ".runTest()");
                  break;
          }
      }
  
  
      /**
       * Convenience method to log out any version or system info.  
       * <p>Logs System.getProperties(), the harnessProps block, plus 
       * info about the classpath.</p>
       */
      protected void logHarnessProps()
      {
          reporter.logHashtable(reporter.WARNINGMSG, System.getProperties(), 
"System.getProperties");
          reporter.logHashtable(reporter.WARNINGMSG, harnessProps, 
"harnessProps");
          // Since we're running a bunch of tests, also check which version 
          //      of various jars we're running against
          logClasspathInfo(System.getProperty("java.class.path"));
      }
  
  
      /**
       * Convenience method to log out misc info about your classpath.  
       * @param classpath presumably the java.class.path to search for jars
       */
      protected void logClasspathInfo(String classpath)
      {
          StringTokenizer st = new StringTokenizer(classpath, 
File.pathSeparator);
          for (int i = 0; st.hasMoreTokens(); i++)
          {
              logClasspathItem(st.nextToken());
          }
      }
  
  
      /**
       * Convenience method to log out misc info about a single classpath 
entry.  
       * <p>Implicitly looks for specific jars, namely xalan.jar, xerces.jar, 
etc.</p>
       * @param filename classpath entry to report about
       */
      protected void logClasspathItem(String filename)
      {
          // Make sure the comparison names are all lower case
          // This allows us to do case-insensitive compares, but 
          //      actually use the case-sensitive filename for lookups
          String filenameLC = filename.toLowerCase();
          String checknames[] = { "xalan.jar", "xerces.jar", "testxsl.jar", 
"minitest.jar"};
  
          for (int i = 0; i < checknames.length; i++)
          {
              if (filenameLC.indexOf(checknames[i]) > -1)
              {
                  File f = new File(filename);
                  if (f.exists())
                  {
                      Hashtable h = new Hashtable(4);
                      h.put("jarname", checknames[i]);
                      h.put("length", String.valueOf(f.length()));
                      h.put("lastModified", String.valueOf(f.lastModified()));
                      h.put("path", f.getAbsolutePath());
                      reporter.logElement(Reporter.INFOMSG, "classpathitem", h, 
null);
                  }
              }
          }
      }
  
  
      /**
       * Cheap-o memory logger - just reports Runtime.totalMemory/freeMemory.  
       */
      protected void logMemory()
      {
          Runtime r = Runtime.getRuntime();
          r.gc();
          reporter.logPerfMsg("UMem", r.freeMemory(), "freeMemory");
          reporter.logPerfMsg("UMem", r.totalMemory(), "totalMemory");
      }
  
  
      /**
       * Run the test harness to execute the specified tests.  
       */
      public void doMain(String args[])
      {
          // Must have at least one arg to continue
          if ((args == null) || (args.length == 0))
          {
              System.err.println("ERROR in usage: must have at least one 
argument");
              System.err.println(usage());
              return;
          }
  
          // Initialize ourselves and a list of tests to execute
          // Side effects: sets harnessProps, debug
          String tests[] = doTestHarnessInit(args);
          if (tests == null)
          {
              System.err.println("ERROR is usage: Problem during initialization 
- no tests!");
              System.err.println(usage());
              return;
          }
  
          // Use a separate copy of our properties to init our Reporter
          Properties reporterProps = (Properties)harnessProps.clone();
  
          // Ensure we have an XMLFileLogger if we have a logName
          String logF = reporterProps.getProperty(Logger.OPT_LOGFILE);
  
          if ((logF != null) && (!logF.equals("")))
          {
              // We should ensure there's an XMLFileReporter
              String r = reporterProps.getProperty(Reporter.OPT_LOGGERS);
  
              if (r == null)
              {
                  reporterProps.put(Reporter.OPT_LOGGERS,
                                "org.apache.qetest.XMLFileLogger");
              }
              else if (r.indexOf("XMLFileLogger") <= 0)
              {
                  reporterProps.put(Reporter.OPT_LOGGERS,
                                r + Reporter.LOGGER_SEPARATOR
                                + "org.apache.qetest.XMLFileLogger");
              }
          }
  
          // Ensure we have a ConsoleLogger unless asked not to
          // @todo improve and document this feature
          String noDefault = reporterProps.getProperty("noDefaultReporter");
          if (noDefault == null)
          {
              // We should ensure there's an XMLFileReporter
              String r = reporterProps.getProperty(Reporter.OPT_LOGGERS);
  
              if (r == null)
              {
                  reporterProps.put(Reporter.OPT_LOGGERS,
                                "org.apache.qetest.ConsoleLogger");
              }
              else if (r.indexOf("ConsoleLogger") <= 0)
              {
                  reporterProps.put(Reporter.OPT_LOGGERS,
                                r + Reporter.LOGGER_SEPARATOR
                                + "org.apache.qetest.ConsoleLogger");
              }
          }
  
          // A Reporter will auto-initialize from the values
          //  in the properties block
          reporter = new Reporter(reporterProps);
          reporter.addDefaultLogger();  // add default logger if needed
  
          // Call worker method to actually run all the tests
          // Worker method manages all it's own reporting, including 
          //  calling testFileInit/testFileClose
          boolean notUsed = runHarness(tests);
  
          // Tell user if a logFile should have been saved
          String logFile = reporterProps.getProperty(Logger.OPT_LOGFILE);
          if (logFile != null)
          {
              System.out.println("");
              System.out.println("Hey! A summary-harness logFile was written 
to: " + logFile);
          }
      }
  
  
      /**
       * Main method to run the harness from the command line.  
       */
      public static void main (String[] args)
      {
          XSLTestHarness app = new XSLTestHarness();
          app.doMain(args);
      }
  }    // end of class XSLTestHarness
  
  
  
  

Reply via email to