Source code formating unification
[framework/web/wrt-commons.git] / modules / test / include / dpl / test / test_runner.h
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *    Licensed under the Apache License, Version 2.0 (the "License");
5  *    you may not use this file except in compliance with the License.
6  *    You may obtain a copy of the License at
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *    Unless required by applicable law or agreed to in writing, software
11  *    distributed under the License is distributed on an "AS IS" BASIS,
12  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *    See the License for the specific language governing permissions and
14  *    limitations under the License.
15  */
16 /*
17  * @file        test_runner.h
18  * @author      Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
19  * @author      Lukasz Wrzosek (l.wrzosek@samsung.com)
20  * @version     1.0
21  * @brief       This file is the header file of test runner
22  */
23 #ifndef DPL_TEST_RUNNER_H
24 #define DPL_TEST_RUNNER_H
25
26 #include <dpl/singleton.h>
27 #include <dpl/unused.h>
28 #include <dpl/atomic.h>
29 #include <dpl/test/test_results_collector.h>
30 #include <sstream>
31 #include <string>
32 #include <vector>
33 #include <list>
34 #include <set>
35 #include <map>
36
37 namespace DPL {
38 namespace Test {
39 class TestRunner
40 {
41     typedef std::map<std::string, TestResultsCollectorBasePtr>
42     TestResultsCollectors;
43     TestResultsCollectors m_collectors;
44
45     std::string m_startTestId;
46     bool m_runIgnored;
47
48   public:
49     TestRunner() :
50         m_terminate(false)
51     {}
52
53     typedef void (*TestCase)();
54
55   private:
56     struct TestCaseStruct
57     {
58         std::string name;
59         TestCase proc;
60
61         bool operator <(const TestCaseStruct &other) const
62         {
63             return name < other.name;
64         }
65
66         bool operator ==(const TestCaseStruct &other) const
67         {
68             return name == other.name;
69         }
70
71         TestCaseStruct(const std::string &n, TestCase p) :
72             name(n),
73             proc(p)
74         {}
75     };
76
77     typedef std::list<TestCaseStruct> TestCaseStructList;
78     typedef std::map<std::string, TestCaseStructList> TestCaseGroupMap;
79     TestCaseGroupMap m_testGroups;
80
81     typedef std::set<std::string> SelectedTestNameSet;
82     SelectedTestNameSet m_selectedTestNamesSet;
83     typedef std::set<std::string> SelectedTestGroupSet;
84     SelectedTestGroupSet m_selectedTestGroupSet;
85     std::string m_currentGroup;
86
87     DPL::Atomic m_totalAssertions;
88
89     // Terminate without any logs.
90     // Some test requires to call fork function.
91     // Child process must not produce any logs and should die quietly.
92     bool m_terminate;
93     void Banner();
94     void InvalidArgs(const std::string& message = "Invalid arguments!");
95     void Usage();
96
97     enum Status { FAILED, IGNORED, PASS };
98
99     Status RunTestCase(const TestCaseStruct& testCase);
100
101     void RunTests();
102
103     void CollectResult(const std::string& id,
104                        const std::string& description,
105                        const TestResultsCollectorBase::FailStatus::Type status
106                            = TestResultsCollectorBase::FailStatus::NONE,
107                        const std::string& reason = std::string());
108
109   public:
110     class TestFailed
111     {
112       private:
113         std::string m_message;
114
115       public:
116         TestFailed()
117         {}
118
119         //! \brief Failed test message creator
120         //!
121         //! \param[in] aTest string for tested expression
122         //! \param[in] aFile source file name
123         //! \param[in] aLine source file line
124         //! \param[in] aMessage error message
125         TestFailed(const char* aTest,
126                    const char* aFile,
127                    int aLine,
128                    const std::string &aMessage);
129
130         TestFailed(const std::string &message);
131
132         std::string GetMessage() const
133         {
134             return m_message;
135         }
136     };
137
138     class Ignored
139     {
140       private:
141         std::string m_message;
142
143       public:
144         Ignored()
145         {}
146
147         Ignored(const std::string &message) :
148             m_message(message)
149         {}
150
151         std::string GetMessage() const
152         {
153             return m_message;
154         }
155     };
156
157     void MarkAssertion();
158
159     void RegisterTest(const char *testName, TestCase proc);
160     void InitGroup(const char* name);
161
162     int ExecTestRunner(int argc, char *argv[]);
163     typedef std::vector<std::string> ArgsList;
164     int ExecTestRunner(const ArgsList& args);
165     bool getRunIgnored() const;
166     // The runner will terminate as soon as possible (after current test).
167     void terminate();
168 };
169
170 typedef DPL::Singleton<TestRunner> TestRunnerSingleton;
171 }
172 } // namespace DPL
173
174 #define RUNNER_TEST_GROUP_INIT(GroupName)                                \
175     static int Static##GroupName##Init()                                 \
176     {                                                                    \
177         DPL::Test::TestRunnerSingleton::Instance().InitGroup(#GroupName); \
178         return 0;                                                        \
179     }                                                                    \
180     const int DPL_UNUSED Static##GroupName##InitVar =                   \
181         Static##GroupName##Init();
182
183 #define RUNNER_TEST(Proc)                                                \
184     void Proc();                                                         \
185     static int Static##Proc##Init()                                      \
186     {                                                                    \
187         DPL::Test::TestRunnerSingleton::Instance().RegisterTest(#Proc, &Proc); \
188         return 0;                                                        \
189     }                                                                    \
190     const int DPL_UNUSED Static##Proc##InitVar = Static##Proc##Init();  \
191     void Proc()
192
193 //! \brief Returns base name for path
194
195 #define RUNNER_ASSERT_MSG(test, message)                                               \
196     do                                                                                     \
197     {                                                                                      \
198         DPL::Test::TestRunnerSingleton::Instance().MarkAssertion();                        \
199                                                                                        \
200         if (!(test))                                                                       \
201         {                                                                                  \
202             std::ostringstream assertMsg;                                                  \
203             assertMsg << message;                                                          \
204             throw DPL::Test::TestRunner::TestFailed(#test, \
205                                                     __FILE__, \
206                                                     __LINE__, \
207                                                     assertMsg.str()); \
208         }                                                                                  \
209     } while (0)
210
211 #define RUNNER_ASSERT(test) RUNNER_ASSERT_MSG(test, "")
212
213 #define RUNNER_FAIL RUNNER_ASSERT(false)
214
215 #define RUNNER_IGNORED_MSG(message) do { std::ostringstream assertMsg; \
216                                          assertMsg << message; \
217                                          throw DPL::Test::TestRunner::Ignored( \
218                                                    assertMsg.str()); \
219 } while (0)
220
221 #endif // DPL_TEST_RUNNER_H