xref: /aosp_15_r20/external/deqp/execserver/tools/xsTest.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 ExecServer Tests.
22*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker 
24*35238bceSAndroid Build Coastguard Worker #include "xsDefs.hpp"
25*35238bceSAndroid Build Coastguard Worker 
26*35238bceSAndroid Build Coastguard Worker #include "xsProtocol.hpp"
27*35238bceSAndroid Build Coastguard Worker #include "deSocket.hpp"
28*35238bceSAndroid Build Coastguard Worker #include "deRingBuffer.hpp"
29*35238bceSAndroid Build Coastguard Worker #include "deFilePath.hpp"
30*35238bceSAndroid Build Coastguard Worker #include "deBlockBuffer.hpp"
31*35238bceSAndroid Build Coastguard Worker #include "deThread.hpp"
32*35238bceSAndroid Build Coastguard Worker #include "deStringUtil.hpp"
33*35238bceSAndroid Build Coastguard Worker #include "deUniquePtr.hpp"
34*35238bceSAndroid Build Coastguard Worker 
35*35238bceSAndroid Build Coastguard Worker #include "deClock.h"
36*35238bceSAndroid Build Coastguard Worker #include "deProcess.h"
37*35238bceSAndroid Build Coastguard Worker #include "deString.h"
38*35238bceSAndroid Build Coastguard Worker #include "deRandom.h"
39*35238bceSAndroid Build Coastguard Worker 
40*35238bceSAndroid Build Coastguard Worker #include <memory>
41*35238bceSAndroid Build Coastguard Worker #include <algorithm>
42*35238bceSAndroid Build Coastguard Worker 
43*35238bceSAndroid Build Coastguard Worker using std::string;
44*35238bceSAndroid Build Coastguard Worker using std::vector;
45*35238bceSAndroid Build Coastguard Worker 
46*35238bceSAndroid Build Coastguard Worker namespace xs
47*35238bceSAndroid Build Coastguard Worker {
48*35238bceSAndroid Build Coastguard Worker 
49*35238bceSAndroid Build Coastguard Worker typedef de::UniquePtr<Message> ScopedMsgPtr;
50*35238bceSAndroid Build Coastguard Worker 
51*35238bceSAndroid Build Coastguard Worker class SocketError : public Error
52*35238bceSAndroid Build Coastguard Worker {
53*35238bceSAndroid Build Coastguard Worker public:
SocketError(deSocketResult result,const char * message,const char * file,int line)54*35238bceSAndroid Build Coastguard Worker     SocketError(deSocketResult result, const char *message, const char *file, int line)
55*35238bceSAndroid Build Coastguard Worker         : Error(message, deGetSocketResultName(result), file, line)
56*35238bceSAndroid Build Coastguard Worker         , m_result(result)
57*35238bceSAndroid Build Coastguard Worker     {
58*35238bceSAndroid Build Coastguard Worker     }
59*35238bceSAndroid Build Coastguard Worker 
getResult(void) const60*35238bceSAndroid Build Coastguard Worker     deSocketResult getResult(void) const
61*35238bceSAndroid Build Coastguard Worker     {
62*35238bceSAndroid Build Coastguard Worker         return m_result;
63*35238bceSAndroid Build Coastguard Worker     }
64*35238bceSAndroid Build Coastguard Worker 
65*35238bceSAndroid Build Coastguard Worker private:
66*35238bceSAndroid Build Coastguard Worker     deSocketResult m_result;
67*35238bceSAndroid Build Coastguard Worker };
68*35238bceSAndroid Build Coastguard Worker 
69*35238bceSAndroid Build Coastguard Worker // Helpers.
sendMessage(de::Socket & socket,const Message & message)70*35238bceSAndroid Build Coastguard Worker void sendMessage(de::Socket &socket, const Message &message)
71*35238bceSAndroid Build Coastguard Worker {
72*35238bceSAndroid Build Coastguard Worker     // Format message.
73*35238bceSAndroid Build Coastguard Worker     vector<uint8_t> buf;
74*35238bceSAndroid Build Coastguard Worker     message.write(buf);
75*35238bceSAndroid Build Coastguard Worker 
76*35238bceSAndroid Build Coastguard Worker     // Write to socket.
77*35238bceSAndroid Build Coastguard Worker     size_t pos = 0;
78*35238bceSAndroid Build Coastguard Worker     while (pos < buf.size())
79*35238bceSAndroid Build Coastguard Worker     {
80*35238bceSAndroid Build Coastguard Worker         size_t numLeft        = buf.size() - pos;
81*35238bceSAndroid Build Coastguard Worker         size_t numSent        = 0;
82*35238bceSAndroid Build Coastguard Worker         deSocketResult result = socket.send(&buf[pos], numLeft, &numSent);
83*35238bceSAndroid Build Coastguard Worker 
84*35238bceSAndroid Build Coastguard Worker         if (result != DE_SOCKETRESULT_SUCCESS)
85*35238bceSAndroid Build Coastguard Worker             throw SocketError(result, "send() failed", __FILE__, __LINE__);
86*35238bceSAndroid Build Coastguard Worker 
87*35238bceSAndroid Build Coastguard Worker         pos += numSent;
88*35238bceSAndroid Build Coastguard Worker     }
89*35238bceSAndroid Build Coastguard Worker }
90*35238bceSAndroid Build Coastguard Worker 
readBytes(de::Socket & socket,vector<uint8_t> & dst,size_t numBytes)91*35238bceSAndroid Build Coastguard Worker void readBytes(de::Socket &socket, vector<uint8_t> &dst, size_t numBytes)
92*35238bceSAndroid Build Coastguard Worker {
93*35238bceSAndroid Build Coastguard Worker     size_t numRead = 0;
94*35238bceSAndroid Build Coastguard Worker     dst.resize(numBytes);
95*35238bceSAndroid Build Coastguard Worker     while (numRead < numBytes)
96*35238bceSAndroid Build Coastguard Worker     {
97*35238bceSAndroid Build Coastguard Worker         size_t numLeft        = numBytes - numRead;
98*35238bceSAndroid Build Coastguard Worker         size_t curNumRead     = 0;
99*35238bceSAndroid Build Coastguard Worker         deSocketResult result = socket.receive(&dst[numRead], numLeft, &curNumRead);
100*35238bceSAndroid Build Coastguard Worker 
101*35238bceSAndroid Build Coastguard Worker         if (result != DE_SOCKETRESULT_SUCCESS)
102*35238bceSAndroid Build Coastguard Worker             throw SocketError(result, "receive() failed", __FILE__, __LINE__);
103*35238bceSAndroid Build Coastguard Worker 
104*35238bceSAndroid Build Coastguard Worker         numRead += curNumRead;
105*35238bceSAndroid Build Coastguard Worker     }
106*35238bceSAndroid Build Coastguard Worker }
107*35238bceSAndroid Build Coastguard Worker 
readMessage(de::Socket & socket)108*35238bceSAndroid Build Coastguard Worker Message *readMessage(de::Socket &socket)
109*35238bceSAndroid Build Coastguard Worker {
110*35238bceSAndroid Build Coastguard Worker     // Header.
111*35238bceSAndroid Build Coastguard Worker     vector<uint8_t> header;
112*35238bceSAndroid Build Coastguard Worker     readBytes(socket, header, MESSAGE_HEADER_SIZE);
113*35238bceSAndroid Build Coastguard Worker 
114*35238bceSAndroid Build Coastguard Worker     MessageType type;
115*35238bceSAndroid Build Coastguard Worker     size_t messageSize;
116*35238bceSAndroid Build Coastguard Worker     Message::parseHeader(&header[0], (int)header.size(), type, messageSize);
117*35238bceSAndroid Build Coastguard Worker 
118*35238bceSAndroid Build Coastguard Worker     // Simple messages without any data.
119*35238bceSAndroid Build Coastguard Worker     switch (type)
120*35238bceSAndroid Build Coastguard Worker     {
121*35238bceSAndroid Build Coastguard Worker     case MESSAGETYPE_KEEPALIVE:
122*35238bceSAndroid Build Coastguard Worker         return new KeepAliveMessage();
123*35238bceSAndroid Build Coastguard Worker     case MESSAGETYPE_PROCESS_STARTED:
124*35238bceSAndroid Build Coastguard Worker         return new ProcessStartedMessage();
125*35238bceSAndroid Build Coastguard Worker     default:
126*35238bceSAndroid Build Coastguard Worker         break; // Read message with data.
127*35238bceSAndroid Build Coastguard Worker     }
128*35238bceSAndroid Build Coastguard Worker 
129*35238bceSAndroid Build Coastguard Worker     vector<uint8_t> messageBuf;
130*35238bceSAndroid Build Coastguard Worker     readBytes(socket, messageBuf, messageSize - MESSAGE_HEADER_SIZE);
131*35238bceSAndroid Build Coastguard Worker 
132*35238bceSAndroid Build Coastguard Worker     switch (type)
133*35238bceSAndroid Build Coastguard Worker     {
134*35238bceSAndroid Build Coastguard Worker     case MESSAGETYPE_HELLO:
135*35238bceSAndroid Build Coastguard Worker         return new HelloMessage(&messageBuf[0], (int)messageBuf.size());
136*35238bceSAndroid Build Coastguard Worker     case MESSAGETYPE_TEST:
137*35238bceSAndroid Build Coastguard Worker         return new TestMessage(&messageBuf[0], (int)messageBuf.size());
138*35238bceSAndroid Build Coastguard Worker     case MESSAGETYPE_PROCESS_LOG_DATA:
139*35238bceSAndroid Build Coastguard Worker         return new ProcessLogDataMessage(&messageBuf[0], (int)messageBuf.size());
140*35238bceSAndroid Build Coastguard Worker     case MESSAGETYPE_INFO:
141*35238bceSAndroid Build Coastguard Worker         return new InfoMessage(&messageBuf[0], (int)messageBuf.size());
142*35238bceSAndroid Build Coastguard Worker     case MESSAGETYPE_PROCESS_LAUNCH_FAILED:
143*35238bceSAndroid Build Coastguard Worker         return new ProcessLaunchFailedMessage(&messageBuf[0], (int)messageBuf.size());
144*35238bceSAndroid Build Coastguard Worker     case MESSAGETYPE_PROCESS_FINISHED:
145*35238bceSAndroid Build Coastguard Worker         return new ProcessFinishedMessage(&messageBuf[0], (int)messageBuf.size());
146*35238bceSAndroid Build Coastguard Worker     default:
147*35238bceSAndroid Build Coastguard Worker         XS_FAIL("Unknown message");
148*35238bceSAndroid Build Coastguard Worker     }
149*35238bceSAndroid Build Coastguard Worker }
150*35238bceSAndroid Build Coastguard Worker 
151*35238bceSAndroid Build Coastguard Worker class TestClock
152*35238bceSAndroid Build Coastguard Worker {
153*35238bceSAndroid Build Coastguard Worker public:
TestClock(void)154*35238bceSAndroid Build Coastguard Worker     inline TestClock(void)
155*35238bceSAndroid Build Coastguard Worker     {
156*35238bceSAndroid Build Coastguard Worker         reset();
157*35238bceSAndroid Build Coastguard Worker     }
158*35238bceSAndroid Build Coastguard Worker 
reset(void)159*35238bceSAndroid Build Coastguard Worker     inline void reset(void)
160*35238bceSAndroid Build Coastguard Worker     {
161*35238bceSAndroid Build Coastguard Worker         m_initTime = deGetMicroseconds();
162*35238bceSAndroid Build Coastguard Worker     }
163*35238bceSAndroid Build Coastguard Worker 
getMilliseconds(void)164*35238bceSAndroid Build Coastguard Worker     inline int getMilliseconds(void)
165*35238bceSAndroid Build Coastguard Worker     {
166*35238bceSAndroid Build Coastguard Worker         return (int)((deGetMicroseconds() - m_initTime) / 1000);
167*35238bceSAndroid Build Coastguard Worker     }
168*35238bceSAndroid Build Coastguard Worker 
169*35238bceSAndroid Build Coastguard Worker private:
170*35238bceSAndroid Build Coastguard Worker     uint64_t m_initTime;
171*35238bceSAndroid Build Coastguard Worker };
172*35238bceSAndroid Build Coastguard Worker 
173*35238bceSAndroid Build Coastguard Worker class TestContext
174*35238bceSAndroid Build Coastguard Worker {
175*35238bceSAndroid Build Coastguard Worker public:
TestContext(void)176*35238bceSAndroid Build Coastguard Worker     TestContext(void) : startServer(false)
177*35238bceSAndroid Build Coastguard Worker     {
178*35238bceSAndroid Build Coastguard Worker     }
179*35238bceSAndroid Build Coastguard Worker 
180*35238bceSAndroid Build Coastguard Worker     std::string serverPath;
181*35238bceSAndroid Build Coastguard Worker     std::string testerPath;
182*35238bceSAndroid Build Coastguard Worker     de::SocketAddress address;
183*35238bceSAndroid Build Coastguard Worker     bool startServer;
184*35238bceSAndroid Build Coastguard Worker 
185*35238bceSAndroid Build Coastguard Worker     // Passed from execserver.
186*35238bceSAndroid Build Coastguard Worker     std::string logFileName;
187*35238bceSAndroid Build Coastguard Worker     std::string caseList;
188*35238bceSAndroid Build Coastguard Worker 
189*35238bceSAndroid Build Coastguard Worker private:
190*35238bceSAndroid Build Coastguard Worker     TestContext(const TestContext &other);
191*35238bceSAndroid Build Coastguard Worker     TestContext &operator=(const TestContext &other);
192*35238bceSAndroid Build Coastguard Worker };
193*35238bceSAndroid Build Coastguard Worker 
194*35238bceSAndroid Build Coastguard Worker class TestCase
195*35238bceSAndroid Build Coastguard Worker {
196*35238bceSAndroid Build Coastguard Worker public:
TestCase(TestContext & testCtx,const char * name)197*35238bceSAndroid Build Coastguard Worker     TestCase(TestContext &testCtx, const char *name) : m_testCtx(testCtx), m_name(name)
198*35238bceSAndroid Build Coastguard Worker     {
199*35238bceSAndroid Build Coastguard Worker     }
~TestCase(void)200*35238bceSAndroid Build Coastguard Worker     virtual ~TestCase(void)
201*35238bceSAndroid Build Coastguard Worker     {
202*35238bceSAndroid Build Coastguard Worker     }
203*35238bceSAndroid Build Coastguard Worker 
getName(void) const204*35238bceSAndroid Build Coastguard Worker     const char *getName(void) const
205*35238bceSAndroid Build Coastguard Worker     {
206*35238bceSAndroid Build Coastguard Worker         return m_name.c_str();
207*35238bceSAndroid Build Coastguard Worker     }
208*35238bceSAndroid Build Coastguard Worker 
209*35238bceSAndroid Build Coastguard Worker     virtual void runClient(de::Socket &socket) = DE_NULL;
210*35238bceSAndroid Build Coastguard Worker     virtual void runProgram(void)              = DE_NULL;
211*35238bceSAndroid Build Coastguard Worker 
212*35238bceSAndroid Build Coastguard Worker protected:
213*35238bceSAndroid Build Coastguard Worker     TestContext &m_testCtx;
214*35238bceSAndroid Build Coastguard Worker     std::string m_name;
215*35238bceSAndroid Build Coastguard Worker };
216*35238bceSAndroid Build Coastguard Worker 
217*35238bceSAndroid Build Coastguard Worker class TestExecutor
218*35238bceSAndroid Build Coastguard Worker {
219*35238bceSAndroid Build Coastguard Worker public:
220*35238bceSAndroid Build Coastguard Worker     TestExecutor(TestContext &testCtx);
221*35238bceSAndroid Build Coastguard Worker     ~TestExecutor(void);
222*35238bceSAndroid Build Coastguard Worker 
223*35238bceSAndroid Build Coastguard Worker     void runCases(const std::vector<TestCase *> &testCases);
224*35238bceSAndroid Build Coastguard Worker     bool runCase(TestCase *testCase);
225*35238bceSAndroid Build Coastguard Worker 
226*35238bceSAndroid Build Coastguard Worker private:
227*35238bceSAndroid Build Coastguard Worker     TestContext &m_testCtx;
228*35238bceSAndroid Build Coastguard Worker };
229*35238bceSAndroid Build Coastguard Worker 
TestExecutor(TestContext & testCtx)230*35238bceSAndroid Build Coastguard Worker TestExecutor::TestExecutor(TestContext &testCtx) : m_testCtx(testCtx)
231*35238bceSAndroid Build Coastguard Worker {
232*35238bceSAndroid Build Coastguard Worker }
233*35238bceSAndroid Build Coastguard Worker 
~TestExecutor(void)234*35238bceSAndroid Build Coastguard Worker TestExecutor::~TestExecutor(void)
235*35238bceSAndroid Build Coastguard Worker {
236*35238bceSAndroid Build Coastguard Worker }
237*35238bceSAndroid Build Coastguard Worker 
runCases(const std::vector<TestCase * > & testCases)238*35238bceSAndroid Build Coastguard Worker void TestExecutor::runCases(const std::vector<TestCase *> &testCases)
239*35238bceSAndroid Build Coastguard Worker {
240*35238bceSAndroid Build Coastguard Worker     int numPassed = 0;
241*35238bceSAndroid Build Coastguard Worker     int numCases  = (int)testCases.size();
242*35238bceSAndroid Build Coastguard Worker 
243*35238bceSAndroid Build Coastguard Worker     for (std::vector<TestCase *>::const_iterator i = testCases.begin(); i != testCases.end(); i++)
244*35238bceSAndroid Build Coastguard Worker     {
245*35238bceSAndroid Build Coastguard Worker         if (runCase(*i))
246*35238bceSAndroid Build Coastguard Worker             numPassed += 1;
247*35238bceSAndroid Build Coastguard Worker     }
248*35238bceSAndroid Build Coastguard Worker 
249*35238bceSAndroid Build Coastguard Worker     printf("\n  %d/%d passed!\n", numPassed, numCases);
250*35238bceSAndroid Build Coastguard Worker }
251*35238bceSAndroid Build Coastguard Worker 
252*35238bceSAndroid Build Coastguard Worker class FilePrinter : public de::Thread
253*35238bceSAndroid Build Coastguard Worker {
254*35238bceSAndroid Build Coastguard Worker public:
FilePrinter(void)255*35238bceSAndroid Build Coastguard Worker     FilePrinter(void) : m_curFile(DE_NULL)
256*35238bceSAndroid Build Coastguard Worker     {
257*35238bceSAndroid Build Coastguard Worker     }
258*35238bceSAndroid Build Coastguard Worker 
start(deFile * file)259*35238bceSAndroid Build Coastguard Worker     void start(deFile *file)
260*35238bceSAndroid Build Coastguard Worker     {
261*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(!m_curFile);
262*35238bceSAndroid Build Coastguard Worker         m_curFile = file;
263*35238bceSAndroid Build Coastguard Worker         de::Thread::start();
264*35238bceSAndroid Build Coastguard Worker     }
265*35238bceSAndroid Build Coastguard Worker 
run(void)266*35238bceSAndroid Build Coastguard Worker     void run(void)
267*35238bceSAndroid Build Coastguard Worker     {
268*35238bceSAndroid Build Coastguard Worker         char buf[256];
269*35238bceSAndroid Build Coastguard Worker         int64_t numRead = 0;
270*35238bceSAndroid Build Coastguard Worker 
271*35238bceSAndroid Build Coastguard Worker         while (deFile_read(m_curFile, &buf[0], (int64_t)sizeof(buf), &numRead) == DE_FILERESULT_SUCCESS)
272*35238bceSAndroid Build Coastguard Worker             fwrite(&buf[0], 1, (size_t)numRead, stdout);
273*35238bceSAndroid Build Coastguard Worker 
274*35238bceSAndroid Build Coastguard Worker         m_curFile = DE_NULL;
275*35238bceSAndroid Build Coastguard Worker     }
276*35238bceSAndroid Build Coastguard Worker 
277*35238bceSAndroid Build Coastguard Worker private:
278*35238bceSAndroid Build Coastguard Worker     deFile *m_curFile;
279*35238bceSAndroid Build Coastguard Worker };
280*35238bceSAndroid Build Coastguard Worker 
runCase(TestCase * testCase)281*35238bceSAndroid Build Coastguard Worker bool TestExecutor::runCase(TestCase *testCase)
282*35238bceSAndroid Build Coastguard Worker {
283*35238bceSAndroid Build Coastguard Worker     printf("%s\n", testCase->getName());
284*35238bceSAndroid Build Coastguard Worker 
285*35238bceSAndroid Build Coastguard Worker     bool success          = false;
286*35238bceSAndroid Build Coastguard Worker     deProcess *serverProc = DE_NULL;
287*35238bceSAndroid Build Coastguard Worker     FilePrinter stdoutPrinter;
288*35238bceSAndroid Build Coastguard Worker     FilePrinter stderrPrinter;
289*35238bceSAndroid Build Coastguard Worker 
290*35238bceSAndroid Build Coastguard Worker     try
291*35238bceSAndroid Build Coastguard Worker     {
292*35238bceSAndroid Build Coastguard Worker         if (m_testCtx.startServer)
293*35238bceSAndroid Build Coastguard Worker         {
294*35238bceSAndroid Build Coastguard Worker             string cmdLine = m_testCtx.serverPath + " --port=" + de::toString(m_testCtx.address.getPort());
295*35238bceSAndroid Build Coastguard Worker             serverProc     = deProcess_create();
296*35238bceSAndroid Build Coastguard Worker             XS_CHECK(serverProc);
297*35238bceSAndroid Build Coastguard Worker 
298*35238bceSAndroid Build Coastguard Worker             if (!deProcess_start(serverProc, cmdLine.c_str(), DE_NULL))
299*35238bceSAndroid Build Coastguard Worker             {
300*35238bceSAndroid Build Coastguard Worker                 string errMsg = deProcess_getLastError(serverProc);
301*35238bceSAndroid Build Coastguard Worker                 deProcess_destroy(serverProc);
302*35238bceSAndroid Build Coastguard Worker                 XS_FAIL(errMsg.c_str());
303*35238bceSAndroid Build Coastguard Worker             }
304*35238bceSAndroid Build Coastguard Worker 
305*35238bceSAndroid Build Coastguard Worker             deSleep(200); /* Give 200ms for server to start. */
306*35238bceSAndroid Build Coastguard Worker             XS_CHECK(deProcess_isRunning(serverProc));
307*35238bceSAndroid Build Coastguard Worker 
308*35238bceSAndroid Build Coastguard Worker             // Start stdout/stderr printers.
309*35238bceSAndroid Build Coastguard Worker             stdoutPrinter.start(deProcess_getStdOut(serverProc));
310*35238bceSAndroid Build Coastguard Worker             stderrPrinter.start(deProcess_getStdErr(serverProc));
311*35238bceSAndroid Build Coastguard Worker         }
312*35238bceSAndroid Build Coastguard Worker 
313*35238bceSAndroid Build Coastguard Worker         // Connect.
314*35238bceSAndroid Build Coastguard Worker         de::Socket socket;
315*35238bceSAndroid Build Coastguard Worker         socket.connect(m_testCtx.address);
316*35238bceSAndroid Build Coastguard Worker 
317*35238bceSAndroid Build Coastguard Worker         // Flags.
318*35238bceSAndroid Build Coastguard Worker         socket.setFlags(DE_SOCKET_CLOSE_ON_EXEC);
319*35238bceSAndroid Build Coastguard Worker 
320*35238bceSAndroid Build Coastguard Worker         // Run case.
321*35238bceSAndroid Build Coastguard Worker         testCase->runClient(socket);
322*35238bceSAndroid Build Coastguard Worker 
323*35238bceSAndroid Build Coastguard Worker         // Disconnect.
324*35238bceSAndroid Build Coastguard Worker         if (socket.isConnected())
325*35238bceSAndroid Build Coastguard Worker             socket.shutdown();
326*35238bceSAndroid Build Coastguard Worker 
327*35238bceSAndroid Build Coastguard Worker         // Kill server.
328*35238bceSAndroid Build Coastguard Worker         if (serverProc && deProcess_isRunning(serverProc))
329*35238bceSAndroid Build Coastguard Worker         {
330*35238bceSAndroid Build Coastguard Worker             XS_CHECK(deProcess_terminate(serverProc));
331*35238bceSAndroid Build Coastguard Worker             deSleep(100);
332*35238bceSAndroid Build Coastguard Worker             XS_CHECK(deProcess_waitForFinish(serverProc));
333*35238bceSAndroid Build Coastguard Worker 
334*35238bceSAndroid Build Coastguard Worker             stdoutPrinter.join();
335*35238bceSAndroid Build Coastguard Worker             stderrPrinter.join();
336*35238bceSAndroid Build Coastguard Worker         }
337*35238bceSAndroid Build Coastguard Worker 
338*35238bceSAndroid Build Coastguard Worker         success = true;
339*35238bceSAndroid Build Coastguard Worker     }
340*35238bceSAndroid Build Coastguard Worker     catch (const std::exception &e)
341*35238bceSAndroid Build Coastguard Worker     {
342*35238bceSAndroid Build Coastguard Worker         printf("FAIL: %s\n\n", e.what());
343*35238bceSAndroid Build Coastguard Worker     }
344*35238bceSAndroid Build Coastguard Worker 
345*35238bceSAndroid Build Coastguard Worker     if (serverProc)
346*35238bceSAndroid Build Coastguard Worker         deProcess_destroy(serverProc);
347*35238bceSAndroid Build Coastguard Worker 
348*35238bceSAndroid Build Coastguard Worker     return success;
349*35238bceSAndroid Build Coastguard Worker }
350*35238bceSAndroid Build Coastguard Worker 
351*35238bceSAndroid Build Coastguard Worker class ConnectTest : public TestCase
352*35238bceSAndroid Build Coastguard Worker {
353*35238bceSAndroid Build Coastguard Worker public:
ConnectTest(TestContext & testCtx)354*35238bceSAndroid Build Coastguard Worker     ConnectTest(TestContext &testCtx) : TestCase(testCtx, "connect")
355*35238bceSAndroid Build Coastguard Worker     {
356*35238bceSAndroid Build Coastguard Worker     }
357*35238bceSAndroid Build Coastguard Worker 
runClient(de::Socket & socket)358*35238bceSAndroid Build Coastguard Worker     void runClient(de::Socket &socket)
359*35238bceSAndroid Build Coastguard Worker     {
360*35238bceSAndroid Build Coastguard Worker         DE_UNREF(socket);
361*35238bceSAndroid Build Coastguard Worker     }
362*35238bceSAndroid Build Coastguard Worker 
runProgram(void)363*35238bceSAndroid Build Coastguard Worker     void runProgram(void)
364*35238bceSAndroid Build Coastguard Worker     { /* nothing */
365*35238bceSAndroid Build Coastguard Worker     }
366*35238bceSAndroid Build Coastguard Worker };
367*35238bceSAndroid Build Coastguard Worker 
368*35238bceSAndroid Build Coastguard Worker class HelloTest : public TestCase
369*35238bceSAndroid Build Coastguard Worker {
370*35238bceSAndroid Build Coastguard Worker public:
HelloTest(TestContext & testCtx)371*35238bceSAndroid Build Coastguard Worker     HelloTest(TestContext &testCtx) : TestCase(testCtx, "hello")
372*35238bceSAndroid Build Coastguard Worker     {
373*35238bceSAndroid Build Coastguard Worker     }
374*35238bceSAndroid Build Coastguard Worker 
runClient(de::Socket & socket)375*35238bceSAndroid Build Coastguard Worker     void runClient(de::Socket &socket)
376*35238bceSAndroid Build Coastguard Worker     {
377*35238bceSAndroid Build Coastguard Worker         xs::HelloMessage msg;
378*35238bceSAndroid Build Coastguard Worker         sendMessage(socket, (const xs::Message &)msg);
379*35238bceSAndroid Build Coastguard Worker     }
380*35238bceSAndroid Build Coastguard Worker 
runProgram(void)381*35238bceSAndroid Build Coastguard Worker     void runProgram(void)
382*35238bceSAndroid Build Coastguard Worker     { /* nothing */
383*35238bceSAndroid Build Coastguard Worker     }
384*35238bceSAndroid Build Coastguard Worker };
385*35238bceSAndroid Build Coastguard Worker 
386*35238bceSAndroid Build Coastguard Worker class ExecFailTest : public TestCase
387*35238bceSAndroid Build Coastguard Worker {
388*35238bceSAndroid Build Coastguard Worker public:
ExecFailTest(TestContext & testCtx)389*35238bceSAndroid Build Coastguard Worker     ExecFailTest(TestContext &testCtx) : TestCase(testCtx, "exec-fail")
390*35238bceSAndroid Build Coastguard Worker     {
391*35238bceSAndroid Build Coastguard Worker     }
392*35238bceSAndroid Build Coastguard Worker 
runClient(de::Socket & socket)393*35238bceSAndroid Build Coastguard Worker     void runClient(de::Socket &socket)
394*35238bceSAndroid Build Coastguard Worker     {
395*35238bceSAndroid Build Coastguard Worker         xs::ExecuteBinaryMessage execMsg;
396*35238bceSAndroid Build Coastguard Worker         execMsg.name     = "foobar-notfound";
397*35238bceSAndroid Build Coastguard Worker         execMsg.params   = "";
398*35238bceSAndroid Build Coastguard Worker         execMsg.caseList = "";
399*35238bceSAndroid Build Coastguard Worker         execMsg.workDir  = "";
400*35238bceSAndroid Build Coastguard Worker 
401*35238bceSAndroid Build Coastguard Worker         sendMessage(socket, execMsg);
402*35238bceSAndroid Build Coastguard Worker 
403*35238bceSAndroid Build Coastguard Worker         const int timeout = 100; // 100ms.
404*35238bceSAndroid Build Coastguard Worker         TestClock clock;
405*35238bceSAndroid Build Coastguard Worker 
406*35238bceSAndroid Build Coastguard Worker         for (;;)
407*35238bceSAndroid Build Coastguard Worker         {
408*35238bceSAndroid Build Coastguard Worker             if (clock.getMilliseconds() > timeout)
409*35238bceSAndroid Build Coastguard Worker                 XS_FAIL("Didn't receive PROCESS_LAUNCH_FAILED");
410*35238bceSAndroid Build Coastguard Worker 
411*35238bceSAndroid Build Coastguard Worker             ScopedMsgPtr msg(readMessage(socket));
412*35238bceSAndroid Build Coastguard Worker 
413*35238bceSAndroid Build Coastguard Worker             if (msg->type == MESSAGETYPE_PROCESS_LAUNCH_FAILED)
414*35238bceSAndroid Build Coastguard Worker                 break;
415*35238bceSAndroid Build Coastguard Worker             else if (msg->type == MESSAGETYPE_KEEPALIVE)
416*35238bceSAndroid Build Coastguard Worker                 continue;
417*35238bceSAndroid Build Coastguard Worker             else
418*35238bceSAndroid Build Coastguard Worker                 XS_FAIL("Invalid message");
419*35238bceSAndroid Build Coastguard Worker         }
420*35238bceSAndroid Build Coastguard Worker     }
421*35238bceSAndroid Build Coastguard Worker 
runProgram(void)422*35238bceSAndroid Build Coastguard Worker     void runProgram(void)
423*35238bceSAndroid Build Coastguard Worker     { /* nothing */
424*35238bceSAndroid Build Coastguard Worker     }
425*35238bceSAndroid Build Coastguard Worker };
426*35238bceSAndroid Build Coastguard Worker 
427*35238bceSAndroid Build Coastguard Worker class SimpleExecTest : public TestCase
428*35238bceSAndroid Build Coastguard Worker {
429*35238bceSAndroid Build Coastguard Worker public:
SimpleExecTest(TestContext & testCtx)430*35238bceSAndroid Build Coastguard Worker     SimpleExecTest(TestContext &testCtx) : TestCase(testCtx, "simple-exec")
431*35238bceSAndroid Build Coastguard Worker     {
432*35238bceSAndroid Build Coastguard Worker     }
433*35238bceSAndroid Build Coastguard Worker 
runClient(de::Socket & socket)434*35238bceSAndroid Build Coastguard Worker     void runClient(de::Socket &socket)
435*35238bceSAndroid Build Coastguard Worker     {
436*35238bceSAndroid Build Coastguard Worker         xs::ExecuteBinaryMessage execMsg;
437*35238bceSAndroid Build Coastguard Worker         execMsg.name     = m_testCtx.testerPath;
438*35238bceSAndroid Build Coastguard Worker         execMsg.params   = "--program=simple-exec";
439*35238bceSAndroid Build Coastguard Worker         execMsg.caseList = "";
440*35238bceSAndroid Build Coastguard Worker         execMsg.workDir  = "";
441*35238bceSAndroid Build Coastguard Worker 
442*35238bceSAndroid Build Coastguard Worker         sendMessage(socket, execMsg);
443*35238bceSAndroid Build Coastguard Worker 
444*35238bceSAndroid Build Coastguard Worker         const int timeout = 5000; // 5s.
445*35238bceSAndroid Build Coastguard Worker         TestClock clock;
446*35238bceSAndroid Build Coastguard Worker 
447*35238bceSAndroid Build Coastguard Worker         bool gotProcessStarted  = false;
448*35238bceSAndroid Build Coastguard Worker         bool gotProcessFinished = false;
449*35238bceSAndroid Build Coastguard Worker 
450*35238bceSAndroid Build Coastguard Worker         for (;;)
451*35238bceSAndroid Build Coastguard Worker         {
452*35238bceSAndroid Build Coastguard Worker             if (clock.getMilliseconds() > timeout)
453*35238bceSAndroid Build Coastguard Worker                 break;
454*35238bceSAndroid Build Coastguard Worker 
455*35238bceSAndroid Build Coastguard Worker             ScopedMsgPtr msg(readMessage(socket));
456*35238bceSAndroid Build Coastguard Worker 
457*35238bceSAndroid Build Coastguard Worker             if (msg->type == MESSAGETYPE_PROCESS_STARTED)
458*35238bceSAndroid Build Coastguard Worker                 gotProcessStarted = true;
459*35238bceSAndroid Build Coastguard Worker             else if (msg->type == MESSAGETYPE_PROCESS_LAUNCH_FAILED)
460*35238bceSAndroid Build Coastguard Worker                 XS_FAIL("Got PROCESS_LAUNCH_FAILED");
461*35238bceSAndroid Build Coastguard Worker             else if (gotProcessStarted && msg->type == MESSAGETYPE_PROCESS_FINISHED)
462*35238bceSAndroid Build Coastguard Worker             {
463*35238bceSAndroid Build Coastguard Worker                 gotProcessFinished = true;
464*35238bceSAndroid Build Coastguard Worker                 break;
465*35238bceSAndroid Build Coastguard Worker             }
466*35238bceSAndroid Build Coastguard Worker             else if (msg->type == MESSAGETYPE_KEEPALIVE || msg->type == MESSAGETYPE_INFO)
467*35238bceSAndroid Build Coastguard Worker                 continue;
468*35238bceSAndroid Build Coastguard Worker             else
469*35238bceSAndroid Build Coastguard Worker                 XS_FAIL((string("Invalid message: ") + de::toString(msg->type)).c_str());
470*35238bceSAndroid Build Coastguard Worker         }
471*35238bceSAndroid Build Coastguard Worker 
472*35238bceSAndroid Build Coastguard Worker         if (!gotProcessStarted)
473*35238bceSAndroid Build Coastguard Worker             XS_FAIL("Did't get PROCESS_STARTED message");
474*35238bceSAndroid Build Coastguard Worker 
475*35238bceSAndroid Build Coastguard Worker         if (!gotProcessFinished)
476*35238bceSAndroid Build Coastguard Worker             XS_FAIL("Did't get PROCESS_FINISHED message");
477*35238bceSAndroid Build Coastguard Worker     }
478*35238bceSAndroid Build Coastguard Worker 
runProgram(void)479*35238bceSAndroid Build Coastguard Worker     void runProgram(void)
480*35238bceSAndroid Build Coastguard Worker     { /* print nothing. */
481*35238bceSAndroid Build Coastguard Worker     }
482*35238bceSAndroid Build Coastguard Worker };
483*35238bceSAndroid Build Coastguard Worker 
484*35238bceSAndroid Build Coastguard Worker class InfoTest : public TestCase
485*35238bceSAndroid Build Coastguard Worker {
486*35238bceSAndroid Build Coastguard Worker public:
487*35238bceSAndroid Build Coastguard Worker     std::string infoStr;
488*35238bceSAndroid Build Coastguard Worker 
InfoTest(TestContext & testCtx)489*35238bceSAndroid Build Coastguard Worker     InfoTest(TestContext &testCtx) : TestCase(testCtx, "info"), infoStr("Hello, World")
490*35238bceSAndroid Build Coastguard Worker     {
491*35238bceSAndroid Build Coastguard Worker     }
492*35238bceSAndroid Build Coastguard Worker 
runClient(de::Socket & socket)493*35238bceSAndroid Build Coastguard Worker     void runClient(de::Socket &socket)
494*35238bceSAndroid Build Coastguard Worker     {
495*35238bceSAndroid Build Coastguard Worker         xs::ExecuteBinaryMessage execMsg;
496*35238bceSAndroid Build Coastguard Worker         execMsg.name     = m_testCtx.testerPath;
497*35238bceSAndroid Build Coastguard Worker         execMsg.params   = "--program=info";
498*35238bceSAndroid Build Coastguard Worker         execMsg.caseList = "";
499*35238bceSAndroid Build Coastguard Worker         execMsg.workDir  = "";
500*35238bceSAndroid Build Coastguard Worker 
501*35238bceSAndroid Build Coastguard Worker         sendMessage(socket, execMsg);
502*35238bceSAndroid Build Coastguard Worker 
503*35238bceSAndroid Build Coastguard Worker         const int timeout = 10000; // 10s.
504*35238bceSAndroid Build Coastguard Worker         TestClock clock;
505*35238bceSAndroid Build Coastguard Worker 
506*35238bceSAndroid Build Coastguard Worker         bool gotProcessStarted   = false;
507*35238bceSAndroid Build Coastguard Worker         bool gotProcessFinished  = false;
508*35238bceSAndroid Build Coastguard Worker         std::string receivedInfo = "";
509*35238bceSAndroid Build Coastguard Worker 
510*35238bceSAndroid Build Coastguard Worker         for (;;)
511*35238bceSAndroid Build Coastguard Worker         {
512*35238bceSAndroid Build Coastguard Worker             if (clock.getMilliseconds() > timeout)
513*35238bceSAndroid Build Coastguard Worker                 break;
514*35238bceSAndroid Build Coastguard Worker 
515*35238bceSAndroid Build Coastguard Worker             ScopedMsgPtr msg(readMessage(socket));
516*35238bceSAndroid Build Coastguard Worker 
517*35238bceSAndroid Build Coastguard Worker             if (msg->type == MESSAGETYPE_PROCESS_STARTED)
518*35238bceSAndroid Build Coastguard Worker                 gotProcessStarted = true;
519*35238bceSAndroid Build Coastguard Worker             else if (msg->type == MESSAGETYPE_PROCESS_LAUNCH_FAILED)
520*35238bceSAndroid Build Coastguard Worker                 XS_FAIL("Got PROCESS_LAUNCH_FAILED");
521*35238bceSAndroid Build Coastguard Worker             else if (gotProcessStarted && msg->type == MESSAGETYPE_INFO)
522*35238bceSAndroid Build Coastguard Worker                 receivedInfo += static_cast<const InfoMessage *>(msg.get())->info;
523*35238bceSAndroid Build Coastguard Worker             else if (gotProcessStarted && msg->type == MESSAGETYPE_PROCESS_FINISHED)
524*35238bceSAndroid Build Coastguard Worker             {
525*35238bceSAndroid Build Coastguard Worker                 gotProcessFinished = true;
526*35238bceSAndroid Build Coastguard Worker                 break;
527*35238bceSAndroid Build Coastguard Worker             }
528*35238bceSAndroid Build Coastguard Worker             else if (msg->type == MESSAGETYPE_KEEPALIVE)
529*35238bceSAndroid Build Coastguard Worker                 continue;
530*35238bceSAndroid Build Coastguard Worker             else
531*35238bceSAndroid Build Coastguard Worker                 XS_FAIL("Invalid message");
532*35238bceSAndroid Build Coastguard Worker         }
533*35238bceSAndroid Build Coastguard Worker 
534*35238bceSAndroid Build Coastguard Worker         if (!gotProcessStarted)
535*35238bceSAndroid Build Coastguard Worker             XS_FAIL("Did't get PROCESS_STARTED message");
536*35238bceSAndroid Build Coastguard Worker 
537*35238bceSAndroid Build Coastguard Worker         if (!gotProcessFinished)
538*35238bceSAndroid Build Coastguard Worker             XS_FAIL("Did't get PROCESS_FINISHED message");
539*35238bceSAndroid Build Coastguard Worker 
540*35238bceSAndroid Build Coastguard Worker         if (receivedInfo != infoStr)
541*35238bceSAndroid Build Coastguard Worker             XS_FAIL("Info data doesn't match");
542*35238bceSAndroid Build Coastguard Worker     }
543*35238bceSAndroid Build Coastguard Worker 
runProgram(void)544*35238bceSAndroid Build Coastguard Worker     void runProgram(void)
545*35238bceSAndroid Build Coastguard Worker     {
546*35238bceSAndroid Build Coastguard Worker         printf("%s", infoStr.c_str());
547*35238bceSAndroid Build Coastguard Worker     }
548*35238bceSAndroid Build Coastguard Worker };
549*35238bceSAndroid Build Coastguard Worker 
550*35238bceSAndroid Build Coastguard Worker class LogDataTest : public TestCase
551*35238bceSAndroid Build Coastguard Worker {
552*35238bceSAndroid Build Coastguard Worker public:
LogDataTest(TestContext & testCtx)553*35238bceSAndroid Build Coastguard Worker     LogDataTest(TestContext &testCtx) : TestCase(testCtx, "logdata")
554*35238bceSAndroid Build Coastguard Worker     {
555*35238bceSAndroid Build Coastguard Worker     }
556*35238bceSAndroid Build Coastguard Worker 
runClient(de::Socket & socket)557*35238bceSAndroid Build Coastguard Worker     void runClient(de::Socket &socket)
558*35238bceSAndroid Build Coastguard Worker     {
559*35238bceSAndroid Build Coastguard Worker         xs::ExecuteBinaryMessage execMsg;
560*35238bceSAndroid Build Coastguard Worker         execMsg.name     = m_testCtx.testerPath;
561*35238bceSAndroid Build Coastguard Worker         execMsg.params   = "--program=logdata";
562*35238bceSAndroid Build Coastguard Worker         execMsg.caseList = "";
563*35238bceSAndroid Build Coastguard Worker         execMsg.workDir  = "";
564*35238bceSAndroid Build Coastguard Worker 
565*35238bceSAndroid Build Coastguard Worker         sendMessage(socket, execMsg);
566*35238bceSAndroid Build Coastguard Worker 
567*35238bceSAndroid Build Coastguard Worker         const int timeout = 10000; // 10s.
568*35238bceSAndroid Build Coastguard Worker         TestClock clock;
569*35238bceSAndroid Build Coastguard Worker 
570*35238bceSAndroid Build Coastguard Worker         bool gotProcessStarted   = false;
571*35238bceSAndroid Build Coastguard Worker         bool gotProcessFinished  = false;
572*35238bceSAndroid Build Coastguard Worker         std::string receivedData = "";
573*35238bceSAndroid Build Coastguard Worker 
574*35238bceSAndroid Build Coastguard Worker         for (;;)
575*35238bceSAndroid Build Coastguard Worker         {
576*35238bceSAndroid Build Coastguard Worker             if (clock.getMilliseconds() > timeout)
577*35238bceSAndroid Build Coastguard Worker                 break;
578*35238bceSAndroid Build Coastguard Worker 
579*35238bceSAndroid Build Coastguard Worker             ScopedMsgPtr msg(readMessage(socket));
580*35238bceSAndroid Build Coastguard Worker 
581*35238bceSAndroid Build Coastguard Worker             if (msg->type == MESSAGETYPE_PROCESS_STARTED)
582*35238bceSAndroid Build Coastguard Worker                 gotProcessStarted = true;
583*35238bceSAndroid Build Coastguard Worker             else if (msg->type == MESSAGETYPE_PROCESS_LAUNCH_FAILED)
584*35238bceSAndroid Build Coastguard Worker                 XS_FAIL("Got PROCESS_LAUNCH_FAILED");
585*35238bceSAndroid Build Coastguard Worker             else if (gotProcessStarted && msg->type == MESSAGETYPE_PROCESS_LOG_DATA)
586*35238bceSAndroid Build Coastguard Worker                 receivedData += static_cast<const ProcessLogDataMessage *>(msg.get())->logData;
587*35238bceSAndroid Build Coastguard Worker             else if (gotProcessStarted && msg->type == MESSAGETYPE_PROCESS_FINISHED)
588*35238bceSAndroid Build Coastguard Worker             {
589*35238bceSAndroid Build Coastguard Worker                 gotProcessFinished = true;
590*35238bceSAndroid Build Coastguard Worker                 break;
591*35238bceSAndroid Build Coastguard Worker             }
592*35238bceSAndroid Build Coastguard Worker             else if (msg->type == MESSAGETYPE_KEEPALIVE)
593*35238bceSAndroid Build Coastguard Worker                 continue;
594*35238bceSAndroid Build Coastguard Worker             else if (msg->type == MESSAGETYPE_INFO)
595*35238bceSAndroid Build Coastguard Worker                 XS_FAIL(static_cast<const InfoMessage *>(msg.get())->info.c_str());
596*35238bceSAndroid Build Coastguard Worker             else
597*35238bceSAndroid Build Coastguard Worker                 XS_FAIL("Invalid message");
598*35238bceSAndroid Build Coastguard Worker         }
599*35238bceSAndroid Build Coastguard Worker 
600*35238bceSAndroid Build Coastguard Worker         if (!gotProcessStarted)
601*35238bceSAndroid Build Coastguard Worker             XS_FAIL("Did't get PROCESS_STARTED message");
602*35238bceSAndroid Build Coastguard Worker 
603*35238bceSAndroid Build Coastguard Worker         if (!gotProcessFinished)
604*35238bceSAndroid Build Coastguard Worker             XS_FAIL("Did't get PROCESS_FINISHED message");
605*35238bceSAndroid Build Coastguard Worker 
606*35238bceSAndroid Build Coastguard Worker         const char *expected = "Foo\nBar\n";
607*35238bceSAndroid Build Coastguard Worker         if (receivedData != expected)
608*35238bceSAndroid Build Coastguard Worker         {
609*35238bceSAndroid Build Coastguard Worker             printf("  received: '%s'\n  expected: '%s'\n", receivedData.c_str(), expected);
610*35238bceSAndroid Build Coastguard Worker             XS_FAIL("Log data doesn't match");
611*35238bceSAndroid Build Coastguard Worker         }
612*35238bceSAndroid Build Coastguard Worker     }
613*35238bceSAndroid Build Coastguard Worker 
runProgram(void)614*35238bceSAndroid Build Coastguard Worker     void runProgram(void)
615*35238bceSAndroid Build Coastguard Worker     {
616*35238bceSAndroid Build Coastguard Worker         deFile *file = deFile_create(m_testCtx.logFileName.c_str(),
617*35238bceSAndroid Build Coastguard Worker                                      DE_FILEMODE_OPEN | DE_FILEMODE_CREATE | DE_FILEMODE_TRUNCATE | DE_FILEMODE_WRITE);
618*35238bceSAndroid Build Coastguard Worker         XS_CHECK(file);
619*35238bceSAndroid Build Coastguard Worker 
620*35238bceSAndroid Build Coastguard Worker         const char line0[] = "Foo\n";
621*35238bceSAndroid Build Coastguard Worker         const char line1[] = "Bar\n";
622*35238bceSAndroid Build Coastguard Worker         int64_t numWritten = 0;
623*35238bceSAndroid Build Coastguard Worker 
624*35238bceSAndroid Build Coastguard Worker         // Write first line.
625*35238bceSAndroid Build Coastguard Worker         XS_CHECK(deFile_write(file, line0, sizeof(line0) - 1, &numWritten) == DE_FILERESULT_SUCCESS);
626*35238bceSAndroid Build Coastguard Worker         XS_CHECK(numWritten == sizeof(line0) - 1);
627*35238bceSAndroid Build Coastguard Worker 
628*35238bceSAndroid Build Coastguard Worker         // Sleep for 0.5s and write line 2.
629*35238bceSAndroid Build Coastguard Worker         deSleep(500);
630*35238bceSAndroid Build Coastguard Worker         XS_CHECK(deFile_write(file, line1, sizeof(line1) - 1, &numWritten) == DE_FILERESULT_SUCCESS);
631*35238bceSAndroid Build Coastguard Worker         XS_CHECK(numWritten == sizeof(line1) - 1);
632*35238bceSAndroid Build Coastguard Worker 
633*35238bceSAndroid Build Coastguard Worker         deFile_destroy(file);
634*35238bceSAndroid Build Coastguard Worker     }
635*35238bceSAndroid Build Coastguard Worker };
636*35238bceSAndroid Build Coastguard Worker 
637*35238bceSAndroid Build Coastguard Worker class BigLogDataTest : public TestCase
638*35238bceSAndroid Build Coastguard Worker {
639*35238bceSAndroid Build Coastguard Worker public:
640*35238bceSAndroid Build Coastguard Worker     enum
641*35238bceSAndroid Build Coastguard Worker     {
642*35238bceSAndroid Build Coastguard Worker         DATA_SIZE = 100 * 1024 * 1024
643*35238bceSAndroid Build Coastguard Worker     };
644*35238bceSAndroid Build Coastguard Worker 
BigLogDataTest(TestContext & testCtx)645*35238bceSAndroid Build Coastguard Worker     BigLogDataTest(TestContext &testCtx) : TestCase(testCtx, "biglogdata")
646*35238bceSAndroid Build Coastguard Worker     {
647*35238bceSAndroid Build Coastguard Worker     }
648*35238bceSAndroid Build Coastguard Worker 
runClient(de::Socket & socket)649*35238bceSAndroid Build Coastguard Worker     void runClient(de::Socket &socket)
650*35238bceSAndroid Build Coastguard Worker     {
651*35238bceSAndroid Build Coastguard Worker         xs::ExecuteBinaryMessage execMsg;
652*35238bceSAndroid Build Coastguard Worker         execMsg.name     = m_testCtx.testerPath;
653*35238bceSAndroid Build Coastguard Worker         execMsg.params   = "--program=biglogdata";
654*35238bceSAndroid Build Coastguard Worker         execMsg.caseList = "";
655*35238bceSAndroid Build Coastguard Worker         execMsg.workDir  = "";
656*35238bceSAndroid Build Coastguard Worker 
657*35238bceSAndroid Build Coastguard Worker         sendMessage(socket, execMsg);
658*35238bceSAndroid Build Coastguard Worker 
659*35238bceSAndroid Build Coastguard Worker         const int timeout = 30000; // 30s.
660*35238bceSAndroid Build Coastguard Worker         TestClock clock;
661*35238bceSAndroid Build Coastguard Worker 
662*35238bceSAndroid Build Coastguard Worker         bool gotProcessStarted  = false;
663*35238bceSAndroid Build Coastguard Worker         bool gotProcessFinished = false;
664*35238bceSAndroid Build Coastguard Worker         int receivedBytes       = 0;
665*35238bceSAndroid Build Coastguard Worker 
666*35238bceSAndroid Build Coastguard Worker         for (;;)
667*35238bceSAndroid Build Coastguard Worker         {
668*35238bceSAndroid Build Coastguard Worker             if (clock.getMilliseconds() > timeout)
669*35238bceSAndroid Build Coastguard Worker                 break;
670*35238bceSAndroid Build Coastguard Worker 
671*35238bceSAndroid Build Coastguard Worker             ScopedMsgPtr msg(readMessage(socket));
672*35238bceSAndroid Build Coastguard Worker 
673*35238bceSAndroid Build Coastguard Worker             if (msg->type == MESSAGETYPE_PROCESS_STARTED)
674*35238bceSAndroid Build Coastguard Worker                 gotProcessStarted = true;
675*35238bceSAndroid Build Coastguard Worker             else if (msg->type == MESSAGETYPE_PROCESS_LAUNCH_FAILED)
676*35238bceSAndroid Build Coastguard Worker                 XS_FAIL("Got PROCESS_LAUNCH_FAILED");
677*35238bceSAndroid Build Coastguard Worker             else if (gotProcessStarted && msg->type == MESSAGETYPE_PROCESS_LOG_DATA)
678*35238bceSAndroid Build Coastguard Worker                 receivedBytes += (int)static_cast<const ProcessLogDataMessage *>(msg.get())->logData.length();
679*35238bceSAndroid Build Coastguard Worker             else if (gotProcessStarted && msg->type == MESSAGETYPE_PROCESS_FINISHED)
680*35238bceSAndroid Build Coastguard Worker             {
681*35238bceSAndroid Build Coastguard Worker                 gotProcessFinished = true;
682*35238bceSAndroid Build Coastguard Worker                 break;
683*35238bceSAndroid Build Coastguard Worker             }
684*35238bceSAndroid Build Coastguard Worker             else if (msg->type == MESSAGETYPE_KEEPALIVE)
685*35238bceSAndroid Build Coastguard Worker             {
686*35238bceSAndroid Build Coastguard Worker                 // Reply with keepalive.
687*35238bceSAndroid Build Coastguard Worker                 sendMessage(socket, KeepAliveMessage());
688*35238bceSAndroid Build Coastguard Worker                 continue;
689*35238bceSAndroid Build Coastguard Worker             }
690*35238bceSAndroid Build Coastguard Worker             else if (msg->type == MESSAGETYPE_INFO)
691*35238bceSAndroid Build Coastguard Worker                 printf("%s", static_cast<const InfoMessage *>(msg.get())->info.c_str());
692*35238bceSAndroid Build Coastguard Worker             else
693*35238bceSAndroid Build Coastguard Worker                 XS_FAIL("Invalid message");
694*35238bceSAndroid Build Coastguard Worker         }
695*35238bceSAndroid Build Coastguard Worker 
696*35238bceSAndroid Build Coastguard Worker         if (!gotProcessStarted)
697*35238bceSAndroid Build Coastguard Worker             XS_FAIL("Did't get PROCESS_STARTED message");
698*35238bceSAndroid Build Coastguard Worker 
699*35238bceSAndroid Build Coastguard Worker         if (!gotProcessFinished)
700*35238bceSAndroid Build Coastguard Worker             XS_FAIL("Did't get PROCESS_FINISHED message");
701*35238bceSAndroid Build Coastguard Worker 
702*35238bceSAndroid Build Coastguard Worker         if (receivedBytes != DATA_SIZE)
703*35238bceSAndroid Build Coastguard Worker         {
704*35238bceSAndroid Build Coastguard Worker             printf("  received: %d bytes\n  expected: %d bytes\n", receivedBytes, DATA_SIZE);
705*35238bceSAndroid Build Coastguard Worker             XS_FAIL("Log data size doesn't match");
706*35238bceSAndroid Build Coastguard Worker         }
707*35238bceSAndroid Build Coastguard Worker 
708*35238bceSAndroid Build Coastguard Worker         int timeMs = clock.getMilliseconds();
709*35238bceSAndroid Build Coastguard Worker         printf("  Streamed %d bytes in %d ms: %.2f MiB/s\n", DATA_SIZE, timeMs,
710*35238bceSAndroid Build Coastguard Worker                ((float)DATA_SIZE / (float)(1024 * 1024)) / ((float)timeMs / 1000.0f));
711*35238bceSAndroid Build Coastguard Worker     }
712*35238bceSAndroid Build Coastguard Worker 
runProgram(void)713*35238bceSAndroid Build Coastguard Worker     void runProgram(void)
714*35238bceSAndroid Build Coastguard Worker     {
715*35238bceSAndroid Build Coastguard Worker         deFile *file = deFile_create(m_testCtx.logFileName.c_str(),
716*35238bceSAndroid Build Coastguard Worker                                      DE_FILEMODE_OPEN | DE_FILEMODE_CREATE | DE_FILEMODE_TRUNCATE | DE_FILEMODE_WRITE);
717*35238bceSAndroid Build Coastguard Worker         XS_CHECK(file);
718*35238bceSAndroid Build Coastguard Worker 
719*35238bceSAndroid Build Coastguard Worker         uint8_t tmpBuf[1024 * 16];
720*35238bceSAndroid Build Coastguard Worker         int numWritten = 0;
721*35238bceSAndroid Build Coastguard Worker 
722*35238bceSAndroid Build Coastguard Worker         deMemset(&tmpBuf, 'a', sizeof(tmpBuf));
723*35238bceSAndroid Build Coastguard Worker 
724*35238bceSAndroid Build Coastguard Worker         while (numWritten < DATA_SIZE)
725*35238bceSAndroid Build Coastguard Worker         {
726*35238bceSAndroid Build Coastguard Worker             int64_t numWrittenInBatch = 0;
727*35238bceSAndroid Build Coastguard Worker             XS_CHECK(deFile_write(file, &tmpBuf[0], de::min((int)sizeof(tmpBuf), DATA_SIZE - numWritten),
728*35238bceSAndroid Build Coastguard Worker                                   &numWrittenInBatch) == DE_FILERESULT_SUCCESS);
729*35238bceSAndroid Build Coastguard Worker             numWritten += (int)numWrittenInBatch;
730*35238bceSAndroid Build Coastguard Worker         }
731*35238bceSAndroid Build Coastguard Worker 
732*35238bceSAndroid Build Coastguard Worker         deFile_destroy(file);
733*35238bceSAndroid Build Coastguard Worker     }
734*35238bceSAndroid Build Coastguard Worker };
735*35238bceSAndroid Build Coastguard Worker 
736*35238bceSAndroid Build Coastguard Worker class KeepAliveTest : public TestCase
737*35238bceSAndroid Build Coastguard Worker {
738*35238bceSAndroid Build Coastguard Worker public:
KeepAliveTest(TestContext & testCtx)739*35238bceSAndroid Build Coastguard Worker     KeepAliveTest(TestContext &testCtx) : TestCase(testCtx, "keepalive")
740*35238bceSAndroid Build Coastguard Worker     {
741*35238bceSAndroid Build Coastguard Worker     }
742*35238bceSAndroid Build Coastguard Worker 
runClient(de::Socket & socket)743*35238bceSAndroid Build Coastguard Worker     void runClient(de::Socket &socket)
744*35238bceSAndroid Build Coastguard Worker     {
745*35238bceSAndroid Build Coastguard Worker         // In milliseconds.
746*35238bceSAndroid Build Coastguard Worker         const int sendInterval       = 5000;
747*35238bceSAndroid Build Coastguard Worker         const int minReceiveInterval = 10000;
748*35238bceSAndroid Build Coastguard Worker         const int testTime           = 30000;
749*35238bceSAndroid Build Coastguard Worker         const int sleepTime          = 200;
750*35238bceSAndroid Build Coastguard Worker         const int expectedTimeout    = 40000;
751*35238bceSAndroid Build Coastguard Worker         int curTime                  = 0;
752*35238bceSAndroid Build Coastguard Worker         int lastSendTime             = 0;
753*35238bceSAndroid Build Coastguard Worker         int lastReceiveTime          = 0;
754*35238bceSAndroid Build Coastguard Worker         TestClock clock;
755*35238bceSAndroid Build Coastguard Worker 
756*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(sendInterval < minReceiveInterval);
757*35238bceSAndroid Build Coastguard Worker 
758*35238bceSAndroid Build Coastguard Worker         curTime = clock.getMilliseconds();
759*35238bceSAndroid Build Coastguard Worker 
760*35238bceSAndroid Build Coastguard Worker         while (curTime < testTime)
761*35238bceSAndroid Build Coastguard Worker         {
762*35238bceSAndroid Build Coastguard Worker             bool tryGetKeepalive = false;
763*35238bceSAndroid Build Coastguard Worker 
764*35238bceSAndroid Build Coastguard Worker             if (curTime - lastSendTime > sendInterval)
765*35238bceSAndroid Build Coastguard Worker             {
766*35238bceSAndroid Build Coastguard Worker                 printf("  %d ms: sending keepalive\n", curTime);
767*35238bceSAndroid Build Coastguard Worker                 sendMessage(socket, KeepAliveMessage());
768*35238bceSAndroid Build Coastguard Worker                 curTime         = clock.getMilliseconds();
769*35238bceSAndroid Build Coastguard Worker                 lastSendTime    = curTime;
770*35238bceSAndroid Build Coastguard Worker                 tryGetKeepalive = true;
771*35238bceSAndroid Build Coastguard Worker             }
772*35238bceSAndroid Build Coastguard Worker 
773*35238bceSAndroid Build Coastguard Worker             if (tryGetKeepalive)
774*35238bceSAndroid Build Coastguard Worker             {
775*35238bceSAndroid Build Coastguard Worker                 // Try to acquire keepalive.
776*35238bceSAndroid Build Coastguard Worker                 printf("  %d ms: waiting for keepalive\n", curTime);
777*35238bceSAndroid Build Coastguard Worker                 ScopedMsgPtr msg(readMessage(socket));
778*35238bceSAndroid Build Coastguard Worker                 int recvTime = clock.getMilliseconds();
779*35238bceSAndroid Build Coastguard Worker 
780*35238bceSAndroid Build Coastguard Worker                 if (msg->type != MESSAGETYPE_KEEPALIVE)
781*35238bceSAndroid Build Coastguard Worker                     XS_FAIL("Got invalid message");
782*35238bceSAndroid Build Coastguard Worker 
783*35238bceSAndroid Build Coastguard Worker                 printf("  %d ms: got keepalive\n", curTime);
784*35238bceSAndroid Build Coastguard Worker 
785*35238bceSAndroid Build Coastguard Worker                 if (recvTime - lastReceiveTime > minReceiveInterval)
786*35238bceSAndroid Build Coastguard Worker                     XS_FAIL("Server doesn't send keepalives");
787*35238bceSAndroid Build Coastguard Worker 
788*35238bceSAndroid Build Coastguard Worker                 lastReceiveTime = recvTime;
789*35238bceSAndroid Build Coastguard Worker             }
790*35238bceSAndroid Build Coastguard Worker 
791*35238bceSAndroid Build Coastguard Worker             deSleep(sleepTime);
792*35238bceSAndroid Build Coastguard Worker             curTime = clock.getMilliseconds();
793*35238bceSAndroid Build Coastguard Worker         }
794*35238bceSAndroid Build Coastguard Worker 
795*35238bceSAndroid Build Coastguard Worker         // Verify that server actually kills the connection upon timeout.
796*35238bceSAndroid Build Coastguard Worker         sendMessage(socket, KeepAliveMessage());
797*35238bceSAndroid Build Coastguard Worker         printf("  waiting %d ms for keepalive timeout...\n", expectedTimeout);
798*35238bceSAndroid Build Coastguard Worker         bool isClosed = false;
799*35238bceSAndroid Build Coastguard Worker 
800*35238bceSAndroid Build Coastguard Worker         try
801*35238bceSAndroid Build Coastguard Worker         {
802*35238bceSAndroid Build Coastguard Worker             // Reset timer.
803*35238bceSAndroid Build Coastguard Worker             clock.reset();
804*35238bceSAndroid Build Coastguard Worker             curTime = clock.getMilliseconds();
805*35238bceSAndroid Build Coastguard Worker 
806*35238bceSAndroid Build Coastguard Worker             while (curTime < expectedTimeout)
807*35238bceSAndroid Build Coastguard Worker             {
808*35238bceSAndroid Build Coastguard Worker                 // Try to get keepalive message.
809*35238bceSAndroid Build Coastguard Worker                 ScopedMsgPtr msg(readMessage(socket));
810*35238bceSAndroid Build Coastguard Worker                 if (msg->type != MESSAGETYPE_KEEPALIVE)
811*35238bceSAndroid Build Coastguard Worker                     XS_FAIL("Got invalid message");
812*35238bceSAndroid Build Coastguard Worker 
813*35238bceSAndroid Build Coastguard Worker                 curTime = clock.getMilliseconds();
814*35238bceSAndroid Build Coastguard Worker                 printf("  %d ms: got keepalive\n", curTime);
815*35238bceSAndroid Build Coastguard Worker             }
816*35238bceSAndroid Build Coastguard Worker         }
817*35238bceSAndroid Build Coastguard Worker         catch (const SocketError &e)
818*35238bceSAndroid Build Coastguard Worker         {
819*35238bceSAndroid Build Coastguard Worker             if (e.getResult() == DE_SOCKETRESULT_CONNECTION_CLOSED)
820*35238bceSAndroid Build Coastguard Worker             {
821*35238bceSAndroid Build Coastguard Worker                 printf("  %d ms: server closed connection", clock.getMilliseconds());
822*35238bceSAndroid Build Coastguard Worker                 isClosed = true;
823*35238bceSAndroid Build Coastguard Worker             }
824*35238bceSAndroid Build Coastguard Worker             else
825*35238bceSAndroid Build Coastguard Worker                 throw;
826*35238bceSAndroid Build Coastguard Worker         }
827*35238bceSAndroid Build Coastguard Worker 
828*35238bceSAndroid Build Coastguard Worker         if (isClosed)
829*35238bceSAndroid Build Coastguard Worker             printf("  ok!\n");
830*35238bceSAndroid Build Coastguard Worker         else
831*35238bceSAndroid Build Coastguard Worker             XS_FAIL("Server didn't close connection");
832*35238bceSAndroid Build Coastguard Worker     }
833*35238bceSAndroid Build Coastguard Worker 
runProgram(void)834*35238bceSAndroid Build Coastguard Worker     void runProgram(void)
835*35238bceSAndroid Build Coastguard Worker     { /* nothing */
836*35238bceSAndroid Build Coastguard Worker     }
837*35238bceSAndroid Build Coastguard Worker };
838*35238bceSAndroid Build Coastguard Worker 
printHelp(const char * binName)839*35238bceSAndroid Build Coastguard Worker void printHelp(const char *binName)
840*35238bceSAndroid Build Coastguard Worker {
841*35238bceSAndroid Build Coastguard Worker     printf("%s:\n", binName);
842*35238bceSAndroid Build Coastguard Worker     printf("  --client=[name]       Run test [name]\n");
843*35238bceSAndroid Build Coastguard Worker     printf("  --program=[name]      Run program for test [name]\n");
844*35238bceSAndroid Build Coastguard Worker     printf("  --host=[host]         Connect to host [host]\n");
845*35238bceSAndroid Build Coastguard Worker     printf("  --port=[name]         Use port [port]\n");
846*35238bceSAndroid Build Coastguard Worker     printf("  --tester-cmd=[cmd]    Launch tester with [cmd]\n");
847*35238bceSAndroid Build Coastguard Worker     printf("  --server-cmd=[cmd]    Launch server with [cmd]\n");
848*35238bceSAndroid Build Coastguard Worker     printf("  --start-server        Start server for test execution\n");
849*35238bceSAndroid Build Coastguard Worker }
850*35238bceSAndroid Build Coastguard Worker 
851*35238bceSAndroid Build Coastguard Worker struct CompareCaseName
852*35238bceSAndroid Build Coastguard Worker {
853*35238bceSAndroid Build Coastguard Worker     std::string name;
854*35238bceSAndroid Build Coastguard Worker 
CompareCaseNamexs::CompareCaseName855*35238bceSAndroid Build Coastguard Worker     CompareCaseName(const string &name_) : name(name_)
856*35238bceSAndroid Build Coastguard Worker     {
857*35238bceSAndroid Build Coastguard Worker     }
858*35238bceSAndroid Build Coastguard Worker 
operator ()xs::CompareCaseName859*35238bceSAndroid Build Coastguard Worker     bool operator()(const TestCase *testCase) const
860*35238bceSAndroid Build Coastguard Worker     {
861*35238bceSAndroid Build Coastguard Worker         return name == testCase->getName();
862*35238bceSAndroid Build Coastguard Worker     }
863*35238bceSAndroid Build Coastguard Worker };
864*35238bceSAndroid Build Coastguard Worker 
runExecServerTests(int argc,const char * const * argv)865*35238bceSAndroid Build Coastguard Worker void runExecServerTests(int argc, const char *const *argv)
866*35238bceSAndroid Build Coastguard Worker {
867*35238bceSAndroid Build Coastguard Worker     // Construct test context.
868*35238bceSAndroid Build Coastguard Worker     TestContext testCtx;
869*35238bceSAndroid Build Coastguard Worker 
870*35238bceSAndroid Build Coastguard Worker     testCtx.serverPath  = "execserver";
871*35238bceSAndroid Build Coastguard Worker     testCtx.testerPath  = argv[0];
872*35238bceSAndroid Build Coastguard Worker     testCtx.startServer = false;
873*35238bceSAndroid Build Coastguard Worker     testCtx.address.setHost("127.0.0.1");
874*35238bceSAndroid Build Coastguard Worker     testCtx.address.setPort(50016);
875*35238bceSAndroid Build Coastguard Worker 
876*35238bceSAndroid Build Coastguard Worker     std::string runClient  = "";
877*35238bceSAndroid Build Coastguard Worker     std::string runProgram = "";
878*35238bceSAndroid Build Coastguard Worker 
879*35238bceSAndroid Build Coastguard Worker     // Parse command line.
880*35238bceSAndroid Build Coastguard Worker     for (int argNdx = 1; argNdx < argc; argNdx++)
881*35238bceSAndroid Build Coastguard Worker     {
882*35238bceSAndroid Build Coastguard Worker         const char *arg = argv[argNdx];
883*35238bceSAndroid Build Coastguard Worker 
884*35238bceSAndroid Build Coastguard Worker         if (deStringBeginsWith(arg, "--client="))
885*35238bceSAndroid Build Coastguard Worker             runClient = arg + 9;
886*35238bceSAndroid Build Coastguard Worker         else if (deStringBeginsWith(arg, "--program="))
887*35238bceSAndroid Build Coastguard Worker             runProgram = arg + 10;
888*35238bceSAndroid Build Coastguard Worker         else if (deStringBeginsWith(arg, "--port="))
889*35238bceSAndroid Build Coastguard Worker             testCtx.address.setPort(atoi(arg + 7));
890*35238bceSAndroid Build Coastguard Worker         else if (deStringBeginsWith(arg, "--host="))
891*35238bceSAndroid Build Coastguard Worker             testCtx.address.setHost(arg + 7);
892*35238bceSAndroid Build Coastguard Worker         else if (deStringBeginsWith(arg, "--server-cmd="))
893*35238bceSAndroid Build Coastguard Worker             testCtx.serverPath = arg + 13;
894*35238bceSAndroid Build Coastguard Worker         else if (deStringBeginsWith(arg, "--tester-cmd="))
895*35238bceSAndroid Build Coastguard Worker             testCtx.testerPath = arg + 13;
896*35238bceSAndroid Build Coastguard Worker         else if (deStringBeginsWith(arg, "--deqp-log-filename="))
897*35238bceSAndroid Build Coastguard Worker             testCtx.logFileName = arg + 20;
898*35238bceSAndroid Build Coastguard Worker         else if (deStringBeginsWith(arg, "--deqp-caselist="))
899*35238bceSAndroid Build Coastguard Worker             testCtx.caseList = arg + 16;
900*35238bceSAndroid Build Coastguard Worker         else if (deStringEqual(arg, "--deqp-stdin-caselist"))
901*35238bceSAndroid Build Coastguard Worker         {
902*35238bceSAndroid Build Coastguard Worker             // \todo [pyry] This is rather brute-force solution...
903*35238bceSAndroid Build Coastguard Worker             char c;
904*35238bceSAndroid Build Coastguard Worker             while (fread(&c, 1, 1, stdin) == 1 && c != 0)
905*35238bceSAndroid Build Coastguard Worker                 testCtx.caseList += c;
906*35238bceSAndroid Build Coastguard Worker         }
907*35238bceSAndroid Build Coastguard Worker         else if (deStringEqual(arg, "--start-server"))
908*35238bceSAndroid Build Coastguard Worker             testCtx.startServer = true;
909*35238bceSAndroid Build Coastguard Worker         else
910*35238bceSAndroid Build Coastguard Worker         {
911*35238bceSAndroid Build Coastguard Worker             printHelp(argv[0]);
912*35238bceSAndroid Build Coastguard Worker             return;
913*35238bceSAndroid Build Coastguard Worker         }
914*35238bceSAndroid Build Coastguard Worker     }
915*35238bceSAndroid Build Coastguard Worker 
916*35238bceSAndroid Build Coastguard Worker     // Test case list.
917*35238bceSAndroid Build Coastguard Worker     std::vector<TestCase *> testCases;
918*35238bceSAndroid Build Coastguard Worker     testCases.push_back(new ConnectTest(testCtx));
919*35238bceSAndroid Build Coastguard Worker     testCases.push_back(new HelloTest(testCtx));
920*35238bceSAndroid Build Coastguard Worker     testCases.push_back(new ExecFailTest(testCtx));
921*35238bceSAndroid Build Coastguard Worker     testCases.push_back(new SimpleExecTest(testCtx));
922*35238bceSAndroid Build Coastguard Worker     testCases.push_back(new InfoTest(testCtx));
923*35238bceSAndroid Build Coastguard Worker     testCases.push_back(new LogDataTest(testCtx));
924*35238bceSAndroid Build Coastguard Worker     testCases.push_back(new KeepAliveTest(testCtx));
925*35238bceSAndroid Build Coastguard Worker     testCases.push_back(new BigLogDataTest(testCtx));
926*35238bceSAndroid Build Coastguard Worker 
927*35238bceSAndroid Build Coastguard Worker     try
928*35238bceSAndroid Build Coastguard Worker     {
929*35238bceSAndroid Build Coastguard Worker         if (!runClient.empty())
930*35238bceSAndroid Build Coastguard Worker         {
931*35238bceSAndroid Build Coastguard Worker             // Run single case.
932*35238bceSAndroid Build Coastguard Worker             vector<TestCase *>::iterator casePos =
933*35238bceSAndroid Build Coastguard Worker                 std::find_if(testCases.begin(), testCases.end(), CompareCaseName(runClient));
934*35238bceSAndroid Build Coastguard Worker             XS_CHECK(casePos != testCases.end());
935*35238bceSAndroid Build Coastguard Worker             TestExecutor executor(testCtx);
936*35238bceSAndroid Build Coastguard Worker             executor.runCase(*casePos);
937*35238bceSAndroid Build Coastguard Worker         }
938*35238bceSAndroid Build Coastguard Worker         else if (!runProgram.empty())
939*35238bceSAndroid Build Coastguard Worker         {
940*35238bceSAndroid Build Coastguard Worker             // Run program part.
941*35238bceSAndroid Build Coastguard Worker             vector<TestCase *>::iterator casePos =
942*35238bceSAndroid Build Coastguard Worker                 std::find_if(testCases.begin(), testCases.end(), CompareCaseName(runProgram));
943*35238bceSAndroid Build Coastguard Worker             XS_CHECK(casePos != testCases.end());
944*35238bceSAndroid Build Coastguard Worker             (*casePos)->runProgram();
945*35238bceSAndroid Build Coastguard Worker             fflush(stdout); // Make sure handles are flushed.
946*35238bceSAndroid Build Coastguard Worker             fflush(stderr);
947*35238bceSAndroid Build Coastguard Worker         }
948*35238bceSAndroid Build Coastguard Worker         else
949*35238bceSAndroid Build Coastguard Worker         {
950*35238bceSAndroid Build Coastguard Worker             // Run all tests.
951*35238bceSAndroid Build Coastguard Worker             TestExecutor executor(testCtx);
952*35238bceSAndroid Build Coastguard Worker             executor.runCases(testCases);
953*35238bceSAndroid Build Coastguard Worker         }
954*35238bceSAndroid Build Coastguard Worker     }
955*35238bceSAndroid Build Coastguard Worker     catch (const std::exception &e)
956*35238bceSAndroid Build Coastguard Worker     {
957*35238bceSAndroid Build Coastguard Worker         printf("ERROR: %s\n", e.what());
958*35238bceSAndroid Build Coastguard Worker     }
959*35238bceSAndroid Build Coastguard Worker 
960*35238bceSAndroid Build Coastguard Worker     // Destroy cases.
961*35238bceSAndroid Build Coastguard Worker     for (std::vector<TestCase *>::const_iterator i = testCases.begin(); i != testCases.end(); i++)
962*35238bceSAndroid Build Coastguard Worker         delete *i;
963*35238bceSAndroid Build Coastguard Worker }
964*35238bceSAndroid Build Coastguard Worker 
965*35238bceSAndroid Build Coastguard Worker } // namespace xs
966*35238bceSAndroid Build Coastguard Worker 
967*35238bceSAndroid Build Coastguard Worker #if 0
968*35238bceSAndroid Build Coastguard Worker void testProcFile (void)
969*35238bceSAndroid Build Coastguard Worker {
970*35238bceSAndroid Build Coastguard Worker     /* Test file api. */
971*35238bceSAndroid Build Coastguard Worker     if (deFileExists("test.txt"))
972*35238bceSAndroid Build Coastguard Worker         deDeleteFile("test.txt");
973*35238bceSAndroid Build Coastguard Worker     deFile* file = deFile_create("test.txt", DE_FILEMODE_CREATE|DE_FILEMODE_WRITE);
974*35238bceSAndroid Build Coastguard Worker     const char test[] = "Hello";
975*35238bceSAndroid Build Coastguard Worker     XS_CHECK(deFile_write(file, test, sizeof(test), DE_NULL) == DE_FILERESULT_SUCCESS);
976*35238bceSAndroid Build Coastguard Worker     deFile_destroy(file);
977*35238bceSAndroid Build Coastguard Worker 
978*35238bceSAndroid Build Coastguard Worker     /* Read. */
979*35238bceSAndroid Build Coastguard Worker     char buf[10] = { 0 };
980*35238bceSAndroid Build Coastguard Worker     file = deFile_create("test.txt", DE_FILEMODE_OPEN|DE_FILEMODE_READ);
981*35238bceSAndroid Build Coastguard Worker     XS_CHECK(deFile_read(file, buf, sizeof(test), DE_NULL) == DE_FILERESULT_SUCCESS);
982*35238bceSAndroid Build Coastguard Worker     printf("buf: %s\n", buf);
983*35238bceSAndroid Build Coastguard Worker     deFile_destroy(file);
984*35238bceSAndroid Build Coastguard Worker 
985*35238bceSAndroid Build Coastguard Worker     /* Process test. */
986*35238bceSAndroid Build Coastguard Worker     deProcess* proc = deProcess_create("ls -lah /Users/pyry", DE_NULL);
987*35238bceSAndroid Build Coastguard Worker     deFile* out = deProcess_getStdOut(proc);
988*35238bceSAndroid Build Coastguard Worker 
989*35238bceSAndroid Build Coastguard Worker     int64_t numRead = 0;
990*35238bceSAndroid Build Coastguard Worker     printf("ls:\n");
991*35238bceSAndroid Build Coastguard Worker     while (deFile_read(out, buf, sizeof(buf)-1, &numRead) == DE_FILERESULT_SUCCESS)
992*35238bceSAndroid Build Coastguard Worker     {
993*35238bceSAndroid Build Coastguard Worker         buf[numRead] = 0;
994*35238bceSAndroid Build Coastguard Worker         printf("%s", buf);
995*35238bceSAndroid Build Coastguard Worker     }
996*35238bceSAndroid Build Coastguard Worker     deProcess_destroy(proc);
997*35238bceSAndroid Build Coastguard Worker }
998*35238bceSAndroid Build Coastguard Worker #endif
999*35238bceSAndroid Build Coastguard Worker 
1000*35238bceSAndroid Build Coastguard Worker #if 0
1001*35238bceSAndroid Build Coastguard Worker void testBlockingFile (const char* filename)
1002*35238bceSAndroid Build Coastguard Worker {
1003*35238bceSAndroid Build Coastguard Worker     deRandom    rnd;
1004*35238bceSAndroid Build Coastguard Worker     int            dataSize = 1024*1024;
1005*35238bceSAndroid Build Coastguard Worker     uint8_t*    data = (uint8_t*)deCalloc(dataSize);
1006*35238bceSAndroid Build Coastguard Worker     deFile*        file;
1007*35238bceSAndroid Build Coastguard Worker 
1008*35238bceSAndroid Build Coastguard Worker     deRandom_init(&rnd, 0);
1009*35238bceSAndroid Build Coastguard Worker 
1010*35238bceSAndroid Build Coastguard Worker     if (deFileExists(filename))
1011*35238bceSAndroid Build Coastguard Worker         DE_VERIFY(deDeleteFile(filename));
1012*35238bceSAndroid Build Coastguard Worker 
1013*35238bceSAndroid Build Coastguard Worker     /* Fill in with random data. */
1014*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(dataSize % sizeof(int) == 0);
1015*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < (int)(dataSize/sizeof(int)); ndx++)
1016*35238bceSAndroid Build Coastguard Worker         ((uint32_t*)data)[ndx] = deRandom_getUint32(&rnd);
1017*35238bceSAndroid Build Coastguard Worker 
1018*35238bceSAndroid Build Coastguard Worker     /* Write with random-sized blocks. */
1019*35238bceSAndroid Build Coastguard Worker     file = deFile_create(filename, DE_FILEMODE_CREATE|DE_FILEMODE_WRITE);
1020*35238bceSAndroid Build Coastguard Worker     DE_VERIFY(file);
1021*35238bceSAndroid Build Coastguard Worker 
1022*35238bceSAndroid Build Coastguard Worker     int curPos = 0;
1023*35238bceSAndroid Build Coastguard Worker     while (curPos < dataSize)
1024*35238bceSAndroid Build Coastguard Worker     {
1025*35238bceSAndroid Build Coastguard Worker         int                blockSize = 1 + deRandom_getUint32(&rnd) % (dataSize-curPos);
1026*35238bceSAndroid Build Coastguard Worker         int64_t            numWritten = 0;
1027*35238bceSAndroid Build Coastguard Worker         deFileResult    result = deFile_write(file, &data[curPos], blockSize, &numWritten);
1028*35238bceSAndroid Build Coastguard Worker 
1029*35238bceSAndroid Build Coastguard Worker         DE_VERIFY(result == DE_FILERESULT_SUCCESS);
1030*35238bceSAndroid Build Coastguard Worker         DE_VERIFY(numWritten == blockSize);
1031*35238bceSAndroid Build Coastguard Worker 
1032*35238bceSAndroid Build Coastguard Worker         curPos += blockSize;
1033*35238bceSAndroid Build Coastguard Worker     }
1034*35238bceSAndroid Build Coastguard Worker 
1035*35238bceSAndroid Build Coastguard Worker     deFile_destroy(file);
1036*35238bceSAndroid Build Coastguard Worker 
1037*35238bceSAndroid Build Coastguard Worker     /* Read and verify file. */
1038*35238bceSAndroid Build Coastguard Worker     file = deFile_create(filename, DE_FILEMODE_OPEN|DE_FILEMODE_READ);
1039*35238bceSAndroid Build Coastguard Worker     curPos = 0;
1040*35238bceSAndroid Build Coastguard Worker     while (curPos < dataSize)
1041*35238bceSAndroid Build Coastguard Worker     {
1042*35238bceSAndroid Build Coastguard Worker         uint8_t            block[1024];
1043*35238bceSAndroid Build Coastguard Worker         int                numToRead = 1 + deRandom_getUint32(&rnd) % deMin(dataSize-curPos, DE_LENGTH_OF_ARRAY(block));
1044*35238bceSAndroid Build Coastguard Worker         int64_t            numRead = 0;
1045*35238bceSAndroid Build Coastguard Worker         deFileResult    result = deFile_read(file, block, numToRead, &numRead);
1046*35238bceSAndroid Build Coastguard Worker 
1047*35238bceSAndroid Build Coastguard Worker         DE_VERIFY(result == DE_FILERESULT_SUCCESS);
1048*35238bceSAndroid Build Coastguard Worker         DE_VERIFY((int)numRead == numToRead);
1049*35238bceSAndroid Build Coastguard Worker         DE_VERIFY(deMemCmp(block, &data[curPos], numToRead) == 0);
1050*35238bceSAndroid Build Coastguard Worker 
1051*35238bceSAndroid Build Coastguard Worker         curPos += numToRead;
1052*35238bceSAndroid Build Coastguard Worker     }
1053*35238bceSAndroid Build Coastguard Worker     deFile_destroy(file);
1054*35238bceSAndroid Build Coastguard Worker }
1055*35238bceSAndroid Build Coastguard Worker #endif
1056*35238bceSAndroid Build Coastguard Worker 
main(int argc,const char * const * argv)1057*35238bceSAndroid Build Coastguard Worker int main(int argc, const char *const *argv)
1058*35238bceSAndroid Build Coastguard Worker {
1059*35238bceSAndroid Build Coastguard Worker     xs::runExecServerTests(argc, argv);
1060*35238bceSAndroid Build Coastguard Worker     return 0;
1061*35238bceSAndroid Build Coastguard Worker }
1062