xref: /aosp_15_r20/external/deqp/executor/tools/xeExtractValues.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 Extract values by name from logs.
22  *//*--------------------------------------------------------------------*/
23 
24 #include "xeTestLogParser.hpp"
25 #include "xeTestResultParser.hpp"
26 #include "deFilePath.hpp"
27 #include "deString.h"
28 
29 #include <vector>
30 #include <string>
31 #include <cstdio>
32 #include <cstdlib>
33 #include <fstream>
34 #include <iostream>
35 #include <stdexcept>
36 
37 using std::map;
38 using std::set;
39 using std::string;
40 using std::vector;
41 
42 struct CommandLine
43 {
CommandLineCommandLine44     CommandLine(void) : statusCode(false)
45     {
46     }
47 
48     string filename;
49     vector<string> tagNames;
50     bool statusCode;
51 };
52 
53 typedef xe::ri::NumericValue Value;
54 
55 struct CaseValues
56 {
57     string casePath;
58     xe::TestCaseType caseType;
59     xe::TestStatusCode statusCode;
60     string statusDetails;
61 
62     vector<Value> values;
63 };
64 
65 class BatchResultValues
66 {
67 public:
BatchResultValues(const vector<string> & tagNames)68     BatchResultValues(const vector<string> &tagNames) : m_tagNames(tagNames)
69     {
70     }
71 
~BatchResultValues(void)72     ~BatchResultValues(void)
73     {
74         for (vector<CaseValues *>::iterator i = m_caseValues.begin(); i != m_caseValues.end(); ++i)
75             delete *i;
76     }
77 
add(const CaseValues & result)78     void add(const CaseValues &result)
79     {
80         CaseValues *copy = new CaseValues(result);
81         try
82         {
83             m_caseValues.push_back(copy);
84         }
85         catch (...)
86         {
87             delete copy;
88             throw;
89         }
90     }
91 
getTagNames(void) const92     const vector<string> &getTagNames(void) const
93     {
94         return m_tagNames;
95     }
96 
size(void) const97     size_t size(void) const
98     {
99         return m_caseValues.size();
100     }
operator [](size_t ndx) const101     const CaseValues &operator[](size_t ndx) const
102     {
103         return *m_caseValues[ndx];
104     }
105 
106 private:
107     vector<string> m_tagNames;
108     vector<CaseValues *> m_caseValues;
109 };
110 
findValueByTag(const xe::ri::List & items,const string & tagName)111 static Value findValueByTag(const xe::ri::List &items, const string &tagName)
112 {
113     for (int ndx = 0; ndx < items.getNumItems(); ndx++)
114     {
115         const xe::ri::Item &item = items.getItem(ndx);
116 
117         if (item.getType() == xe::ri::TYPE_SECTION)
118         {
119             const Value value = findValueByTag(static_cast<const xe::ri::Section &>(item).items, tagName);
120             if (value.getType() != Value::NUMVALTYPE_EMPTY)
121                 return value;
122         }
123         else if (item.getType() == xe::ri::TYPE_NUMBER)
124         {
125             const xe::ri::Number &value = static_cast<const xe::ri::Number &>(item);
126             return value.value;
127         }
128     }
129 
130     return Value();
131 }
132 
133 class TagParser : public xe::TestLogHandler
134 {
135 public:
TagParser(BatchResultValues & result)136     TagParser(BatchResultValues &result) : m_result(result)
137     {
138     }
139 
setSessionInfo(const xe::SessionInfo &)140     void setSessionInfo(const xe::SessionInfo &)
141     {
142         // Ignored.
143     }
144 
startTestCaseResult(const char * casePath)145     xe::TestCaseResultPtr startTestCaseResult(const char *casePath)
146     {
147         return xe::TestCaseResultPtr(new xe::TestCaseResultData(casePath));
148     }
149 
testCaseResultUpdated(const xe::TestCaseResultPtr &)150     void testCaseResultUpdated(const xe::TestCaseResultPtr &)
151     {
152         // Ignored.
153     }
154 
testCaseResultComplete(const xe::TestCaseResultPtr & caseData)155     void testCaseResultComplete(const xe::TestCaseResultPtr &caseData)
156     {
157         const vector<string> &tagNames = m_result.getTagNames();
158         CaseValues tagResult;
159 
160         tagResult.casePath      = caseData->getTestCasePath();
161         tagResult.caseType      = xe::TESTCASETYPE_SELF_VALIDATE;
162         tagResult.statusCode    = caseData->getStatusCode();
163         tagResult.statusDetails = caseData->getStatusDetails();
164         tagResult.values.resize(tagNames.size());
165 
166         if (caseData->getDataSize() > 0 && caseData->getStatusCode() == xe::TESTSTATUSCODE_LAST)
167         {
168             xe::TestCaseResult fullResult;
169             xe::TestResultParser::ParseResult parseResult;
170 
171             m_testResultParser.init(&fullResult);
172             parseResult = m_testResultParser.parse(caseData->getData(), caseData->getDataSize());
173 
174             if ((parseResult != xe::TestResultParser::PARSERESULT_ERROR &&
175                  fullResult.statusCode != xe::TESTSTATUSCODE_LAST) ||
176                 (tagResult.statusCode == xe::TESTSTATUSCODE_LAST && fullResult.statusCode != xe::TESTSTATUSCODE_LAST))
177             {
178                 tagResult.statusCode    = fullResult.statusCode;
179                 tagResult.statusDetails = fullResult.statusDetails;
180             }
181             else if (tagResult.statusCode == xe::TESTSTATUSCODE_LAST)
182             {
183                 DE_ASSERT(parseResult == xe::TestResultParser::PARSERESULT_ERROR);
184                 tagResult.statusCode    = xe::TESTSTATUSCODE_INTERNAL_ERROR;
185                 tagResult.statusDetails = "Test case result parsing failed";
186             }
187 
188             if (parseResult != xe::TestResultParser::PARSERESULT_ERROR)
189             {
190                 for (int valNdx = 0; valNdx < (int)tagNames.size(); valNdx++)
191                     tagResult.values[valNdx] = findValueByTag(fullResult.resultItems, tagNames[valNdx]);
192             }
193         }
194 
195         m_result.add(tagResult);
196     }
197 
198 private:
199     BatchResultValues &m_result;
200     xe::TestResultParser m_testResultParser;
201 };
202 
readLogFile(BatchResultValues & batchResult,const char * filename)203 static void readLogFile(BatchResultValues &batchResult, const char *filename)
204 {
205     std::ifstream in(filename, std::ifstream::binary | std::ifstream::in);
206     TagParser resultHandler(batchResult);
207     xe::TestLogParser parser(&resultHandler);
208     uint8_t buf[1024];
209     int numRead = 0;
210 
211     if (!in.good())
212         throw std::runtime_error(string("Failed to open '") + filename + "'");
213 
214     for (;;)
215     {
216         in.read((char *)&buf[0], DE_LENGTH_OF_ARRAY(buf));
217         numRead = (int)in.gcount();
218 
219         if (numRead <= 0)
220             break;
221 
222         parser.parse(&buf[0], numRead);
223     }
224 
225     in.close();
226 }
227 
printTaggedValues(const CommandLine & cmdLine,std::ostream & dst)228 static void printTaggedValues(const CommandLine &cmdLine, std::ostream &dst)
229 {
230     BatchResultValues values(cmdLine.tagNames);
231 
232     readLogFile(values, cmdLine.filename.c_str());
233 
234     // Header
235     {
236         dst << "CasePath";
237         if (cmdLine.statusCode)
238             dst << ",StatusCode";
239 
240         for (vector<string>::const_iterator tagName = values.getTagNames().begin();
241              tagName != values.getTagNames().end(); ++tagName)
242             dst << "," << *tagName;
243 
244         dst << "\n";
245     }
246 
247     for (int resultNdx = 0; resultNdx < (int)values.size(); resultNdx++)
248     {
249         const CaseValues &result = values[resultNdx];
250 
251         dst << result.casePath;
252         if (cmdLine.statusCode)
253             dst << "," << xe::getTestStatusCodeName(result.statusCode);
254 
255         for (vector<Value>::const_iterator value = result.values.begin(); value != result.values.end(); ++value)
256             dst << "," << *value;
257 
258         dst << "\n";
259     }
260 }
261 
printHelp(const char * binName)262 static void printHelp(const char *binName)
263 {
264     printf("%s: [filename] [name 1] [[name 2]...]\n", binName);
265     printf(" --statuscode     Include status code as first entry.\n");
266 }
267 
parseCommandLine(CommandLine & cmdLine,int argc,const char * const * argv)268 static bool parseCommandLine(CommandLine &cmdLine, int argc, const char *const *argv)
269 {
270     for (int argNdx = 1; argNdx < argc; argNdx++)
271     {
272         const char *arg = argv[argNdx];
273 
274         if (deStringEqual(arg, "--statuscode"))
275             cmdLine.statusCode = true;
276         else if (!deStringBeginsWith(arg, "--"))
277         {
278             if (cmdLine.filename.empty())
279                 cmdLine.filename = arg;
280             else
281                 cmdLine.tagNames.push_back(arg);
282         }
283         else
284             return false;
285     }
286 
287     if (cmdLine.filename.empty())
288         return false;
289 
290     return true;
291 }
292 
main(int argc,const char * const * argv)293 int main(int argc, const char *const *argv)
294 {
295     try
296     {
297         CommandLine cmdLine;
298 
299         if (!parseCommandLine(cmdLine, argc, argv))
300         {
301             printHelp(argv[0]);
302             return -1;
303         }
304 
305         printTaggedValues(cmdLine, std::cout);
306     }
307     catch (const std::exception &e)
308     {
309         printf("FATAL ERROR: %s\n", e.what());
310         return -1;
311     }
312 
313     return 0;
314 }
315