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