From a472fec381e7abc3d9e1384d1b7581a9e304a16c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Boisnard?= Date: Fri, 10 Jan 2014 18:46:10 +0100 Subject: Allow starting test-platform as a Daemon MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BZ: 151780 Currently, test-platform does not return when it is launched. In particular, one has to try to connect to it in order to know if it has correctly been initialized. Added a new '-d' option to test-platform to start it as a daemon: test-platform [-d] [port number, default 5001] When test-platform is started as a daemon, a child process is created and the main process immediatly returns its status. Change-Id: I70a33691909c958904cf50d156a563b998f92657 Signed-off-by: Frédéric Boisnard --- test/test-platform/TestPlatform.cpp | 6 +- test/test-platform/TestPlatform.h | 3 + test/test-platform/main.cpp | 170 ++++++++++++++++++++++++++++++++---- 3 files changed, 163 insertions(+), 16 deletions(-) (limited to 'test') diff --git a/test/test-platform/TestPlatform.cpp b/test/test-platform/TestPlatform.cpp index b69a10e..1b9951e 100644 --- a/test/test-platform/TestPlatform.cpp +++ b/test/test-platform/TestPlatform.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include "TestPlatform.h" #include "ParameterMgrPlatformConnector.h" #include "RemoteProcessorServer.h" @@ -53,6 +54,7 @@ public: CTestPlatform::CTestPlatform(const string& strClass, int iPortNumber, sem_t& exitSemaphore) : _pParameterMgrPlatformConnector(new CParameterMgrPlatformConnector(strClass)), _pParameterMgrPlatformConnectorLogger(new CParameterMgrPlatformConnectorLogger), + _portNumber(iPortNumber), _exitSemaphore(exitSemaphore) { _pCommandHandler = new CCommandHandler(this); @@ -146,7 +148,9 @@ bool CTestPlatform::load(std::string& strError) // Start remote processor server if (!_pRemoteProcessorServer->start()) { - strError = "Unable to start remote processor server"; + ostringstream oss; + oss << "TestPlatform: Unable to start remote processor server on port " << _portNumber; + strError = oss.str(); return false; } diff --git a/test/test-platform/TestPlatform.h b/test/test-platform/TestPlatform.h index 8673e9d..9198ef8 100644 --- a/test/test-platform/TestPlatform.h +++ b/test/test-platform/TestPlatform.h @@ -150,6 +150,9 @@ private: // Remote Processor Server CRemoteProcessorServer* _pRemoteProcessorServer; + // Port number for the server socket + int _portNumber; + // Semaphore used by calling thread to avoid exiting sem_t& _exitSemaphore; }; diff --git a/test/test-platform/main.cpp b/test/test-platform/main.cpp index d97a449..6ed5a38 100644 --- a/test/test-platform/main.cpp +++ b/test/test-platform/main.cpp @@ -28,21 +28,16 @@ #include #include #include +#include +#include using namespace std; const int iDefaultPortNumber = 5001; -int main(int argc, char *argv[]) +// Starts test-platform in blocking mode +static bool startBlockingTestPlatform(const char *filePath, int portNumber, string &strError) { - if (argc < 2) { - - cerr << "Missing arguments: test-platform [port number, default " << iDefaultPortNumber << "]" << endl; - - return -1; - } - - string strError; // Init semaphore sem_t sem; @@ -50,24 +45,169 @@ int main(int argc, char *argv[]) sem_init(&sem, false, 0); // Create param mgr - CTestPlatform testPlatform(argv[1], argc > 2 ? atoi(argv[2]) : iDefaultPortNumber, sem); + CTestPlatform testPlatform(filePath, portNumber, sem); // Start platformmgr if (!testPlatform.load(strError)) { - cerr << strError << endl; - sem_destroy(&sem); - return -1; + return false; } - // Change criteria - // Block here sem_wait(&sem); sem_destroy(&sem); + return true; +} + +// Starts test-platform in daemon mode +static bool startDaemonTestPlatform(const char *filePath, int portNumber, string &strError) +{ + // Pipe used for communication between the child and the parent processes + int pipefd[2]; + + if (pipe(pipefd) == -1) { + + strError = "pipe failed"; + return false; + } + + // Fork the current process: + // - Child process is used to start test-platform + // - Parent process is killed in order to turn its child into a daemon + pid_t pid = fork(); + + if (pid < 0) { + + strError = "fork failed!"; + return false; + + } else if (pid == 0) { + + // Child process : starts test-platform and notify the parent if it succeeds. + + // Close read side of the pipe + close(pipefd[0]); + + // Init semaphore + sem_t sem; + + sem_init(&sem, false, 0); + + // Create param mgr + CTestPlatform testPlatform(filePath, portNumber, sem); + + // Message to send to parent process + bool msgToParent; + + // Start platformmgr + if (!testPlatform.load(strError)) { + + cerr << strError << endl; + + // Notify parent of failure; + msgToParent = false; + write(pipefd[1], &msgToParent, sizeof(msgToParent)); + + sem_destroy(&sem); + } else { + + // Notify parent of success + msgToParent = true; + write(pipefd[1], &msgToParent, sizeof(msgToParent)); + + // Block here + sem_wait(&sem); + + sem_destroy(&sem); + } + + return msgToParent; + + } else { + + // Parent process : need to kill it once the child notifies the successs/failure to start + // test-platform (this status is used as exit value of the program). + + // Close write side of the pipe + close(pipefd[1]); + + // Message received from the child process + bool msgFromChild = false; + + if (read(pipefd[0], &msgFromChild, sizeof(msgFromChild)) <= 0) { + + strError = "Read pipe failed"; + } + + // return success/failure in exit status + return msgFromChild; + } +} + +static void usage() +{ + cerr << "Invalid arguments: test-platform [-d] [port number, default " + << iDefaultPortNumber << "]" << endl; +} + +int main(int argc, char *argv[]) +{ + // Option found by call to getopt() + int opt; + + // Port number to be used by test-platform + int portNumber; + + // Daemon flag + bool isDaemon = false; + + // Index of the argument in the arguments list provided + int indexFilePath = 1; + + // Handle the -d option + while ((opt = getopt(argc, argv, "d")) != -1) { + switch (opt) { + case 'd': + isDaemon = true; + indexFilePath = 2; + break; + + default: + usage(); + return -1; + } + } + + // Check the number of arguments + if ((argc < indexFilePath + 1) || (argc > indexFilePath + 2)) { + + usage(); + return -1; + } + + char *filePath = argv[indexFilePath]; + portNumber = argc > indexFilePath + 1 ? atoi(argv[indexFilePath + 1]) : iDefaultPortNumber; + + // Choose either blocking or daemon test-platform + bool startError; + string strError; + + if (isDaemon) { + + startError = startDaemonTestPlatform(filePath, portNumber, strError); + } else { + + startError = startBlockingTestPlatform(filePath, portNumber, strError); + } + + if (!startError) { + + cerr << "Test-platform error:" << strError.c_str() << endl; + return -1; + } return 0; } -- cgit v1.1