Home | History | Annotate | Download | only in tools
      1 /*-------------------------------------------------------------------------
      2  * drawElements Quality Program Test Executor
      3  * ------------------------------------------
      4  *
      5  * Copyright 2014 The Android Open Source Project
      6  *
      7  * Licensed under the Apache License, Version 2.0 (the "License");
      8  * you may not use this file except in compliance with the License.
      9  * You may obtain a copy of the License at
     10  *
     11  *      http://www.apache.org/licenses/LICENSE-2.0
     12  *
     13  * Unless required by applicable law or agreed to in writing, software
     14  * distributed under the License is distributed on an "AS IS" BASIS,
     15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     16  * See the License for the specific language governing permissions and
     17  * limitations under the License.
     18  *
     19  *//*!
     20  * \file
     21  * \brief Batch result to JUnit report conversion tool.
     22  *//*--------------------------------------------------------------------*/
     23 
     24 #include "xeTestLogParser.hpp"
     25 #include "xeTestResultParser.hpp"
     26 #include "xeXMLWriter.hpp"
     27 #include "deFilePath.hpp"
     28 #include "deString.h"
     29 #include "deStringUtil.hpp"
     30 
     31 #include <vector>
     32 #include <string>
     33 #include <map>
     34 #include <cstdio>
     35 #include <fstream>
     36 
     37 using std::vector;
     38 using std::string;
     39 using std::map;
     40 
     41 struct CommandLine
     42 {
     43 	CommandLine (void)
     44 	{
     45 	}
     46 
     47 	std::string		batchResultFile;
     48 	std::string		outputFile;
     49 };
     50 
     51 static void printHelp (const char* binName)
     52 {
     53 	printf("%s: [testlog] [output file]\n", binName);
     54 }
     55 
     56 static void parseCommandLine (CommandLine& cmdLine, int argc, const char* const* argv)
     57 {
     58 	if (argc != 3)
     59 		throw xe::Error("Expected input and output paths");
     60 
     61 	cmdLine.batchResultFile	= argv[argc-2];
     62 	cmdLine.outputFile		= argv[argc-1];
     63 }
     64 
     65 static void parseBatchResult (xe::TestLogParser& parser, const char* filename)
     66 {
     67 	std::ifstream	in			(filename, std::ios_base::binary);
     68 	deUint8			buf[2048];
     69 
     70 	for (;;)
     71 	{
     72 		in.read((char*)&buf[0], sizeof(buf));
     73 		int numRead = (int)in.gcount();
     74 
     75 		if (numRead > 0)
     76 			parser.parse(&buf[0], numRead);
     77 
     78 		if (numRead < (int)sizeof(buf))
     79 			break;
     80 	}
     81 }
     82 
     83 class ResultToJUnitHandler : public xe::TestLogHandler
     84 {
     85 public:
     86 	ResultToJUnitHandler (xe::xml::Writer& writer)
     87 		: m_writer(writer)
     88 	{
     89 	}
     90 
     91 	void setSessionInfo (const xe::SessionInfo&)
     92 	{
     93 	}
     94 
     95 	xe::TestCaseResultPtr startTestCaseResult (const char* casePath)
     96 	{
     97 		return xe::TestCaseResultPtr(new xe::TestCaseResultData(casePath));
     98 	}
     99 
    100 	void testCaseResultUpdated (const xe::TestCaseResultPtr&)
    101 	{
    102 	}
    103 
    104 	void testCaseResultComplete (const xe::TestCaseResultPtr& resultData)
    105 	{
    106 		using xe::xml::Writer;
    107 
    108 		xe::TestCaseResult result;
    109 
    110 		xe::parseTestCaseResultFromData(&m_resultParser, &result, *resultData.get());
    111 
    112 		// Split group and case names.
    113 		size_t			sepPos		= result.casePath.find_last_of('.');
    114 		std::string		caseName	= result.casePath.substr(sepPos+1);
    115 		std::string		groupName	= result.casePath.substr(0, sepPos);
    116 
    117 		// Write result.
    118 		m_writer << Writer::BeginElement("testcase")
    119 				 << Writer::Attribute("name", caseName)
    120 				 << Writer::Attribute("classname", groupName);
    121 
    122 		if (result.statusCode != xe::TESTSTATUSCODE_PASS)
    123 			m_writer << Writer::BeginElement("failure")
    124 					 << Writer::Attribute("type", xe::getTestStatusCodeName(result.statusCode))
    125 					 << result.statusDetails
    126 					 << Writer::EndElement;
    127 
    128 		m_writer << Writer::EndElement;
    129 	}
    130 
    131 private:
    132 	xe::xml::Writer&		m_writer;
    133 	xe::TestResultParser	m_resultParser;
    134 };
    135 
    136 static void batchResultToJUnitReport (const char* batchResultFilename, const char* dstFileName)
    137 {
    138 	std::ofstream				out			(dstFileName, std::ios_base::binary);
    139 	xe::xml::Writer				writer		(out);
    140 	ResultToJUnitHandler		handler		(writer);
    141 	xe::TestLogParser			parser		(&handler);
    142 
    143 	XE_CHECK(out.good());
    144 
    145 	out << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
    146 
    147 	writer << xe::xml::Writer::BeginElement("testsuites")
    148 		   << xe::xml::Writer::BeginElement("testsuite");
    149 
    150 	// Parse and write individual cases
    151 	parseBatchResult(parser, batchResultFilename);
    152 
    153 	writer << xe::xml::Writer::EndElement << xe::xml::Writer::EndElement;
    154 }
    155 
    156 int main (int argc, const char* const* argv)
    157 {
    158 	CommandLine cmdLine;
    159 	try
    160 	{
    161 		parseCommandLine(cmdLine, argc, argv);
    162 	}
    163 	catch (const std::exception&)
    164 	{
    165 		printHelp(argv[0]);
    166 		return -1;
    167 	}
    168 
    169 	try
    170 	{
    171 		batchResultToJUnitReport(cmdLine.batchResultFile.c_str(), cmdLine.outputFile.c_str());
    172 	}
    173 	catch (const std::exception& e)
    174 	{
    175 		printf("%s\n", e.what());
    176 		return -1;
    177 	}
    178 
    179 	return 0;
    180 }
    181