/*------------------------------------------------------------------------- * drawElements Quality Program Test Executor * ------------------------------------------ * * Copyright 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *//*! * \file * \brief Test log parser. *//*--------------------------------------------------------------------*/ #include "xeTestLogParser.hpp" #include "deString.h" using std::string; using std::vector; using std::map; namespace xe { TestLogParser::TestLogParser (TestLogHandler* handler) : m_handler (handler) , m_inSession (false) { } TestLogParser::~TestLogParser (void) { } void TestLogParser::reset (void) { m_containerParser.clear(); m_currentCaseData.clear(); m_sessionInfo = SessionInfo(); m_inSession = false; } void TestLogParser::parse (const deUint8* bytes, size_t numBytes) { m_containerParser.feed(bytes, numBytes); for (;;) { ContainerElement element = m_containerParser.getElement(); if (element == CONTAINERELEMENT_INCOMPLETE) break; switch (element) { case CONTAINERELEMENT_BEGIN_SESSION: { if (m_inSession) throw Error("Unexpected #beginSession"); m_handler->setSessionInfo(m_sessionInfo); m_inSession = true; break; } case CONTAINERELEMENT_END_SESSION: { if (!m_inSession) throw Error("Unexpected #endSession"); m_inSession = false; break; } case CONTAINERELEMENT_SESSION_INFO: { if (m_inSession) throw Error("Unexpected #sessionInfo"); const char* attribute = m_containerParser.getSessionInfoAttribute(); const char* value = m_containerParser.getSessionInfoValue(); if (deStringEqual(attribute, "releaseName")) m_sessionInfo.releaseName = value; else if (deStringEqual(attribute, "releaseId")) m_sessionInfo.releaseId = value; else if (deStringEqual(attribute, "targetName")) m_sessionInfo.targetName = value; else if (deStringEqual(attribute, "candyTargetName")) m_sessionInfo.candyTargetName = value; else if (deStringEqual(attribute, "configName")) m_sessionInfo.configName = value; else if (deStringEqual(attribute, "resultName")) m_sessionInfo.resultName = value; else if (deStringEqual(attribute, "timestamp")) m_sessionInfo.timestamp = value; // \todo [2012-06-09 pyry] What to do with unknown/duplicate attributes? Currently just ignored. break; } case CONTAINERELEMENT_BEGIN_TEST_CASE_RESULT: { if (!m_inSession) throw Error("Unexpected #beginTestCaseResult"); const char* casePath = m_containerParser.getTestCasePath(); m_currentCaseData = m_handler->startTestCaseResult(casePath); // Clear and set to running state. m_currentCaseData->setDataSize(0); m_currentCaseData->setTestResult(TESTSTATUSCODE_RUNNING, "Running"); m_handler->testCaseResultUpdated(m_currentCaseData); break; } case CONTAINERELEMENT_END_TEST_CASE_RESULT: if (m_currentCaseData) { // \todo [2012-06-16 pyry] Parse status code already here? m_currentCaseData->setTestResult(TESTSTATUSCODE_LAST, ""); m_handler->testCaseResultComplete(m_currentCaseData); } m_currentCaseData.clear(); break; case CONTAINERELEMENT_TERMINATE_TEST_CASE_RESULT: if (m_currentCaseData) { TestStatusCode statusCode = TESTSTATUSCODE_CRASH; const char* reason = m_containerParser.getTerminateReason(); try { statusCode = getTestStatusCode(reason); } catch (const xe::ParseError&) { // Could not map status code. } m_currentCaseData->setTestResult(statusCode, reason); m_handler->testCaseResultComplete(m_currentCaseData); } m_currentCaseData.clear(); break; case CONTAINERELEMENT_END_OF_STRING: if (m_currentCaseData) { // Terminate current case. m_currentCaseData->setTestResult(TESTSTATUSCODE_TERMINATED, "Unexpected end of string"); m_handler->testCaseResultComplete(m_currentCaseData); } m_currentCaseData.clear(); break; case CONTAINERELEMENT_TEST_LOG_DATA: if (m_currentCaseData) { int offset = m_currentCaseData->getDataSize(); int numDataBytes = m_containerParser.getDataSize(); m_currentCaseData->setDataSize(offset+numDataBytes); m_containerParser.getData(m_currentCaseData->getData()+offset, numDataBytes, 0); m_handler->testCaseResultUpdated(m_currentCaseData); } break; default: throw ContainerParseError("Unknown container element"); } m_containerParser.advance(); } } } // xe