Create class for test result
[platform/core/test/security-tests.git] / src / framework / include / dpl / test / test_runner.h
1 /*
2  * Copyright (c) 2011-2015 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
24 #ifndef DPL_TEST_RUNNER_H
25 #define DPL_TEST_RUNNER_H
26
27 #include <chrono>
28 #include <cstring>
29 #include <exception>
30 #include <iostream>
31 #include <list>
32 #include <map>
33 #include <queue>
34 #include <set>
35 #include <sstream>
36 #include <string>
37 #include <vector>
38
39 #include <dpl/atomic.h>
40 #include <dpl/availability.h>
41 #include <dpl/colors.h>
42 #include <dpl/gdbbacktrace.h>
43 #include <dpl/singleton.h>
44 #include <dpl/test/performance_result.h>
45 #include <dpl/test/test_result.h>
46 #include <dpl/test/test_results_collector.h>
47
48 namespace DPL {
49 namespace Test {
50 class TestRunner
51 {
52     typedef std::map<std::string, TestResultsCollectorBasePtr>
53     TestResultsCollectors;
54     TestResultsCollectors m_collectors;
55
56     std::string m_startTestId;
57     bool m_runIgnored;
58
59     std::queue<std::string> m_failReason;
60
61   public:
62     TestRunner() :
63         m_currentTestCase(nullptr)
64       , m_terminate(false)
65       , m_allowChildLogs(false)
66     {}
67
68     void beginPerformance(std::chrono::system_clock::duration maxDurationInMicroseconds);
69     void endPerformance();
70     void setCurrentTestCasePerformanceResult(const PerformanceResultPtr &performance);
71     ConstPerformanceResultPtr getCurrentTestCasePerformanceResult();
72
73     void addFailReason(const std::string &reason);
74
75     typedef void (*TestCase)();
76
77   private:
78     struct TestCaseStruct
79     {
80         std::string name;
81         TestCase proc;
82         PerformanceResultPtr performance;
83
84         bool operator <(const TestCaseStruct &other) const
85         {
86             return name < other.name;
87         }
88
89         bool operator ==(const TestCaseStruct &other) const
90         {
91             return name == other.name;
92         }
93
94         TestCaseStruct(const std::string &n, TestCase p) :
95             name(n),
96             proc(p)
97         {}
98     };
99
100     typedef std::list<TestCaseStruct> TestCaseStructList;
101     typedef std::map<std::string, TestCaseStructList> TestCaseGroupMap;
102     TestCaseGroupMap m_testGroups;
103
104     TestCaseStruct * m_currentTestCase;
105
106     typedef std::set<std::string> SelectedTestNameSet;
107     SelectedTestNameSet m_selectedTestNamesSet;
108     typedef std::set<std::string> SelectedTestGroupSet;
109     SelectedTestGroupSet m_selectedTestGroupSet;
110     std::string m_currentGroup;
111
112     DPL::Atomic m_totalAssertions;
113
114     // Terminate without any logs.
115     // Some test requires to call fork function.
116     // Child process must not produce any logs and should die quietly.
117     bool m_terminate;
118     bool m_allowChildLogs;
119
120     void Banner();
121     void InvalidArgs(const std::string& message = "Invalid arguments!");
122     void Usage();
123
124     bool filterGroupsByXmls(const std::vector<std::string> & files);
125     bool filterByXML(std::map<std::string, bool> & casesMap);
126     void normalizeXMLTag(std::string& str, const std::string& testcase);
127
128     enum Status { FAILED, IGNORED, PASS };
129
130     Status RunTestCase(const TestCaseStruct& testCase);
131
132     void setCurrentTestCase(TestCaseStruct* testCase);
133     TestCaseStruct *getCurrentTestCase();
134
135     void RunTests();
136
137     std::string getConcatedFailReason(const std::string &reason);
138
139     void CollectResult(const std::string& id, const TestResult &result);
140
141   public:
142     class TestFailed
143     {
144       private:
145         std::string m_message;
146
147       public:
148         TestFailed()
149         {}
150
151         //! \brief Failed test message creator
152         //!
153         //! \param[in] aTest string for tested expression
154         //! \param[in] aFile source file name
155         //! \param[in] aLine source file line
156         //! \param[in] aMessage error message
157         TestFailed(const char* aTest,
158                    const char* aFile,
159                    int aLine,
160                    const std::string &aMessage);
161
162         TestFailed(const std::string &message);
163
164         std::string GetMessage() const
165         {
166             return m_message;
167         }
168     };
169
170     class Ignored
171     {
172       private:
173         std::string m_message;
174
175       public:
176         Ignored()
177         {}
178
179         Ignored(const std::string &message) :
180             m_message(message)
181         {}
182
183         std::string GetMessage() const
184         {
185             return m_message;
186         }
187     };
188
189     void MarkAssertion();
190
191     void RegisterTest(const char *testName, TestCase proc);
192     void InitGroup(const char* name);
193
194     int ExecTestRunner(int argc, char *argv[]);
195     typedef std::vector<std::string> ArgsList;
196     int ExecTestRunner(ArgsList args);
197     bool getRunIgnored() const;
198     // The runner will terminate as soon as possible (after current test).
199     void Terminate();
200     bool GetAllowChildLogs();
201 };
202
203 typedef DPL::Singleton<TestRunner> TestRunnerSingleton;
204 }
205 } // namespace DPL
206
207 #define RUNNER_TEST_GROUP_INIT(GroupName)                                 \
208     static int Static##GroupName##Init()                                  \
209     {                                                                     \
210         DPL::Test::TestRunnerSingleton::Instance().InitGroup(#GroupName); \
211         return 0;                                                         \
212     }                                                                     \
213     const int DPL_UNUSED Static##GroupName##InitVar =                     \
214         Static##GroupName##Init();
215
216 #define RUNNER_TEST(Proc)                                                      \
217     void Proc();                                                               \
218     static int Static##Proc##Init()                                            \
219     {                                                                          \
220         DPL::Test::TestRunnerSingleton::Instance().RegisterTest(#Proc, &Proc); \
221         return 0;                                                              \
222     }                                                                          \
223     const int DPL_UNUSED Static##Proc##InitVar = Static##Proc##Init();         \
224     void Proc()
225
226
227 /**
228  * ASSERT MACROS
229  *
230  * Use them to create assertions in test cases. To do that put them inside test
231  * body. Failing assertion indicates failing test.
232  */
233
234 #define RUNNER_ASSERT_MSG(test, message)                                              \
235     do                                                                                \
236     {                                                                                 \
237         DPL::Test::TestRunnerSingleton::Instance().MarkAssertion();                   \
238                                                                                       \
239         if (!(test))                                                                  \
240         {                                                                             \
241             std::ostringstream assertMsg;                                             \
242             assertMsg << message << DPL::gdbbacktrace();                              \
243             DPL::Test::TestRunner::TestFailed e(#test,                                \
244                                                 __FILE__,                             \
245                                                 __LINE__,                             \
246                                                 assertMsg.str());                     \
247             if (!std::uncaught_exception())                                           \
248                 throw e;                                                              \
249             DPL::Test::TestRunnerSingleton::Instance().addFailReason(e.GetMessage()); \
250         }                                                                             \
251     } while (0)
252
253 #define RUNNER_ASSERT_ERRNO_MSG(test, message)                                        \
254     do                                                                                \
255     {                                                                                 \
256         DPL::Test::TestRunnerSingleton::Instance().MarkAssertion();                   \
257                                                                                       \
258         if (!(test))                                                                  \
259         {                                                                             \
260             const char *err = strerror(errno);                                        \
261             std::ostringstream assertMsg;                                             \
262             assertMsg << message;                                                     \
263             if (!assertMsg.str().empty())                                             \
264                 assertMsg << ". ";                                                    \
265             assertMsg << err << DPL::gdbbacktrace();                                  \
266             DPL::Test::TestRunner::TestFailed e(#test,                                \
267                                                 __FILE__,                             \
268                                                 __LINE__,                             \
269                                                 assertMsg.str());                     \
270             if (!std::uncaught_exception())                                           \
271                 throw e;                                                              \
272             DPL::Test::TestRunnerSingleton::Instance().addFailReason(e.GetMessage()); \
273         }                                                                             \
274     } while (0)
275
276 #define RUNNER_ASSERT_ERRNO(test) \
277     RUNNER_ASSERT_ERRNO_MSG(test, "")
278
279 #define RUNNER_FAIL_MSG(message) \
280     RUNNER_ASSERT_MSG(false, message)
281
282 #define RUNNER_ASSERT(test) \
283     RUNNER_ASSERT_MSG(test, "")
284
285 /**
286  * IGNORE MACRO
287  *
288  * When test reaches this macro call, its furhter code will be ignored.
289  * To ignore whole test, put this macro call at the beginning of this tests
290  * body.
291  */
292
293 #define RUNNER_IGNORED_MSG(message)                            \
294     do                                                         \
295     {                                                          \
296         std::ostringstream assertMsg;                          \
297         assertMsg << message;                                  \
298         throw DPL::Test::TestRunner::Ignored(assertMsg.str()); \
299     } while (0)
300
301 /**
302  * PERF MACROS
303  *
304  * Use these macros to do the time measurement. The first macro will start time measurement,
305  * the second will gather the result. These macros can be used only once per test-case.
306  * The result of time measurement will be displayed only if the test will pass.
307  * Notice that these macros will work only if will be used in parent process. If these
308  * macros will be used in child process then there will be no time measure results printed.
309  * This macro in multiprocess tests has effect only if used in parent process. This macro
310  * used in child process in multiprocess test has no effect.
311  * The precision of measurement is 1 microsecond - the smallest time value that can be
312  * measured is 0.000001s.
313  * The time measure results will be printed only specific output format:
314  *     - text
315  *     - html
316  *     - xml
317  */
318
319 #define RUNNER_PERF_TEST_BEGIN(maxTime)                                                \
320     do {                                                                               \
321         DPL::Test::TestRunnerSingleton::Instance().beginPerformance(                   \
322             std::chrono::microseconds{static_cast<long long int>(maxTime*1000000.0)}); \
323     } while (0)
324
325 #define RUNNER_PERF_TEST_END()                                       \
326     do {                                                             \
327         DPL::Test::TestRunnerSingleton::Instance().endPerformance(); \
328     } while (0)
329
330 /**
331  * MSG MACROS
332  *
333  * Use these macros to print error messages during test run time
334  */
335
336 #define RUNNER_ERROR_MSG(message)                             \
337     do {                                                      \
338         std::cerr << DPL::Colors::Text::RED_BEGIN << message  \
339                   << DPL::Colors::Text::RED_END << std::endl; \
340     } while (0)
341
342 #endif // DPL_TEST_RUNNER_H