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