xref: /aosp_15_r20/external/deqp/executor/xeLocalTcpIpLink.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker  * drawElements Quality Program Test Executor
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 Tcp/Ip link that manages execserver process.
22*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker 
24*35238bceSAndroid Build Coastguard Worker #include "xeLocalTcpIpLink.hpp"
25*35238bceSAndroid Build Coastguard Worker #include "deClock.h"
26*35238bceSAndroid Build Coastguard Worker #include "deThread.h"
27*35238bceSAndroid Build Coastguard Worker 
28*35238bceSAndroid Build Coastguard Worker #include <sstream>
29*35238bceSAndroid Build Coastguard Worker 
30*35238bceSAndroid Build Coastguard Worker enum
31*35238bceSAndroid Build Coastguard Worker {
32*35238bceSAndroid Build Coastguard Worker     SERVER_START_TIMEOUT    = 1000,
33*35238bceSAndroid Build Coastguard Worker     SERVER_START_IDLE_SLEEP = 50
34*35238bceSAndroid Build Coastguard Worker };
35*35238bceSAndroid Build Coastguard Worker 
36*35238bceSAndroid Build Coastguard Worker namespace xe
37*35238bceSAndroid Build Coastguard Worker {
38*35238bceSAndroid Build Coastguard Worker 
LocalTcpIpLink(void)39*35238bceSAndroid Build Coastguard Worker LocalTcpIpLink::LocalTcpIpLink(void) : m_process(DE_NULL)
40*35238bceSAndroid Build Coastguard Worker {
41*35238bceSAndroid Build Coastguard Worker }
42*35238bceSAndroid Build Coastguard Worker 
~LocalTcpIpLink(void)43*35238bceSAndroid Build Coastguard Worker LocalTcpIpLink::~LocalTcpIpLink(void)
44*35238bceSAndroid Build Coastguard Worker {
45*35238bceSAndroid Build Coastguard Worker     stop();
46*35238bceSAndroid Build Coastguard Worker }
47*35238bceSAndroid Build Coastguard Worker 
start(const char * execServerPath,const char * workDir,int port)48*35238bceSAndroid Build Coastguard Worker void LocalTcpIpLink::start(const char *execServerPath, const char *workDir, int port)
49*35238bceSAndroid Build Coastguard Worker {
50*35238bceSAndroid Build Coastguard Worker     XE_CHECK(!m_process);
51*35238bceSAndroid Build Coastguard Worker 
52*35238bceSAndroid Build Coastguard Worker     std::ostringstream cmdLine;
53*35238bceSAndroid Build Coastguard Worker     cmdLine << execServerPath << " --single --port=" << port;
54*35238bceSAndroid Build Coastguard Worker 
55*35238bceSAndroid Build Coastguard Worker     m_process = deProcess_create();
56*35238bceSAndroid Build Coastguard Worker     XE_CHECK(m_process);
57*35238bceSAndroid Build Coastguard Worker 
58*35238bceSAndroid Build Coastguard Worker     if (deProcess_start(m_process, cmdLine.str().c_str(), workDir) != true)
59*35238bceSAndroid Build Coastguard Worker     {
60*35238bceSAndroid Build Coastguard Worker         std::string err = deProcess_getLastError(m_process);
61*35238bceSAndroid Build Coastguard Worker         deProcess_destroy(m_process);
62*35238bceSAndroid Build Coastguard Worker         m_process = DE_NULL;
63*35238bceSAndroid Build Coastguard Worker 
64*35238bceSAndroid Build Coastguard Worker         XE_FAIL((std::string("Failed to start ExecServer '") + execServerPath + "' : " + err).c_str());
65*35238bceSAndroid Build Coastguard Worker     }
66*35238bceSAndroid Build Coastguard Worker 
67*35238bceSAndroid Build Coastguard Worker     try
68*35238bceSAndroid Build Coastguard Worker     {
69*35238bceSAndroid Build Coastguard Worker         de::SocketAddress address;
70*35238bceSAndroid Build Coastguard Worker         address.setFamily(DE_SOCKETFAMILY_INET4);
71*35238bceSAndroid Build Coastguard Worker         address.setProtocol(DE_SOCKETPROTOCOL_TCP);
72*35238bceSAndroid Build Coastguard Worker         address.setHost("127.0.0.1");
73*35238bceSAndroid Build Coastguard Worker         address.setPort(port);
74*35238bceSAndroid Build Coastguard Worker 
75*35238bceSAndroid Build Coastguard Worker         // Wait until server has started - \todo [2012-07-19 pyry] This could be improved by having server to signal when it is ready.
76*35238bceSAndroid Build Coastguard Worker         uint64_t waitStart = deGetMicroseconds();
77*35238bceSAndroid Build Coastguard Worker         for (;;)
78*35238bceSAndroid Build Coastguard Worker         {
79*35238bceSAndroid Build Coastguard Worker             if (!deProcess_isRunning(m_process))
80*35238bceSAndroid Build Coastguard Worker                 XE_FAIL("ExecServer died");
81*35238bceSAndroid Build Coastguard Worker 
82*35238bceSAndroid Build Coastguard Worker             try
83*35238bceSAndroid Build Coastguard Worker             {
84*35238bceSAndroid Build Coastguard Worker                 m_link.connect(address);
85*35238bceSAndroid Build Coastguard Worker                 break;
86*35238bceSAndroid Build Coastguard Worker             }
87*35238bceSAndroid Build Coastguard Worker             catch (const de::SocketError &)
88*35238bceSAndroid Build Coastguard Worker             {
89*35238bceSAndroid Build Coastguard Worker                 if (deGetMicroseconds() - waitStart > SERVER_START_TIMEOUT * 1000)
90*35238bceSAndroid Build Coastguard Worker                     XE_FAIL("Server start timeout");
91*35238bceSAndroid Build Coastguard Worker 
92*35238bceSAndroid Build Coastguard Worker                 deSleep(SERVER_START_IDLE_SLEEP);
93*35238bceSAndroid Build Coastguard Worker             }
94*35238bceSAndroid Build Coastguard Worker         }
95*35238bceSAndroid Build Coastguard Worker 
96*35238bceSAndroid Build Coastguard Worker         // Close stdout/stderr or otherwise process will hang once OS pipe buffers are full.
97*35238bceSAndroid Build Coastguard Worker         // \todo [2012-07-19 pyry] Read and store stdout/stderr from execserver.
98*35238bceSAndroid Build Coastguard Worker         XE_CHECK(deProcess_closeStdOut(m_process));
99*35238bceSAndroid Build Coastguard Worker         XE_CHECK(deProcess_closeStdErr(m_process));
100*35238bceSAndroid Build Coastguard Worker     }
101*35238bceSAndroid Build Coastguard Worker     catch (const std::exception &)
102*35238bceSAndroid Build Coastguard Worker     {
103*35238bceSAndroid Build Coastguard Worker         stop();
104*35238bceSAndroid Build Coastguard Worker         throw;
105*35238bceSAndroid Build Coastguard Worker     }
106*35238bceSAndroid Build Coastguard Worker }
107*35238bceSAndroid Build Coastguard Worker 
stop(void)108*35238bceSAndroid Build Coastguard Worker void LocalTcpIpLink::stop(void)
109*35238bceSAndroid Build Coastguard Worker {
110*35238bceSAndroid Build Coastguard Worker     if (m_process)
111*35238bceSAndroid Build Coastguard Worker     {
112*35238bceSAndroid Build Coastguard Worker         try
113*35238bceSAndroid Build Coastguard Worker         {
114*35238bceSAndroid Build Coastguard Worker             m_link.disconnect();
115*35238bceSAndroid Build Coastguard Worker         }
116*35238bceSAndroid Build Coastguard Worker         catch (...)
117*35238bceSAndroid Build Coastguard Worker         {
118*35238bceSAndroid Build Coastguard Worker             // Silently ignore since this is called in destructor.
119*35238bceSAndroid Build Coastguard Worker         }
120*35238bceSAndroid Build Coastguard Worker 
121*35238bceSAndroid Build Coastguard Worker         // \note --single flag is used so execserver should kill itself once one connection is handled.
122*35238bceSAndroid Build Coastguard Worker         //         This is here to make sure it dies even in case of hang.
123*35238bceSAndroid Build Coastguard Worker         deProcess_terminate(m_process);
124*35238bceSAndroid Build Coastguard Worker         deProcess_waitForFinish(m_process);
125*35238bceSAndroid Build Coastguard Worker         deProcess_destroy(m_process);
126*35238bceSAndroid Build Coastguard Worker 
127*35238bceSAndroid Build Coastguard Worker         m_process = DE_NULL;
128*35238bceSAndroid Build Coastguard Worker     }
129*35238bceSAndroid Build Coastguard Worker }
130*35238bceSAndroid Build Coastguard Worker 
reset(void)131*35238bceSAndroid Build Coastguard Worker void LocalTcpIpLink::reset(void)
132*35238bceSAndroid Build Coastguard Worker {
133*35238bceSAndroid Build Coastguard Worker     m_link.reset();
134*35238bceSAndroid Build Coastguard Worker }
135*35238bceSAndroid Build Coastguard Worker 
getState(void) const136*35238bceSAndroid Build Coastguard Worker CommLinkState LocalTcpIpLink::getState(void) const
137*35238bceSAndroid Build Coastguard Worker {
138*35238bceSAndroid Build Coastguard Worker     if (!m_process)
139*35238bceSAndroid Build Coastguard Worker         return COMMLINKSTATE_ERROR;
140*35238bceSAndroid Build Coastguard Worker     else
141*35238bceSAndroid Build Coastguard Worker         return m_link.getState();
142*35238bceSAndroid Build Coastguard Worker }
143*35238bceSAndroid Build Coastguard Worker 
getState(std::string & error) const144*35238bceSAndroid Build Coastguard Worker CommLinkState LocalTcpIpLink::getState(std::string &error) const
145*35238bceSAndroid Build Coastguard Worker {
146*35238bceSAndroid Build Coastguard Worker     if (!m_process)
147*35238bceSAndroid Build Coastguard Worker     {
148*35238bceSAndroid Build Coastguard Worker         error = "Not started";
149*35238bceSAndroid Build Coastguard Worker         return COMMLINKSTATE_ERROR;
150*35238bceSAndroid Build Coastguard Worker     }
151*35238bceSAndroid Build Coastguard Worker     else
152*35238bceSAndroid Build Coastguard Worker         return m_link.getState();
153*35238bceSAndroid Build Coastguard Worker }
154*35238bceSAndroid Build Coastguard Worker 
setCallbacks(StateChangedFunc stateChangedCallback,LogDataFunc testLogDataCallback,LogDataFunc infoLogDataCallback,void * userPtr)155*35238bceSAndroid Build Coastguard Worker void LocalTcpIpLink::setCallbacks(StateChangedFunc stateChangedCallback, LogDataFunc testLogDataCallback,
156*35238bceSAndroid Build Coastguard Worker                                   LogDataFunc infoLogDataCallback, void *userPtr)
157*35238bceSAndroid Build Coastguard Worker {
158*35238bceSAndroid Build Coastguard Worker     m_link.setCallbacks(stateChangedCallback, testLogDataCallback, infoLogDataCallback, userPtr);
159*35238bceSAndroid Build Coastguard Worker }
160*35238bceSAndroid Build Coastguard Worker 
startTestProcess(const char * name,const char * params,const char * workingDir,const char * caseList)161*35238bceSAndroid Build Coastguard Worker void LocalTcpIpLink::startTestProcess(const char *name, const char *params, const char *workingDir,
162*35238bceSAndroid Build Coastguard Worker                                       const char *caseList)
163*35238bceSAndroid Build Coastguard Worker {
164*35238bceSAndroid Build Coastguard Worker     if (m_process)
165*35238bceSAndroid Build Coastguard Worker         m_link.startTestProcess(name, params, workingDir, caseList);
166*35238bceSAndroid Build Coastguard Worker     else
167*35238bceSAndroid Build Coastguard Worker         XE_FAIL("Not started");
168*35238bceSAndroid Build Coastguard Worker }
169*35238bceSAndroid Build Coastguard Worker 
stopTestProcess(void)170*35238bceSAndroid Build Coastguard Worker void LocalTcpIpLink::stopTestProcess(void)
171*35238bceSAndroid Build Coastguard Worker {
172*35238bceSAndroid Build Coastguard Worker     if (m_process)
173*35238bceSAndroid Build Coastguard Worker         m_link.stopTestProcess();
174*35238bceSAndroid Build Coastguard Worker     else
175*35238bceSAndroid Build Coastguard Worker         XE_FAIL("Not started");
176*35238bceSAndroid Build Coastguard Worker }
177*35238bceSAndroid Build Coastguard Worker 
178*35238bceSAndroid Build Coastguard Worker } // namespace xe
179