You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xalan.apache.org by cu...@apache.org on 2001/02/09 02:55:24 UTC
cvs commit: xml-xalan/test/java/src/org/apache/qetest/xsl PerformanceDatalet.java PerformanceTestlet.java
curcuru 01/02/08 17:55:24
Modified: test/java/src/org/apache/qetest/trax TransformerAPITest.java
Added: test/java/src/org/apache/qetest Datalet.java
NullDatalet.java Testlet.java TestletImpl.java
test/java/src/org/apache/qetest/xsl PerformanceDatalet.java
PerformanceTestlet.java
Log:
New Testlet/Datalet classes for a whole new kind of data-driven testing
Revision Changes Path
1.1 xml-xalan/test/java/src/org/apache/qetest/Datalet.java
Index: Datalet.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2001 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 apache@apache.org.
*
* 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/>.
*/
/*
*
* Datalet.java
*
*/
package org.apache.qetest;
import java.util.Hashtable;
/**
* Minimal interface defining a datalet, a single set of data
* for a simple test case.
* <p>A Datalet defines a single group of data that a matching
* Testlet needs to execute it's simple test case. Normally,
* Testlets and Datalets are matched.</p>
*
* <p>This makes creating data-driven tests simpler, by separating
* the test algorithim from the definition of the test data. Note
* that logging what happened during the test is already separated
* out into the Logger interface.</p>
*
* <p>Normally Datalets will simply be collections of public members
* that can be written or read by anyone. An enclosing test can
* simply create or load a number of Datalets and then pass them
* to a Testlet to execute the whole bunch of them.</p>
*
* <p>One way to look at a Datalet is basically an intelligent
* Properties / Hashtable / InputSource, designed for a
* specific set of data. They can be loaded from a variety of
* inputs and will intelligently create the right kind of data
* that their corresponding Testlet is expecting.
* For example, and DOM-based InputSource Datalet might be
* loaded from a number of Strings denoting filenames or URLs.
* The Datalet would then know how to parse each of the files
* into a DOM, which a Testlet could then use directly.</p>
*
* <p>//@todo what metaphor is best? I.e. Should Datalets break OO
* paradigms and just have public members, or should they work more
* like a Hashtable with some Properties-like features thrown in?
* Or: what are the most important
* things to optimize: syntactic sugar-like simplicity for callers;
* more functionality for different datatypes; ease of use by
* inexperienced coders (perhaps testers who are just learning Java);
* ease of use by experienced coders?</p>
*
*
* <p>//@todo Should we add a getParameterInfo() method?</p>
* @author Shane_Curcuru@lotus.com
* @version $Id: Datalet.java,v 1.1 2001/02/09 01:55:22 curcuru Exp $
*/
public interface Datalet
{
/**
* Accesor method for a brief description of this Datalet.
*
* @return String describing the specific set of data
* this Datalet contains (can often be used as the description
* of any check() calls made from the Testlet).
*/
public abstract String getDescription();
/**
* Accesor method for a brief description of this Datalet.
* Datalets must have this as a read/write property, since many
* users will programmatically construct Datalets.
*
* @param s description to use for this Datalet.
*/
public abstract void setDescription(String s);
/**
* Load fields of this Datalet from a Hashtable.
* Note many datalets might take in a Properties block
* instead for simple String-valued data.
*
* @param Hashtable to load; Datalet should attempt to fill
* in as many member variables as possible from this, leaving
* any non-specified variables null or some default; behavior
* if null is passed is undefined
*/
public abstract void load(Hashtable h);
/**
* Load fields of this Datalet from an array.
* This allows most Datalets to be initialized from a main()
* command line or the like. For any String-valued types, or
* types that can easily be derived from a String, this makes
* running ad-hoc tests very easy.
*
* @param args array of Strings, as if from the command line;
* Datalet should attempt to fill in as many member variables
* as possible from this, defining the order itself, leaving
* any non-specified variables null or some default; behavior
* if null is passed is undefined
*/
public abstract void load(String[] args);
} // end of class Datalet
1.1 xml-xalan/test/java/src/org/apache/qetest/NullDatalet.java
Index: NullDatalet.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2001 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 apache@apache.org.
*
* 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/>.
*/
/*
*
* NullDatalet.java
*
*/
package org.apache.qetest;
import java.util.Hashtable;
/**
* A default implementation of a Datalet with no data points.
* "Conversation... is the art of never appearing a bore, of
* knowing how to say everything interestingly, to entertain with
* no matter what, to be charming with nothing at all."
* -- Guy de Maupassant, <u>Sur l'Eau</u>
*
* @author Shane_Curcuru@lotus.com
* @version $Id: NullDatalet.java,v 1.1 2001/02/09 01:55:22 curcuru Exp $
*/
public class NullDatalet implements Datalet
{
/**
* Default no-arg, no-op constructor.
*/
public NullDatalet() { } // no-op
/**
* Accesor method for a brief description of this NullDatalet.
*
* @return String "NullDatalet: no data contained".
*/
public String getDescription()
{
return "NullDatalet: no data contained";
}
/**
* Accesor method for a brief description of this NullDatalet.
*
* @param s unused, you cannot set our description
*/
public void setDescription(String s) { } // no-op
/**
* Load fields of this NullDatalet from a Hashtable.
*
* @param Hashtable unused, you cannot set our fields
*/
public void load(Hashtable h) { } // no-op
/**
* Load fields of this NullDatalet from an array.
*
* @param args unused, you cannot set our fields
*/
public void load(String[] args) { } // no-op
} // end of class NullDatalet
1.1 xml-xalan/test/java/src/org/apache/qetest/Testlet.java
Index: Testlet.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2001 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 apache@apache.org.
*
* 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/>.
*/
/*
*
* Testlet.java
*
*/
package org.apache.qetest;
/**
* Minimal interface defining a testlet, a sort of mini-test.
* A Testlet defines a single, simple test case that is completely
* independent. Commonly a Testlet will perform a single
* test operation and verify it, usually given a set of test
* data to perform the operation on.
*
* <p>This makes creating data-driven tests simpler, by separating
* the test algorithim from the definition of the test data. Note
* that logging what happened during the test is already separated
* out into the Logger interface.</p>
*
* <p>Testlets are used with Datalets, which provide a single set
* of data to execute this test case with.
* For example:</p>
* <ul>
* <li>We define a Testlet that processes an XML file with a
* stylesheet in a certain manner - perhaps using a specific
* set of SAX calls.</li>
* <li>The Testlet takes as an argument a matching Datalet, that
* defines any parameters that may change - like the names
* of the XML file and the stylesheet file to use.</li>
* <li>Test authors or users running a harness or the like can
* then easily define a large set of Datalets for various
* types of input files that they want to test, and simply
* iterate over the set of Datalets, repeatedly calling
* Testlet.execute(). Each execution of the Testlet will
* be independent.</li>
* </ul>
*
* <p>Testlets may provide additional worker methods that allow them
* to be easily run in varying situations; for example, a
* testwriter may have a Test object that calls a number of Testlets
* for it's test cases. If one of the Testlets finds a bug, the
* testwriter can simply reference the single Testlet and it's
* current Datalet in the bug report, without having to reference
* the enclosing Test file. This makes it easier for others to
* reproduce the problem with a minimum of overhead.</p>
*
* @author Shane_Curcuru@lotus.com
* @version $Id: Testlet.java,v 1.1 2001/02/09 01:55:22 curcuru Exp $
*/
public interface Testlet
{
/**
* Accesor method for a brief description of this Testlet.
* <p>Testlet implementers should provide a brief, one line
* description of the algorithim of their test case.</p>
* //@todo do we need to define a setDescription() method?
* Since Testlets are pretty self-sufficient, implementers
* should always just define this, and not let callers
* re-set them.
*
* @return String describing what this Testlet does.
*/
public abstract String getDescription();
/**
* Accesor methods for our Logger.
* <p>Testlets use simple Loggers that they rely on the caller
* to have setup. This frees the Testlet and the Logger from
* having to store any other state about the Testlet. It is
* the caller's responsibility to do any overall rolling-up
* or aggregating of results reporting, if needed.</p>
*
* @param l the Logger to have this test use for logging
* results; or null to use a default logger
*/
public abstract void setLogger(Logger l);
/**
* Accesor methods for our Logger.
*
* @return Logger we tell all our secrets to; may be null
*/
public abstract Logger getLogger();
/**
* Get a default Logger for use with this Testlet.
* <p>Provided to allow subclasses to override this in different
* ways. This would probably be called when setLogger(null)
* is called. The most common implementation would be to
* return a Logger.DEFAULT_LOGGER (which simply
* logs things to the console).</p>
*
* //@todo this sort of functionality should really be provided
* by the Logger class itself - any caller should be able to ask
* Logger (or a Logger factory, if you want to get fancy) for a
* default Logger for use without having to supply any params.
*
* @return Logger suitable for passing to setLogger()
*/
public abstract Logger getDefaultLogger();
/**
* Return this Testlet's default Datalet.
* <p>Every Testlet should have created a default Datalet that can
* be used with this test: i.e. the test case itself has a
* default, or sample set of data to execute the test with. This
* way a user can simply execute the Testlet on the fly without
* having to provide any input data.</p>
* <p>If the Testlet can't provide a default Datalet, either
* the user must provide one somehow, or an error message
* should be printed out. Note that the Testlet must still
* return a Datalet of the correct class from this method, even
* if the Datalet returned has no data set into it. This would
* allow a harness with random test data generation capabilities
* to discover this Testlet, and then generate random Datalets to
* pass to it.</p>
*
* @return Datalet this Testlet can use as a default test case.
*/
public abstract Datalet getDefaultDatalet();
/**
* Run this Testlet: execute it's test and return.
* <p>The Testlet should perform it's test operation, logging
* information as needed to it's Logger, using the provided
* Datalet as a test point.</p>
* <p>If the Datalet passed is null, the Testlet should use
* it's default Datalet as the test point data.</p>
* <p>Testlets should not throw exceptions and should not
* return anything nor worry about checking their state or
* rolling up any overall results to their Logger. Testlets
* should simply focus on performing their one test operation
* and outputting any simple pass/fail/other results to their
* Logger. It is the responsibility of the caller to do any
* overall or rolled-up reporting that is desired.</p>
*
* @author Shane_Curcuru@lotus.com
* @param Datalet to use as data points for the test; if null,
* will attempt to use getDefaultDatalet()
*/
public abstract void execute(Datalet datalet);
} // end of class Testlet
1.1 xml-xalan/test/java/src/org/apache/qetest/TestletImpl.java
Index: TestletImpl.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2001 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 apache@apache.org.
*
* 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/>.
*/
/*
*
* TestletImpl.java
*
*/
package org.apache.qetest;
import java.lang.reflect.Constructor;
/**
* Simple implementation of a testlet, a sort of mini-test.
* <p>A TestletImpl defines some common implementations that
* may be useful, including sample implementations that
* can be copied if you don't want to exend this class.</p>
*
* <p>The most useful implementation is of main(String[]), which
* allows a Testlet to be executed independently from the command
* line. See the code comments for a way to get this behavior in
* your testlet without having to re-implement the whole main
* method - by just including a static{} initializer with the
* fully qualified classname of your class.</p>
*
* <b>Note:</b> Testlets based on this class are probably
* not threadsafe, and must be executed singly!
* See comments for thisClassName.
*
* @author Shane_Curcuru@lotus.com
* @version $Id: TestletImpl.java,v 1.1 2001/02/09 01:55:22 curcuru Exp $
*/
public class TestletImpl implements Testlet
{
//-----------------------------------------------------
//---- Implement Testlet interface methods
//-----------------------------------------------------
/**
* Accesor method for a brief description of this test.
*
* @return String "TestletImpl: default implementation, does nothing"
*/
public String getDescription()
{
return "TestletImpl: default implementation, does nothing";
}
/**
* Accesor methods for our Logger.
*
* @param l the Logger to have this test use for logging
* results; or null to use a default logger
*/
public void setLogger(Logger l)
{
// if null, set a default one
if (null == l)
logger = getDefaultLogger();
else
logger = l;
}
/**
* Accesor methods for our Logger.
*
* @return Logger we tell all our secrets to.
*/
public Logger getLogger()
{
return logger;
}
/**
* Get a default Logger for use with this Testlet.
* Gets a default ConsoleLogger (only if a Logger isn't
* currently set!).
*
* @return current logger; if null, then creates a
* Logger.DEFAULT_LOGGER and returns that; if it cannot
* create one, throws a RuntimeException
*/
public Logger getDefaultLogger()
{
if (logger != null)
return logger;
try
{
Class rClass = Class.forName(Logger.DEFAULT_LOGGER);
return (Logger)rClass.newInstance();
}
catch (Exception e)
{
// Must re-throw the exception, since returning
// null or the like could lead to recursion
e.printStackTrace();
throw new RuntimeException(e.toString());
}
}
/**
* Return this TestletImpl's default Datalet.
*
* @return Datalet <code>defaultDatalet</code>.
*/
public Datalet getDefaultDatalet()
{
return defaultDatalet;
}
/**
* Run this TestletImpl: execute it's test and return.
* This must (obviously) be overriden by subclasses. Here,
* we simply log a message for debugging purposes.
*
* @param Datalet to use as data points for the test.
*/
public void execute(Datalet datalet)
{
logger.logMsg(Logger.STATUSMSG, "TestletImpl.execute(" + datalet + ")");
}
//-----------------------------------------------------
//---- Implement useful worker methods and main()
//-----------------------------------------------------
/**
* Process default command line args.
* Provides simple usage functionality: given a first arg of
* -h, -H, -?, prints a usage statement based on getDescription()
* and on getDefaultDatalet().getDescription()
*
* @param args command line args from the JVM
* @return true if we got and handled any default command line
* args (i.e. you can quit now); false otherwise (i.e. you
* should go ahead and execute)
*/
protected boolean handledDefaultArgs(String[] args)
{
// We don't handle null or blank args
if ((null == args) || (0 == args.length))
return false;
// Provide basic processing for help, usage cases
if ("-h".equals(args[0])
|| "-H".equals(args[0])
|| "-?".equals(args[0])
)
{
logger.logMsg(Logger.STATUSMSG, thisClassName + " usage:");
logger.logMsg(Logger.STATUSMSG, " Testlet: " + getDescription());
logger.logMsg(Logger.STATUSMSG, " Datalet: " + getDefaultDatalet().getDescription());
return true;
}
// Otherwise, don't handle any other args
return false;
}
/**
* Default implementation for command line use.
* Note subclasses can easily get the functionality we provide
* here without having to copy this method merely by copying the
* static initalization block shown above, replacing the
* "thisClassName" with their own FQCN.
*
* This default implementation installs a default Logger, then
* checks for and handles a few default command line args, and
* then executes the Testlet.
*
* //@todo How do we easily specify alternate Datalets or
* data to load a Datalet from? What about the Datalet that
* actually wants the first arg to be -h?
*
* @param args command line args from the JVM
*/
public static void main(String[] args)
{
if (true)
System.out.println("TestletImpl.main");
TestletImpl t = null;
try
{
// Create an instance of the specific class at runtime
// This relies on subclasses to reset 'thisClassName'
// in their own static[] initialization block!
t = (TestletImpl)Class.forName(thisClassName).newInstance();
// Set a default logger automatically
t.setLogger(t.getDefaultLogger());
// Process default -h, etc. args
if (!t.handledDefaultArgs(args))
{
if (args.length > 0)
{
// If we do have any args, then attempt to
// load the correct-typed Datalet from the args
Class dataletClass = t.getDefaultDatalet().getClass();
t.logger.logMsg(Logger.TRACEMSG, "Loading Datalet "
+ dataletClass.getName() + " from args");
Datalet d = (Datalet)dataletClass.newInstance();
d.load(args);
t.execute(d);
}
else
{
// Otherwise, use the defaultDatalet for that Testlet
t.logger.logMsg(Logger.TRACEMSG, "Using defaultDatalet");
t.execute(t.getDefaultDatalet());
}
}
}
catch (Exception e)
{
if ((null != t) && (null != t.logger))
{
// Use the logger which is (hopefully) OK
t.logger.checkErr("TestletImpl threw: " + e.toString());
java.io.StringWriter sw = new java.io.StringWriter();
java.io.PrintWriter pw = new java.io.PrintWriter(sw);
e.printStackTrace(pw);
t.logger.logArbitrary(Logger.ERRORMSG, sw.toString());
}
else
{
// Otherwise, just dump to System.err
System.err.println("TestletImpl threw: " + e.toString());
e.printStackTrace();
}
}
}
/**
* The FQCN of the current class.
* See comments in main() and in the static initializer.
* <b>Note:</b> Testlets based on this class are probably
* not threadsafe, and must be executed singly!
*/
protected static String thisClassName = null;
/**
* A static initializer setting the value of thisClassName.
* Subclasses must copy this static block, and replace the
* name of "...TestletImpl" with their own name. Then, when
* a user executes the subclassed Testlet on the command line
* or calls it's main() method, the correct thing will happen.
*/
static { thisClassName = "org.apache.qetest.TestletImpl"; }
/**
* Our Logger, who we tell all our secrets to.
*/
protected Logger logger = null;
/**
* Our deafult Datalet: in this case, not very interesting.
* Provide a default 'null' datalet so unsuspecting callers
* don't get NullPointerExceptions.
*/
protected Datalet defaultDatalet = new NullDatalet();
} // end of class TestletImpl
1.10 +227 -21 xml-xalan/test/java/src/org/apache/qetest/trax/TransformerAPITest.java
Index: TransformerAPITest.java
===================================================================
RCS file: /home/cvs/xml-xalan/test/java/src/org/apache/qetest/trax/TransformerAPITest.java,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- TransformerAPITest.java 2001/02/08 17:49:04 1.9
+++ TransformerAPITest.java 2001/02/09 01:55:23 1.10
@@ -92,6 +92,7 @@
import java.io.FileOutputStream;
import java.util.Enumeration;
import java.util.Properties;
+import java.util.Hashtable;
//-------------------------------------------------------------------------
@@ -168,7 +169,7 @@
public TransformerAPITest()
{
- numTestCases = 3; // REPLACE_num
+ numTestCases = 5; // REPLACE_num
testName = "TransformerAPITest";
testComment = "Basic API coverage test for the Transformer class";
}
@@ -276,7 +277,7 @@
* functional test coverage on setting different kinds
* and types of parameters, etc.
*
- * NEEDSDOC ($objectName$) @return
+ * @return false if we should abort the test
*/
public boolean testCase1()
{
@@ -487,18 +488,15 @@
/**
- * TRAX Transformer: cover basic get/setOutputFormat APIs.
- * See {@link OutputFormatTest} for more coverage on setting
+ * API coverage test of Transformer.set/getOutputProperty()
+ * See {@link OutputPropertiesTest} for more coverage on setting
* different kinds of outputs, etc.
*
- * NEEDSDOC ($objectName$) @return
+ * @return false if we should abort the test
*/
public boolean testCase2()
{
-
- reporter.testCaseInit(
- "TRAX Transformer: cover basic get/setOutputFormat APIs");
-
+ reporter.testCaseInit("API coverage test of Transformer.set/getOutputProperty()");
TransformerFactory factory = null;
Templates outputTemplates = null;
Transformer outputTransformer = null;
@@ -511,9 +509,9 @@
}
catch (Throwable t)
{
- reporter.checkFail("Problem creating Templates; cannot continue testcase");
+ reporter.checkFail("Problem creating Templates; cannot continue");
reporter.logThrowable(reporter.ERRORMSG, t,
- "Problem creating Templates; cannot continue testcase");
+ "Problem creating Templates; cannot continue");
return true;
}
@@ -532,9 +530,9 @@
}
catch (Exception e)
{
- reporter.checkFail("Problem with identity output properties", "SCUU4RXQYH");
+ reporter.checkFail("Problem with identity output property", "SCUU4RXQYH");
reporter.logThrowable(reporter.ERRORMSG, e,
- "Problem with identity output properties");
+ "Problem with identity output property");
}
try
@@ -698,12 +696,121 @@
"Problem with set/get output properties(0)");
}
- reporter.testCaseClose();
+ // Negative testing: various illegal arguments, etc.
+ try
+ {
+ Transformer negTransformer = outputTemplates.newTransformer();
+ }
+ catch (Exception e)
+ {
+ reporter.checkFail("Problem with negative setOutputProperty/ies tests");
+ reporter.logThrowable(reporter.ERRORMSG, e,
+ "Problem with negative setOutputProperty/ies tests");
+ }
+ reporter.testCaseClose();
return true;
}
/**
+ * API coverage test of Transformer.set/getOutputProperties()
+ * See {@link OutputPropertiesTest} for more coverage on setting
+ * different kinds of outputs, etc.
+ *
+ * @return false if we should abort the test
+ */
+ public boolean testCase3()
+ {
+ reporter.testCaseInit("API coverage test of Transformer.set/getOutputProperties()");
+ TransformerFactory factory = null;
+ Templates outputTemplates = null;
+ Transformer outputTransformer = null;
+ Transformer identityTransformer = null;
+ try
+ {
+ factory = TransformerFactory.newInstance();
+ identityTransformer = factory.newTransformer();
+ outputTemplates = factory.newTemplates(new StreamSource(outputFormatTest.inputName));
+ }
+ catch (Throwable t)
+ {
+ reporter.checkFail("Problem creating Templates; cannot continue");
+ reporter.logThrowable(reporter.ERRORMSG, t,
+ "Problem creating Templates; cannot continue");
+ return true;
+ }
+ try
+ {
+ // See what the default 'identity' transform has by default
+ Properties identityProps = identityTransformer.getOutputProperties(); // SPR SCUU4RXQYH throws npe
+ reporter.check((null != identityProps), true, "identityTransformer.getOutputProperties() is non-null");
+ reporter.logHashtable(reporter.STATUSMSG, identityProps,
+ "default identityTransformer.getOutputProperties()");
+ }
+ catch (Exception e)
+ {
+ reporter.checkFail("Problem with identity OutputProperties", "SCUU4RXQYH");
+ reporter.logThrowable(reporter.ERRORMSG, e,
+ "Problem with identity OutputProperties");
+ }
+
+ reporter.logTraceMsg("More work to be done here!");
+ reporter.testCaseClose();
+ return true;
+ } // end testCase3
+
+
+ /**
+ * Negative tests of Transformer.set/getOutputProperty/ies()
+ *
+ * @return false if we should abort the test
+ */
+ public boolean testCase4()
+ {
+ reporter.testCaseInit("Negative tests of Transformer.set/getOutputProperty/ies()");
+ TransformerFactory factory = null;
+ Templates outputTemplates = null;
+ Transformer outputTransformer = null;
+ Transformer identityTransformer = null;
+ try
+ {
+ factory = TransformerFactory.newInstance();
+ identityTransformer = factory.newTransformer();
+ outputTemplates = factory.newTemplates(new StreamSource(outputFormatTest.inputName));
+ }
+ catch (Throwable t)
+ {
+ reporter.checkFail("Problem creating Templates; cannot continue");
+ reporter.logThrowable(reporter.ERRORMSG, t,
+ "Problem creating Templates; cannot continue");
+ return true;
+ }
+
+ // Negative tests of getOutputProperty()
+ String testDesc = "getOutputProperty of bogus-name";
+ try
+ {
+ Transformer t = factory.newTransformer();
+ String val = t.getOutputProperty("bogus-name");
+ reporter.checkFail(testDesc);
+ }
+ catch (IllegalArgumentException iae)
+ {
+ reporter.checkPass(testDesc + ", threw: " + iae.toString());
+ }
+ catch (Throwable t)
+ {
+ reporter.checkFail(testDesc + ", threw: " + t.toString());
+ }
+
+
+
+ reporter.testCaseClose();
+ return true;
+ } // end testCase4
+
+
+ /**
* TRAX Transformer: cover transform() API and basic
* functionality; plus set/getURIResolver() API;
* plus set/getErrorListener() API; .
@@ -715,9 +822,9 @@
*
* @todo should the Features.SAX and Features.DOM tests be in
* this file, or should they be in sax/dom subdirectory tests?
- * NEEDSDOC ($objectName$) @return
+ * @return false if we should abort the test
*/
- public boolean testCase3()
+ public boolean testCase5()
{
reporter.testCaseInit(
"TRAX Transformer: cover transform() and set/getURIResolver API and functionality");
@@ -812,7 +919,7 @@
reporter.testCaseClose();
return true;
- }
+ } // end testCase5
/**
@@ -839,11 +946,112 @@
}
}
+ public class GetOutputPropertyDatalet implements Datalet
+ {
+ public GetOutputPropertyDatalet(String[] args)
+ {
+ load(args);
+ }
+ public final String IDENTITY = "identity";
+ protected String description = "no data";
+ public String getDescription() { return description; }
+ public void setDescription(String d) { description = d; }
+ public Transformer transformer = null;
+ public String propName = null;
+ public String expectedValue = null;
+ public String expectedException = null;
+ public void load(String[] args)
+ {
+ try
+ {
+ if (IDENTITY.equals(args[0]))
+ transformer = (TransformerFactory.newInstance()).newTransformer();
+ else
+ transformer = (TransformerFactory.newInstance()).newTransformer(new StreamSource(args[0]));
+ propName = args[1];
+ String tmp = args[2];
+ // Semi-hack: if it looks like the FQCN of a
+ // Throwable derivative, then use one
+ // of those; otherwise, assume it's the expected
+ // value to get back from getOutputProperty
+ if ((tmp.indexOf("Exception") >= 0) || (tmp.indexOf("Error") >= 0))
+ expectedException = tmp;
+ else
+ expectedValue = tmp;
+ }
+ catch (Throwable t)
+ { /* no-op, let it fail elsewhere */
+ }
+ }
+ public void load(Hashtable h)
+ {
+ transformer = (Transformer)h.get("transformer");
+ propName = (String)h.get("propName");
+ expectedValue = (String)h.get("expectedValue ");
+ expectedException = (String)h.get("expectedException");
+ }
+
+ } // end class GetOutputPropertyTestlet
+
+ /**
+ * Calls getOutputProperty() on the Transformer supplied, and
+ * then either validates the returned String, or the classname
+ * of any exception thrown.
+ *
+ * This is almost more complex to implement as a Testlet than
+ * is really worth it, but I wanted to experiment with using one.
+ */
+ public class GetOutputPropertyTestlet extends TestletImpl
+ {
+ { thisClassName = "org.apache.qetest.xsl.GetOutputPropertyTestlet"; }
+ public String getDescription() { return "gets OutputProperty and validates"; }
+ public Datalet getDefaultDatalet()
+ {
+ return new GetOutputPropertyDatalet(new String[] { "identity", "method", "xml" });
+ }
+ public void execute(Datalet d)
+ {
+ GetOutputPropertyDatalet datalet = null;
+ try
+ {
+ datalet = (GetOutputPropertyDatalet)d;
+ }
+ catch (ClassCastException e)
+ {
+ logger.checkErr("Datalet provided is not a GetOutputPropertyDatalet; cannot continue");
+ return;
+ }
+ try
+ {
+ String val = datalet.transformer.getOutputProperty(datalet.propName);
+ if (null != datalet.expectedValue)
+ {
+ if (datalet.expectedValue.equals(val))
+ logger.checkPass(datalet.getDescription());
+ else
+ logger.checkFail(datalet.getDescription());
+ }
+ else if (null != datalet.expectedException)
+ logger.checkFail(datalet.getDescription());
+ }
+ catch (Throwable t)
+ {
+ if (null != datalet.expectedException)
+ {
+ if (datalet.expectedException.equals(t.getClass().getName()))
+ logger.checkPass(datalet.getDescription());
+ else
+ logger.checkFail(datalet.getDescription());
+ }
+ else
+ logger.checkFail(datalet.getDescription() + ", threw: " + t.toString());
+ }
+ }
+ } // end class GetOutputPropertyTestlet
/**
* Convenience method to print out usage information - update if needed.
- *
- * NEEDSDOC ($objectName$) @return
+ * @return usage string
*/
public String usage()
{
@@ -859,9 +1067,7 @@
*/
public static void main(String[] args)
{
-
TransformerAPITest app = new TransformerAPITest();
-
app.doMain(args);
}
}
1.1 xml-xalan/test/java/src/org/apache/qetest/xsl/PerformanceDatalet.java
Index: PerformanceDatalet.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2001 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 apache@apache.org.
*
* 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/>.
*/
/*
*
* Datalet.java
*
*/
package org.apache.qetest.xsl;
import org.apache.qetest.*;
import java.util.Hashtable;
/**
* Minimal interface defining a datalet, a single set of data
* for a simple test case.
* A Datalet defines a single group of data that a matching
* Testlet needs to execute it's simple test case.
* For example:
* - We define a Datalet that processes an XML file with a
* stylesheet in a certain manner - perhaps using a specific
* set of SAX calls.
* - The Datalet takes as an argument a matching Datalet, that
* defines any parameters that may change - like the names
* of the XML file and the stylesheet file to use.
* - Test authors or users running a harness or the like can
* then easily define a large set of Datalets for various
* types of input files that they want to test, and simply
* pass a list or Vector of the Datalets to the Datalet to
* be iterated over.
* Normally Datalets will simply be collections of public members
* that can be written or read by anyone. An enclosing test can
* simply
* @author Shane_Curcuru@lotus.com
* @version $Id: PerformanceDatalet.java,v 1.1 2001/02/09 01:55:23 curcuru Exp $
*/
public class PerformanceDatalet extends DataletImpl
{
/** URL of the stylesheet. */
public String inputName = "identity.xsl";
/** URL of the xml document. */
public String xmlName = "identity.xml";
/** URL to put output into. */
public String outputName = "identity.out";
/** URL of the a gold file or data. */
public String goldName = "identity.gold";
/** Flavor of a ProcessorWrapper to use. */
public String flavor = "trax";
/** Number of loops to perform. */
public int iterations = 10;
/** if we should preload a single process first. */
public boolean preload = true;
/** Description of what this Datalet tests. */
protected String description = "PerformanceDatalet: String inputName, String xmlName, String outputName, String goldName, int iterations, boolean preload";
/**
* Accesor method for a brief description of this Datalet.
*
* @return String describing the specific set of data
* this Datalet contains (can often be used as the description
* of any check() calls made from the Testlet).
*/
public String getDescription()
{
return description;
}
/**
* Accesor method for a brief description of this Datalet.
*
* @param s description to use for this Datalet.
*/
public void setDescription(String s)
{
description = s;
}
/**
* Load fields of this Datalet from a Hashtable.
* Caller must provide data for all of our fields.
*
* @param Hashtable to load
*/
public void load(Hashtable p)
{
if (null == p)
return; //@todo should this have a return val or exception?
inputName = (String)p.get("inputName");
xmlName = (String)p.get("xmlName");
outputName = (String)p.get("outputName");
goldName = (String)p.get("goldName");
flavor = (String)p.get("flavor");
iterations = ((Integer)p.get("iterations")).intValue();
try
{
// Check string value first
String tmp = (String)p.get("preload");
// Only check for non-default case
if ("false".equalsIgnoreCase(tmp) || "no".equalsIgnoreCase(tmp))
preload = false;
}
catch (ClassCastException cce1)
{
try
{
// Check boolean value next
Boolean tmp2 = (Boolean)p.get("preload");
preload = tmp2.booleanValue();
}
catch (ClassCastException cce2)
{
// No-op, leave as default
}
}
}
/**
* Load fields of this Datalet from an array.
* Order: inputName, xmlName, outputName, goldName, flavor, iterations, preload
* If too few args, then fields at end of list are left at default value.
* @param args array of Strings
*/
public void load(String[] args)
{
if (null == args)
return; //@todo should this have a return val or exception?
try
{
inputName = args[0];
xmlName = args[1];
outputName = args[2];
goldName = args[3];
flavor = args[4];
try
{
iterations = Integer.parseInt(args[5]);
}
catch (NumberFormatException nfe)
{
// No-op, leave as default and continue
}
String tmp = args[6];
// Only check for non-default case
if ("false".equalsIgnoreCase(tmp) || "no".equalsIgnoreCase(tmp))
preload = false;
}
catch (ArrayIndexOutOfBoundsException aioobe)
{
// No-op, leave remaining items as default
}
}
} // end of class PerformanceDatalet
1.1 xml-xalan/test/java/src/org/apache/qetest/xsl/PerformanceTestlet.java
Index: PerformanceTestlet.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2001 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 apache@apache.org.
*
* 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/>.
*/
/*
*
* PerformanceTestlet.java
*
*/
package org.apache.qetest.xsl;
import org.apache.qetest.*;
import org.apache.qetest.xslwrapper.ProcessorWrapper;
import java.io.File;
/**
* Testlet to capture basic timing performance data.
*
* @author Shane_Curcuru@lotus.com
* @version $Id: PerformanceTestlet.java,v 1.1 2001/02/09 01:55:23 curcuru Exp $
*/
public class PerformanceTestlet extends TestletImpl
{
// Initialize our classname for TestletImpl's main() method
static { thisClassName = "org.apache.qetest.xsl.PerformanceTestlet"; }
// Initialize our defaultDatalet
{ defaultDatalet = new PerformanceDatalet(); }
/**
* Accesor method for a brief description of this test.
*
* @return String describing what this PerformanceTestlet does.
*/
public String getDescription()
{
return "PerformanceTestlet: processes supplied file over multiple iterations and logs timing data";
}
/** Markers for performance logging - Preload time. */
public static final String PERF_PRELOAD = "UPre;";
/** Markers for performance logging - single iteration time. */
public static final String PERF_ITERATION = "UItr;";
/** Markers for performance logging - average of iteration times. */
public static final String PERF_AVERAGE = "UAvg;";
/** Markers for memory logging. */
public static final String PERF_MEMORY = "UMem;";
/**
* Run this PerformanceTestlet: execute it's test and return.
*
* @param Datalet to use as data point for the test.
*/
public void execute(Datalet d)
{
PerformanceDatalet datalet = null;
try
{
datalet = (PerformanceDatalet)d;
}
catch (ClassCastException e)
{
logger.checkErr("Datalet provided is not a PerformanceDatalet; cannot continue");
return;
}
// Cleanup outName - delete the file on disk
try
{
File outFile = new File(datalet.outputName);
boolean btmp = outFile.delete();
logger.logMsg(Logger.TRACEMSG, "Deleting OutFile of::" + datalet.outputName
+ " status: " + btmp);
}
catch (SecurityException se)
{
logger.logMsg(Logger.WARNINGMSG, "Deleting OutFile of::" + datalet.outputName
+ " threw: " + se.toString());
// But continue anyways...
}
// Go do performance stuff!
try
{
// Create a new ProcessorWrapper of appropriate flavor
ProcessorWrapper processorWrapper = ProcessorWrapper.getWrapper(datalet.flavor);
if (null == processorWrapper.createNewProcessor(null))
{
logger.checkErr("ERROR: could not create processorWrapper, aborting.");
return;
}
logger.logMsg(Logger.TRACEMSG, "executing with: inputName=" + datalet.inputName
+ " xmlName=" + datalet.xmlName + " outputName=" + datalet.outputName
+ " goldName=" + datalet.goldName + " flavor=" + datalet.flavor
+ " iterations=" + datalet.iterations + " preload=" + datalet.preload);
// Prime the pump, so to speak, if desired
if (datalet.preload)
{
logMemory(true); // dumps Runtime.freeMemory/totalMemory
long preloadTime = processorWrapper.processToFile(datalet.xmlName, datalet.inputName,
datalet.outputName);
if (preloadTime == ProcessorWrapper.ERROR)
{
logger.checkFail("ERROR: Preload process had a problem of::"
+ datalet.inputName);
return;
}
logger.logStatistic(Logger.STATUSMSG, preloadTime, 0,
PERF_PRELOAD + "Preload process of::" + datalet.inputName);
// @todo add verification of output file
}
logMemory(true); // dumps Runtime.freeMemory/totalMemory
long aggregate = 0L;
int ctr;
for (ctr = 1; ctr <= datalet.iterations; ctr++)
{
long retVal;
// Note: We re-write the same output file each time, so
// I suppose in theory that could affect future iterations
retVal = processorWrapper.processToFile(datalet.xmlName, datalet.inputName, datalet.outputName);
if (retVal == ProcessorWrapper.ERROR)
{
logger.checkFail("ERROR: PerformanceTestlet problem on iteration("
+ ctr + ") of::" + datalet.inputName);
return;
}
// Increment our overall counter
aggregate += retVal;
// Log this particular iteration's time
logger.logStatistic(Logger.STATUSMSG, retVal, 0,
PERF_ITERATION + "processToFile(" + ctr + ") of::"
+ datalet.inputName);
// Should really make this optional
logMemory(false);
}
logger.logStatistic(Logger.STATUSMSG, (aggregate / datalet.iterations), 0,
PERF_AVERAGE + "Average of (" + datalet.iterations
+ ") iterations of::" + datalet.inputName);
}
catch (Throwable t)
{
logger.checkFail("PerformanceTestlet of::" + datalet.inputName
+ " threw: " + t.toString());
java.io.StringWriter sw = new java.io.StringWriter();
java.io.PrintWriter pw = new java.io.PrintWriter(sw);
t.printStackTrace(pw);
logger.logArbitrary(Logger.ERRORMSG, sw.toString());
return;
}
// If we get here, attempt to validate the contents of
// the last outputFile created
CheckService fileChecker = new XHTFileCheckService();
if (Logger.PASS_RESULT
!= fileChecker.check(logger,
new File(datalet.outputName),
new File(datalet.goldName),
getDescription() + ", " + datalet.getDescription())
)
logger.logMsg(Logger.WARNINGMSG, "Failure reason: " + fileChecker.getExtendedInfo());
}
/**
* Worker method: just reports Runtime.totalMemory/freeMemory.
*/
protected void logMemory(boolean doGC)
{
if (doGC)
{
Runtime.getRuntime().gc();
}
logger.logStatistic(Logger.STATUSMSG, Runtime.getRuntime().freeMemory(), 0, PERF_MEMORY + "freeMemory");
logger.logStatistic(Logger.STATUSMSG, Runtime.getRuntime().totalMemory(), 0, PERF_MEMORY + "totalMemory");
}
} // end of class PerformanceTestlet