1e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------- 2e5c31af7Sopenharmony_ci * drawElements Quality Program Execution Server 3e5c31af7Sopenharmony_ci * --------------------------------------------- 4e5c31af7Sopenharmony_ci * 5e5c31af7Sopenharmony_ci * Copyright 2014 The Android Open Source Project 6e5c31af7Sopenharmony_ci * 7e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 8e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License. 9e5c31af7Sopenharmony_ci * You may obtain a copy of the License at 10e5c31af7Sopenharmony_ci * 11e5c31af7Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 12e5c31af7Sopenharmony_ci * 13e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 14e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 15e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and 17e5c31af7Sopenharmony_ci * limitations under the License. 18e5c31af7Sopenharmony_ci * 19e5c31af7Sopenharmony_ci *//*! 20e5c31af7Sopenharmony_ci * \file 21e5c31af7Sopenharmony_ci * \brief Test Driver. 22e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 23e5c31af7Sopenharmony_ci 24e5c31af7Sopenharmony_ci#include "xsTestDriver.hpp" 25e5c31af7Sopenharmony_ci#include "deClock.h" 26e5c31af7Sopenharmony_ci 27e5c31af7Sopenharmony_ci#include <string> 28e5c31af7Sopenharmony_ci#include <vector> 29e5c31af7Sopenharmony_ci#include <cstdio> 30e5c31af7Sopenharmony_ci 31e5c31af7Sopenharmony_ciusing std::string; 32e5c31af7Sopenharmony_ciusing std::vector; 33e5c31af7Sopenharmony_ci 34e5c31af7Sopenharmony_ci#if 0 35e5c31af7Sopenharmony_ci# define DBG_PRINT(X) printf X 36e5c31af7Sopenharmony_ci#else 37e5c31af7Sopenharmony_ci# define DBG_PRINT(X) 38e5c31af7Sopenharmony_ci#endif 39e5c31af7Sopenharmony_ci 40e5c31af7Sopenharmony_cinamespace xs 41e5c31af7Sopenharmony_ci{ 42e5c31af7Sopenharmony_ci 43e5c31af7Sopenharmony_ciTestDriver::TestDriver (xs::TestProcess* testProcess) 44e5c31af7Sopenharmony_ci : m_state (STATE_NOT_STARTED) 45e5c31af7Sopenharmony_ci , m_lastExitCode (0) 46e5c31af7Sopenharmony_ci , m_process (testProcess) 47e5c31af7Sopenharmony_ci , m_lastProcessDataTime (0) 48e5c31af7Sopenharmony_ci , m_dataMsgTmpBuf (SEND_RECV_TMP_BUFFER_SIZE) 49e5c31af7Sopenharmony_ci{ 50e5c31af7Sopenharmony_ci} 51e5c31af7Sopenharmony_ci 52e5c31af7Sopenharmony_ciTestDriver::~TestDriver (void) 53e5c31af7Sopenharmony_ci{ 54e5c31af7Sopenharmony_ci reset(); 55e5c31af7Sopenharmony_ci} 56e5c31af7Sopenharmony_ci 57e5c31af7Sopenharmony_civoid TestDriver::reset (void) 58e5c31af7Sopenharmony_ci{ 59e5c31af7Sopenharmony_ci m_process->cleanup(); 60e5c31af7Sopenharmony_ci 61e5c31af7Sopenharmony_ci m_state = STATE_NOT_STARTED; 62e5c31af7Sopenharmony_ci} 63e5c31af7Sopenharmony_ci 64e5c31af7Sopenharmony_civoid TestDriver::startProcess (const char* name, const char* params, const char* workingDir, const char* caseList) 65e5c31af7Sopenharmony_ci{ 66e5c31af7Sopenharmony_ci try 67e5c31af7Sopenharmony_ci { 68e5c31af7Sopenharmony_ci m_process->start(name, params, workingDir, caseList); 69e5c31af7Sopenharmony_ci m_state = STATE_PROCESS_STARTED; 70e5c31af7Sopenharmony_ci } 71e5c31af7Sopenharmony_ci catch (const TestProcessException& e) 72e5c31af7Sopenharmony_ci { 73e5c31af7Sopenharmony_ci printf("Failed to launch test process: %s\n", e.what()); 74e5c31af7Sopenharmony_ci m_state = STATE_PROCESS_LAUNCH_FAILED; 75e5c31af7Sopenharmony_ci m_lastLaunchFailure = e.what(); 76e5c31af7Sopenharmony_ci } 77e5c31af7Sopenharmony_ci} 78e5c31af7Sopenharmony_ci 79e5c31af7Sopenharmony_civoid TestDriver::stopProcess (void) 80e5c31af7Sopenharmony_ci{ 81e5c31af7Sopenharmony_ci m_process->terminate(); 82e5c31af7Sopenharmony_ci} 83e5c31af7Sopenharmony_ci 84e5c31af7Sopenharmony_cibool TestDriver::poll (ByteBuffer& messageBuffer) 85e5c31af7Sopenharmony_ci{ 86e5c31af7Sopenharmony_ci switch (m_state) 87e5c31af7Sopenharmony_ci { 88e5c31af7Sopenharmony_ci case STATE_NOT_STARTED: 89e5c31af7Sopenharmony_ci return false; // Nothing to report. 90e5c31af7Sopenharmony_ci 91e5c31af7Sopenharmony_ci case STATE_PROCESS_LAUNCH_FAILED: 92e5c31af7Sopenharmony_ci DBG_PRINT((" STATE_PROCESS_LAUNCH_FAILED\n")); 93e5c31af7Sopenharmony_ci if (writeMessage(messageBuffer, ProcessLaunchFailedMessage(m_lastLaunchFailure.c_str()))) 94e5c31af7Sopenharmony_ci { 95e5c31af7Sopenharmony_ci m_state = STATE_NOT_STARTED; 96e5c31af7Sopenharmony_ci m_lastLaunchFailure = ""; 97e5c31af7Sopenharmony_ci return true; 98e5c31af7Sopenharmony_ci } 99e5c31af7Sopenharmony_ci else 100e5c31af7Sopenharmony_ci return false; 101e5c31af7Sopenharmony_ci 102e5c31af7Sopenharmony_ci case STATE_PROCESS_STARTED: 103e5c31af7Sopenharmony_ci DBG_PRINT((" STATE_PROCESS_STARTED\n")); 104e5c31af7Sopenharmony_ci if (writeMessage(messageBuffer, ProcessStartedMessage())) 105e5c31af7Sopenharmony_ci { 106e5c31af7Sopenharmony_ci m_state = STATE_PROCESS_RUNNING; 107e5c31af7Sopenharmony_ci return true; 108e5c31af7Sopenharmony_ci } 109e5c31af7Sopenharmony_ci else 110e5c31af7Sopenharmony_ci return false; 111e5c31af7Sopenharmony_ci 112e5c31af7Sopenharmony_ci case STATE_PROCESS_RUNNING: 113e5c31af7Sopenharmony_ci { 114e5c31af7Sopenharmony_ci DBG_PRINT((" STATE_PROCESS_RUNNING\n")); 115e5c31af7Sopenharmony_ci bool gotProcessData = false; 116e5c31af7Sopenharmony_ci 117e5c31af7Sopenharmony_ci // Poll log file and info buffer. 118e5c31af7Sopenharmony_ci gotProcessData = pollLogFile(messageBuffer) || gotProcessData; 119e5c31af7Sopenharmony_ci gotProcessData = pollInfo(messageBuffer) || gotProcessData; 120e5c31af7Sopenharmony_ci 121e5c31af7Sopenharmony_ci if (gotProcessData) 122e5c31af7Sopenharmony_ci return true; // Got IO. 123e5c31af7Sopenharmony_ci 124e5c31af7Sopenharmony_ci if (!m_process->isRunning()) 125e5c31af7Sopenharmony_ci { 126e5c31af7Sopenharmony_ci // Process died. 127e5c31af7Sopenharmony_ci m_state = STATE_READING_DATA; 128e5c31af7Sopenharmony_ci m_lastExitCode = m_process->getExitCode(); 129e5c31af7Sopenharmony_ci m_lastProcessDataTime = deGetMicroseconds(); 130e5c31af7Sopenharmony_ci 131e5c31af7Sopenharmony_ci return true; // Got state change. 132e5c31af7Sopenharmony_ci } 133e5c31af7Sopenharmony_ci 134e5c31af7Sopenharmony_ci return false; // Nothing to report. 135e5c31af7Sopenharmony_ci } 136e5c31af7Sopenharmony_ci 137e5c31af7Sopenharmony_ci case STATE_READING_DATA: 138e5c31af7Sopenharmony_ci { 139e5c31af7Sopenharmony_ci DBG_PRINT((" STATE_READING_DATA\n")); 140e5c31af7Sopenharmony_ci bool gotProcessData = false; 141e5c31af7Sopenharmony_ci 142e5c31af7Sopenharmony_ci // Poll log file and info buffer. 143e5c31af7Sopenharmony_ci gotProcessData = pollLogFile(messageBuffer) || gotProcessData; 144e5c31af7Sopenharmony_ci gotProcessData = pollInfo(messageBuffer) || gotProcessData; 145e5c31af7Sopenharmony_ci 146e5c31af7Sopenharmony_ci if (gotProcessData) 147e5c31af7Sopenharmony_ci { 148e5c31af7Sopenharmony_ci // Got data. 149e5c31af7Sopenharmony_ci m_lastProcessDataTime = deGetMicroseconds(); 150e5c31af7Sopenharmony_ci return true; 151e5c31af7Sopenharmony_ci } 152e5c31af7Sopenharmony_ci else if (deGetMicroseconds() - m_lastProcessDataTime > READ_DATA_TIMEOUT*1000) 153e5c31af7Sopenharmony_ci { 154e5c31af7Sopenharmony_ci // Read timeout occurred. 155e5c31af7Sopenharmony_ci m_state = STATE_PROCESS_FINISHED; 156e5c31af7Sopenharmony_ci return true; // State change. 157e5c31af7Sopenharmony_ci } 158e5c31af7Sopenharmony_ci else 159e5c31af7Sopenharmony_ci return false; // Still waiting for data. 160e5c31af7Sopenharmony_ci } 161e5c31af7Sopenharmony_ci 162e5c31af7Sopenharmony_ci case STATE_PROCESS_FINISHED: 163e5c31af7Sopenharmony_ci DBG_PRINT((" STATE_PROCESS_FINISHED\n")); 164e5c31af7Sopenharmony_ci if (writeMessage(messageBuffer, ProcessFinishedMessage(m_lastExitCode))) 165e5c31af7Sopenharmony_ci { 166e5c31af7Sopenharmony_ci // Signal TestProcess to clean up any remaining resources. 167e5c31af7Sopenharmony_ci m_process->cleanup(); 168e5c31af7Sopenharmony_ci 169e5c31af7Sopenharmony_ci m_state = STATE_NOT_STARTED; 170e5c31af7Sopenharmony_ci m_lastExitCode = 0; 171e5c31af7Sopenharmony_ci return true; 172e5c31af7Sopenharmony_ci } 173e5c31af7Sopenharmony_ci else 174e5c31af7Sopenharmony_ci return false; 175e5c31af7Sopenharmony_ci 176e5c31af7Sopenharmony_ci default: 177e5c31af7Sopenharmony_ci DE_ASSERT(DE_FALSE); 178e5c31af7Sopenharmony_ci return false; 179e5c31af7Sopenharmony_ci } 180e5c31af7Sopenharmony_ci} 181e5c31af7Sopenharmony_ci 182e5c31af7Sopenharmony_cibool TestDriver::pollLogFile (ByteBuffer& messageBuffer) 183e5c31af7Sopenharmony_ci{ 184e5c31af7Sopenharmony_ci return pollBuffer(messageBuffer, MESSAGETYPE_PROCESS_LOG_DATA); 185e5c31af7Sopenharmony_ci} 186e5c31af7Sopenharmony_ci 187e5c31af7Sopenharmony_cibool TestDriver::pollInfo (ByteBuffer& messageBuffer) 188e5c31af7Sopenharmony_ci{ 189e5c31af7Sopenharmony_ci return pollBuffer(messageBuffer, MESSAGETYPE_INFO); 190e5c31af7Sopenharmony_ci} 191e5c31af7Sopenharmony_ci 192e5c31af7Sopenharmony_cibool TestDriver::pollBuffer (ByteBuffer& messageBuffer, MessageType msgType) 193e5c31af7Sopenharmony_ci{ 194e5c31af7Sopenharmony_ci const int minBytesAvailable = MESSAGE_HEADER_SIZE + MIN_MSG_PAYLOAD_SIZE; 195e5c31af7Sopenharmony_ci 196e5c31af7Sopenharmony_ci if (messageBuffer.getNumFree() < minBytesAvailable) 197e5c31af7Sopenharmony_ci return false; // Not enough space in message buffer. 198e5c31af7Sopenharmony_ci 199e5c31af7Sopenharmony_ci const int maxMsgSize = de::min((int)m_dataMsgTmpBuf.size(), messageBuffer.getNumFree()); 200e5c31af7Sopenharmony_ci int numRead = 0; 201e5c31af7Sopenharmony_ci int msgSize = MESSAGE_HEADER_SIZE+1; // One byte is reserved for terminating 0. 202e5c31af7Sopenharmony_ci 203e5c31af7Sopenharmony_ci // Fill in data \note Last byte is reserved for 0. 204e5c31af7Sopenharmony_ci numRead = msgType == MESSAGETYPE_PROCESS_LOG_DATA 205e5c31af7Sopenharmony_ci ? m_process->readTestLog(&m_dataMsgTmpBuf[MESSAGE_HEADER_SIZE], maxMsgSize-MESSAGE_HEADER_SIZE-1) 206e5c31af7Sopenharmony_ci : m_process->readInfoLog(&m_dataMsgTmpBuf[MESSAGE_HEADER_SIZE], maxMsgSize-MESSAGE_HEADER_SIZE-1); 207e5c31af7Sopenharmony_ci 208e5c31af7Sopenharmony_ci if (numRead <= 0) 209e5c31af7Sopenharmony_ci return false; // Didn't get any data. 210e5c31af7Sopenharmony_ci 211e5c31af7Sopenharmony_ci msgSize += numRead; 212e5c31af7Sopenharmony_ci 213e5c31af7Sopenharmony_ci // Terminate with 0. 214e5c31af7Sopenharmony_ci m_dataMsgTmpBuf[msgSize-1] = 0; 215e5c31af7Sopenharmony_ci 216e5c31af7Sopenharmony_ci // Write header. 217e5c31af7Sopenharmony_ci Message::writeHeader(msgType, msgSize, &m_dataMsgTmpBuf[0], MESSAGE_HEADER_SIZE); 218e5c31af7Sopenharmony_ci 219e5c31af7Sopenharmony_ci // Write to messagebuffer. 220e5c31af7Sopenharmony_ci messageBuffer.pushFront(&m_dataMsgTmpBuf[0], msgSize); 221e5c31af7Sopenharmony_ci 222e5c31af7Sopenharmony_ci DBG_PRINT((" wrote %d bytes of %s data\n", msgSize, msgType == MESSAGETYPE_INFO ? "info" : "log")); 223e5c31af7Sopenharmony_ci 224e5c31af7Sopenharmony_ci return true; 225e5c31af7Sopenharmony_ci} 226e5c31af7Sopenharmony_ci 227e5c31af7Sopenharmony_cibool TestDriver::writeMessage (ByteBuffer& messageBuffer, const Message& message) 228e5c31af7Sopenharmony_ci{ 229e5c31af7Sopenharmony_ci vector<deUint8> buf; 230e5c31af7Sopenharmony_ci message.write(buf); 231e5c31af7Sopenharmony_ci 232e5c31af7Sopenharmony_ci if (messageBuffer.getNumFree() < (int)buf.size()) 233e5c31af7Sopenharmony_ci return false; 234e5c31af7Sopenharmony_ci 235e5c31af7Sopenharmony_ci messageBuffer.pushFront(&buf[0], (int)buf.size()); 236e5c31af7Sopenharmony_ci return true; 237e5c31af7Sopenharmony_ci} 238e5c31af7Sopenharmony_ci 239e5c31af7Sopenharmony_ci} // xs 240