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 27using std::string; 28using std::vector; 29using std::map; 30 31namespace xe 32{ 33 34TestLogParser::TestLogParser (TestLogHandler* handler) 35 : m_handler (handler) 36 , m_inSession (false) 37{ 38} 39 40TestLogParser::~TestLogParser (void) 41{ 42} 43 44void TestLogParser::reset (void) 45{ 46 m_containerParser.clear(); 47 m_currentCaseData.clear(); 48 m_sessionInfo = SessionInfo(); 49 m_inSession = false; 50} 51 52void 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