13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*------------------------------------------------------------------------- 23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program Test Executor 33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * ------------------------------------------ 43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Copyright 2014 The Android Open Source Project 63c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Licensed under the Apache License, Version 2.0 (the "License"); 83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * you may not use this file except in compliance with the License. 93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * You may obtain a copy of the License at 103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * http://www.apache.org/licenses/LICENSE-2.0 123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Unless required by applicable law or agreed to in writing, software 143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * distributed under the License is distributed on an "AS IS" BASIS, 153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * See the License for the specific language governing permissions and 173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * limitations under the License. 183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*! 203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \file 213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Batch result to XML export. 223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "xeTestLogParser.hpp" 253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "xeTestResultParser.hpp" 263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "xeXMLWriter.hpp" 273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "xeTestLogWriter.hpp" 283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deFilePath.hpp" 293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deString.h" 303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deStringUtil.hpp" 313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deCommandLine.hpp" 323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <vector> 343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <string> 353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <map> 363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <cstdio> 373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <fstream> 383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <iostream> 393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 403c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::vector; 413c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::string; 423c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::map; 433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 443c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const char* CASELIST_STYLESHEET = "caselist.xsl"; 453c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const char* TESTCASE_STYLESHEET = "testlog.xsl"; 463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 473c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum OutputMode 483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry OUTPUTMODE_SEPARATE = 0, //!< Separate 503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry OUTPUTMODE_SINGLE, 513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry OUTPUTMODE_LAST 533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 553c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace opt 563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 583c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDE_DECLARE_COMMAND_LINE_OPT(OutMode, OutputMode); 593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 603c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid registerOptions (de::cmdline::Parser& parser) 613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry using de::cmdline::Option; 633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry using de::cmdline::NamedValue; 643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const NamedValue<OutputMode> s_modes[] = 663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "single", OUTPUTMODE_SINGLE }, 683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "separate", OUTPUTMODE_SEPARATE } 693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry parser << Option<OutMode>("m", "mode", "Output mode", s_modes, "single"); 723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // opt 753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 763c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct CommandLine 773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry CommandLine (void) 793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : outputMode(OUTPUTMODE_SINGLE) 803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::string batchResultFile; 843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::string outputPath; 853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry OutputMode outputMode; 863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 883c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool parseCommandLine (CommandLine& cmdLine, int argc, const char* const* argv) 893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry de::cmdline::Parser parser; 913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry de::cmdline::CommandLine opts; 923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry opt::registerOptions(parser); 943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!parser.parse(argc-1, argv+1, &opts, std::cerr) || 963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry opts.getArgs().size() != 2) 973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry printf("%s: [options] [testlog] [destination path]\n", argv[0]); 993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry parser.help(std::cout); 1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry cmdLine.outputMode = opts.getOption<opt::OutMode>(); 1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry cmdLine.batchResultFile = opts.getArgs()[0]; 1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry cmdLine.outputPath = opts.getArgs()[1]; 1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return true; 1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void parseBatchResult (xe::TestLogParser& parser, const char* filename) 1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ifstream in (filename, std::ios_base::binary); 1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint8 buf[2048]; 1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (;;) 1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry in.read((char*)&buf[0], sizeof(buf)); 1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int numRead = (int)in.gcount(); 1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (numRead > 0) 1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry parser.parse(&buf[0], numRead); 1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (numRead < (int)sizeof(buf)) 1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Export to single file 1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct BatchResultTotals 1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry BatchResultTotals (void) 1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int i = 0;i < xe::TESTSTATUSCODE_LAST; i++) 1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry countByCode[i] = 0; 1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int countByCode[xe::TESTSTATUSCODE_LAST]; 1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ResultToSingleXmlLogHandler : public xe::TestLogHandler 1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ResultToSingleXmlLogHandler (xe::xml::Writer& writer, BatchResultTotals& totals) 1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_writer (writer) 1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_totals (totals) 1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void setSessionInfo (const xe::SessionInfo&) 1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry xe::TestCaseResultPtr startTestCaseResult (const char* casePath) 1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return xe::TestCaseResultPtr(new xe::TestCaseResultData(casePath)); 1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void testCaseResultUpdated (const xe::TestCaseResultPtr&) 1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void testCaseResultComplete (const xe::TestCaseResultPtr& resultData) 1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry xe::TestCaseResult result; 1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry xe::parseTestCaseResultFromData(&m_resultParser, &result, *resultData.get()); 1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Write result. 1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry xe::writeTestResult(result, m_writer); 1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Record total 1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry XE_CHECK(de::inBounds<int>(result.statusCode, 0, xe::TESTSTATUSCODE_LAST)); 1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_totals.countByCode[result.statusCode] += 1; 1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry xe::xml::Writer& m_writer; 1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry BatchResultTotals& m_totals; 1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry xe::TestResultParser m_resultParser; 1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void writeTotals (xe::xml::Writer& writer, const BatchResultTotals& totals) 1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry using xe::xml::Writer; 1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int totalCases = 0; 1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry writer << Writer::BeginElement("ResultTotals"); 1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int code = 0; code < xe::TESTSTATUSCODE_LAST; code++) 1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry writer << Writer::Attribute(xe::getTestStatusCodeName((xe::TestStatusCode)code), de::toString(totals.countByCode[code]).c_str()); 1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry totalCases += totals.countByCode[code]; 1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry writer << Writer::Attribute("All", de::toString(totalCases).c_str()) 1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << Writer::EndElement; 1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void batchResultToSingleXmlFile (const char* batchResultFilename, const char* dstFileName) 2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ofstream out (dstFileName, std::ios_base::binary); 2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry xe::xml::Writer writer (out); 2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry BatchResultTotals totals; 2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ResultToSingleXmlLogHandler handler (writer, totals); 2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry xe::TestLogParser parser (&handler); 2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry XE_CHECK(out.good()); 2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry out << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" 2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "<?xml-stylesheet href=\"" << TESTCASE_STYLESHEET << "\" type=\"text/xsl\"?>\n"; 2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry writer << xe::xml::Writer::BeginElement("BatchResult") 2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << xe::xml::Writer::Attribute("FileName", de::FilePath(batchResultFilename).getBaseName()); 2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Parse and write individual cases 2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry parseBatchResult(parser, batchResultFilename); 2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Write ResultTotals 2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry writeTotals(writer, totals); 2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry writer << xe::xml::Writer::EndElement; 2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry out << "\n"; 2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Export to separate files 2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ResultToXmlFilesLogHandler : public xe::TestLogHandler 2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ResultToXmlFilesLogHandler (vector<xe::TestCaseResultHeader>& resultHeaders, const char* dstPath) 2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_resultHeaders (resultHeaders) 2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_dstPath (dstPath) 2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void setSessionInfo (const xe::SessionInfo&) 2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry xe::TestCaseResultPtr startTestCaseResult (const char* casePath) 2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return xe::TestCaseResultPtr(new xe::TestCaseResultData(casePath)); 2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void testCaseResultUpdated (const xe::TestCaseResultPtr&) 2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void testCaseResultComplete (const xe::TestCaseResultPtr& resultData) 2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry xe::TestCaseResult result; 2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry xe::parseTestCaseResultFromData(&m_resultParser, &result, *resultData.get()); 2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Write result. 2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry de::FilePath casePath = de::FilePath::join(m_dstPath, (result.casePath + ".xml").c_str()); 2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ofstream out (casePath.getPath(), std::ofstream::binary|std::ofstream::trunc); 2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry xe::xml::Writer xmlWriter (out); 2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!out.good()) 2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw xe::Error(string("Failed to open ") + casePath.getPath()); 2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry out << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" 2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "<?xml-stylesheet href=\"" << TESTCASE_STYLESHEET << "\" type=\"text/xsl\"?>\n"; 2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry xe::writeTestResult(result, xmlWriter); 2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry out << "\n"; 2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_resultHeaders.push_back(xe::TestCaseResultHeader(result)); 2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<xe::TestCaseResultHeader>& m_resultHeaders; 2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::string m_dstPath; 2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry xe::TestResultParser m_resultParser; 2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypedef std::map<const xe::TestCase*, const xe::TestCaseResultHeader*> ShortTestResultMap; 2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void writeTestCaseListNode (const xe::TestNode* testNode, const ShortTestResultMap& resultMap, xe::xml::Writer& dst) 2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry using xe::xml::Writer; 2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool isGroup = testNode->getNodeType() == xe::TESTNODETYPE_GROUP; 2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string fullPath; 2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry testNode->getFullPath(fullPath); 2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (isGroup) 2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const xe::TestGroup* group = static_cast<const xe::TestGroup*>(testNode); 2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry dst << Writer::BeginElement("TestGroup") 2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << Writer::Attribute("Name", testNode->getName()); 2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int childNdx = 0; childNdx < group->getNumChildren(); childNdx++) 2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry writeTestCaseListNode(group->getChild(childNdx), resultMap, dst); 3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry dst << Writer::EndElement; 3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(testNode->getNodeType() == xe::TESTNODETYPE_TEST_CASE); 3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const xe::TestCase* testCase = static_cast<const xe::TestCase*>(testNode); 3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ShortTestResultMap::const_iterator resultPos = resultMap.find(testCase); 3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const xe::TestCaseResultHeader* result = resultPos != resultMap.end() ? resultPos->second : DE_NULL; 3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(result); 3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry dst << Writer::BeginElement("TestCase") 3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << Writer::Attribute("Name", testNode->getName()) 3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << Writer::Attribute("Type", xe::getTestCaseTypeName(result->caseType)) 3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << Writer::Attribute("StatusCode", xe::getTestStatusCodeName(result->statusCode)) 3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << Writer::Attribute("StatusDetails", result->statusDetails.c_str()) 3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << Writer::EndElement; 3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void writeTestCaseList (const xe::TestRoot& root, const ShortTestResultMap& resultMap, xe::xml::Writer& dst) 3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry using xe::xml::Writer; 3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry dst << Writer::BeginElement("TestRoot"); 3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int childNdx = 0; childNdx < root.getNumChildren(); childNdx++) 3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry writeTestCaseListNode(root.getChild(childNdx), resultMap, dst); 3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry dst << Writer::EndElement; 3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void batchResultToSeparateXmlFiles (const char* batchResultFilename, const char* dstPath) 3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry xe::TestRoot testRoot; 3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<xe::TestCaseResultHeader> shortResults; 3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ShortTestResultMap resultMap; 3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Initialize destination directory. 3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!de::FilePath(dstPath).exists()) 3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry de::createDirectoryAndParents(dstPath); 3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry XE_CHECK_MSG(de::FilePath(dstPath).getType() == de::FilePath::TYPE_DIRECTORY, "Destination is not directory"); 3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Parse batch result and write out test cases. 3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ResultToXmlFilesLogHandler handler (shortResults, dstPath); 3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry xe::TestLogParser parser (&handler); 3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry parseBatchResult(parser, batchResultFilename); 3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Build case hierarchy & short result map. 3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry xe::TestHierarchyBuilder hierarchyBuilder(&testRoot); 3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (vector<xe::TestCaseResultHeader>::const_iterator result = shortResults.begin(); result != shortResults.end(); result++) 3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry xe::TestCase* testCase = hierarchyBuilder.createCase(result->casePath.c_str(), result->caseType); 3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry resultMap.insert(std::make_pair(testCase, &(*result))); 3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Create caselist. 3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry de::FilePath indexPath = de::FilePath::join(dstPath, "caselist.xml"); 3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ofstream out (indexPath.getPath(), std::ofstream::binary|std::ofstream::trunc); 3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry xe::xml::Writer xmlWriter (out); 3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry XE_CHECK_MSG(out.good(), "Failed to open caselist.xml"); 3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry out << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" 3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "<?xml-stylesheet href=\"" << CASELIST_STYLESHEET << "\" type=\"text/xsl\"?>\n"; 3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry writeTestCaseList(testRoot, resultMap, xmlWriter); 3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry out << "\n"; 3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint main (int argc, const char* const* argv) 3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry try 3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry CommandLine cmdLine; 3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!parseCommandLine(cmdLine, argc, argv)) 3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return -1; 3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (cmdLine.outputMode == OUTPUTMODE_SINGLE) 3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry batchResultToSingleXmlFile(cmdLine.batchResultFile.c_str(), cmdLine.outputPath.c_str()); 3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry batchResultToSeparateXmlFiles(cmdLine.batchResultFile.c_str(), cmdLine.outputPath.c_str()); 3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry catch (const std::exception& e) 3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry printf("%s\n", e.what()); 3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return -1; 3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return 0; 4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 401