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 JUnit report conversion tool.
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "xeTestLogParser.hpp"
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "xeTestResultParser.hpp"
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "xeXMLWriter.hpp"
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deFilePath.hpp"
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deString.h"
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deStringUtil.hpp"
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <vector>
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <string>
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <map>
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <cstdio>
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <fstream>
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::vector;
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::string;
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::map;
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct CommandLine
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	CommandLine (void)
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::string		batchResultFile;
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::string		outputFile;
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void printHelp (const char* binName)
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	printf("%s: [testlog] [output file]\n", binName);
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void parseCommandLine (CommandLine& cmdLine, int argc, const char* const* argv)
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (argc != 3)
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw xe::Error("Expected input and output paths");
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	cmdLine.batchResultFile	= argv[argc-2];
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	cmdLine.outputFile		= argv[argc-1];
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void parseBatchResult (xe::TestLogParser& parser, const char* filename)
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ifstream	in			(filename, std::ios_base::binary);
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint8			buf[2048];
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (;;)
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		in.read((char*)&buf[0], sizeof(buf));
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int numRead = (int)in.gcount();
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (numRead > 0)
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			parser.parse(&buf[0], numRead);
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (numRead < (int)sizeof(buf))
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ResultToJUnitHandler : public xe::TestLogHandler
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ResultToJUnitHandler (xe::xml::Writer& writer)
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: m_writer(writer)
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void setSessionInfo (const xe::SessionInfo&)
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	xe::TestCaseResultPtr startTestCaseResult (const char* casePath)
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return xe::TestCaseResultPtr(new xe::TestCaseResultData(casePath));
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void testCaseResultUpdated (const xe::TestCaseResultPtr&)
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void testCaseResultComplete (const xe::TestCaseResultPtr& resultData)
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		using xe::xml::Writer;
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		xe::TestCaseResult result;
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		xe::parseTestCaseResultFromData(&m_resultParser, &result, *resultData.get());
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Split group and case names.
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		size_t			sepPos		= result.casePath.find_last_of('.');
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		std::string		caseName	= result.casePath.substr(sepPos+1);
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		std::string		groupName	= result.casePath.substr(0, sepPos);
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Write result.
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_writer << Writer::BeginElement("testcase")
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				 << Writer::Attribute("name", caseName)
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				 << Writer::Attribute("classname", groupName);
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (result.statusCode != xe::TESTSTATUSCODE_PASS)
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_writer << Writer::BeginElement("failure")
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 << Writer::Attribute("type", xe::getTestStatusCodeName(result.statusCode))
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 << result.statusDetails
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 << Writer::EndElement;
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_writer << Writer::EndElement;
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	xe::xml::Writer&		m_writer;
1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	xe::TestResultParser	m_resultParser;
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void batchResultToJUnitReport (const char* batchResultFilename, const char* dstFileName)
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ofstream				out			(dstFileName, std::ios_base::binary);
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	xe::xml::Writer				writer		(out);
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ResultToJUnitHandler		handler		(writer);
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	xe::TestLogParser			parser		(&handler);
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	XE_CHECK(out.good());
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	out << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	writer << xe::xml::Writer::BeginElement("testsuites")
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   << xe::xml::Writer::BeginElement("testsuite");
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Parse and write individual cases
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	parseBatchResult(parser, batchResultFilename);
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	writer << xe::xml::Writer::EndElement << xe::xml::Writer::EndElement;
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint main (int argc, const char* const* argv)
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	CommandLine cmdLine;
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	try
1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		parseCommandLine(cmdLine, argc, argv);
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	catch (const std::exception&)
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		printHelp(argv[0]);
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return -1;
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	try
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		batchResultToJUnitReport(cmdLine.batchResultFile.c_str(), cmdLine.outputFile.c_str());
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	catch (const std::exception& e)
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		printf("%s\n", e.what());
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return -1;
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return 0;
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
181