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