Add init and finish functionality
[platform/core/test/security-tests.git] / src / framework / src / test_runner_child.cpp
index 19ed08c..fcb745e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2013-2015 Samsung Electronics Co., Ltd All Rights Reserved
  *
  *    Licensed under the Apache License, Version 2.0 (the "License");
  *    you may not use this file except in compliance with the License.
  *    See the License for the specific language governing permissions and
  *    limitations under the License.
  */
-/*
+/**
  * @file        test_runner_child.cpp
  * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
  * @version     1.0
  * @brief       This file is the implementation file of test runner
  */
 #include <stddef.h>
+#include <dpl/assert.h>
+#include <dpl/test/test_failed.h>
+#include <dpl/test/test_ignored.h>
 #include <dpl/test/test_runner.h>
 #include <dpl/test/test_runner_child.h>
 #include <dpl/test/test_results_collector.h>
@@ -47,9 +50,6 @@ const int CHILD_TEST_FAIL    = 0;
 const int CHILD_TEST_PASS    = 1;
 const int CHILD_TEST_IGNORED = 2;
 
-const int MSG_TYPE_MESSAGE   = 0; // sizeof(Message) + Message
-const int MSG_TYPE_PERF_TIME = 1; // perfTime + maxTime
-
 int closeOutput() {
     int devnull;
     int retcode = -1;
@@ -113,7 +113,6 @@ PipeWrapper::Status PipeWrapper::send(int code, std::string &message)
 
     std::ostringstream output;
     output << toBinaryString(code);
-    output << toBinaryString(MSG_TYPE_MESSAGE);
     output << toBinaryString(static_cast<int>(message.size()));
     output << message;
 
@@ -129,21 +128,16 @@ PipeWrapper::Status PipeWrapper::send(int code, std::string &message)
     return SUCCESS;
 }
 
