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 Test log parser.
22 *//*--------------------------------------------------------------------*/
23
24 #include "xeTestLogParser.hpp"
25 #include "deString.h"
26
27 using std::string;
28 using std::vector;
29 using std::map;
30
31 namespace xe
32 {
33
TestLogParser(TestLogHandler * handler)34 TestLogParser::TestLogParser (TestLogHandler* handler)
35 : m_handler (handler)
36 , m_inSession (false)
37 {
38 }
39
~TestLogParser(void)40 TestLogParser::~TestLogParser (void)
41 {
42 }
43
reset(void)44 void TestLogParser::reset (void)
45 {
46 m_containerParser.clear();
47 m_currentCaseData.clear();
48 m_sessionInfo = SessionInfo();
49 m_inSession = false;
50 }
51
parse(const deUint8 * bytes,size_t numBytes)52 void TestLogParser::parse (const deUint8* bytes, size_t numBytes)
53 {
54 m_containerParser.feed(bytes, numBytes);
55
56 for (;;)
57 {
58 ContainerElement element = m_containerParser.getElement();
59
60 if (element == CONTAINERELEMENT_INCOMPLETE)
61 break;
62
63 switch (element)
64 {
65 case CONTAINERELEMENT_BEGIN_SESSION:
66 {
67 if (m_inSession)
68 throw Error("Unexpected #beginSession");
69
70 m_handler->setSessionInfo(m_sessionInfo);
71 m_inSession = true;
72 break;
73 }
74
75 case CONTAINERELEMENT_END_SESSION:
76 {
77 if (!m_inSession)
78 throw Error("Unexpected #endSession");
79
80 m_inSession = false;
81 break;
82 }
83
84 case CONTAINERELEMENT_SESSION_INFO:
85 {
86 if (m_inSession)
87 throw Error("Unexpected #sessionInfo");
88
89 const char* attribute = m_containerParser.getSessionInfoAttribute();
90 const char* value = m_containerParser.getSessionInfoValue();
91
92 if (deStringEqual(attribute, "releaseName"))
93 m_sessionInfo.releaseName = value;
94 else if (deStringEqual(attribute, "releaseId"))
95 m_sessionInfo.releaseId = value;
96 else if (deStringEqual(attribute, "targetName"))
97 m_sessionInfo.targetName = value;
98 else if (deStringEqual(attribute, "candyTargetName"))
99 m_sessionInfo.candyTargetName = value;
100 else if (deStringEqual(attribute, "configName"))
101 m_sessionInfo.configName = value;
102 else if (deStringEqual(attribute, "resultName"))
103 m_sessionInfo.resultName = value;
104 else if (deStringEqual(attribute, "timestamp"))
105 m_sessionInfo.timestamp = value;
106 else if (deStringEqual(attribute, "commandLineParameters"))
107 m_sessionInfo.qpaCommandLineParameters = value;
108
109 // \todo [2012-06-09 pyry] What to do with unknown/duplicate attributes? Currently just ignored.
110 break;
111 }
112
113 case CONTAINERELEMENT_BEGIN_TEST_CASE_RESULT:
114 {
115 if (!m_inSession)
116 throw Error("Unexpected #beginTestCaseResult");
117
118 const char* casePath = m_containerParser.getTestCasePath();
119 m_currentCaseData = m_handler->startTestCaseResult(casePath);
120
121 // Clear and set to running state.
122 m_currentCaseData->setDataSize(0);
123 m_currentCaseData->setTestResult(TESTSTATUSCODE_RUNNING, "Running");
124
125 m_handler->testCaseResultUpdated(m_currentCaseData);
126 break;
127 }
128
129 case CONTAINERELEMENT_END_TEST_CASE_RESULT:
130 if (m_currentCaseData)
131 {
132 // \todo [2012-06-16 pyry] Parse status code already here?
133 m_currentCaseData->setTestResult(TESTSTATUSCODE_LAST, "");
134 m_handler->testCaseResultComplete(m_currentCaseData);
135 }
136 m_currentCaseData.clear();
137 break;
138
139 case CONTAINERELEMENT_TERMINATE_TEST_CASE_RESULT:
140 if (m_currentCaseData)
141 {
142 TestStatusCode statusCode = TESTSTATUSCODE_CRASH;
143 const char* reason = m_containerParser.getTerminateReason();
144 try
145 {
146 statusCode = getTestStatusCode(reason);
147 }
148 catch (const xe::ParseError&)
149 {
150 // Could not map status code.
151 }
152 m_currentCaseData->setTestResult(statusCode, reason);
153 m_handler->testCaseResultComplete(m_currentCaseData);
154 }
155 m_currentCaseData.clear();
156 break;
157
158 case CONTAINERELEMENT_END_OF_STRING:
159 if (m_currentCaseData)
160 {
161 // Terminate current case.
162 m_currentCaseData->setTestResult(TESTSTATUSCODE_TERMINATED, "Unexpected end of string");
163 m_handler->testCaseResultComplete(m_currentCaseData);
164 }
165 m_currentCaseData.clear();
166 break;
167
168 case CONTAINERELEMENT_TEST_LOG_DATA:
169 if (m_currentCaseData)
170 {
171 int offset = m_currentCaseData->getDataSize();
172 int numDataBytes = m_containerParser.getDataSize();
173
174 m_currentCaseData->setDataSize(offset+numDataBytes);
175 m_containerParser.getData(m_currentCaseData->getData()+offset, numDataBytes, 0);
176
177 m_handler->testCaseResultUpdated(m_currentCaseData);
178 }
179 break;
180
181 default:
182 throw ContainerParseError("Unknown container element");
183 }
184
185 m_containerParser.advance();
186 }
187 }
188
189 } // xe
190