Add init and finish functionality
[platform/core/test/security-tests.git] / src / framework / src / test_runner.cpp
index 95e1698..79e9666 100644 (file)
 #include <pcrecpp.h>
 #include <algorithm>
 #include <cstdio>
-#include <memory.h>
+#include <exception>
+#include <functional>
+#include <memory>
+#include <string>
 
 #include <libxml/xpath.h>
 #include <libxml/xpathInternals.h>
@@ -55,13 +58,33 @@ std::string getXMLNode(xmlNodePtr node)
 
 }
 
-
 namespace DPL {
 namespace Test {
 
-void TestRunner::RegisterTest(const char *testName, TestCase proc)
+TestResult::FailStatus TryCatch(const std::function<void(void)> &func, std::string &reason) {
+    try {
+        func();
+    } catch (const DPL::Test::TestFailed &e) {
+        reason = e.GetMessage();
+        return TestResult::FailStatus::FAILED;
+    } catch (const DPL::Test::TestIgnored &e) {
+        reason = e.GetMessage();
+        return TestResult::FailStatus::IGNORED;
+    } catch (const std::exception &e) {
+        reason = e.what();
+        return TestResult::FailStatus::FAILED;
+    } catch (...) {
+        reason = "Unknown exception";
+        return TestResult::FailStatus::FAILED;
+    }
+    reason = std::string();
+    return TestResult::FailStatus::NONE;
+}
+
+void TestRunner::RegisterTest(TestCasePtr testCase)
 {
-    m_testGroups[m_currentGroup].push_back(TestCaseStruct(testName, proc));
+    m_testGroups[m_currentGroup].push_back(testCase);
+    m_testCaseSet.insert(testCase);
 }
 
 void TestRunner::InitGroup(const char* name)
@@ -99,9 +122,9 @@ bool TestRunner::filterGroupsByXmls(const std::vector<std::string> & files)
         {
             if(!cit->second.empty())
             {
-                for(TestCaseStructList::const_iterator cj = cit->second.begin(); cj != cit->second.end(); ++cj)
+                for(TestCaseList::const_iterator cj = cit->second.begin(); cj != cit->second.end(); ++cj)
                 {
-                    std::string name = cj->name;
+                    std::string name = (*cj)->GetName();
                     std::string::size_type st = name.find('_');
                     if(st != std::string::npos)
                     {
@@ -185,11 +208,11 @@ bool TestRunner::filterGroupsByXmls(const std::vector<std::string> & files)
 bool TestRunner::filterByXML(std::map<std::string, bool> & casesMap)
 {
     for (auto &group : m_testGroups) {
-        TestCaseStructList newList;
+        TestCaseList newList;
         for (auto &tc : group.second)
         {
-            if (casesMap.find(tc.name) != casesMap.end()) {
-                casesMap[tc.name] = true;
+            if (casesMap.find(tc->GetName()) != casesMap.end()) {
+                casesMap[tc->GetName()] = true;
                 newList.push_back(tc);
             }
         }
@@ -206,49 +229,50 @@ bool TestRunner::filterByXML(std::map<std::string, bool> & casesMap)
     return true;
 }
 
-void TestRunner::RunTestCase(const TestCaseStruct& testCase)
+void TestRunner::RunTestCase(TestCasePtr testCase)
 {
-    setCurrentTestCase(&(const_cast<TestCaseStruct &>(testCase)));
-    m_deferDeepness = 0U;
-    try {
-        testCase.proc();
-    } catch (const TestFailed &e) {
-        // Simple test failure
-        CollectResult(testCase.name,
-                      TestResult(TestResult::FailStatus::FAILED,
-                                 getConcatedFailReason(e.GetMessage())));
-
-        setCurrentTestCase(nullptr);
-        return;
-    } catch (const TestIgnored &e) {
-        if (m_runIgnored) {
-            // Simple test have to be implemented
-            CollectResult(testCase.name,
-                          TestResult(TestResult::FailStatus::IGNORED, e.GetMessage()));
-        }
-
+    setCurrentTestCase(testCase);
+
+    std::string initReason;
+    TestResult::FailStatus initStatus = TryCatch(std::bind(&TestCase::Init, testCase),
+                                                 initReason);
+    if (initStatus != TestResult::FailStatus::NONE) {
+        CollectResult(testCase->GetName(),
+                      TestResult(initStatus, getConcatedFailReason(initReason), testCase->GetPerformance()));
         setCurrentTestCase(nullptr);
         return;
-    } catch (const std::exception &) {
-        // std exception failure
-        CollectResult(testCase.name,
-                      TestResult(TestResult::FailStatus::FAILED, "std exception"));
+    }
 
-        setCurrentTestCase(nullptr);
-        return;
-    } catch (...) {
-        // Unknown exception failure
-        CollectResult(testCase.name,
-                      TestResult(TestResult::FailStatus::FAILED, "unknown exception"));
-        setCurrentTestCase(nullptr);
-        return;
+    std::string testReason;
+    TestResult::FailStatus testStatus = TryCatch(std::bind(&TestCase::Test, testCase),
+                                                 testReason);
+    testReason = getConcatedFailReason(testReason);
+    std::string finishReason;
+    TestResult::FailStatus finishStatus = TryCatch(std::bind(&TestCase::Finish, testCase),
+                                                   finishReason);
+    finishReason = getConcatedFailReason(finishReason);
+
+    switch (finishStatus) {
+        case TestResult::FailStatus::FAILED:
+            testStatus = TestResult::FailStatus::FAILED;
+            if (!testReason.empty())
+                testReason += "\n";
+            testReason += finishReason;
+            break;
+        case TestResult::FailStatus::IGNORED:
+            if (testStatus == TestResult::FailStatus::NONE)
+                testStatus = TestResult::FailStatus::IGNORED;
+            if (!testReason.empty())
+                testReason += "\n";
+            testReason += finishReason;
+        case TestResult::FailStatus::NONE:
+            break;
+        default:
+            Assert(false && "Unhandled fail status");
     }
 
-    // Everything OK
-    CollectResult(testCase.name,
-                  TestResult(TestResult::FailStatus::NONE,
-                             std::string(),
-                             testCase.performance));
+    CollectResult(testCase->GetName(),
+                  TestResult(testStatus, testReason, testCase->GetPerformance()));
     setCurrentTestCase(nullptr);
 }
 
@@ -268,19 +292,19 @@ void TestRunner::RunTests()
     fprintf(stderr, "%sFound %d testcases...%s\n", GREEN_BEGIN, count, GREEN_END);
     fprintf(stderr, "%s%s%s\n", GREEN_BEGIN, "Running tests...", GREEN_END);
     for (auto &group : m_testGroups) {
-        TestCaseStructList list = group.second;
+        TestCaseList list = group.second;
         if (!list.empty()) {
             for (auto &collector : m_collectors) {
                 collector.second->CollectCurrentTestGroupName(group.first);
             }
             list.sort();
 
-            for (TestCaseStructList::const_iterator iterator = list.begin();
+            for (TestCaseList::const_iterator iterator = list.begin();
                  iterator != list.end();
                  ++iterator)
             {
-                TestCaseStruct test = *iterator;
-                if (m_startTestId == test.name) {
+                TestCasePtr test = *iterator;
+                if (m_startTestId == test->GetName()) {
                     m_startTestId = "";
                 }
 
@@ -306,51 +330,53 @@ void TestRunner::RunTests()
     fprintf(stderr, "%s%s%s\n\n", GREEN_BEGIN, "Finished", GREEN_END);
 }
 
-TestRunner::TestCaseStruct *TestRunner::getCurrentTestCase()
+TestCasePtr TestRunner::getCurrentTestCase()
 {
     return m_currentTestCase;
 }
 
-void TestRunner::setCurrentTestCase(TestCaseStruct* testCase)
+void TestRunner::setCurrentTestCase(TestCasePtr testCase)
 {
     m_currentTestCase = testCase;
 }
 
 void TestRunner::beginPerformance(std::chrono::system_clock::duration maxDurationInMicroseconds)
 {
-    TestCaseStruct* testCase = getCurrentTestCase();
+    TestCasePtr testCase = getCurrentTestCase();
     if (!testCase)
         return;
 
-    if (!testCase->performance)
-        testCase->performance.reset(new PerformanceResult(maxDurationInMicroseconds));
+    if (!testCase->GetPerformance())
+        testCase->SetPerformance(
+            std::unique_ptr<PerformanceResult>                  \
+            (new PerformanceResult(maxDurationInMicroseconds)));
 }
 
 void TestRunner::endPerformance()
 {
-    TestCaseStruct* testCase = getCurrentTestCase();
+    TestCasePtr testCase = getCurrentTestCase();
     if (!testCase)
         return;
 
-    testCase->performance->Finish();
+    testCase->GetPerformance()->Finish();
 }
 
 ConstPerformanceResultPtr TestRunner::getCurrentTestCasePerformanceResult()
 {
-    TestCaseStruct* testCase = getCurrentTestCase();
+    TestCasePtr testCase = getCurrentTestCase();
     if (!testCase)
         return nullptr;
 
-    return testCase->performance;
+    return testCase->GetPerformance();
 }
 
 void TestRunner::setCurrentTestCasePerformanceResult(const PerformanceResultPtr &performance)
 {
-    TestCaseStruct* testCase = getCurrentTestCase();
+    TestCasePtr testCase = getCurrentTestCase();
     if (!testCase)
         return;
 
-    testCase->performance = performance;
+    testCase->SetPerformance(performance);
 }
 
 void TestRunner::addFailReason(const std::string &reason)
@@ -369,8 +395,17 @@ std::string TestRunner::getConcatedFailReason(const std::string &reason)
     return reason + ret;
 }
 
+TestRunner::~TestRunner()
+{
+    for(auto &t : m_testCaseSet)
+        delete t;
+}
+
 void TestRunner::CollectResult(const std::string& id, const TestResult& result)
 {
+    if (result.GetFailStatus() == TestResult::FailStatus::IGNORED && m_runIgnored)
+        return;
+
     std::for_each(m_collectors.begin(),
                   m_collectors.end(),
                   [&](const TestResultsCollectors::value_type & collector)
@@ -499,7 +534,7 @@ int TestRunner::ExecTestRunner(ArgsList args)
             arg.erase(0, startCmd.length());
             for (auto &group : m_testGroups) {
                 for (auto &tc : group.second) {
-                    if (tc.name == arg) {
+                    if (tc->GetName() == arg) {
                         m_startTestId = arg;
                         break;
                     }
@@ -520,7 +555,7 @@ int TestRunner::ExecTestRunner(ArgsList args)
             TestCaseGroupMap::iterator found = m_testGroups.find(arg);
             if (found != m_testGroups.end()) {
                 std::string name = found->first;
-                TestCaseStructList newList = found->second;
+                TestCaseList newList = found->second;
                 m_testGroups.clear();
                 m_testGroups[name] = newList;
             } else {
@@ -541,7 +576,7 @@ int TestRunner::ExecTestRunner(ArgsList args)
         } else if (arg.find(listInGroup) == 0) {
             arg.erase(0, listInGroup.length());
             for (auto &test : m_testGroups[arg]) {
-                printf("ID:%s\n", test.name.c_str());
+                printf("ID:%s\n", test->GetName().c_str());
             }
             return 0;
         } else if (arg.find(allowChildLogs) == 0) {
@@ -585,10 +620,10 @@ int TestRunner::ExecTestRunner(ArgsList args)
 
             pcrecpp::RE re(arg.c_str());
             for (auto &group : m_testGroups) {
-                TestCaseStructList newList;
+                TestCaseList newList;
                 for (auto &tc : group.second)
                 {
-                    if (re.PartialMatch(tc.name)) {
+                    if (re.PartialMatch(tc->GetName())) {
                         newList.push_back(tc);
                     }
                 }
@@ -634,7 +669,7 @@ int TestRunner::ExecTestRunner(ArgsList args)
     {
         for (auto &group : m_testGroups) {
             for (auto &tc : group.second) {
-                printf("ID:%s:%s\n", group.first.c_str(), tc.name.c_str());
+                printf("ID:%s:%s\n", group.first.c_str(), tc->GetName().c_str());
             }
         }
         return 0;