xref: /aosp_15_r20/external/deqp/executor/tools/xeBatchResultToJUnit.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
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::map;
38 using std::string;
39 using std::vector;
40 
41 struct CommandLine
42 {
CommandLineCommandLine43     CommandLine(void)
44     {
45     }
46 
47     std::string batchResultFile;
48     std::string outputFile;
49 };
50 
printHelp(const char * binName)51 static void printHelp(const char *binName)
52 {
53     printf("%s: [testlog] [output file]\n", binName);
54 }
55 
parseCommandLine(CommandLine & cmdLine,int argc,const char * const * argv)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 
parseBatchResult(xe::TestLogParser & parser,const char * filename)65 static void parseBatchResult(xe::TestLogParser &parser, const char *filename)
66 {
67     std::ifstream in(filename, std::ios_base::binary);
68     uint8_t 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:
ResultToJUnitHandler(xe::xml::Writer & writer)86     ResultToJUnitHandler(xe::xml::Writer &writer) : m_writer(writer)
87     {
88     }
89 
setSessionInfo(const xe::SessionInfo &)90     void setSessionInfo(const xe::SessionInfo &)
91     {
92     }
93 
startTestCaseResult(const char * casePath)94     xe::TestCaseResultPtr startTestCaseResult(const char *casePath)
95     {
96         return xe::TestCaseResultPtr(new xe::TestCaseResultData(casePath));
97     }
98 
testCaseResultUpdated(const xe::TestCaseResultPtr &)99     void testCaseResultUpdated(const xe::TestCaseResultPtr &)
100     {
101     }
102 
testCaseResultComplete(const xe::TestCaseResultPtr & resultData)103     void testCaseResultComplete(const xe::TestCaseResultPtr &resultData)
104     {
105         using xe::xml::Writer;
106 
107         xe::TestCaseResult result;
108 
109         xe::parseTestCaseResultFromData(&m_resultParser, &result, *resultData.get());
110 
111         // Split group and case names.
112         size_t sepPos         = result.casePath.find_last_of('.');
113         std::string caseName  = result.casePath.substr(sepPos + 1);
114         std::string groupName = result.casePath.substr(0, sepPos);
115 
116         // Write result.
117         m_writer << Writer::BeginElement("testcase") << Writer::Attribute("name", caseName)
118                  << Writer::Attribute("classname", groupName);
119 
120         if (result.statusCode != xe::TESTSTATUSCODE_PASS)
121             m_writer << Writer::BeginElement("failure")
122                      << Writer::Attribute("type", xe::getTestStatusCodeName(result.statusCode)) << result.statusDetails
123                      << Writer::EndElement;
124 
125         m_writer << Writer::EndElement;
126     }
127 
128 private:
129     xe::xml::Writer &m_writer;
130     xe::TestResultParser m_resultParser;
131 };
132 
batchResultToJUnitReport(const char * batchResultFilename,const char * dstFileName)133 static void batchResultToJUnitReport(const char *batchResultFilename, const char *dstFileName)
134 {
135     std::ofstream out(dstFileName, std::ios_base::binary);
136     xe::xml::Writer writer(out);
137     ResultToJUnitHandler handler(writer);
138     xe::TestLogParser parser(&handler);
139 
140     XE_CHECK(out.good());
141 
142     out << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
143 
144     writer << xe::xml::Writer::BeginElement("testsuites") << xe::xml::Writer::BeginElement("testsuite");
145 
146     // Parse and write individual cases
147     parseBatchResult(parser, batchResultFilename);
148 
149     writer << xe::xml::Writer::EndElement << xe::xml::Writer::EndElement;
150 }
151 
main(int argc,const char * const * argv)152 int main(int argc, const char *const *argv)
153 {
154     CommandLine cmdLine;
155     try
156     {
157         parseCommandLine(cmdLine, argc, argv);
158     }
159     catch (const std::exception &)
160     {
161         printHelp(argv[0]);
162         return -1;
163     }
164 
165     try
166     {
167         batchResultToJUnitReport(cmdLine.batchResultFile.c_str(), cmdLine.outputFile.c_str());
168     }
169     catch (const std::exception &e)
170     {
171         printf("%s\n", e.what());
172         return -1;
173     }
174 
175     return 0;
176 }
177