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, int 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 107 // \todo [2012-06-09 pyry] What to do with unknown/duplicate attributes? Currently just ignored. 108 break; 109 } 110 111 case CONTAINERELEMENT_BEGIN_TEST_CASE_RESULT: 112 { 113 if (!m_inSession) 114 throw Error("Unexpected #beginTestCaseResult"); 115 116 const char* casePath = m_containerParser.getTestCasePath(); 117 m_currentCaseData = m_handler->startTestCaseResult(casePath); 118 119 // Clear and set to running state. 120 m_currentCaseData->setDataSize(0); 121 m_currentCaseData->setTestResult(TESTSTATUSCODE_RUNNING, "Running"); 122 123 m_handler->testCaseResultUpdated(m_currentCaseData); 124 break; 125 } 126 127 case CONTAINERELEMENT_END_TEST_CASE_RESULT: 128 if (m_currentCaseData) 129 { 130 // \todo [2012-06-16 pyry] Parse status code already here? 131 m_currentCaseData->setTestResult(TESTSTATUSCODE_LAST, ""); 132 m_handler->testCaseResultComplete(m_currentCaseData); 133 } 134 m_currentCaseData.clear(); 135 break; 136 137 case CONTAINERELEMENT_TERMINATE_TEST_CASE_RESULT: 138 if (m_currentCaseData) 139 { 140 TestStatusCode statusCode = TESTSTATUSCODE_CRASH; 141 const char* reason = m_containerParser.getTerminateReason(); 142 try 143 { 144 statusCode = getTestStatusCode(reason); 145 } 146 catch (const xe::ParseError&) 147 { 148 // Could not map status code. 149 } 150 m_currentCaseData->setTestResult(statusCode, reason); 151 m_handler->testCaseResultComplete(m_currentCaseData); 152 } 153 m_currentCaseData.clear(); 154 break; 155 156 case CONTAINERELEMENT_END_OF_STRING: 157 if (m_currentCaseData) 158 { 159 // Terminate current case. 160 m_currentCaseData->setTestResult(TESTSTATUSCODE_TERMINATED, "Unexpected end of string"); 161 m_handler->testCaseResultComplete(m_currentCaseData); 162 } 163 m_currentCaseData.clear(); 164 break; 165 166 case CONTAINERELEMENT_TEST_LOG_DATA: 167 if (m_currentCaseData) 168 { 169 int offset = m_currentCaseData->getDataSize(); 170 int numDataBytes = m_containerParser.getDataSize(); 171 172 m_currentCaseData->setDataSize(offset+numDataBytes); 173 m_containerParser.getData(m_currentCaseData->getData()+offset, numDataBytes, 0); 174 175 m_handler->testCaseResultUpdated(m_currentCaseData); 176 } 177 break; 178 179 default: 180 throw ContainerParseError("Unknown container element"); 181 } 182 183 m_containerParser.advance(); 184 } 185} 186 187} // xe 188