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