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