Merge branch 'cynara' into tizen
[platform/core/test/security-tests.git] / src / framework / include / dpl / test / test_runner.h
index 8fb8803..9da89df 100644 (file)
@@ -25,6 +25,7 @@
 #define DPL_TEST_RUNNER_H
 
 #include <chrono>
+#include <cstdlib>
 #include <cstring>
 #include <exception>
 #include <iostream>
@@ -42,6 +43,9 @@
 #include <dpl/gdbbacktrace.h>
 #include <dpl/singleton.h>
 #include <dpl/test/performance_result.h>
+#include <dpl/test/test_exception.h>
+#include <dpl/test/test_failed.h>
+#include <dpl/test/test_ignored.h>
 #include <dpl/test/test_result.h>
 #include <dpl/test/test_results_collector.h>
 
@@ -63,6 +67,8 @@ class TestRunner
         m_currentTestCase(nullptr)
       , m_terminate(false)
       , m_allowChildLogs(false)
+      , m_deferDeepness(0U)
+      , m_firstDeferredExceptionType(DeferredExceptionType::DEFERRED_FAILED)
     {}
 
     void beginPerformance(std::chrono::system_clock::duration maxDurationInMicroseconds);
@@ -137,53 +143,6 @@ class TestRunner
     void CollectResult(const std::string& id, const TestResult &result);
 
   public:
-    class TestFailed
-    {
-      private:
-        std::string m_message;
-
-      public:
-        TestFailed()
-        {}
-
-        //! \brief Failed test message creator
-        //!
-        //! \param[in] aTest string for tested expression
-        //! \param[in] aFile source file name
-        //! \param[in] aLine source file line
-        //! \param[in] aMessage error message
-        TestFailed(const char* aTest,
-                   const char* aFile,
-                   int aLine,
-                   const std::string &aMessage);
-
-        TestFailed(const std::string &message);
-
-        std::string GetMessage() const
-        {
-            return m_message;
-        }
-    };
-
-    class Ignored
-    {
-      private:
-        std::string m_message;
-
-      public:
-        Ignored()
-        {}
-
-        Ignored(const std::string &message) :
-            m_message(message)
-        {}
-
-        std::string GetMessage() const
-        {
-            return m_message;
-        }
-    };
-
     void MarkAssertion();
 
     void RegisterTest(const char *testName, TestCase proc);
@@ -196,6 +155,21 @@ class TestRunner
     // The runner will terminate as soon as possible (after current test).
     void Terminate();
     bool GetAllowChildLogs();
+
+    void deferFailedException(const DPL::Test::TestFailed &ex);
+    void deferIgnoredException(const DPL::Test::TestIgnored &ex);
+    void deferBegin();
+    void deferEnd();
+
+private:
+    std::vector<std::string> m_deferredExceptionsMessages;
+    std::size_t m_deferDeepness;
+    enum DeferredExceptionType {
+        DEFERRED_FAILED,
+        DEFERRED_IGNORED,
+    } m_firstDeferredExceptionType;
+    DPL::Test::TestFailed m_firstDeferredFail;
+    DPL::Test::TestIgnored m_firstDeferredIgnore;
 };
 
 typedef DPL::Singleton<TestRunner> TestRunnerSingleton;
@@ -238,10 +212,10 @@ typedef DPL::Singleton<TestRunner> TestRunnerSingleton;
         {                                                                             \
             std::ostringstream assertMsg;                                             \
             assertMsg << message << DPL::gdbbacktrace();                              \
-            DPL::Test::TestRunner::TestFailed e(#test,                                \
-                                                __FILE__,                             \
-                                                __LINE__,                             \
-                                                assertMsg.str());                     \
+            DPL::Test::TestFailed e(#test,                                            \
+                                    __FILE__,                                         \
+                                    __LINE__,                                         \
+                                    assertMsg.str());                                 \
             if (!std::uncaught_exception())                                           \
                 throw e;                                                              \
             DPL::Test::TestRunnerSingleton::Instance().addFailReason(e.GetMessage()); \
@@ -261,10 +235,10 @@ typedef DPL::Singleton<TestRunner> TestRunnerSingleton;
             if (!assertMsg.str().empty())                                             \
                 assertMsg << ". ";                                                    \
             assertMsg << err << DPL::gdbbacktrace();                                  \
-            DPL::Test::TestRunner::TestFailed e(#test,                                \
-                                                __FILE__,                             \
-                                                __LINE__,                             \
-                                                assertMsg.str());                     \
+            DPL::Test::TestFailed e(#test,                                            \
+                                    __FILE__,                                         \
+                                    __LINE__,                                         \
+                                    assertMsg.str());                                 \
             if (!std::uncaught_exception())                                           \
                 throw e;                                                              \
             DPL::Test::TestRunnerSingleton::Instance().addFailReason(e.GetMessage()); \
@@ -288,12 +262,12 @@ typedef DPL::Singleton<TestRunner> TestRunnerSingleton;
  * body.
  */
 
-#define RUNNER_IGNORED_MSG(message)                            \
-    do                                                         \
-    {                                                          \
-        std::ostringstream assertMsg;                          \
-        assertMsg << message;                                  \
-        throw DPL::Test::TestRunner::Ignored(assertMsg.str()); \
+#define RUNNER_IGNORED_MSG(message)                    \
+    do                                                 \
+    {                                                  \
+        std::ostringstream assertMsg;                  \
+        assertMsg << message;                          \
+        throw DPL::Test::TestIgnored(assertMsg.str()); \
     } while (0)
 
 /**
@@ -337,4 +311,39 @@ typedef DPL::Singleton<TestRunner> TestRunnerSingleton;
                   << DPL::Colors::Text::RED_END << std::endl; \
     } while (0)
 
+/**
+ * DEFER MACROS
+ *
+ * Use them to defer fails and ignores in test cases.
+ * Some code constructions disallow to throw. Such places can be surrounded
+ * with RUNNER_DEFER_SCOPE macro. RUNNER_DEFER_TRYCATCH macro can be used to catch possibly thrown
+ * exceptions within such scope. Possibly catched exceptions will be rethrown
+ * when leaving RUNNER_DEFER_SCOPE scope.
+ * Macros can be safely nested.
+ */
+
+
+#define RUNNER_DEFER_TRYCATCH(scope)                                              \
+    do {                                                                          \
+        try                                                                       \
+        {                                                                         \
+            scope                                                                 \
+        }                                                                         \
+        catch (const DPL::Test::TestFailed &ex)                                   \
+        {                                                                         \
+            DPL::Test::TestRunnerSingleton::Instance().deferFailedException(ex);  \
+        }                                                                         \
+        catch (const DPL::Test::TestIgnored &ex)                                  \
+        {                                                                         \
+            DPL::Test::TestRunnerSingleton::Instance().deferIgnoredException(ex); \
+        }                                                                         \
+    } while (0)                                                                   \
+
+#define RUNNER_DEFER_SCOPE(scope)                                \
+    do {                                                         \
+        DPL::Test::TestRunnerSingleton::Instance().deferBegin(); \
+        scope                                                    \
+        DPL::Test::TestRunnerSingleton::Instance().deferEnd();   \
+    } while (0)                                                  \
+
 #endif // DPL_TEST_RUNNER_H