/* * 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 #include #include #include #include #include #include #include #include #include #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) XALAN_USING_STD(endl) /** * 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 ProcessorOptionsMap; ProcessorOptionsMap processorOptions; }; typedef TestCase TestCaseType; typedef XalanVector TestCasesType; /** * Test harness */ template 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 void TestHarness::executeTestCases(const TestCasesType& testCases) { TestCasesType::const_iterator testCaseIter = testCases.begin(); while (testCaseIter != testCases.end()) { executeTestCase(*testCaseIter); ++testCaseIter; } } template void TestHarness::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 TestHarness::TestHarness() { } template void TestHarness::init( XalanFileUtility& fileUtility, XalanXMLFileReporter& reporter, Logger& logger) { m_processor.init(); m_fileUtility = &fileUtility; m_reporter = &reporter; m_logger = &logger; } template void TestHarness::terminate() { m_processor.terminate(); } #endif // TESTHARNESS_HEADER_GUARD_1357924680