xref: /aosp_15_r20/external/deqp/execserver/tools/xsClient.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 Client.
22*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker 
24*35238bceSAndroid Build Coastguard Worker #include "xsDefs.hpp"
25*35238bceSAndroid Build Coastguard Worker #include "xsProtocol.hpp"
26*35238bceSAndroid Build Coastguard Worker #include "deSocket.hpp"
27*35238bceSAndroid Build Coastguard Worker #include "deUniquePtr.hpp"
28*35238bceSAndroid Build Coastguard Worker 
29*35238bceSAndroid Build Coastguard Worker #include "deString.h"
30*35238bceSAndroid Build Coastguard Worker 
31*35238bceSAndroid Build Coastguard Worker #include <memory>
32*35238bceSAndroid Build Coastguard Worker #include <sstream>
33*35238bceSAndroid Build Coastguard Worker #include <fstream>
34*35238bceSAndroid Build Coastguard Worker #include <cstdio>
35*35238bceSAndroid Build Coastguard Worker #include <cstdlib>
36*35238bceSAndroid Build Coastguard Worker 
37*35238bceSAndroid Build Coastguard Worker using std::string;
38*35238bceSAndroid Build Coastguard Worker using std::vector;
39*35238bceSAndroid Build Coastguard Worker 
40*35238bceSAndroid Build Coastguard Worker namespace xs
41*35238bceSAndroid Build Coastguard Worker {
42*35238bceSAndroid Build Coastguard Worker 
43*35238bceSAndroid Build Coastguard Worker typedef de::UniquePtr<Message> ScopedMsgPtr;
44*35238bceSAndroid Build Coastguard Worker 
45*35238bceSAndroid Build Coastguard Worker class SocketError : public Error
46*35238bceSAndroid Build Coastguard Worker {
47*35238bceSAndroid Build Coastguard Worker public:
SocketError(deSocketResult result,const char * message,const char * file,int line)48*35238bceSAndroid Build Coastguard Worker     SocketError(deSocketResult result, const char *message, const char *file, int line)
49*35238bceSAndroid Build Coastguard Worker         : Error(message, deGetSocketResultName(result), file, line)
50*35238bceSAndroid Build Coastguard Worker         , m_result(result)
51*35238bceSAndroid Build Coastguard Worker     {
52*35238bceSAndroid Build Coastguard Worker     }
53*35238bceSAndroid Build Coastguard Worker 
getResult(void) const54*35238bceSAndroid Build Coastguard Worker     deSocketResult getResult(void) const
55*35238bceSAndroid Build Coastguard Worker     {
56*35238bceSAndroid Build Coastguard Worker         return m_result;
57*35238bceSAndroid Build Coastguard Worker     }
58*35238bceSAndroid Build Coastguard Worker 
59*35238bceSAndroid Build Coastguard Worker private:
60*35238bceSAndroid Build Coastguard Worker     deSocketResult m_result;
61*35238bceSAndroid Build Coastguard Worker };
62*35238bceSAndroid Build Coastguard Worker 
63*35238bceSAndroid Build Coastguard Worker // Helpers.
sendMessage(de::Socket & socket,const Message & message)64*35238bceSAndroid Build Coastguard Worker void sendMessage(de::Socket &socket, const Message &message)
65*35238bceSAndroid Build Coastguard Worker {
66*35238bceSAndroid Build Coastguard Worker     // Format message.
67*35238bceSAndroid Build Coastguard Worker     vector<uint8_t> buf;
68*35238bceSAndroid Build Coastguard Worker     message.write(buf);
69*35238bceSAndroid Build Coastguard Worker 
70*35238bceSAndroid Build Coastguard Worker     // Write to socket.
71*35238bceSAndroid Build Coastguard Worker     size_t pos = 0;
72*35238bceSAndroid Build Coastguard Worker     while (pos < buf.size())
73*35238bceSAndroid Build Coastguard Worker     {
74*35238bceSAndroid Build Coastguard Worker         size_t numLeft        = buf.size() - pos;
75*35238bceSAndroid Build Coastguard Worker         size_t numSent        = 0;
76*35238bceSAndroid Build Coastguard Worker         deSocketResult result = socket.send(&buf[pos], numLeft, &numSent);
77*35238bceSAndroid Build Coastguard Worker 
78*35238bceSAndroid Build Coastguard Worker         if (result != DE_SOCKETRESULT_SUCCESS)
79*35238bceSAndroid Build Coastguard Worker             throw SocketError(result, "send() failed", __FILE__, __LINE__);
80*35238bceSAndroid Build Coastguard Worker 
81*35238bceSAndroid Build Coastguard Worker         pos += numSent;
82*35238bceSAndroid Build Coastguard Worker     }
83*35238bceSAndroid Build Coastguard Worker }
84*35238bceSAndroid Build Coastguard Worker 
readBytes(de::Socket & socket,vector<uint8_t> & dst,size_t numBytes)85*35238bceSAndroid Build Coastguard Worker void readBytes(de::Socket &socket, vector<uint8_t> &dst, size_t numBytes)
86*35238bceSAndroid Build Coastguard Worker {
87*35238bceSAndroid Build Coastguard Worker     size_t numRead = 0;
88*35238bceSAndroid Build Coastguard Worker     dst.resize(numBytes);
89*35238bceSAndroid Build Coastguard Worker     while (numRead < numBytes)
90*35238bceSAndroid Build Coastguard Worker     {
91*35238bceSAndroid Build Coastguard Worker         size_t numLeft        = numBytes - numRead;
92*35238bceSAndroid Build Coastguard Worker         size_t curNumRead     = 0;
93*35238bceSAndroid Build Coastguard Worker         deSocketResult result = socket.receive(&dst[numRead], numLeft, &curNumRead);
94*35238bceSAndroid Build Coastguard Worker 
95*35238bceSAndroid Build Coastguard Worker         if (result != DE_SOCKETRESULT_SUCCESS)
96*35238bceSAndroid Build Coastguard Worker             throw SocketError(result, "receive() failed", __FILE__, __LINE__);
97*35238bceSAndroid Build Coastguard Worker 
98*35238bceSAndroid Build Coastguard Worker         numRead += curNumRead;
99*35238bceSAndroid Build Coastguard Worker     }
100*35238bceSAndroid Build Coastguard Worker }
101*35238bceSAndroid Build Coastguard Worker 
readMessage(de::Socket & socket)102*35238bceSAndroid Build Coastguard Worker Message *readMessage(de::Socket &socket)
103*35238bceSAndroid Build Coastguard Worker {
104*35238bceSAndroid Build Coastguard Worker     // Header.
105*35238bceSAndroid Build Coastguard Worker     vector<uint8_t> header;
106*35238bceSAndroid Build Coastguard Worker     readBytes(socket, header, MESSAGE_HEADER_SIZE);
107*35238bceSAndroid Build Coastguard Worker 
108*35238bceSAndroid Build Coastguard Worker     MessageType type;
109*35238bceSAndroid Build Coastguard Worker     size_t messageSize;
110*35238bceSAndroid Build Coastguard Worker     Message::parseHeader(&header[0], (int)header.size(), type, messageSize);
111*35238bceSAndroid Build Coastguard Worker 
112*35238bceSAndroid Build Coastguard Worker     // Simple messages without any data.
113*35238bceSAndroid Build Coastguard Worker     switch (type)
114*35238bceSAndroid Build Coastguard Worker     {
115*35238bceSAndroid Build Coastguard Worker     case MESSAGETYPE_KEEPALIVE:
116*35238bceSAndroid Build Coastguard Worker         return new KeepAliveMessage();
117*35238bceSAndroid Build Coastguard Worker     case MESSAGETYPE_PROCESS_STARTED:
118*35238bceSAndroid Build Coastguard Worker         return new ProcessStartedMessage();
119*35238bceSAndroid Build Coastguard Worker     default:
120*35238bceSAndroid Build Coastguard Worker         break; // Read message with data.
121*35238bceSAndroid Build Coastguard Worker     }
122*35238bceSAndroid Build Coastguard Worker 
123*35238bceSAndroid Build Coastguard Worker     vector<uint8_t> messageBuf;
124*35238bceSAndroid Build Coastguard Worker     readBytes(socket, messageBuf, messageSize - MESSAGE_HEADER_SIZE);
125*35238bceSAndroid Build Coastguard Worker 
126*35238bceSAndroid Build Coastguard Worker     switch (type)
127*35238bceSAndroid Build Coastguard Worker     {
128*35238bceSAndroid Build Coastguard Worker     case MESSAGETYPE_HELLO:
129*35238bceSAndroid Build Coastguard Worker         return new HelloMessage(&messageBuf[0], (int)messageBuf.size());
130*35238bceSAndroid Build Coastguard Worker     case MESSAGETYPE_TEST:
131*35238bceSAndroid Build Coastguard Worker         return new TestMessage(&messageBuf[0], (int)messageBuf.size());
132*35238bceSAndroid Build Coastguard Worker     case MESSAGETYPE_PROCESS_LOG_DATA:
133*35238bceSAndroid Build Coastguard Worker         return new ProcessLogDataMessage(&messageBuf[0], (int)messageBuf.size());
134*35238bceSAndroid Build Coastguard Worker     case MESSAGETYPE_INFO:
135*35238bceSAndroid Build Coastguard Worker         return new InfoMessage(&messageBuf[0], (int)messageBuf.size());
136*35238bceSAndroid Build Coastguard Worker     case MESSAGETYPE_PROCESS_LAUNCH_FAILED:
137*35238bceSAndroid Build Coastguard Worker         return new ProcessLaunchFailedMessage(&messageBuf[0], (int)messageBuf.size());
138*35238bceSAndroid Build Coastguard Worker     case MESSAGETYPE_PROCESS_FINISHED:
139*35238bceSAndroid Build Coastguard Worker         return new ProcessFinishedMessage(&messageBuf[0], (int)messageBuf.size());
140*35238bceSAndroid Build Coastguard Worker     default:
141*35238bceSAndroid Build Coastguard Worker         XS_FAIL("Unknown message");
142*35238bceSAndroid Build Coastguard Worker     }
143*35238bceSAndroid Build Coastguard Worker }
144*35238bceSAndroid Build Coastguard Worker 
145*35238bceSAndroid Build Coastguard Worker class CommandLine
146*35238bceSAndroid Build Coastguard Worker {
147*35238bceSAndroid Build Coastguard Worker public:
148*35238bceSAndroid Build Coastguard Worker     de::SocketAddress address;
149*35238bceSAndroid Build Coastguard Worker     std::string program;
150*35238bceSAndroid Build Coastguard Worker     std::string params;
151*35238bceSAndroid Build Coastguard Worker     std::string workingDir;
152*35238bceSAndroid Build Coastguard Worker     std::string caseList;
153*35238bceSAndroid Build Coastguard Worker     std::string dstFileName;
154*35238bceSAndroid Build Coastguard Worker };
155*35238bceSAndroid Build Coastguard Worker 
156*35238bceSAndroid Build Coastguard Worker class Client
157*35238bceSAndroid Build Coastguard Worker {
158*35238bceSAndroid Build Coastguard Worker public:
159*35238bceSAndroid Build Coastguard Worker     Client(const CommandLine &cmdLine);
160*35238bceSAndroid Build Coastguard Worker     ~Client(void);
161*35238bceSAndroid Build Coastguard Worker 
162*35238bceSAndroid Build Coastguard Worker     void run(void);
163*35238bceSAndroid Build Coastguard Worker 
164*35238bceSAndroid Build Coastguard Worker private:
165*35238bceSAndroid Build Coastguard Worker     const CommandLine &m_cmdLine;
166*35238bceSAndroid Build Coastguard Worker     de::Socket m_socket;
167*35238bceSAndroid Build Coastguard Worker };
168*35238bceSAndroid Build Coastguard Worker 
Client(const CommandLine & cmdLine)169*35238bceSAndroid Build Coastguard Worker Client::Client(const CommandLine &cmdLine) : m_cmdLine(cmdLine)
170*35238bceSAndroid Build Coastguard Worker {
171*35238bceSAndroid Build Coastguard Worker }
172*35238bceSAndroid Build Coastguard Worker 
~Client(void)173*35238bceSAndroid Build Coastguard Worker Client::~Client(void)
174*35238bceSAndroid Build Coastguard Worker {
175*35238bceSAndroid Build Coastguard Worker }
176*35238bceSAndroid Build Coastguard Worker 
run(void)177*35238bceSAndroid Build Coastguard Worker void Client::run(void)
178*35238bceSAndroid Build Coastguard Worker {
179*35238bceSAndroid Build Coastguard Worker     // Connect to server.
180*35238bceSAndroid Build Coastguard Worker     m_socket.connect(m_cmdLine.address);
181*35238bceSAndroid Build Coastguard Worker 
182*35238bceSAndroid Build Coastguard Worker     printf("Connected to %s:%d!\n", m_cmdLine.address.getHost(), m_cmdLine.address.getPort());
183*35238bceSAndroid Build Coastguard Worker 
184*35238bceSAndroid Build Coastguard Worker     // Open result file.
185*35238bceSAndroid Build Coastguard Worker     std::fstream out(m_cmdLine.dstFileName.c_str(), std::fstream::out | std::fstream::binary);
186*35238bceSAndroid Build Coastguard Worker 
187*35238bceSAndroid Build Coastguard Worker     printf("  writing to %s\n", m_cmdLine.dstFileName.c_str());
188*35238bceSAndroid Build Coastguard Worker 
189*35238bceSAndroid Build Coastguard Worker     // Send execution request.
190*35238bceSAndroid Build Coastguard Worker     {
191*35238bceSAndroid Build Coastguard Worker         ExecuteBinaryMessage msg;
192*35238bceSAndroid Build Coastguard Worker 
193*35238bceSAndroid Build Coastguard Worker         msg.name     = m_cmdLine.program;
194*35238bceSAndroid Build Coastguard Worker         msg.params   = m_cmdLine.params;
195*35238bceSAndroid Build Coastguard Worker         msg.workDir  = m_cmdLine.workingDir;
196*35238bceSAndroid Build Coastguard Worker         msg.caseList = m_cmdLine.caseList;
197*35238bceSAndroid Build Coastguard Worker 
198*35238bceSAndroid Build Coastguard Worker         sendMessage(m_socket, msg);
199*35238bceSAndroid Build Coastguard Worker         printf("  execution request sent.\n");
200*35238bceSAndroid Build Coastguard Worker     }
201*35238bceSAndroid Build Coastguard Worker 
202*35238bceSAndroid Build Coastguard Worker     // Run client loop.
203*35238bceSAndroid Build Coastguard Worker     bool isRunning = true;
204*35238bceSAndroid Build Coastguard Worker     while (isRunning)
205*35238bceSAndroid Build Coastguard Worker     {
206*35238bceSAndroid Build Coastguard Worker         ScopedMsgPtr msg(readMessage(m_socket));
207*35238bceSAndroid Build Coastguard Worker 
208*35238bceSAndroid Build Coastguard Worker         switch (msg->type)
209*35238bceSAndroid Build Coastguard Worker         {
210*35238bceSAndroid Build Coastguard Worker         case MESSAGETYPE_HELLO:
211*35238bceSAndroid Build Coastguard Worker             printf("  HelloMessage\n");
212*35238bceSAndroid Build Coastguard Worker             break;
213*35238bceSAndroid Build Coastguard Worker 
214*35238bceSAndroid Build Coastguard Worker         case MESSAGETYPE_KEEPALIVE:
215*35238bceSAndroid Build Coastguard Worker         {
216*35238bceSAndroid Build Coastguard Worker             printf("  KeepAliveMessage\n");
217*35238bceSAndroid Build Coastguard Worker 
218*35238bceSAndroid Build Coastguard Worker             // Reply with keepalive.
219*35238bceSAndroid Build Coastguard Worker             sendMessage(m_socket, KeepAliveMessage());
220*35238bceSAndroid Build Coastguard Worker             break;
221*35238bceSAndroid Build Coastguard Worker         }
222*35238bceSAndroid Build Coastguard Worker 
223*35238bceSAndroid Build Coastguard Worker         case MESSAGETYPE_INFO:
224*35238bceSAndroid Build Coastguard Worker             printf("  InfoMessage: '%s'\n", static_cast<InfoMessage *>(msg.get())->info.c_str());
225*35238bceSAndroid Build Coastguard Worker             break;
226*35238bceSAndroid Build Coastguard Worker 
227*35238bceSAndroid Build Coastguard Worker         case MESSAGETYPE_PROCESS_STARTED:
228*35238bceSAndroid Build Coastguard Worker             printf("  ProcessStartedMessage\n");
229*35238bceSAndroid Build Coastguard Worker             break;
230*35238bceSAndroid Build Coastguard Worker 
231*35238bceSAndroid Build Coastguard Worker         case MESSAGETYPE_PROCESS_FINISHED:
232*35238bceSAndroid Build Coastguard Worker             printf("  ProcessFinished: exit code = %d\n", static_cast<ProcessFinishedMessage *>(msg.get())->exitCode);
233*35238bceSAndroid Build Coastguard Worker             isRunning = false;
234*35238bceSAndroid Build Coastguard Worker             break;
235*35238bceSAndroid Build Coastguard Worker 
236*35238bceSAndroid Build Coastguard Worker         case MESSAGETYPE_PROCESS_LAUNCH_FAILED:
237*35238bceSAndroid Build Coastguard Worker             printf("  ProcessLaunchFailed: '%s'\n",
238*35238bceSAndroid Build Coastguard Worker                    static_cast<ProcessLaunchFailedMessage *>(msg.get())->reason.c_str());
239*35238bceSAndroid Build Coastguard Worker             isRunning = false;
240*35238bceSAndroid Build Coastguard Worker             break;
241*35238bceSAndroid Build Coastguard Worker 
242*35238bceSAndroid Build Coastguard Worker         case MESSAGETYPE_PROCESS_LOG_DATA:
243*35238bceSAndroid Build Coastguard Worker         {
244*35238bceSAndroid Build Coastguard Worker             ProcessLogDataMessage *logDataMsg = static_cast<ProcessLogDataMessage *>(msg.get());
245*35238bceSAndroid Build Coastguard Worker             printf("  ProcessLogDataMessage: %d bytes\n", (int)logDataMsg->logData.length());
246*35238bceSAndroid Build Coastguard Worker             out << logDataMsg->logData;
247*35238bceSAndroid Build Coastguard Worker             break;
248*35238bceSAndroid Build Coastguard Worker         }
249*35238bceSAndroid Build Coastguard Worker 
250*35238bceSAndroid Build Coastguard Worker         default:
251*35238bceSAndroid Build Coastguard Worker             XS_FAIL("Unknown message");
252*35238bceSAndroid Build Coastguard Worker         }
253*35238bceSAndroid Build Coastguard Worker     }
254*35238bceSAndroid Build Coastguard Worker 
255*35238bceSAndroid Build Coastguard Worker     // Close output file.
256*35238bceSAndroid Build Coastguard Worker     out.close();
257*35238bceSAndroid Build Coastguard Worker 
258*35238bceSAndroid Build Coastguard Worker     // Close connection.
259*35238bceSAndroid Build Coastguard Worker     m_socket.shutdown();
260*35238bceSAndroid Build Coastguard Worker     m_socket.close();
261*35238bceSAndroid Build Coastguard Worker 
262*35238bceSAndroid Build Coastguard Worker     printf("Done!\n");
263*35238bceSAndroid Build Coastguard Worker }
264*35238bceSAndroid Build Coastguard Worker 
parseString(const char * str)265*35238bceSAndroid Build Coastguard Worker string parseString(const char *str)
266*35238bceSAndroid Build Coastguard Worker {
267*35238bceSAndroid Build Coastguard Worker     if (str[0] == '\'' || str[0] == '"')
268*35238bceSAndroid Build Coastguard Worker     {
269*35238bceSAndroid Build Coastguard Worker         const char *p = str;
270*35238bceSAndroid Build Coastguard Worker         char endChar  = *p++;
271*35238bceSAndroid Build Coastguard Worker         std::ostringstream o;
272*35238bceSAndroid Build Coastguard Worker 
273*35238bceSAndroid Build Coastguard Worker         while (*p != endChar && *p)
274*35238bceSAndroid Build Coastguard Worker         {
275*35238bceSAndroid Build Coastguard Worker             if (*p == '\\')
276*35238bceSAndroid Build Coastguard Worker             {
277*35238bceSAndroid Build Coastguard Worker                 switch (p[1])
278*35238bceSAndroid Build Coastguard Worker                 {
279*35238bceSAndroid Build Coastguard Worker                 case 0:
280*35238bceSAndroid Build Coastguard Worker                     DE_ASSERT(false);
281*35238bceSAndroid Build Coastguard Worker                     break;
282*35238bceSAndroid Build Coastguard Worker                 case 'n':
283*35238bceSAndroid Build Coastguard Worker                     o << '\n';
284*35238bceSAndroid Build Coastguard Worker                     break;
285*35238bceSAndroid Build Coastguard Worker                 case 't':
286*35238bceSAndroid Build Coastguard Worker                     o << '\t';
287*35238bceSAndroid Build Coastguard Worker                     break;
288*35238bceSAndroid Build Coastguard Worker                 default:
289*35238bceSAndroid Build Coastguard Worker                     o << p[1];
290*35238bceSAndroid Build Coastguard Worker                     break;
291*35238bceSAndroid Build Coastguard Worker                 }
292*35238bceSAndroid Build Coastguard Worker 
293*35238bceSAndroid Build Coastguard Worker                 p += 2;
294*35238bceSAndroid Build Coastguard Worker             }
295*35238bceSAndroid Build Coastguard Worker             else
296*35238bceSAndroid Build Coastguard Worker                 o << *p++;
297*35238bceSAndroid Build Coastguard Worker         }
298*35238bceSAndroid Build Coastguard Worker 
299*35238bceSAndroid Build Coastguard Worker         return o.str();
300*35238bceSAndroid Build Coastguard Worker     }
301*35238bceSAndroid Build Coastguard Worker     else
302*35238bceSAndroid Build Coastguard Worker         return string(str);
303*35238bceSAndroid Build Coastguard Worker }
304*35238bceSAndroid Build Coastguard Worker 
printHelp(const char * binName)305*35238bceSAndroid Build Coastguard Worker void printHelp(const char *binName)
306*35238bceSAndroid Build Coastguard Worker {
307*35238bceSAndroid Build Coastguard Worker     printf("%s:\n", binName);
308*35238bceSAndroid Build Coastguard Worker     printf("  --host=[host]          Connect to host [host]\n");
309*35238bceSAndroid Build Coastguard Worker     printf("  --port=[name]          Use port [port]\n");
310*35238bceSAndroid Build Coastguard Worker     printf("  --program=[program]    Test program\n");
311*35238bceSAndroid Build Coastguard Worker     printf("  --params=[params]      Test program params\n");
312*35238bceSAndroid Build Coastguard Worker     printf("  --workdir=[dir]        Working directory\n");
313*35238bceSAndroid Build Coastguard Worker     printf("  --caselist=[caselist]  Test case list\n");
314*35238bceSAndroid Build Coastguard Worker     printf("  --out=filename         Test result file\n");
315*35238bceSAndroid Build Coastguard Worker }
316*35238bceSAndroid Build Coastguard Worker 
runClient(int argc,const char * const * argv)317*35238bceSAndroid Build Coastguard Worker int runClient(int argc, const char *const *argv)
318*35238bceSAndroid Build Coastguard Worker {
319*35238bceSAndroid Build Coastguard Worker     CommandLine cmdLine;
320*35238bceSAndroid Build Coastguard Worker 
321*35238bceSAndroid Build Coastguard Worker     // Defaults.
322*35238bceSAndroid Build Coastguard Worker     cmdLine.address.setHost("127.0.0.1");
323*35238bceSAndroid Build Coastguard Worker     cmdLine.address.setPort(50016);
324*35238bceSAndroid Build Coastguard Worker     cmdLine.dstFileName = "TestResults.qpa";
325*35238bceSAndroid Build Coastguard Worker 
326*35238bceSAndroid Build Coastguard Worker     // Parse command line.
327*35238bceSAndroid Build Coastguard Worker     for (int argNdx = 1; argNdx < argc; argNdx++)
328*35238bceSAndroid Build Coastguard Worker     {
329*35238bceSAndroid Build Coastguard Worker         const char *arg = argv[argNdx];
330*35238bceSAndroid Build Coastguard Worker 
331*35238bceSAndroid Build Coastguard Worker         if (deStringBeginsWith(arg, "--port="))
332*35238bceSAndroid Build Coastguard Worker             cmdLine.address.setPort(atoi(arg + 7));
333*35238bceSAndroid Build Coastguard Worker         else if (deStringBeginsWith(arg, "--host="))
334*35238bceSAndroid Build Coastguard Worker             cmdLine.address.setHost(parseString(arg + 7).c_str());
335*35238bceSAndroid Build Coastguard Worker         else if (deStringBeginsWith(arg, "--program="))
336*35238bceSAndroid Build Coastguard Worker             cmdLine.program = parseString(arg + 10);
337*35238bceSAndroid Build Coastguard Worker         else if (deStringBeginsWith(arg, "--params="))
338*35238bceSAndroid Build Coastguard Worker             cmdLine.params = parseString(arg + 9);
339*35238bceSAndroid Build Coastguard Worker         else if (deStringBeginsWith(arg, "--workdir="))
340*35238bceSAndroid Build Coastguard Worker             cmdLine.workingDir = parseString(arg + 10);
341*35238bceSAndroid Build Coastguard Worker         else if (deStringBeginsWith(arg, "--caselist="))
342*35238bceSAndroid Build Coastguard Worker             cmdLine.caseList = parseString(arg + 11);
343*35238bceSAndroid Build Coastguard Worker         else if (deStringBeginsWith(arg, "--out="))
344*35238bceSAndroid Build Coastguard Worker             cmdLine.dstFileName = parseString(arg + 6);
345*35238bceSAndroid Build Coastguard Worker         else
346*35238bceSAndroid Build Coastguard Worker         {
347*35238bceSAndroid Build Coastguard Worker             printHelp(argv[0]);
348*35238bceSAndroid Build Coastguard Worker             return -1;
349*35238bceSAndroid Build Coastguard Worker         }
350*35238bceSAndroid Build Coastguard Worker     }
351*35238bceSAndroid Build Coastguard Worker 
352*35238bceSAndroid Build Coastguard Worker     // Run client.
353*35238bceSAndroid Build Coastguard Worker     try
354*35238bceSAndroid Build Coastguard Worker     {
355*35238bceSAndroid Build Coastguard Worker         Client client(cmdLine);
356*35238bceSAndroid Build Coastguard Worker         client.run();
357*35238bceSAndroid Build Coastguard Worker     }
358*35238bceSAndroid Build Coastguard Worker     catch (const std::exception &e)
359*35238bceSAndroid Build Coastguard Worker     {
360*35238bceSAndroid Build Coastguard Worker         printf("%s\n", e.what());
361*35238bceSAndroid Build Coastguard Worker         return -1;
362*35238bceSAndroid Build Coastguard Worker     }
363*35238bceSAndroid Build Coastguard Worker 
364*35238bceSAndroid Build Coastguard Worker     return 0;
365*35238bceSAndroid Build Coastguard Worker }
366*35238bceSAndroid Build Coastguard Worker 
367*35238bceSAndroid Build Coastguard Worker } // namespace xs
368*35238bceSAndroid Build Coastguard Worker 
main(int argc,const char * const * argv)369*35238bceSAndroid Build Coastguard Worker int main(int argc, const char *const *argv)
370*35238bceSAndroid Build Coastguard Worker {
371*35238bceSAndroid Build Coastguard Worker     return xs::runClient(argc, argv);
372*35238bceSAndroid Build Coastguard Worker }
373