You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xalan.apache.org by mh...@apache.org on 2005/04/07 09:03:06 UTC
cvs commit: xml-xalan/c/Tests/Performance Logger.cpp Logger.hpp Parameters.cpp Parameters.hpp TestHarness.cpp TestHarness.hpp Timer.hpp Utils.cpp Utils.hpp XalanCProcessor.cpp XalanCProcessor.hpp comparereport.xsl config.xml report.xsl perf.cpp
mhoyt 2005/04/07 00:03:06
Modified: c/Projects/Win32/VC7.1/Performance perf.vcproj
c/Tests/Performance perf.cpp
Added: c/Tests/Performance Logger.cpp Logger.hpp Parameters.cpp
Parameters.hpp TestHarness.cpp TestHarness.hpp
Timer.hpp Utils.cpp Utils.hpp XalanCProcessor.cpp
XalanCProcessor.hpp comparereport.xsl config.xml
report.xsl
Log:
Initial implementation of alternate performance testing tool
Revision Changes Path
1.3 +33 -0 xml-xalan/c/Projects/Win32/VC7.1/Performance/perf.vcproj
Index: perf.vcproj
===================================================================
RCS file: /home/cvs/xml-xalan/c/Projects/Win32/VC7.1/Performance/perf.vcproj,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- perf.vcproj 1 Dec 2004 20:33:01 -0000 1.2
+++ perf.vcproj 7 Apr 2005 07:03:05 -0000 1.3
@@ -203,6 +203,18 @@
</References>
<Files>
<File
+ RelativePath="..\..\..\..\Tests\Performance\Logger.cpp">
+ </File>
+ <File
+ RelativePath="..\..\..\..\Tests\Performance\Logger.hpp">
+ </File>
+ <File
+ RelativePath="..\..\..\..\Tests\Performance\Parameters.cpp">
+ </File>
+ <File
+ RelativePath="..\..\..\..\Tests\Performance\Parameters.hpp">
+ </File>
+ <File
RelativePath="..\..\..\..\Tests\Performance\perf.cpp">
<FileConfiguration
Name="Release|Win32">
@@ -223,6 +235,27 @@
ObjectFile="$(IntDir)/$(InputName)1.obj"/>
</FileConfiguration>
</File>
+ <File
+ RelativePath="..\..\..\..\Tests\Performance\TestHarness.cpp">
+ </File>
+ <File
+ RelativePath="..\..\..\..\Tests\Performance\TestHarness.hpp">
+ </File>
+ <File
+ RelativePath="..\..\..\..\Tests\Performance\Timer.hpp">
+ </File>
+ <File
+ RelativePath="..\..\..\..\Tests\Performance\Utils.cpp">
+ </File>
+ <File
+ RelativePath="..\..\..\..\Tests\Performance\Utils.hpp">
+ </File>
+ <File
+ RelativePath="..\..\..\..\Tests\Performance\XalanCProcessor.cpp">
+ </File>
+ <File
+ RelativePath="..\..\..\..\Tests\Performance\XalanCProcessor.hpp">
+ </File>
</Files>
<Globals>
</Globals>
1.43 +212 -486 xml-xalan/c/Tests/Performance/perf.cpp
Index: perf.cpp
===================================================================
RCS file: /home/cvs/xml-xalan/c/Tests/Performance/perf.cpp,v
retrieving revision 1.42
retrieving revision 1.43
diff -u -r1.42 -r1.43
--- perf.cpp 1 Dec 2004 20:33:01 -0000 1.42
+++ perf.cpp 7 Apr 2005 07:03:05 -0000 1.43
@@ -18,558 +18,284 @@
#include <xalanc/Include/PlatformDefinitions.hpp>
-
-#include <cstdio>
-
-#if defined(XALAN_CLASSIC_IOSTREAMS)
-#include <iostream.h>
-#else
#include <iostream>
-#endif
-// This is here for memory leak testing.
-#if !defined(NDEBUG) && defined(_MSC_VER)
-#include <crtdbg.h>
-#endif
#include <xercesc/util/PlatformUtils.hpp>
-#include <xalanc/PlatformSupport/DOMStringHelper.hpp>
-#include <xalanc/PlatformSupport/XalanFileOutputStream.hpp>
-#include <xalanc/PlatformSupport/XalanOutputStreamPrintWriter.hpp>
-
-#include <xalanc/XalanSourceTree/XalanSourceTreeDOMSupport.hpp>
-#include <xalanc/XalanSourceTree/XalanSourceTreeParserLiaison.hpp>
-
-#include <xalanc/XPath/XObjectFactoryDefault.hpp>
-#include <xalanc/XPath/XPathFactoryDefault.hpp>
-
-#include <xalanc/XSLT/StylesheetConstructionContextDefault.hpp>
-#include <xalanc/XSLT/StylesheetExecutionContextDefault.hpp>
-#include <xalanc/XSLT/StylesheetRoot.hpp>
-#include <xalanc/XSLT/XSLTEngineImpl.hpp>
-#include <xalanc/XSLT/XSLTInit.hpp>
-#include <xalanc/XSLT/XSLTInputSource.hpp>
-#include <xalanc/XSLT/XSLTProcessorEnvSupportDefault.hpp>
-#include <xalanc/XSLT/XSLTResultTarget.hpp>
+#include <xalanc/XalanTransformer/XalanTransformer.hpp>
-#include <xalanc/Harness/XalanXMLFileReporter.hpp>
-#include <xalanc/Harness/XalanFileUtility.hpp>
+#include <xalanc/XalanDOM/XalanDOMString.hpp>
-XALAN_USING_STD(cerr)
-XALAN_USING_STD(cout)
-XALAN_USING_STD(endl)
+#include <xalanc/Harness/XalanXMLFileReporter.hpp>
+#include <xalanc/Harness/XalanFileUtility.hpp>
-const char* const excludeStylesheets[] =
-{
- "large-evans_large.xsl",
- 0
-};
+#include "Parameters.hpp"
+#include "TestHarness.hpp"
+#include "XalanCProcessor.hpp"
+#include "Logger.hpp"
+#include "Utils.hpp"
-// Just hoist everything...
-XALAN_CPP_NAMESPACE_USE
+XALAN_USING_STD(cout);
+XALAN_USING_STD(cerr);
+XALAN_USING_STD(endl);
-inline bool
-checkForExclusion(const XalanDOMString& currentFile)
-{
- for (int i=0; excludeStylesheets[i] != 0; i++)
- {
- if (equals(currentFile, XalanDOMString(excludeStylesheets[i])))
- {
- return true;
- }
- }
- return false;
-}
+XALAN_USING_XERCES(XMLPlatformUtils)
-inline StylesheetRoot*
-processStylesheet(
- const XalanDOMString& theFileName,
- XSLTProcessor& theProcessor,
- StylesheetConstructionContext& theConstructionContext)
-{
- const XSLTInputSource theInputSource(theFileName);
+XALAN_USING_XALAN(XalanTransformer)
+XALAN_USING_XALAN(XalanDOMString)
+XALAN_USING_XALAN(XalanXMLFileReporter)
+XALAN_USING_XALAN(XalanFileUtility)
- return theProcessor.processStylesheet(theInputSource, theConstructionContext);
-}
-
-inline XalanNode*
-parseSourceDocument(
- const XalanDOMString& theFileName,
- XSLTProcessor& theProcessor)
+void usage()
{
- const XSLTInputSource theInputSource(theFileName);
-
- return theProcessor.getSourceTreeFromInput(theInputSource);
+ cerr << "Usage: perf"
+ << " [options]"
+ << " -test [test directory ]"
+ << " -result [result directory ]"
+ << " -report [report directory ]"
+ << " configfile" << endl
+ << "Options:" << endl
+ << " -? Display this message" << endl;
}
-inline double
-calculateElapsedTime(
- clock_t theStartTime,
- clock_t theEndTime)
+void generateReports(
+ Parameters& params,
+ const XalanDOMString& reportFile,
+ Logger& logger)
{
- return double(theEndTime - theStartTime) / CLOCKS_PER_SEC * 1000.0;
-}
-
+ XalanTransformer transformer;
+ // report XSL file
+ XalanDOMString reportFileXSL = params.getReportDirectory();
+ reportFileXSL += XalanDOMString("report.xsl");
-inline double
-calculateAvgTime(
- clock_t accTime,
- long theIterationCount)
-{
- assert(theIterationCount > 0);
-
- return double(accTime) / theIterationCount;
-}
+ // html result
+ XalanDOMString htmlReport = params.getResultDirectory();
+ htmlReport += params.getResultFile();
+ htmlReport += params.getUniqId();
+ htmlReport += XalanDOMString(".html");
+ if (checkFileExists(reportFileXSL))
+ {
+ if (transformer.transform(reportFile, reportFileXSL, htmlReport) < 0)
+ {
+ logger.warning()
+ << "Failed to generate HTML report: "
+ << htmlReport.c_str()
+ << ", error: "
+ << transformer.getLastError() << endl;
+ }
+ else
+ {
+ logger.message() << "Generated HTML report: " << htmlReport.c_str() << endl;
+ }
+ }
+ else
+ {
+ logger.warning()
+ << "Could not generate HTML report, stylesheet: "
+ << reportFileXSL.c_str()
+ << ", file not found" << endl;
+ }
+ XalanDOMString baselineFile = params.getBaselineDirectory();
+ baselineFile += params.getBaselineFile();
-inline double
-calculateAverageElapsedTime(
- clock_t theStartTime,
- clock_t theEndTime,
- long theIterationCount)
-{
- assert(theIterationCount > 0);
-
- return calculateElapsedTime(theStartTime, theEndTime) / theIterationCount;
-}
-
-
-
-inline clock_t
-transformWUnparsedSource(
- const XalanDOMString& theFileName,
- XSLTProcessor& theProcessor,
- const StylesheetRoot* theStylesheetRoot,
- XSLTResultTarget& theResults,
- StylesheetExecutionContextDefault& theExecutionContext)
-{
- const XSLTInputSource csSourceXML(c_wstr(theFileName));
-
- theProcessor.setStylesheetRoot(theStylesheetRoot);
-
- const clock_t startTime = clock();
-
- theProcessor.process(csSourceXML, theResults, theExecutionContext);
+ if (checkFileExists(baselineFile))
+ {
+ // comparison report XSL file
+ XalanDOMString compareReportFileXSL = params.getReportDirectory();
+ compareReportFileXSL += XalanDOMString("comparereport.xsl");
+
+ // html result
+ XalanDOMString htmlCompareReport = params.getResultDirectory();
+ htmlCompareReport += XalanDOMString("compare");
+ htmlCompareReport += params.getResultFile();
+ htmlCompareReport += params.getUniqId();
+ htmlCompareReport += XalanDOMString(".html");
- return clock() - startTime;
+ transformer.setStylesheetParam(XalanDOMString("threshold"),params.getThreshold());
+ transformer.setStylesheetParam(XalanDOMString("baseline"), baselineFile);
+ if (checkFileExists(compareReportFileXSL))
+ {
+ if (transformer.transform(reportFile, compareReportFileXSL, htmlCompareReport) < 0)
+ {
+ logger.warning()
+ << "Failed to generate HTML report: "
+ << htmlCompareReport.c_str()
+ << ", error: "
+ << transformer.getLastError() << endl;
+ }
+ else
+ {
+ logger.message() << "Generated HTML report: " << htmlCompareReport.c_str() << endl;
+ }
+ }
+ else
+ {
+ logger.warning()
+ << "Could not generate HTML report, stylesheet: "
+ << compareReportFileXSL.c_str()
+ << ", file not found" << endl;
+ }
+ }
+ else
+ {
+ logger.warning()
+ << "No baseline file found: "
+ << baselineFile.c_str()
+ << endl;
+ }
}
-
-inline clock_t
-transformWParsedSource(
- XalanNode* theParsedSource,
- XSLTProcessor& theProcessor,
- const StylesheetRoot* theStylesheetRoot,
- XSLTResultTarget& theResults,
- StylesheetExecutionContextDefault& theExecutionContext)
+int main(int argc, char* argv[])
{
- // Put the parsed document into an XSLTInputSource,
- // and set stylesheet root in the processor
- const XSLTInputSource csSourceDocument(theParsedSource);
-
- theProcessor.setStylesheetRoot(theStylesheetRoot);
-
- const clock_t startTime = clock();
-
- theProcessor.process(csSourceDocument, theResults, theExecutionContext);
-
- return clock() - startTime;
-}
+ XMLPlatformUtils::Initialize();
+ XalanTransformer::initialize();
+ Logger logger(cerr);
+ if (argc < 2 ||
+ XalanDOMString("-?").compare(XalanDOMString(argv[1])) == 0)
+ {
+ usage();
+ }
+ else
+ {
+ XalanDOMString testDirectory;
+ XalanDOMString resultDirectory;
+ XalanDOMString reportDirectory;
+ XalanDOMString runFileName;
+
+ // process command line parameters
+ int i = 1;
+ while (i < argc)
+ {
+ if (stricmp(argv[i],"-test") == 0)
+ {
+ ++i;
+ if (i >= argc)
+ {
+ logger.error() << "Test directory missing" << endl;
+ usage();
+ exit(1);
+ }
+ testDirectory.assign(argv[i]);
+ }
+ else if (stricmp(argv[i],"-result") == 0)
+ {
+ ++i;
+ if (i >= argc)
+ {
+ logger.error() << "Result directory missing" << endl;
+ usage();
+ exit(1);
+ }
+ resultDirectory.assign(argv[i]);
+ }
+ else if (stricmp(argv[i],"-report") == 0)
+ {
+ ++i;
+ if (i >= argc)
+ {
+ logger.error() << "Report directory missing" << endl;
+ usage();
+ exit(1);
+ }
+ reportDirectory.assign(argv[i]);
+ }
+ else
+ {
+ break;
+ }
-inline long
-eTOeTransform(
- const XSLTInputSource& inputSource,
- const XSLTInputSource& stylesheetSource,
- XSLTResultTarget& outputTarget,
- StylesheetConstructionContext& constructionContext,
- StylesheetExecutionContext& executionContext,
- XSLTProcessor& theProcessor)
-{
- const clock_t startTime=clock();
-
- theProcessor.process(
- inputSource,
- stylesheetSource,
- outputTarget,
- constructionContext,
- executionContext);
+ ++i;
+ }
- const clock_t endTime=clock();
+ if (i >= argc)
+ {
+ logger.error() << "Run file not specified" << endl;
+ usage();
+ exit(1);
+ }
+ else
+ {
+ runFileName.assign(argv[i]);
+ }
- return endTime - startTime;
-}
+ XalanFileUtility fileUtility(XalanMemMgrs::getDefaultXercesMemMgr());
+ // setup testing parameters
+ Parameters params(
+ runFileName,
+ testDirectory,
+ resultDirectory,
+ reportDirectory,
+ fileUtility,
+ logger);
-void
-setHelp(XalanFileUtility& h)
-{
- h.args.getHelpStream() << endl
- << "Perf dir [-out -sub -i -iter]"
- << endl
- << endl
- << "dir (base directory for testcases)"
- << endl
- << "-out dir (base directory for output)"
- << endl
- << "-sub dir (run files only from a specific directory)"
- << endl
- << "-i (include all testcases)"
- << endl
- << "-iter n (specifies number of iterations; must be > 0)"
- << endl;
-}
+ if (!params.initialized())
+ {
+ exit(1);
+ }
-int
-main(
- int argc,
- char* argv[])
-{
-#if !defined(NDEBUG) && defined(_MSC_VER)
- _CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF);
- _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
- _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
-#endif
-
- XERCES_CPP_NAMESPACE_QUALIFIER XMLPlatformUtils::Initialize();
-
- MemoryManagerType & theManager = XalanMemMgrs::getDefaultXercesMemMgr();
-
- const XalanDOMString processorType(XALAN_STATIC_UCODE_STRING("XalanC"), theManager);
- bool skip = true; // Default will skip long tests
- bool setGold = false;
-
- XalanFileUtility h(theManager);
-
- // Set the program help string, then get the command line parameters.
- //
- setHelp(h);
+ // create report file
+ XalanDOMString reportFile = params.getResultDirectory();
+ reportFile += params.getResultFile();
+ reportFile += params.getUniqId();
+ reportFile += XalanDOMString(".xml");
- if (h.getParams(argc, argv, "PERF-RESULTS", setGold) == true)
- {
+ XalanXMLFileReporter reporter(XalanMemMgrs::getDefaultXercesMemMgr(), reportFile);
- // Generate Unique Run id and processor info
- XalanDOMString UniqRunid(theManager);
- h.generateUniqRunid(UniqRunid);
- const XalanDOMString resultFilePrefix(XalanDOMString("cpp"));
- XalanDOMString resultsFile = h.args.output;
- resultsFile += resultFilePrefix;
- resultsFile += UniqRunid;
- resultsFile += XalanFileUtility::s_xmlSuffix;
+ reporter.logTestFileInit(params.getDescription());
- XalanXMLFileReporter logFile(theManager, resultsFile);
+ // run test harness
+ typedef TestHarness<XalanCProcessor> XalanCTestHarness;
- logFile.logTestFileInit("Performance Testing - Reports performance times for single transform, and average for multiple transforms using compiled stylesheet");
+ XalanCTestHarness testHarness;
- try
- {
- // Call the static initializers... and define file suffixes
- // Having xmlplatformutils in it's own class like this means that if there are
- // exceptions then terminate() is sure to run because it will automatically get
- // cleaned up when this instance goes out of scope.
- bool foundDir = false; // Flag indicates directory found. Used in conjunction with -sub cmd-line arg.
- {
- XSLTInit theInit(theManager);
-
- typedef XalanFileUtility::FileNameVectorType FileNameVectorType;
+ testHarness.init(fileUtility, reporter, logger);
- // Get the list of Directories that are below perf and iterate through them
- FileNameVectorType dirs(theManager);
-
- h.getDirectoryNames(h.args.base, dirs);
-
- const long iterCount = h.args.iters;
-
- for(FileNameVectorType::size_type j = 0; j < dirs.size(); j++)
- {
- // Run specific sub of files from given directory
- if (length(h.args.sub) > 0 && !equals(dirs[j], h.args.sub))
- {
- continue;
- }
-
- // Check that output directory is there.
- XalanDOMString theOutputDir = h.args.output;
- theOutputDir += dirs[j];
- h.checkAndCreateDir(theOutputDir);
-
- XalanDOMString logEntry("Performance Directory: ");
- logEntry += dirs[j];
- logFile.logTestCaseInit(logEntry);
-
- // Indicate that directory was processed and get test files from the directory
- foundDir = true;
- FileNameVectorType files(theManager);
- h.getTestFileNames(h.args.base, dirs[j], false, files);
-
- for(FileNameVectorType::size_type i = 0; i < files.size(); i++)
- {
- // Define variables used for timing and reporting ...
- clock_t startTime, endTime, accmTime, avgEtoe;
- double timeinMilliseconds, theAverage;
-
- typedef XalanXMLFileReporter::Hashtable Hashtable;
-
- Hashtable attrs(theManager);
-
- if (skip && checkForExclusion(files[i]))
- {
- continue;
- }
-
- XalanDOMString theXSLFile= h.args.base;
- theXSLFile += dirs[j];
- theXSLFile += XalanFileUtility::s_pathSep;
- theXSLFile += files[i];
- XalanDOMString theXMLFile(theManager);
- h.generateFileName(theXSLFile,"xml", theXMLFile);
-
- XalanDOMString theOutput = h.args.output;
- theOutput += dirs[j];
- theOutput += XalanFileUtility::s_pathSep;
- theOutput += files[i];
- XalanDOMString theOutputFile;
- h.generateFileName(theOutput, "out", theOutputFile);
-
-
- attrs.insert(Hashtable::value_type(XalanDOMString("href"), theXSLFile));
- // Create the necessary support objects to instantiate a processor.
-
- XercesDOMSupport csDOMSupport;
- XercesParserLiaison csParserLiaison(theManager, csDOMSupport);
-
- /*XalanSourceTreeDOMSupport csDOMSupport;
- XalanSourceTreeParserLiaison csParserLiaison(csDOMSupport);
-
- csDOMSupport.setParserLiaison(&csParserLiaison);
- */
-
- XSLTProcessorEnvSupportDefault csXSLTProcessorEnvSupport(theManager);
- XObjectFactoryDefault csXObjectFactory;
- XPathFactoryDefault csXPathFactory;
-
- // Create a processor and connect to ProcessorEnvSupport object
- XSLTEngineImpl csProcessor(
- theManager,
- csParserLiaison,
- csXSLTProcessorEnvSupport,
- csDOMSupport,
- csXObjectFactory,
- csXPathFactory);
-
- // Hook up the processor the the support object.
- csXSLTProcessorEnvSupport.setProcessor(&csProcessor);
-
- // Create separate factory support object, so the stylesheet's
- // factory-created XPath instance are independent from processor's.
- XPathFactoryDefault ssXPathFactory;
-
- // Create a stylesheet construction context, using the
- // stylesheet's factory support objects.
- StylesheetConstructionContextDefault csConstructionContext(
- theManager,
- csProcessor,
- ssXPathFactory);
- cout << endl << files[i] << endl;
-
- // Create a parsed stylesheet (StylesheetRoot) for the
- // specified input XSL. We don't have to delete it, since
- // it is owned by the StylesheetConstructionContextDefault
- // instance. Time it as well...
-
- startTime = clock();
- const StylesheetRoot* const glbStylesheetRoot = processStylesheet(
- theXSLFile,
- csProcessor,
- csConstructionContext);
- endTime = clock();
- assert(glbStylesheetRoot != 0);
-
- // Calculate & report performance on stylesheet parse to console and log file.
- timeinMilliseconds = calculateElapsedTime(startTime, endTime);
- cout << " XSL: " << timeinMilliseconds << " milliseconds, Parse" << endl;
- logFile.addMetricToAttrs("parsexsl",timeinMilliseconds, attrs);
-
-
- // Parse the input XML and report how long it took...
- startTime = clock();
- XalanNode* const glbSourceXML = parseSourceDocument(theXMLFile,
- csProcessor);
- endTime = clock();
- assert(glbSourceXML != 0);
-
- // Calculate & report performance on source document parse to console and log file.
- timeinMilliseconds = calculateElapsedTime(startTime, endTime);
- cout << " XML: " << timeinMilliseconds << " milliseconds, Parse" << endl;
- logFile.addMetricToAttrs("parsexml",timeinMilliseconds, attrs);
-
-
-
- // The execution context uses the same factory support objects as
- // the processor, since those objects have the same lifetime as
- // other objects created as a result of the execution.
-
- XSLTResultTarget theResultTarget(theOutputFile);
- const XSLTInputSource xslInputSource(theXSLFile);
- const XSLTInputSource xmlInputSource(theXMLFile);
-
- StylesheetExecutionContextDefault psExecutionContext(
- theManager,
- csProcessor,
- csXSLTProcessorEnvSupport,
- csDOMSupport,
- csXObjectFactory);
-
- // Perform a single transform using parsed stylesheet and unparsed xml source, report results...
- csProcessor.setStylesheetRoot(glbStylesheetRoot);
- //const XSLTInputSource csSourceDocument(glbSourceXML);
-
- startTime = clock();
- csProcessor.process(xmlInputSource,
- theResultTarget,
- psExecutionContext);
- endTime = clock();
-
- psExecutionContext.reset(); // Reset the execution context...
- timeinMilliseconds = calculateElapsedTime(startTime, endTime);
-
- // Output single transform time to console and result log
- cout << endl << " One: " << timeinMilliseconds << " w/Parsed XSL" << endl;
- logFile.addMetricToAttrs("single",timeinMilliseconds, attrs);
-
-
- // Do a total end to end transform with no pre parsing of either xsl or xml files.
- const etoetran = eTOeTransform(xmlInputSource,
- xslInputSource,
- theResultTarget,
- csConstructionContext,
- psExecutionContext,
- csProcessor);
-
- // Output single etoe transform time to console and result log
- cout << " One: " << etoetran << " eToe" << endl;
- logFile.addMetricToAttrs("etoe", etoetran, attrs);
-
-
- // Perform multiple transforms and calculate the average time ..
- // These are done 3 different ways.
- // FIRST: Parsed XSL Stylesheet and Parsed XML Source.
-
- accmTime = 0;
- for(int j = 0; j < iterCount; ++j)
- {
- accmTime += transformWParsedSource(glbSourceXML,
- csProcessor,
- glbStylesheetRoot,
- theResultTarget,
- psExecutionContext);
- psExecutionContext.reset();
- }
- csParserLiaison.reset();
- theAverage = calculateAvgTime(accmTime, iterCount);
-
- // Output average transform time to console and result log
- cout << endl << " Avg: " << theAverage << " for " << iterCount << " iter's w/Parsed files" << endl;
- logFile.addMetricToAttrs("avgparsedxml",theAverage, attrs);
-
- // SECOND: Parsed Stylesheet and UnParsed XML Source.
- // This is currently how the XalanJ 2.0 is performing transforms,
- // i.e. with the unparsed XML Source.
-
- accmTime = 0;
- for(int k = 0; k < iterCount; ++k)
- {
- accmTime += transformWUnparsedSource(theXMLFile,
- csProcessor,
- glbStylesheetRoot,
- theResultTarget,
- psExecutionContext);
- psExecutionContext.reset(); // Resets the execution context
- csParserLiaison.reset(); // This deletes the document
- }
+ testHarness.executeTestCases(params.getTestCases());
- theAverage = calculateAvgTime(accmTime, iterCount);
- cout << " Avg: " << theAverage << " for " << iterCount << " iter's w/UnParsed XML" << endl;
+ reporter.logTestFileClose("","");
- logFile.addMetricToAttrs("avgunparsedxml",theAverage, attrs);
+ reporter.close();
- // THIRD: Neither Stylesheet nor XML Source are parsed.
- // Perform multiple etoe transforms and calculate the average ...
+ // generate reports
+ generateReports(params, reportFile, logger);
- avgEtoe = 0;
- for(int jj = 0; jj < iterCount; ++jj)
- {
- avgEtoe += eTOeTransform(xmlInputSource,
- xslInputSource,
- theResultTarget,
- csConstructionContext,
- psExecutionContext,
- csProcessor);
- psExecutionContext.reset();
- csParserLiaison.reset();
- }
-
- theAverage = calculateAvgTime(avgEtoe,iterCount);
-
- // Output average transform time to console and result log
- cout << " Avg: " << theAverage << " for " << iterCount << " iter's of eToe" << endl;
- logFile.addMetricToAttrs("avgetoe",theAverage, attrs);
- logFile.logElementWAttrs(10, "perf", attrs, "xxx");
- }
-
- logEntry = "Performance Directory: ";
- logEntry += dirs[j];
- logFile.logTestCaseClose(logEntry, XalanDOMString("Done"));
- }
-
- }
-
- // Check to see if -sub cmd-line directory was processed correctly.
- if (!foundDir)
- {
- cout << "Specified test directory: \"" << c_str(TranscodeToLocalCodePage(h.args.sub)) << "\" not found" << endl;
- }
-
- h.reportPassFail(logFile, UniqRunid);
- logFile.logTestFileClose("Performance", "Done");
- logFile.close();
- }
- catch(const XalanFileOutputStream::XalanFileOutputStreamOpenException& ex)
- {
- cerr << ex.getMessage() << endl << endl;
- }
- catch(...)
- {
- cerr << "Exception caught!!!" << endl << endl;
- }
+ // create latest copy for baseline testing
+ XalanDOMString latestReportFile = params.getResultDirectory();
+ latestReportFile += params.getResultFile();
+ latestReportFile += XalanDOMString("_latest.xml");
+ copyFile(latestReportFile, reportFile);
}
- XERCES_CPP_NAMESPACE_QUALIFIER XMLPlatformUtils::Terminate();
+ XalanTransformer::terminate();
+ XMLPlatformUtils::Terminate();
return 0;
}
1.1 xml-xalan/c/Tests/Performance/Logger.cpp
Index: Logger.cpp
===================================================================
/*
* Copyright 1999-2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Base header file. Must be first.
#include <xalanc/Include/PlatformDefinitions.hpp>
#include <ctime>
#include <iomanip>
#include "Logger.hpp"
using namespace std;
Logger::Logger(ostream & stream) :
m_stream(stream)
{
logText[eMessage] = "Message";
logText[eWarning] = "Warning";
logText[eError] = "Error";
}
ostream&
Logger::message()
{
return log(eMessage);
}
ostream&
Logger::warning()
{
return log(eWarning);
}
ostream&
Logger::error()
{
return log(eError);
}
ostream&
Logger::log(eLogType logType)
{
time_t theTime;
time(&theTime);
// Not thread safe
char * timeStr = ctime(&theTime);
timeStr[24] = '\0';
m_stream << timeStr << setw(10) << logText[logType] << ": ";
return m_stream;
}
1.1 xml-xalan/c/Tests/Performance/Logger.hpp
Index: Logger.hpp
===================================================================
/*
* Copyright 1999-2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#if !defined(LOGGER_HEADER_GUARD_1357924680)
#define LOGGER_HEADER_GUARD_1357924680
// Base header file. Must be first.
#include <xalanc/Include/PlatformDefinitions.hpp>
#include <iostream>
#include <xalanc/XalanDOM/XalanDOMString.hpp>
XALAN_USING_STD(ostream)
XALAN_USING_XALAN(XalanDOMString)
class Logger
{
public:
Logger(ostream & stream);
typedef enum { eMessage = 0, eWarning = 1, eError = 2} eLogType;
ostream& message();
ostream& warning();
ostream& error();
ostream& log(eLogType logType);
protected:
char * logText[3];
ostream& m_stream;
};
#endif LOGGER_HEADER_GUARD_1357924680
1.1 xml-xalan/c/Tests/Performance/Parameters.cpp
Index: Parameters.cpp
===================================================================
/*
* Copyright 1999-2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <iostream>
#include <xalanc/Include/XalanMemoryManagement.hpp>
#include <xalanc/XalanTransformer/XalanParsedSource.hpp>
#include <xalanc/PlatformSupport/DOMStringHelper.hpp>
#include <xalanc/XalanDOM/XalanDocument.hpp>
#include <xalanc/XalanDOM/XalanNode.hpp>
#include <xalanc/XalanDOM/XalanNamedNodeMap.hpp>
#include <xalanc/XalanDOM/XalanDOMString.hpp>
#include <xalanc/Harness/XalanFileUtility.hpp>
#include "Parameters.hpp"
#include "Utils.hpp"
XALAN_USING_XALAN(XalanTransformer)
XALAN_USING_XALAN(XalanParsedSource)
XALAN_USING_XALAN(XalanDocument)
XALAN_USING_XALAN(XalanNode)
XALAN_USING_XALAN(XalanNamedNodeMap)
XALAN_USING_XALAN(XalanDOMString)
XALAN_USING_XALAN(WideStringToLong)
XALAN_USING_XALAN(compareIgnoreCaseASCII)
XALAN_USING_XALAN(XalanMemMgrs)
XALAN_USING_XALAN(MemoryManagerType)
XALAN_USING_XALAN(XalanFileUtility)
XALAN_USING_STD(endl);
/**
* Processes parameters for the test harness
*/
Parameters::Parameters(
const XalanDOMString& runFileName,
const XalanDOMString& testDirectory,
const XalanDOMString& resultDirectory,
const XalanDOMString& reportDirectory,
XalanFileUtility& fileUtility,
Logger & logger) :
m_name(),
m_description(),
m_resultDirectory(resultDirectory),
m_resultFile("results"),
m_threshold("5"),
m_baselineDirectory(),
m_baselineFile(),
m_defaultTestCase(),
m_testDirectory(testDirectory),
m_goldDirectory(),
m_reportDirectory(reportDirectory),
m_transformer(),
m_initialized(false),
m_uniqId()
{
fileUtility.generateUniqRunid(m_uniqId);
if (parseConfigurationFile(runFileName, logger))
{
if (m_testDirectory.empty())
{
logger.error() << "No test directory specified on command line or in configuration file" << endl;
}
else
{
// configure directories
// result directory
if (m_resultDirectory.empty())
{
m_resultDirectory = getWorkingDirectory();
}
m_resultDirectory += getPathSep();
// gold directory
if (m_goldDirectory.empty())
{
m_goldDirectory = m_testDirectory;
m_goldDirectory += XalanDOMString("-gold");
}
// test directory
m_testDirectory += getPathSep();
if (readTestCases(fileUtility, logger))
{
m_initialized = true;
}
// baseline directory
if (m_baselineDirectory.empty())
{
m_baselineDirectory = m_resultDirectory;
}
else
{
m_baselineDirectory += getPathSep();
}
if (m_baselineFile.empty())
{
m_baselineFile = m_resultFile;
m_baselineFile += XalanDOMString("_latest.xml");
}
// report directory
if (m_reportDirectory.empty())
{
m_reportDirectory = getWorkingDirectory();
}
m_reportDirectory += getPathSep();
}
}
}
const TestCasesType&
Parameters::getTestCases()
{
return m_testCases;
}
bool
Parameters::parseConfigurationFile(
const XalanDOMString& runFileName,
Logger& logger)
{
// parse the configuration file and get default settings
XalanParsedSource* theParsedSource;
if (m_transformer.parseSource(runFileName, theParsedSource) < 0)
{
logger.error() << "Failed to parse: "
<< runFileName.c_str()
<< ", error: "
<< m_transformer.getLastError()
<< endl;
return false;
}
XalanDocument* document = theParsedSource->getDocument();
XalanNode* runNode = document->getFirstChild();
while (runNode->getNodeType() != XalanNode::ELEMENT_NODE)
{
runNode = runNode->getNextSibling();
if (0 == runNode)
{
logger.error() << "Failed to parse: "
<< runFileName.c_str()
<< ", error: no <testconfig> found"
<< endl;
return false;
}
}
if(!(runNode->getNodeName() == XalanDOMString("testconfig")))
{
logger.error() << "Invalid configuration file: "
<< runFileName.c_str()
<< ", error: Missing <testconfig> tag"
<< endl;
return false;
}
const XalanNamedNodeMap* attributes = runNode->getAttributes();
if (attributes != 0)
{
XalanNode* nameAttribute = attributes->getNamedItem(XalanDOMString("name"));
if (nameAttribute != 0 &&
!nameAttribute->getNodeValue().empty())
{
m_name = nameAttribute->getNodeValue();
}
else
{
logger.error() << "Invalid configuration file: "
<< runFileName.c_str()
<< ", error: Missing name attribute"
<< endl;
return false;
}
}
XalanNode* currentNode = runNode->getFirstChild();
while(currentNode != 0)
{
if (currentNode->getNodeType() != XalanNode::ELEMENT_NODE)
{
currentNode = currentNode->getNextSibling();
continue;
}
// description element
if (currentNode->getNodeName() == XalanDOMString("description") &&
currentNode->getFirstChild() != 0 &&
currentNode->getFirstChild()->getNodeType() == XalanNode::TEXT_NODE)
{
m_description = currentNode->getFirstChild()->getNodeValue();
}
// results element
else if (currentNode->getNodeName() == XalanDOMString("results"))
{
// file-path
const XalanNamedNodeMap* resultAttributes = currentNode->getAttributes();
XalanNode * attributeNode = resultAttributes->getNamedItem(XalanDOMString("file-path"));
if (attributeNode != 0 &&
attributeNode->getNodeType() == XalanNode::ATTRIBUTE_NODE)
{
if (!m_resultDirectory.empty())
{
m_resultDirectory += getPathSep();
}
m_resultDirectory += attributeNode->getNodeValue();
}
// result report file name
XalanNode * resultsNode = currentNode->getFirstChild();
if (resultsNode != 0
&& resultsNode->getNodeType() == XalanNode::TEXT_NODE
&& !resultsNode->getNodeValue().empty())
{
m_resultFile = resultsNode->getNodeValue();
}
}
// baseline element
else if (currentNode->getNodeName() == XalanDOMString("baseline"))
{
const XalanNamedNodeMap* attributeParams = currentNode->getAttributes();
XalanNode* attributeNode;
// threshold
attributeNode = attributeParams->getNamedItem(XalanDOMString("threshold"));
if (attributeNode != 0
&& !attributeNode->getNodeValue().empty())
{
m_threshold = attributeNode->getNodeValue().c_str();
}
// file-path
attributeNode = attributeParams->getNamedItem(XalanDOMString("file-path"));
if (attributeNode != 0)
{
m_baselineDirectory = attributeNode->getNodeValue();
}
// baseline file
XalanNode * baselineNode = currentNode->getFirstChild();
if (baselineNode != 0
&& baselineNode->getNodeType() == XalanNode::TEXT_NODE
&& !baselineNode->getNodeValue().empty())
{
m_baselineFile += baselineNode->getNodeValue();
}
}
// default parameters
else if (currentNode->getNodeName() == XalanDOMString("default-parameter-set"))
{
const XalanNamedNodeMap* attributeParams = currentNode->getAttributes();
XalanNode* attributeNode;
attributeNode = attributeParams->getNamedItem(XalanDOMString("input-mode"));
if (attributeNode != 0 &&
attributeNode->getNodeType() == XalanNode::ATTRIBUTE_NODE &&
!attributeNode->getNodeValue().empty())
{
m_defaultTestCase.inputMode = attributeNode->getNodeValue();
}
// number of iterations
attributeNode = attributeParams->getNamedItem(XalanDOMString("num-iterations"));
if (attributeNode != 0 &&
attributeNode->getNodeType() == XalanNode::ATTRIBUTE_NODE &&
WideStringToLong(attributeNode->getNodeValue().c_str()) > 0)
{
m_defaultTestCase.numIterations = WideStringToLong(attributeNode->getNodeValue().c_str());
}
// minimum time to execute
attributeNode = attributeParams->getNamedItem(XalanDOMString("min-time-to-execute"));
if (attributeNode != 0 &&
attributeNode->getNodeType() == XalanNode::ATTRIBUTE_NODE &&
WideStringToLong(attributeNode->getNodeValue().c_str()) > 0)
{
m_defaultTestCase.minTimeToExecute = WideStringToLong(attributeNode->getNodeValue().c_str());
}
// verify the result
attributeNode = attributeParams->getNamedItem(XalanDOMString("verify-result"));
if (attributeNode != 0 &&
attributeNode->getNodeType() == XalanNode::ATTRIBUTE_NODE &&
compareIgnoreCaseASCII(attributeNode->getNodeValue().c_str(),XalanDOMString("yes").c_str()) == 0)
{
m_defaultTestCase.verifyResult = true;
}
// get processor specific parameters
XalanNode * options = currentNode->getFirstChild();
while (options != 0)
{
if (options->getNodeType() != XalanNode::ELEMENT_NODE)
{
options = options->getNextSibling();
continue;
}
const XalanDOMString* processorName = 0;
const XalanNamedNodeMap* optionAttributes = options->getAttributes();
XalanNode* processorOption = optionAttributes->getNamedItem(XalanDOMString("processor"));
if (processorOption != 0 &&
processorOption->getNodeType() == XalanNode::ATTRIBUTE_NODE)
{
processorName = &(processorOption->getNodeValue());
}
if (processorName != 0 && processorName->empty() == true)
{
options = options->getNextSibling();
continue;
}
if (options->getNodeName() == XalanDOMString("init-options"))
{
m_defaultTestCase.processorOptions[*processorName].initOptions = options->getFirstChild();
}
else if (options->getNodeName() == XalanDOMString("compile-options"))
{
m_defaultTestCase.processorOptions[*processorName].compileOptions = options->getFirstChild();
}
else if (options->getNodeName() == XalanDOMString("parse-options"))
{
m_defaultTestCase.processorOptions[*processorName].parseOptions = options->getFirstChild();
}
else if (options->getNodeName() == XalanDOMString("result-options"))
{
m_defaultTestCase.processorOptions[*processorName].resultOptions = options->getFirstChild();
}
else if (options->getNodeName() == XalanDOMString("transform-options"))
{
m_defaultTestCase.processorOptions[*processorName].transformOptions = options->getFirstChild();
}
options = options->getNextSibling();
}
}
else if (currentNode->getNodeName() == XalanDOMString("testcases"))
{
// file-path
const XalanNamedNodeMap* testCasesAttributes = currentNode->getAttributes();
XalanNode * attributeNode = testCasesAttributes->getNamedItem(XalanDOMString("file-path"));
if (attributeNode != 0 &&
attributeNode->getNodeType() == XalanNode::ATTRIBUTE_NODE)
{
if (!m_testDirectory.empty())
{
m_testDirectory += getPathSep();
}
m_testDirectory += attributeNode->getNodeValue();
}
// gold file-path
attributeNode = testCasesAttributes->getNamedItem(XalanDOMString("gold-file-path"));
if (attributeNode != 0 &&
attributeNode->getNodeType() == XalanNode::ATTRIBUTE_NODE)
{
m_goldDirectory = attributeNode->getNodeValue();
}
}
currentNode = currentNode->getNextSibling();
}
return true;
}
bool
Parameters::readTestCases(
XalanFileUtility& fileUtility,
Logger& logger)
{
if (!fileUtility.checkDir(m_testDirectory))
{
logger.error() << "Invalid test directory: " << m_testDirectory.c_str() << endl;
return false;
}
if (!fileUtility.checkDir(m_goldDirectory))
{
logger.error() << "Invalid gold directory: " << m_goldDirectory.c_str() << endl;
return false;
}
fileUtility.checkAndCreateDir(m_resultDirectory);
typedef XalanFileUtility::FileNameVectorType FileNamesType;
FileNamesType dirNames;
fileUtility.getDirectoryNames(m_testDirectory, dirNames);
FileNamesType::iterator dirIter = dirNames.begin();
// for each test directory
while (dirIter != dirNames.end())
{
FileNamesType xslTestFiles;
fileUtility.getTestFileNames(m_testDirectory, *dirIter, true, xslTestFiles);
FileNamesType::const_iterator xslIter = xslTestFiles.begin();
// for each stylesheet
while (xslIter != xslTestFiles.end())
{
// configure the stylesheet
TestCase testCase = m_defaultTestCase;
testCase.stylesheet = m_testDirectory;
testCase.stylesheet += *dirIter;
testCase.stylesheet += getPathSep();
testCase.stylesheet += *xslIter;
bool status = true;
// configure the input document
fileUtility.generateFileName(testCase.stylesheet, "xml", testCase.inputDocument, &status);
if (status != true)
{
logger.warning() << "No matching input file for" << testCase.stylesheet.c_str() << endl;
++xslIter;
continue;
}
// configure result directory
testCase.resultDirectory = m_resultDirectory;
testCase.resultDirectory += *dirIter;
// configure result document
XalanDOMString outFile = testCase.resultDirectory;
outFile += getPathSep();
outFile += *xslIter;
fileUtility.generateFileName(outFile, "out", testCase.resultDocument);
// configure gold result
outFile = m_goldDirectory;
outFile += getPathSep();
outFile += *dirIter;
outFile += getPathSep();
outFile += *xslIter;
status = true;
fileUtility.generateFileName(outFile, "out", testCase.goldResult, &status);
if (true == testCase.verifyResult && !status)
{
logger.warning() << "Verification on, but no matching gold file: " << testCase.goldResult.c_str() << endl;
}
m_testCases.push_back(testCase);
++xslIter;
}
++dirIter;
}
return true;
}
1.1 xml-xalan/c/Tests/Performance/Parameters.hpp
Index: Parameters.hpp
===================================================================
/*
* Copyright 1999-2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#if !defined(XALANCPARAMETERS_HEADER_GUARD_1357924680)
#define XALANCPARAMETERS_HEADER_GUARD_1357924680
// Base header file. Must be first.
#include <xalanc/Include/PlatformDefinitions.hpp>
#include <xalanc/XalanDOM/XalanDOMString.hpp>
#include <xalanc/XalanTransformer/XalanTransformer.hpp>
#include <xalanc/Harness/XalanFileUtility.hpp>
#include "TestHarness.hpp"
#include "Logger.hpp"
XALAN_USING_XALAN(XalanDOMChar)
XALAN_USING_XALAN(XalanDOMString)
XALAN_USING_XALAN(XalanTransformer)
XALAN_USING_XALAN(XalanFileUtility)
class Parameters
{
public:
Parameters(
const XalanDOMString& runFileName,
const XalanDOMString& testDirectory,
const XalanDOMString& resultDirectory,
const XalanDOMString& reportDirectory,
XalanFileUtility& fileUtility,
Logger& log);
/*
const XalanDOMString&
getRunName() { return m_name;}
*/
bool
initialized() {return m_initialized;}
XalanDOMString&
getName() {return m_name;}
XalanDOMString&
getUniqId() {return m_uniqId;}
XalanDOMString&
getDescription() {return m_description;}
XalanDOMString&
getResultDirectory() {return m_resultDirectory;}
XalanDOMString&
getResultFile() {return m_resultFile;}
XalanDOMString&
getThreshold() { return m_threshold;}
XalanDOMString&
getBaselineDirectory() {return m_baselineDirectory;}
XalanDOMString&
getBaselineFile() {return m_baselineFile;}
XalanDOMString&
getReportDirectory() {return m_reportDirectory;}
const TestCasesType&
getTestCases();
protected:
bool parseConfigurationFile(
const XalanDOMString& runFileName,
Logger& logger);
bool readTestCases(
XalanFileUtility& fileUtility,
Logger & logger);
XalanDOMString m_name;
XalanDOMString m_description;
XalanDOMString m_resultDirectory;
XalanDOMString m_resultFile;
XalanDOMString m_threshold;
XalanDOMString m_baselineDirectory;
XalanDOMString m_baselineFile;
TestCase m_defaultTestCase;
XalanDOMString m_testDirectory;
XalanDOMString m_goldDirectory;
XalanDOMString m_reportDirectory;
TestCasesType m_testCases;
XalanTransformer m_transformer;
XalanDOMString m_uniqId;
bool m_initialized;
};
#endif // XALANCPARAMETERS_HEADER_GUARD_1357924680
1.1 xml-xalan/c/Tests/Performance/TestHarness.cpp
Index: TestHarness.cpp
===================================================================
/*
* Copyright 1999-2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "TestHarness.hpp"
#include <xalanc/Include/XalanMemoryManagement.hpp>
#include <xalanc/PlatformSupport/DOMStringHelper.hpp>
XALAN_USING_XALAN(XalanMemMgrs)
XALAN_USING_XALAN(CharVectorType)
XALAN_USING_XALAN(c_str)
XALAN_USING_STD(ostringstream)
TestCase::TestCase() :
stylesheet(""),
inputDocument(""),
resultDocument(""),
resultDirectory(""),
goldResult(""),
numIterations(1),
minTimeToExecute(0),
verifyResult(false),
inputMode("file"),
processorOptions(XalanMemMgrs::getDefaultXercesMemMgr())
{
}
TestCase::TestCase(const TestCase& theRhs) :
stylesheet(theRhs.stylesheet),
inputDocument(theRhs.inputDocument),
resultDocument(theRhs.resultDocument),
resultDirectory(theRhs.resultDirectory),
goldResult(theRhs.goldResult),
numIterations(theRhs.numIterations),
minTimeToExecute(theRhs.minTimeToExecute),
verifyResult(theRhs.verifyResult),
inputMode(theRhs.inputMode),
processorOptions(theRhs.processorOptions, XalanMemMgrs::getDefaultXercesMemMgr())
{
}
1.1 xml-xalan/c/Tests/Performance/TestHarness.hpp
Index: TestHarness.hpp
===================================================================
/*
* Copyright 1999-2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#if !defined(TESTHARNESS_HEADER_GUARD_1357924680)
#define TESTHARNESS_HEADER_GUARD_1357924680
// Base header file. Must be first.
#include <xalanc/Include/PlatformDefinitions.hpp>
#include <fstream>
#include <xalanc/Include/XalanMemoryManagement.hpp>
#include <xalanc/Include/XalanVector.hpp>
#include <xalanc/Include/XalanMap.hpp>
#include <xalanc/PlatformSupport/DOMStringHelper.hpp>
#include <xalanc/XalanDOM/XalanNode.hpp>
#include <xalanc/XalanDOM/XalanDOMString.hpp>
#include <xalanc/Harness/XalanFileUtility.hpp>
#include <xalanc/Harness/XalanXMLFileReporter.hpp>
#include "Utils.hpp"
#include "Logger.hpp"
#include "Timer.hpp"
XALAN_USING_XALAN(XalanMemMgrs)
XALAN_USING_XALAN(XalanVector)
XALAN_USING_XALAN(XalanMap)
XALAN_USING_XALAN(XalanNode)
XALAN_USING_XALAN(XalanDOMString)
XALAN_USING_XALAN(XalanFileUtility)
XALAN_USING_XALAN(XalanXMLFileReporter)
XALAN_USING_STD(istringstream)
/**
* Processor interface options
*/
struct ProcessorOptions
{
XalanNode* initOptions;
XalanNode* compileOptions;
XalanNode* parseOptions;
XalanNode* resultOptions;
XalanNode* transformOptions;
ProcessorOptions() :
initOptions(0),
compileOptions(0),
parseOptions(0),
resultOptions(0),
transformOptions(0)
{
}
};
/**
* Test case
*/
class TestCase
{
public:
TestCase();
TestCase(const TestCase& theRhs);
XalanDOMString stylesheet;
XalanDOMString inputDocument;
XalanDOMString resultDocument;
XalanDOMString resultDirectory;
XalanDOMString goldResult;
long numIterations;
long minTimeToExecute;
bool verifyResult;
XalanDOMString inputMode;
typedef XalanMap<XalanDOMString, ProcessorOptions> ProcessorOptionsMap;
ProcessorOptionsMap processorOptions;
};
typedef TestCase TestCaseType;
typedef XalanVector<TestCaseType> TestCasesType;
/**
* Test harness
*/
template <class Processor>
class TestHarness
{
public:
typedef typename Processor::CompiledStylesheetType CompiledStylesheetType;
typedef typename Processor::ParsedInputSourceType ParsedInputSourceType;
typedef typename Processor::ResultTargetType ResultTargetType;
typedef typename XalanXMLFileReporter::Hashtable TestAttributesType;
TestHarness();
void init(
XalanFileUtility& fileUtility,
XalanXMLFileReporter& reporter,
Logger& logger);
void terminate();
void executeTestCase(const TestCaseType& testCase);
void executeTestCases(const TestCasesType& testCases);
protected:
Processor m_processor;
XalanFileUtility* m_fileUtility;
XalanXMLFileReporter* m_reporter;
Logger* m_logger;
};
template <class Processor>
void
TestHarness<Processor>::executeTestCases(const TestCasesType& testCases)
{
TestCasesType::const_iterator testCaseIter = testCases.begin();
while (testCaseIter != testCases.end())
{
executeTestCase(*testCaseIter);
++testCaseIter;
}
}
template <class Processor>
void
TestHarness<Processor>::executeTestCase(const TestCaseType& testCase)
{
TestAttributesType testAttributes(XalanMemMgrs::getDefaultXercesMemMgr());
testAttributes.insert(TestAttributesType::value_type(XalanDOMString("stylesheet"), testCase.stylesheet));
testAttributes.insert(TestAttributesType::value_type(XalanDOMString("input-document"), testCase.inputDocument));
try {
CompiledStylesheetType compiledStylesheet;
ParsedInputSourceType parsedInputSource;
ResultTargetType resultTarget;
static const ProcessorOptions defaultProcessor;
TestCase::ProcessorOptionsMap::const_iterator iter = testCase.processorOptions.find(m_processor.getName());
const ProcessorOptions& processor = iter != testCase.processorOptions.end() ? iter->second : defaultProcessor;
m_fileUtility->checkAndCreateDir(testCase.resultDirectory);
Timer timeCompile;
if (testCase.inputMode == XalanDOMString("stream"))
{
istringstream compilerStream;
fileToStream(testCase.stylesheet, compilerStream);
timeCompile.start();
compiledStylesheet = m_processor.compileStylesheet(
compilerStream,
processor.compileOptions);
timeCompile.stop();
}
else if (testCase.inputMode == XalanDOMString("file"))
{
timeCompile.start();
compiledStylesheet = m_processor.compileStylesheet(
testCase.stylesheet,
processor.compileOptions);
timeCompile.stop();
}
else
{
m_logger->error()
<< "Mode: "
<< testCase.inputMode.c_str()
<< " is inavlid for stylesheet: "
<< testCase.stylesheet
<< endl;
}
m_reporter->addMetricToAttrs("compile-xsl", timeCompile.getElapsedTime(), testAttributes);
long numIterations = 0;
long totalParseInputTime = 0;
long minParseInputTime = LONG_MAX;
long maxParseInputTime = 0 ;
long totalTransformTime = 0;
long minTransformTime = LONG_MAX;
long maxTransformTime = 0;
Timer timeTotalRun;
timeTotalRun.start();
while (numIterations < testCase.numIterations
&& timeTotalRun.getElapsedTime() < testCase.minTimeToExecute)
{
Timer timeInput;
if (testCase.inputMode == XalanDOMString("stream"))
{
istringstream inputStream;
fileToStream(testCase.inputDocument, inputStream);
timeInput.start();
parsedInputSource = m_processor.parseInputSource(
inputStream,
processor.parseOptions);
timeInput.stop();
}
else if (testCase.inputMode == XalanDOMString("file"))
{
timeInput.start();
parsedInputSource = m_processor.parseInputSource(
testCase.inputDocument,
processor.parseOptions);
timeInput.stop();
}
else
{
m_logger->error()
<< "Mode: "
<< testCase.inputMode.c_str()
<< " is inavlid for input document: "
<< testCase.inputDocument
<< endl;
}
totalParseInputTime += timeInput.getElapsedTime();
minParseInputTime = timeInput.getElapsedTime() < minParseInputTime ? timeInput.getElapsedTime() : minParseInputTime;
maxParseInputTime = timeInput.getElapsedTime() > maxParseInputTime ? timeInput.getElapsedTime() : maxParseInputTime;
resultTarget = m_processor.createResultTarget(
testCase.resultDocument,
processor.resultOptions);
Timer timeTransform;
timeTransform.start();
m_processor.transform(
compiledStylesheet,
parsedInputSource,
resultTarget);
timeTransform.stop();
totalTransformTime += timeTransform.getElapsedTime();
minTransformTime = timeTransform.getElapsedTime() < minTransformTime ? timeTransform.getElapsedTime() : minTransformTime;
maxTransformTime = timeTransform.getElapsedTime() > maxTransformTime ? timeTransform.getElapsedTime() : maxTransformTime;
++numIterations;
}
timeTotalRun.stop();
m_processor.releaseStylesheet(compiledStylesheet);
m_processor.releaseInputSource(parsedInputSource);
m_processor.releaseResultTarget(resultTarget);
if (true == testCase.verifyResult)
{
testAttributes.insert(TestAttributesType::value_type(XalanDOMString("verify"), XalanDOMString("yes")));
if (checkFileExists(testCase.resultDocument))
{
if (checkFileExists(testCase.goldResult))
{
if (m_fileUtility->compareSerializedResults(
testCase.resultDocument,
testCase.goldResult))
{
testAttributes.insert(TestAttributesType::value_type(XalanDOMString("result"), XalanDOMString("pass")));
}
else
{
testAttributes.insert(TestAttributesType::value_type(XalanDOMString("result"), XalanDOMString("fail")));
}
}
else
{
testAttributes.insert(TestAttributesType::value_type(XalanDOMString("result"), XalanDOMString("incomplete")));
}
}
else
{
testAttributes.insert(TestAttributesType::value_type(XalanDOMString("result"), XalanDOMString("incomplete")));
}
}
else
{
testAttributes.insert(TestAttributesType::value_type(XalanDOMString("verify"), XalanDOMString("no")));
}
m_reporter->addMetricToAttrs("num-iterations", numIterations, testAttributes);
m_reporter->addMetricToAttrs("elapsed-time", timeTotalRun.getElapsedTime(), testAttributes);
m_reporter->addMetricToAttrs("min-parse-input", minParseInputTime, testAttributes);
m_reporter->addMetricToAttrs("max-parse-input", maxParseInputTime, testAttributes);
m_reporter->addMetricToAttrs("avg-parse-input", totalParseInputTime / numIterations, testAttributes);
m_reporter->addMetricToAttrs("min-transform", minTransformTime, testAttributes);
m_reporter->addMetricToAttrs("max-transform", maxTransformTime, testAttributes);
m_reporter->addMetricToAttrs("avg-transform", totalTransformTime / numIterations, testAttributes);
testAttributes.insert(TestAttributesType::value_type(XalanDOMString("complete"), XalanDOMString("yes")));
}
catch (XalanDOMString exception)
{
m_logger->error()
<< "Error encountered during transformation: "
<< testCase.stylesheet.c_str()
<< ", error: "
<< exception.c_str()
<< endl;
testAttributes.insert(TestAttributesType::value_type(XalanDOMString("complete"), XalanDOMString("no")));
}
m_reporter->logElementWAttrs(1, "testcase", testAttributes, "");
}
template <class Processor>
TestHarness<Processor>::TestHarness()
{
}
template <class Processor>
void
TestHarness<Processor>::init(
XalanFileUtility& fileUtility,
XalanXMLFileReporter& reporter,
Logger& logger)
{
m_processor.init();
m_fileUtility = &fileUtility;
m_reporter = &reporter;
m_logger = &logger;
}
template <class Processor>
void
TestHarness<Processor>::terminate()
{
m_processor.terminate();
}
#endif // TESTHARNESS_HEADER_GUARD_1357924680
1.1 xml-xalan/c/Tests/Performance/Timer.hpp
Index: Timer.hpp
===================================================================
/*
* Copyright 1999-2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#if !defined(TIMER_HEADER_GUARD_1357924680)
#define TIMER_HEADER_GUARD_1357924680
// Base header file. Must be first.
#include <xalanc/Include/PlatformDefinitions.hpp>
#include <ctime>
class Timer
{
public:
typedef XALAN_STD_QUALIFIER clock_t TimerType;
Timer() :
m_startTime(0),
m_totalTime(0)
{
}
void start()
{
m_startTime = XALAN_STD_QUALIFIER clock();
}
TimerType stop()
{
TimerType stopTime = XALAN_STD_QUALIFIER clock();
m_totalTime = stopTime - m_startTime;
return m_totalTime;
}
TimerType getElapsedTime()
{
return m_totalTime;
}
private:
TimerType m_startTime;
TimerType m_totalTime;
};
#endif TIMER_HEADER_GUARD_1357924680
1.1 xml-xalan/c/Tests/Performance/Utils.cpp
Index: Utils.cpp
===================================================================
/*
* Copyright 1999-2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Base header file. Must be first.
#include <xalanc/Include/PlatformDefinitions.hpp>
#include <stdio.h>
#include <sstream>
#if defined(WIN32)
#include <direct.h>
#define getcwd _getcwd
#else
#include <unistd.h>
#endif
#include <xalanc/Include/XalanMemoryManagement.hpp>
#include <xalanc/PlatformSupport/DOMStringHelper.hpp>
#include "Utils.hpp"
XALAN_USING_XALAN(XalanMemMgrs)
XALAN_USING_XALAN(CharVectorType)
XALAN_USING_XALAN(TranscodeToLocalCodePage)
XALAN_USING_XALAN(c_str)
XALAN_USING_STD(ostringstream)
XALAN_USING_STD(fstream)
XALAN_USING_STD(ofstream)
bool checkFileExists(const XalanDOMString& fileName)
{
CharVectorType theResult(XalanMemMgrs::getDefaultXercesMemMgr());
TranscodeToLocalCodePage(fileName, theResult, true);
FILE* fileHandle = fopen(c_str(theResult), "r");
if (fileHandle != 0)
{
fclose(fileHandle);
return true;
}
else
{
return false;
}
}
XalanDOMString getWorkingDirectory()
{
char path[4096];
getcwd(path, 4096);
return XalanDOMString(path);
}
const XalanDOMChar* getPathSep()
{
return XalanFileUtility::s_pathSep;
}
void fileToStream(
const XalanDOMString& fileName,
istringstream& resultStream)
{
CharVectorType resultFileName;
fileName.transcode(resultFileName);
fstream resultFile(c_str(resultFileName));
ostringstream fileOutputStream;
char ch;
while(resultFile.get(ch))
{
fileOutputStream.put(ch);
}
resultStream.str(fileOutputStream.str());
}
void copyFile(
const XalanDOMString& destFile,
const XalanDOMString& sourceFile)
{
CharVectorType sourceFileName;
sourceFile.transcode(sourceFileName);
fstream sourceFileStream(c_str(sourceFileName));
CharVectorType destFileName;
destFile.transcode(destFileName);
ofstream destFileStream(c_str(destFileName));
char ch;
while (sourceFileStream.get(ch))
{
destFileStream.put(ch);
}
sourceFileStream.close();
destFileStream.close();
}
1.1 xml-xalan/c/Tests/Performance/Utils.hpp
Index: Utils.hpp
===================================================================
/*
* Copyright 1999-2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#if !defined(UTILS_HEADER_GUARD_1357924680)
#define UTILS_HEADER_GUARD_1357924680
// Base header file. Must be first.
#include <xalanc/Include/PlatformDefinitions.hpp>
#include <fstream>
#include <xalanc/Harness/XalanFileUtility.hpp>
#include <xalanc/XalanDOM/XalanDOMString.hpp>
XALAN_USING_XALAN(XalanDOMChar)
XALAN_USING_XALAN(XalanDOMString)
XALAN_USING_XALAN(XalanFileUtility)
XALAN_USING_STD(istringstream)
/**
* Checks if a file exists
*/
bool checkFileExists(const XalanDOMString& fileName);
/**
* Gets the current working directory
*/
XalanDOMString getWorkingDirectory();
/**
* Gets the system path seperator
*/
const XalanDOMChar* getPathSep();
/**
* Reads file into a stream
*/
void fileToStream(
const XalanDOMString& fileName,
istringstream& resultStream);
/**
* Copies a file
*/
void copyFile(
const XalanDOMString& destFile,
const XalanDOMString& sourceFile);
#endif UTILS_HEADER_GUARD_1357924680
1.1 xml-xalan/c/Tests/Performance/XalanCProcessor.cpp
Index: XalanCProcessor.cpp
===================================================================
/*
* Copyright 1999-2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <iostream>
using namespace std;
#include <xalanc/XMLSupport/FormatterToNull.hpp>
#include <xalanc/XalanSourceTree/FormatterToSourceTree.hpp>
#include "XalanCProcessor.hpp"
XALAN_USING_XERCES(XMLPlatformUtils)
XALAN_USING_XALAN(XalanTransformer)
XALAN_USING_XALAN(XalanMemMgrs)
typedef XalanCProcessor::CompiledStylesheetType CompiledStylesheetType;
typedef XalanCProcessor::ParsedInputSourceType ParsedInputSourceType;
typedef XalanCProcessor::ResultTargetType ResultTargetType;
typedef XalanCProcessor::ParseOptionType ParseOptionType;
typedef XalanCProcessor::ResultTarget ResultTarget;
XalanCProcessor::XalanCProcessor() :
m_resultOptionsMap(XalanMemMgrs::getDefaultXercesMemMgr()),
m_name("Xalan")
{
}
XalanCProcessor::~XalanCProcessor()
{
}
void
XalanCProcessor::init()
{
m_transformer = new XalanTransformer();
m_resultOptionsMap[XalanDOMString("")] = &m_fileResult;
m_resultOptionsMap[XalanDOMString("file")] = &m_fileResult;
m_resultOptionsMap[XalanDOMString("xst")] = &m_xalanSourceTreeResult;
m_resultOptionsMap[XalanDOMString("xerces-dom")] = &m_xercesDOMResult;
m_resultOptionsMap[XalanDOMString("null")] = &m_nullResult;
m_resultOptionsMap[XalanDOMString("stream")] = &m_streamResult;
}
void
XalanCProcessor::terminate()
{
delete m_transformer;
}
ParseOptionType
XalanCProcessor::getParseOption(const XalanNode* option)
{
if (option != 0
&& option->getNodeType() == XalanNode::TEXT_NODE)
{
if (option->getNodeValue() == XalanDOMString("")
|| option->getNodeValue() == XalanDOMString("xst"))
{
return eXalanSourceTree;
}
else if (option->getNodeValue() == XalanDOMString("xerces-dom"))
{
return eXercesDOM;
}
else
{
return eInvalid;
}
}
else
{
return eInvalid;
}
}
ResultTarget*
XalanCProcessor::getResultOption(
const XalanDOMString& fileName,
const XalanNode* option)
{
if (option != 0
&& option->getNodeType() == XalanNode::TEXT_NODE
&& m_resultOptionsMap.find(option->getNodeValue()) != m_resultOptionsMap.end())
{
return m_resultOptionsMap[option->getNodeValue()]->clone(fileName);
}
else
{
return m_resultOptionsMap[XalanDOMString("")]->clone(fileName);
}
}
CompiledStylesheetType
XalanCProcessor::compileStylesheet(
const XalanDOMString& fileName,
const XalanNode* /* compileOptions */)
{
CompiledStylesheetType theCompiledStylesheet= 0;
m_transformer->compileStylesheet(fileName, theCompiledStylesheet);
return theCompiledStylesheet;
}
CompiledStylesheetType
XalanCProcessor::compileStylesheet(
StreamType& stream,
const XalanNode* /* compileOptions */)
{
CompiledStylesheetType theCompiledStylesheet = 0;
m_transformer->compileStylesheet(stream, theCompiledStylesheet);
return theCompiledStylesheet;
}
void
XalanCProcessor::releaseStylesheet(CompiledStylesheetType stylesheet)
{
m_transformer->destroyStylesheet(stylesheet);
}
ParsedInputSourceType
XalanCProcessor::parseInputSource(
const XalanDOMString& fileName,
const XalanNode* parseOptions )
{
ParsedInputSourceType theParsedSource = 0;
switch(getParseOption(parseOptions))
{
case eXercesDOM:
m_transformer->parseSource(fileName, theParsedSource, true);
break;
case eXalanSourceTree:
default:
m_transformer->parseSource(fileName, theParsedSource);
break;
}
return theParsedSource;
}
ParsedInputSourceType
XalanCProcessor::parseInputSource(
StreamType& stream,
const XalanNode* parseOptions)
{
ParsedInputSourceType theParsedSource = 0;
switch(getParseOption(parseOptions))
{
case eXercesDOM:
m_transformer->parseSource(stream, theParsedSource, true);
break;
case eXalanSourceTree:
default:
m_transformer->parseSource(stream, theParsedSource);
break;
}
return theParsedSource;
}
void
XalanCProcessor::releaseInputSource(ParsedInputSourceType inputSource)
{
m_transformer->destroyParsedSource(inputSource);
}
ResultTargetType
XalanCProcessor::createResultTarget(
const XalanDOMString& resultFileName,
const XalanNode* resultOptions)
{
return getResultOption(resultFileName, resultOptions);
}
void
XalanCProcessor::releaseResultTarget(ResultTargetType resultTarget)
{
delete resultTarget;
}
void
XalanCProcessor::transform(
const CompiledStylesheetType& compiledStylesheet,
const ParsedInputSourceType& parsedInputSourceType,
const ResultTargetType& resultTargetType,
const XalanNode* /* transformOptions */)
{
m_transformer->transform(*parsedInputSourceType, compiledStylesheet, resultTargetType->resultTarget);
}
1.1 xml-xalan/c/Tests/Performance/XalanCProcessor.hpp
Index: XalanCProcessor.hpp
===================================================================
/*
* Copyright 1999-2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#if !defined(XALANCRPROCESSOR_HEADER_GUARD_1357924680)
#define XALANCRPROCESSOR_HEADER_GUARD_1357924680
// Base header file. Must be first.
#include <xalanc/Include/PlatformDefinitions.hpp>
#include <sstream>
#include <istream>
#include <xercesc/dom/DOMDocument.hpp>
#include <xalanc/Include/XalanMap.hpp>
#include <xalanc/PlatformSupport/DOMStringHelper.hpp>
#include <xalanc/XMLSupport/FormatterToNull.hpp>
#include <xalanc/XalanSourceTree/FormatterToSourceTree.hpp>
#include <xalanc/XalanSourceTree/XalanSourceTreeDocument.hpp>
#include <xalanc/XercesParserLiaison/XercesParserLiaison.hpp>
#include <xalanc/XercesParserLiaison/FormatterToXercesDOM.hpp>
#include <xalanc/XalanTransformer/XalanTransformer.hpp>
#include <xalanc/XalanDOM/XalanDOMString.hpp>
XALAN_USING_XERCES(DOMDocument);
XALAN_CPP_NAMESPACE_USE
/**
* Implementation of the test interface for XalanC 1.x
*
*/
class XalanCProcessor
{
public:
XalanDOMString m_name;
typedef XalanCompiledStylesheet* CompiledStylesheetType;
typedef XalanParsedSource* ParsedInputSourceType;
struct ResultTarget {
XSLTResultTarget resultTarget;
virtual ResultTarget* clone(const XalanDOMString&) = 0;
virtual void reset() = 0;
};
typedef ResultTarget* ResultTargetType;
typedef XSLTInputSource::StreamType StreamType;
XalanCProcessor();
~XalanCProcessor();
/**
* Initializes the processor interface.
* Assumes static processor initialization functions are already completed.
*/
void
init();
/**
* Terminates the processor interface.
*/
void
terminate();
/**
* Returns the name of the processor implementation.
* @returns name of the processor
*/
XalanDOMString& getName() { return m_name;}
/**
* Compiles the specified stylesheet.
* Xalan interface does not support any options.
* @param fileName stylesheet to compile
* @param compileOptions (none for this interface)
* @returns compiled stylesheet
*/
CompiledStylesheetType
compileStylesheet(
const XalanDOMString& fileName,
const XalanNode* compileOptions = 0);
/**
* Compiles the specified stylesheet.
* Xalan interface does not support any options.
* @param stream stylesheet to compile
* @param compileOptions (none for this interface)
* @returns compiled stylesheet
*/
CompiledStylesheetType
compileStylesheet(
StreamType& stream,
const XalanNode* compileOptions = 0);
/**
* Release stylesheet object
* @param stylesheet object to release
*/
void
releaseStylesheet(CompiledStylesheetType stylesheet);
/**
* Parses an input document.
* Parse options, a text node containing:<ul>
* <li><b>xst</b>: parse to XalanSourceTree (default)
* <li><b>xerces-dom</b>: parse to XercesDOM</ul>
* @param fileName input document to parse.
* @param parseOptions options to the parser.
* @returns parsed document
*/
ParsedInputSourceType
parseInputSource(
const XalanDOMString& fileName,
const XalanNode* parseOptions = 0);
/**
* Parses an input document.
* Parse options, a text node containing:<ul>
* <li><b>xst</b>: parse to XalanSourceTree (default)
* <li><b>xerces-dom</b>: parse to XercesDOM</ul>
* @param stream input document to parse.
* @param parseOptions options to the parser.
* @returns parsed document
*/
ParsedInputSourceType
parseInputSource(
StreamType& stream,
const XalanNode* parseOptions = 0);
/**
* Releases and parsed input source
* @param inputSource source to release
*/
void
releaseInputSource(ParsedInputSourceType inputSource);
/**
* Creates a result target.
* Result target options, a text node containing:<ul>
* <li><b>file</b>: result to a file (default)</li>
* <li><b>xst</b>: result to a XalanSourceTree</li>
* <li><b>xerces-dom</b>: result to XercesDOM</li>
* <li><b>null</b>: generate no result</li>
* <li><b>stream</b>: result to a stream (string)</li></ul>
* @param resultFileName file to write result to, if any
* @param resultOptions options to create result
* @return result target
*/
ResultTargetType
createResultTarget(
const XalanDOMString& resultFileName,
const XalanNode* resultOptions = 0);
/**
* Releases result target
* @param resultTarget target to release
*/
void
releaseResultTarget(ResultTargetType resultTarget);
/**
* Executes a transform
* @param compileStyle stylesheet
* @param parsedInputSourceType parsed document
* @param resultTargetType result target
* @param transformOptions (none for this interface)
*/
void transform(
const CompiledStylesheetType& compiledStylesheet,
const ParsedInputSourceType& parsedInputSourceType,
const ResultTargetType& resultTargetType,
const XalanNode* transformOptions = 0);
typedef enum {eInvalid, eXalanSourceTree, eXercesDOM} ParseOptionType;
protected:
ParseOptionType getParseOption(const XalanNode* option);
typedef XalanMap<XalanDOMString, ResultTarget*> ResultsMapType;
ResultTarget* getResultOption(
const XalanDOMString& fileName,
const XalanNode* option);
ResultsMapType m_resultOptionsMap;
XalanTransformer *m_transformer;
struct NullResult : public ResultTarget
{
NullResult()
{
resultTarget.setFormatterListener(&formatterToNull);
}
ResultTarget *
clone(const XalanDOMString&) { return new NullResult;}
void reset() {}
FormatterToNull formatterToNull;
};
NullResult m_nullResult;
struct XalanSourceTreeResult : public ResultTarget
{
XalanSourceTreeResult() :
document(XalanMemMgrs::getDefaultXercesMemMgr())
{
formatterToSourceTree.setDocument(&document);
resultTarget.setFormatterListener(&formatterToSourceTree);
}
ResultTarget *
clone(const XalanDOMString&) { return new XalanSourceTreeResult;}
void reset() { formatterToSourceTree.resetDocument();}
FormatterToSourceTree formatterToSourceTree;
XalanSourceTreeDocument document;
};
XalanSourceTreeResult m_xalanSourceTreeResult;
struct XercesDOMResult : public ResultTarget
{
XercesDOMResult() :
parserLiaison(),
document(parserLiaison.createDOMFactory()),
formatterToXercesDOM(document, 0)
{
}
ResultTarget *
clone(const XalanDOMString&) { return new XercesDOMResult;}
void reset() { formatterToXercesDOM.resetDocument();}
XercesParserLiaison parserLiaison;
DOMDocument* document;
FormatterToXercesDOM formatterToXercesDOM;
};
XercesDOMResult m_xercesDOMResult;
struct FileResult : public ResultTarget
{
FileResult(const XalanDOMString & fileName = XalanDOMString(""))
{
resultTarget.setFileName(fileName);
}
ResultTarget *
clone(const XalanDOMString& fileName) { return new FileResult(fileName);}
void reset() {}
};
FileResult m_fileResult;
struct StreamResult : public XalanCProcessor::ResultTarget
{
StreamResult()
{
resultTarget.setByteStream(&stringstream);
}
ResultTarget *
clone(const XalanDOMString&) { return new StreamResult;}
void reset() { stringstream.flush();}
XALAN_STD_QUALIFIER ostringstream stringstream;
};
StreamResult m_streamResult;
};
#endif // XALANCRPROCESSOR_HEADER_GUARD_1357924680
1.1 xml-xalan/c/Tests/Performance/comparereport.xsl
Index: comparereport.xsl
===================================================================
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html"/>
<xsl:param name="baseline" select="'R2.xml'"/>
<xsl:param name="threshold" select="5"/>
<xsl:template match="/">
<html>
<title>Comparison Result Report</title>
<body>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
<xsl:template match="resultsfile">
<table border="1">
<tr>
<td>
<b>Filename:</b>
</td>
<td>
<xsl:value-of select="@filename"/>
</td>
</tr>
<tr>
<td>
<b>Description:</b>
</td>
<td>
<xsl:value-of select="testfile/@desc"/>
</td>
</tr>
<tr>
<td>
<b>Time:</b>
</td>
<td>
<xsl:value-of select="testfile/@time"/>
</td>
</tr>
</table>
<P/>
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="testfile">
<table border='1'>
<tr>
<td><b>Stylesheet</b></td>
<td><b>Verify</b></td>
<td><b>Result</b></td>
<td><b>Time to compile</b></td>
<td><b>Iterations</b></td>
<td><b>Total transform time</b></td>
<td><b>Min. parse input</b></td>
<td><b>Avg. parse input</b></td>
<td><b>Max. parse input</b></td>
<td><b>Min. transform</b></td>
<td><b>Avg. transform</b></td>
<td><b>Max. transform</b></td>
</tr>
<xsl:apply-templates/>
</table>
</xsl:template>
<xsl:template match="testcase">
<tr>
<td colspan='12'> </td>
</tr>
<tr>
<xsl:variable name="ss" select="@stylesheet"/>
<xsl:variable name="baselineTestCase" select="document($baseline)/resultsfile/testfile/testcase[attribute::stylesheet = $ss]"/>
<tr>
<td><xsl:value-of select="@stylesheet"/></td>
<td><xsl:value-of select="@verify"/></td>
<td><xsl:value-of select="@result"/></td>
<td><xsl:value-of select="@compile-xsl"/></td>
<td><xsl:value-of select="@num-iterations"/></td>
<td><xsl:value-of select="@elapsed-time"/></td>
<td><xsl:value-of select="@min-parse-input"/></td>
<td><xsl:value-of select="@avg-parse-input"/></td>
<td><xsl:value-of select="@max-parse-input"/></td>
<td><xsl:value-of select="@min-transform"/></td>
<td><xsl:value-of select="@avg-transform"/></td>
<td><xsl:value-of select="@max-transform"/></td>
</tr>
<td>Baseline</td>
<td><xsl:value-of select="$baselineTestCase/@verify"/></td>
<td><xsl:value-of select="$baselineTestCase/@result"/></td>
<td><xsl:value-of select="$baselineTestCase/@compile-xsl"/></td>
<td><xsl:value-of select="$baselineTestCase/@num-iterations"/></td>
<td><xsl:value-of select="$baselineTestCase/@elapsed-time"/></td>
<td><xsl:value-of select="$baselineTestCase/@min-parse-input"/></td>
<td><xsl:value-of select="$baselineTestCase/@avg-parse-input"/></td>
<td><xsl:value-of select="$baselineTestCase/@max-parse-input"/></td>
<td><xsl:value-of select="$baselineTestCase/@min-transform"/></td>
<td><xsl:value-of select="$baselineTestCase/@avg-transform"/></td>
<td><xsl:value-of select="$baselineTestCase/@max-transform"/></td>
</tr>
<tr>
<xsl:variable name="ss" select="@stylesheet"/>
<xsl:variable name="baselineTestCase" select="document($baseline)/resultsfile/testfile/testcase[attribute::stylesheet = $ss]"/>
<td>Difference:</td>
<xsl:call-template name="HighlightChange">
<xsl:with-param name="orig" select="$baselineTestCase/@verify"/>
<xsl:with-param name="new" select="@verify"/>
</xsl:call-template>
<xsl:call-template name="HighlightChange">
<xsl:with-param name="orig" select="$baselineTestCase/@result"/>
<xsl:with-param name="new" select="@result"/>
</xsl:call-template>
<xsl:call-template name="HighlightChange">
<xsl:with-param name="orig" select="$baselineTestCase/@compile-xsl"/>
<xsl:with-param name="new" select="@compile-xsl"/>
</xsl:call-template>
<xsl:call-template name="HighlightChange">
<xsl:with-param name="new" select="$baselineTestCase/@num-iterations"/>
<xsl:with-param name="orig" select="@num-iterations"/>
</xsl:call-template>
<xsl:call-template name="HighlightChange">
<xsl:with-param name="orig" select="$baselineTestCase/@elapsed-time"/>
<xsl:with-param name="new" select="@elapsed-time"/>
</xsl:call-template>
<xsl:call-template name="HighlightChange">
<xsl:with-param name="orig" select="$baselineTestCase/@min-parse-input"/>
<xsl:with-param name="new" select="@min-parse-input"/>
</xsl:call-template>
<xsl:call-template name="HighlightChange">
<xsl:with-param name="orig" select="$baselineTestCase/@avg-parse-input"/>
<xsl:with-param name="new" select="@avg-parse-input"/>
</xsl:call-template>
<xsl:call-template name="HighlightChange">
<xsl:with-param name="orig" select="$baselineTestCase/@max-parse-input"/>
<xsl:with-param name="new" select="@max-parse-input"/>
</xsl:call-template>
<xsl:call-template name="HighlightChange">
<xsl:with-param name="orig" select="$baselineTestCase/@min-transform"/>
<xsl:with-param name="new" select="@min-transform"/>
</xsl:call-template>
<xsl:call-template name="HighlightChange">
<xsl:with-param name="orig" select="$baselineTestCase/@avg-transform"/>
<xsl:with-param name="new" select="@avg-transform"/>
</xsl:call-template>
<xsl:call-template name="HighlightChange">
<xsl:with-param name="orig" select="$baselineTestCase/@max-transform"/>
<xsl:with-param name="new" select="@max-transform"/>
</xsl:call-template>
</tr>
</xsl:template>
<xsl:template name="HighlightChange">
<xsl:param name="orig"/>
<xsl:param name="new"/>
<xsl:choose>
<xsl:when test="number($orig) or $orig = 0">
<xsl:variable name="n-orig">
<xsl:choose>
<xsl:when test="$orig= 0">
<xsl:value-of select="1"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$orig"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="n-new">
<xsl:choose>
<xsl:when test="$new= 0">
<xsl:value-of select="1"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$new"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:choose>
<xsl:when test="$n-new > $n-orig">
<xsl:variable name="difference" select="(($n-new div $n-orig) - 1) * 100"/>
<xsl:choose>
<xsl:when test="$difference > ($threshold div 100)">
<td bgcolor="red">
<xsl:value-of select="concat($difference,'%')"/>
</td>
</xsl:when>
<xsl:otherwise>
<td>
<xsl:value-of select="concat($difference,'%')"/>
</td>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="difference" select="(1 - ($n-new div $n-orig)) * 100"/>
<xsl:choose>
<xsl:when test="$difference > ($threshold div 100)">
<td bgcolor="#10F0F0">
<xsl:value-of select="concat($difference,'%')"/>
</td>
</xsl:when>
<xsl:otherwise>
<td>
<xsl:value-of select="concat($difference,'%')"/>
</td>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:choose>
<xsl:when test="$orig = $new">
<td>Same</td>
</xsl:when>
<xsl:otherwise>
<td bgcolor="red">Diff</td>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
1.1 xml-xalan/c/Tests/Performance/config.xml
Index: config.xml
===================================================================
<?xml version="1.0"?>
<!-- Test configuration file that describes the testing parameters -->
<testconfig name="DefaultRun">
<description>This is a sample test configuratoin file</description>
<!-- Location to place results along with Report name prefix.
Default is the working directory. -->
<results file-path="SampleTestRunResults">ResultReport</results>
<!-- Location where previous result to be used for comparison is located.
Threshold is percentage of variance to highlight.
Default is the working directory -->
<!--<baseline threshold="5" file-path="BaseLineResults">Standard.xml</baseline> -->
<!-- Parameters for the test cases:
num-iterations number of iterations
min-time-to-execute minimum time of process (milliseconds)
verify-result compare against the gold file (yes|no)
input-mode mode to provide input (file|stream) -->
<default-parameter-set
num-iterations="10"
min-time-to-execute="1"
input-mode="stream"
verify-result="yes">
<!-- Init options: N/A at this time -->
<!-- <init-options/> -->
<!-- Compile options: N/A at this time -->
<!-- <compile-options/> -->
<!-- Parse options for Xalan:
xst XalanSourceTree (default)
xerces-dom XercesDOM -->
<!-- <parse-options processor="Xalan">xst</parse-options> -->
<!-- Result options for Xalan:
file File (default)
xst XalanSourceTree
xerces-dom XercesDOM
null Null
stream Stream -->
<!-- <result-options processor="Xalan">file</result-options> -->
<!-- Transform options: N/A at this time -->
<!-- <transform-options processor="Xalan"/> -->
</default-parameter-set>
</testconfig>
1.1 xml-xalan/c/Tests/Performance/report.xsl
Index: report.xsl
===================================================================
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html"/>
<xsl:template match="/">
<html>
<title>Result Report</title>
<body>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
<xsl:template match="resultsfile">
<table border="1">
<tr>
<td>
<b>Filename:</b>
</td>
<td>
<xsl:value-of select="@filename"/>
</td>
</tr>
<tr>
<td>
<b>Description:</b>
</td>
<td>
<xsl:value-of select="testfile/@desc"/>
</td>
</tr>
<tr>
<td>
<b>Time:</b>
</td>
<td>
<xsl:value-of select="testfile/@time"/>
</td>
</tr>
</table>
<P/>
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="testfile">
<table border='1'>
<tr>
<td><b>Stylesheet</b></td>
<td><b>Verify</b></td>
<td><b>Result</b></td>
<td><b>Time to compile</b></td>
<td><b>Iterations</b></td>
<td><b>Total transform time</b></td>
<td><b>Min. parse input</b></td>
<td><b>Avg. parse input</b></td>
<td><b>Max. parse input</b></td>
<td><b>Min. transform</b></td>
<td><b>Avg. transform</b></td>
<td><b>Max. transform</b></td>
</tr>
<xsl:apply-templates/>
</table>
</xsl:template>
<xsl:template match="testcase">
<tr>
<td><xsl:value-of select="@stylesheet"/></td>
<td><xsl:value-of select="@verify"/></td>
<td><xsl:value-of select="@result"/></td>
<td><xsl:value-of select="@compile-xsl"/></td>
<td><xsl:value-of select="@num-iterations"/></td>
<td><xsl:value-of select="@elapsed-time"/></td>
<td><xsl:value-of select="@min-parse-input"/></td>
<td><xsl:value-of select="@avg-parse-input"/></td>
<td><xsl:value-of select="@max-parse-input"/></td>
<td><xsl:value-of select="@min-transform"/></td>
<td><xsl:value-of select="@avg-transform"/></td>
<td><xsl:value-of select="@max-transform"/></td>
</tr>
</xsl:template>
</xsl:stylesheet>
---------------------------------------------------------------------
To unsubscribe, e-mail: xalan-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: xalan-cvs-help@xml.apache.org