From: Eduardo Ramos Testillano Date: Sun, 20 Sep 2015 19:43:31 +0000 (+0200) Subject: Comments and popen solution (commented) X-Git-Tag: REFACTORING_TESTING_LIBRARY~110 X-Git-Url: https://git.teslayout.com/public/public/public/?p=anna.git;a=commitdiff_plain;h=cbbe8862e2d4f395e61c1939fbbabf9e7f92fa2b Comments and popen solution (commented) --- diff --git a/example/diameter/launcher/testing/TestStep.cpp b/example/diameter/launcher/testing/TestStep.cpp index bf56391..491ec65 100644 --- a/example/diameter/launcher/testing/TestStep.cpp +++ b/example/diameter/launcher/testing/TestStep.cpp @@ -16,7 +16,6 @@ #include // exit #include // waitpid, pid_t, WNOHANG - // Project #include #include @@ -39,7 +38,7 @@ namespace { void handle_sigchld(int sig) { - while (waitpid((pid_t)(-1), 0, WNOHANG|WNOWAIT) > 0) {} + while (waitpid((pid_t)(-1 /* any child (the only) */), 0, WNOHANG|WNOWAIT) > 0) {} } void cmdRunOnThread (TestStepCmd *step, const std::string &cmd) { @@ -47,33 +46,46 @@ namespace { // Thread running: step->setThreadRunning(true); - // Result code: - int rc = 1; + int status = -2; struct sigaction sa; sa.sa_handler = &handle_sigchld; sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART | SA_NOCLDSTOP; if (sigaction(SIGCHLD, &sa, 0) != -1) { - rc = system(cmd.c_str()); + status = system(cmd.c_str()); + /* POPEN version: + char readbuf[256]; + FILE *fp = popen(cmd.c_str(), "r"); + if (fp) { + while(fgets(readbuf, sizeof(readbuf), fp)) + step->appendOutput("\n"); + step->appendOutput(readbuf); + status = pclose(fp); + } + else { + status = -1; + } + */ } else { perror(0); } + // This can be implemented portably and somewhat more concisely with the signal function if you prefer: + // if (signal(SIGCHLD, SIG_IGN) == SIG_ERR) { + // perror(0); + // exit(1); + // } - if (rc < 0) { + if (status < 0) { char buf[256]; char const * str = strerror_r(errno, buf, 256); - step->setErrorMsg(anna::functions::asString("errno = %d(%s)", errno, str)); - //std::terminate; - } - else { - rc >>= 8; // divide by 256 + step->setErrorMsg(anna::functions::asString("errno = %d (%s)", errno, str)); } - step->setResultCode(rc); + step->setResultCode(WEXITSTATUS(status)); // rc = status >>= 8; // divide by 256 step->complete(); - // TODO: timeout the system call + // TODO: terminate thread when deprecated (RT signal ?) // TODO: mutex the step while setting data here !! } } @@ -458,7 +470,6 @@ throw() { result->createAttribute("Script", (a_script != "") ? a_script:""); result->createAttribute("Parameters", (a_parameters != "") ? a_parameters:""); - result->createAttribute("CommandInProgress", a_threadRunning ? "yes":"no"); if (a_errorMsg != "") result->createAttribute("ErrorMessage", a_errorMsg); if (!a_threadRunning && a_resultCode != -2) { result->createAttribute("ResultCode", a_resultCode); @@ -469,7 +480,7 @@ throw() { } bool TestStepCmd::do_execute() throw() { - if (!a_threadRunning) { + if (!a_threadRunning /* || a_threadDeprecated DO NOT WANT TO OVERLAP ... */) { // Special tags to replace: std::string cmd = getScript(); cmd += " "; @@ -486,7 +497,8 @@ bool TestStepCmd::do_execute() throw() { a_thread.detach(); } - return false; // don't go next (wait complete) + return false; // don't go next (wait complete): If system function on thread stucks, then the reset test case will stuck here forever. + // We must implement a interrupt procedure for the thread on reset call... TODO ! } void TestStepCmd::do_complete() throw() { @@ -495,6 +507,8 @@ void TestStepCmd::do_complete() throw() { if (a_threadDeprecated) { a_threadDeprecated = false; do_reset(); + setErrorMsg(anna::functions::asString("Step %d deprecated due to previous reset for Test Case %llu", getNumber(), a_testCase->getId())); + a_testCase->setState(TestCase::State::Failed); return; // ignore TODO: interrupt the thread to avoid execution of the script } diff --git a/example/diameter/launcher/testing/TestStep.hpp b/example/diameter/launcher/testing/TestStep.hpp index 38f40b6..1cb062d 100644 --- a/example/diameter/launcher/testing/TestStep.hpp +++ b/example/diameter/launcher/testing/TestStep.hpp @@ -213,7 +213,7 @@ class TestStepCmd : public TestStep { bool a_threadDeprecated; int a_resultCode; std::string a_errorMsg; - //std::string a_output; + //std::string a_output; // for POPEN public: TestStepCmd(TestCase *testCase) : TestStep(testCase), a_threadRunning(false), a_threadDeprecated(false), a_resultCode(-2)/*, a_output("")*/, a_errorMsg("") { a_type = Type::Cmd; } @@ -228,7 +228,7 @@ class TestStepCmd : public TestStep { int getResultCode() const throw() { return a_resultCode; } void setErrorMsg(const std::string &em) throw() { a_errorMsg = em; } const std::string &getErrorMsg() const throw() { return a_errorMsg; } - //void setOutput(const std::string &output) throw() { a_output = output; } + //void appendOutput(const std::string &output) throw() { a_output += output; } //const std::string &getOutput() const throw() { return a_output; } void setScript(const std::string &script) throw() { a_script = script; }