-PipeWrapper::Status PipeWrapper::sendTime(int code,
-                                          std::chrono::system_clock::duration time,
-                                          std::chrono::system_clock::duration timeMax)
+PipeWrapper::Status PipeWrapper::sendPerformance(const ConstPerformanceResultPtr &performance)
 {
+    int foo = 0;
     if (m_pipefd[1] == PIPE_CLOSED) {
         return ERROR;
     }
+    if (!performance)
+        return writeHelp(&foo, sizeof(int));
 
-    std::ostringstream output;
-    output << toBinaryString(code);
-    output << toBinaryString(MSG_TYPE_PERF_TIME);
-    output << toBinaryString(time);
-    output << toBinaryString(timeMax);
-
-    std::string binary = output.str();
+    std::string binary = performance->ToBinaryString();
     int size = binary.size();
 
     if ((writeHelp(&size,
@@ -156,10 +150,8 @@ PipeWrapper::Status PipeWrapper::sendTime(int code,
 }
 
 PipeWrapper::Status PipeWrapper::receive(int &code,
-                                         int &msgType,
                                          std::string &data,
-                                         std::chrono::system_clock::duration &time,
-                                         std::chrono::system_clock::duration &timeMax,
+                                         PerformanceResultPtr &performance,
                                          time_t deadline)
 {
     if (m_pipefd[0] == PIPE_CLOSED) {
@@ -185,24 +177,34 @@ PipeWrapper::Status PipeWrapper::receive(int &code,
         queue.AppendCopy(&buffer[0], size);
 
         queue.FlattenConsume(&code, sizeof(int));
-        queue.FlattenConsume(&msgType, sizeof(int));
-
-        switch (msgType) {
-        case MSG_TYPE_MESSAGE:
-            queue.FlattenConsume(&size, sizeof(int));
-
-            buffer.resize(size);
-
-            queue.FlattenConsume(&buffer[0], size);
-            data.assign(buffer.begin(), buffer.end());
-            break;
-        case MSG_TYPE_PERF_TIME:
-            queue.FlattenConsume(&time, sizeof(std::chrono::system_clock::duration));
-            queue.FlattenConsume(&timeMax, sizeof(std::chrono::system_clock::duration));
-            break;
-        default:
-            return ERROR;
+        queue.FlattenConsume(&size, sizeof(int));
+
+        buffer.resize(size);
+
+        queue.FlattenConsume(&buffer[0], size);
+        data.assign(buffer.begin(), buffer.end());
+
+        if (code != CHILD_TEST_PASS)
+            return SUCCESS;
+
+        if ((ret = readHelp(&size, sizeof(int), deadline)) != SUCCESS) {
+            return ret;
         }
+
+        if (size == 0) {
+            performance = nullptr;
+            return SUCCESS;
+        }
+
+        buffer.resize(size);
+
+        if ((ret = readHelp(buffer.data(), size, deadline)) != SUCCESS) {
+            return ret;
+        }
+
+        queue.AppendCopy(buffer.data(), size);
+
+        performance.reset(new PerformanceResult(queue));
     } catch (DPL::BinaryQueue::Exception::Base &e) {
         return ERROR;
     }
@@ -222,13 +224,6 @@ std::string PipeWrapper::toBinaryString(int data)
     return std::string(buffer, buffer + sizeof(int));
 }
 
-std::string PipeWrapper::toBinaryString(std::chrono::system_clock::duration data)
-{
-    char buffer[sizeof(std::chrono::system_clock::duration)];
-    memcpy(buffer, &data, sizeof(std::chrono::system_clock::duration));
-    return std::string(buffer, buffer + sizeof(std::chrono::system_clock::duration));
-}
-
 void PipeWrapper::closeHelp(int desc)
 {
     if (m_pipefd[desc] != PIPE_CLOSED) {
@@ -293,17 +288,17 @@ PipeWrapper::Status PipeWrapper::readHelp(void *buf, int size, time_t deadline)
     return SUCCESS;
 }
 
-void RunChildProc(TestRunner::TestCase procChild)
+void RunChildProc(const std::function<void(void)> &testFunc)
 {
     PipeWrapper pipe;
     if (!pipe.isReady()) {
-        throw TestRunner::TestFailed("Pipe creation failed");
+        throw TestFailed("Pipe creation failed");
     }
 
     pid_t pid = fork();
 
     if (pid == -1) {
-        throw TestRunner::TestFailed("Child creation failed");
+        throw TestFailed("Child creation failed");
     }
 
     if (pid != 0) {
@@ -311,12 +306,10 @@ void RunChildProc(TestRunner::TestCase procChild)
         pipe.setUsage(PipeWrapper::READONLY);
 
         int code;
-        int msgType;
-        std::chrono::system_clock::duration time_m;
-        std::chrono::system_clock::duration timeMax_m;
         std::string message;
+        PerformanceResultPtr performance;
 
-        int pipeReturn = pipe.receive(code, msgType, message, time_m, timeMax_m, time(0) + 10);
+        int pipeReturn = pipe.receive(code, message, performance, time(0) + 10);
 
         if (pipeReturn != PipeWrapper::SUCCESS) { // Timeout or reading error
             pipe.closeAll();
@@ -327,23 +320,19 @@ void RunChildProc(TestRunner::TestCase procChild)
         waitpid(pid, &status, 0);
 
         if (pipeReturn == PipeWrapper::TIMEOUT) {
-            throw TestRunner::TestFailed("Timeout");
+            throw TestFailed("Timeout");
         }
 
         if (pipeReturn == PipeWrapper::ERROR) {
-            throw TestRunner::TestFailed("Reading pipe error");
+            throw TestFailed("Reading pipe error");
         }
 
-        if (code == CHILD_TEST_PASS && msgType == MSG_TYPE_PERF_TIME) {
-            DPL::Test::TestRunnerSingleton::Instance().setCurrentTestCasePerformanceResult(true,
-                                                                                           time_m,
-                                                                                           timeMax_m);
-        }
+        TestRunnerSingleton::Instance().setCurrentTestCasePerformanceResult(performance);
 
         if (code == CHILD_TEST_FAIL) {
-            throw TestRunner::TestFailed(message);
+            throw TestFailed(message);
         } else if (code == CHILD_TEST_IGNORED) {
-            throw TestRunner::Ignored(message);
+            throw TestIgnored(message);
         }
     } else {
         // child code
@@ -351,12 +340,6 @@ void RunChildProc(TestRunner::TestCase procChild)
         // End Runner after current test
         TestRunnerSingleton::Instance().Terminate();
 
-        int code = CHILD_TEST_PASS;
-        std::string msg;
-        bool isPerformanceTest;
-        std::chrono::system_clock::duration time_m;
-        std::chrono::system_clock::duration timeMax_m;
-
         bool allowLogs = TestRunnerSingleton::Instance().GetAllowChildLogs();
 
         close(STDIN_FILENO);
@@ -366,33 +349,30 @@ void RunChildProc(TestRunner::TestCase procChild)
 
         pipe.setUsage(PipeWrapper::WRITEONLY);
 
-        try {
-            procChild();
-        } catch (const DPL::Test::TestRunner::TestFailed &e) {
-            msg = e.GetMessage();
-            code = CHILD_TEST_FAIL;
-        } catch (const DPL::Test::TestRunner::Ignored &e) {
-            msg = e.GetMessage();
-            code = CHILD_TEST_IGNORED;
-        } catch (...) { // catch all exception generated by "user" code
-            msg = "unhandled exeception";
-            code = CHILD_TEST_FAIL;
+        int code;
+        std::string msg;
+        switch (TryCatch(testFunc, msg)) {
+            case TestResult::FailStatus::FAILED:
+                code = CHILD_TEST_FAIL;
+                break;
+            case TestResult::FailStatus::IGNORED:
+                code = CHILD_TEST_IGNORED;
+                break;
+            case TestResult::FailStatus::NONE:
+                code = CHILD_TEST_PASS;
+                break;
+            default:
+                Assert(false && "Unhandled fail status");
         }
 
         if (allowLogs) {
             closeOutput();
         }
 
-        DPL::Test::TestRunnerSingleton::Instance().getCurrentTestCasePerformanceResult(isPerformanceTest,
-                                                                                       time_m,
-                                                                                       timeMax_m);
-
-        if (code == CHILD_TEST_PASS && isPerformanceTest){
-            pipe.sendTime(code,
-                    time_m,
-                    timeMax_m);
-        } else {
-            pipe.send(code, msg);
+        pipe.send(code, msg);
+        if (code == CHILD_TEST_PASS){
+            pipe.sendPerformance(TestRunnerSingleton::Instance() \
+                 .getCurrentTestCasePerformanceResult());
         }
     }
 }