Initialize Tizen 2.3
[framework/web/wrt-commons.git] / modules_wearable / 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/availability.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       , m_allowChildLogs(false)
52     {}
53
54     typedef void (*TestCase)();
55
56   private:
57     struct TestCaseStruct
58     {
59         std::string name;
60         TestCase proc;
61
62         bool operator <(const TestCaseStruct &other) const
63         {
64             return name < other.name;
65         }
66
67         bool operator ==(const TestCaseStruct &other) const
68         {
69             return name == other.name;
70         }
71
72         TestCaseStruct(const std::string &n, TestCase p) :
73             name(n),
74             proc(p)
75         {}
76     };
77
78     typedef std::list<TestCaseStruct> TestCaseStructList;
79     typedef std::map<std::string, TestCaseStructList> TestCaseGroupMap;
80     TestCaseGroupMap m_testGroups;
81
82     typedef std::set<std::string> SelectedTestNameSet;
83     SelectedTestNameSet m_selectedTestNamesSet;
84     typedef std::set<std::string> SelectedTestGroupSet;
85     SelectedTestGroupSet m_selectedTestGroupSet;
86     std::string m_currentGroup;
87
88     DPL::Atomic m_totalAssertions;
89
90     // Terminate without any logs.
91     // Some test requires to call fork function.
92     // Child process must not produce any logs and should die quietly.
93     bool m_terminate;
94     bool m_allowChildLogs;
95
96     void Banner();
97     void InvalidArgs(const std::string& message = "Invalid arguments!");
98     void Usage();
99
100     bool filterGroupsByXmls(const std::vector<std::string> & files);
101     bool filterByXML(std::map<std::string, bool> & casesMap);
102     void normalizeXMLTag(std::string& str, const std::string& testcase);
103
104     enum Status { FAILED, IGNORED, PASS };
105
106     Status RunTestCase(const TestCaseStruct& testCase);
107
108     void RunTests();
109
110     void CollectResult(const std::string& id,
111                        const std::string& description,
112                        const TestResultsCollectorBase::FailStatus::Type status
113                            = TestResultsCollectorBase::FailStatus::NONE,
114                        const std::string& reason = std::string());
115
116   public:
117     class TestFailed
118     {
119       private:
120         std::string m_message;
121
122       public:
123         TestFailed()
124         {}
125
126         //! \brief Failed test message creator
127         //!
128         //! \param[in] aTest string for tested expression
129         //! \param[in] aFile source file name
130         //! \param[in] aLine source file line
131         //! \param[in] aMessage error message
132         TestFailed(const char* aTest,
133                    const char* aFile,
134                    int aLine,
135                    const std::string &aMessage);
136
137         TestFailed(const std::string &message);
138
139         std::string GetMessage() const
140         {
141             return m_message;
142         }
143     };
144
145     class Ignored
146     {
147       private:
148         std::string m_message;
149
150       public:
151         Ignored()
152         {}
153
154         Ignored(const std::string &message) :
155             m_message(message)
156         {}
157
158         std::string GetMessage() const
159         {
160             return m_message;
161         }
162     };
163
164     void MarkAssertion();
165
166     void RegisterTest(const char *testName, TestCase proc);
167     void InitGroup(const char* name);
168
169     int ExecTestRunner(int argc, char *argv[]);
170     typedef std::vector<std::string> ArgsList;
171     int ExecTestRunner(const ArgsList& args);
172     bool getRunIgnored() const;
173     // The runner will terminate as soon as possible (after current test).
174     void Terminate();
175     bool GetAllowChildLogs();
176 };
177
178 typedef DPL::Singleton<TestRunner> TestRunnerSingleton;
179 }
180 } // namespace DPL
181
182 #define RUNNER_TEST_GROUP_INIT(GroupName)                                \
183     static int Static##GroupName##Init()                                 \
184     {                                                                    \
185         DPL::Test::TestRunnerSingleton::Instance().InitGroup(#GroupName); \
186         return 0;                                                        \
187     }                                                                    \
188     const int DPL_UNUSED Static##GroupName##InitVar =                   \
189         Static##GroupName##Init();
190
191 #define RUNNER_TEST(Proc)                                                \
192     void Proc();                                                         \
193     static int Static##Proc##Init()                                      \
194     {                                                                    \
195         DPL::Test::TestRunnerSingleton::Instance().RegisterTest(#Proc, &Proc); \
196         return 0;                                                        \
197     }                                                                    \
198     const int DPL_UNUSED Static##Proc##InitVar = Static##Proc##Init();  \
199     void Proc()
200
201 //! \brief Returns base name for path
202
203 #define RUNNER_ASSERT_MSG(test, message)                                               \
204     do                                                                                     \
205     {                                                                                      \
206         DPL::Test::TestRunnerSingleton::Instance().MarkAssertion();                        \
207                                                                                        \
208         if (!(test))                                                                       \
209         {                                                                                  \
210             std::ostringstream assertMsg;                                                  \
211             assertMsg << message;                                                          \
212             throw DPL::Test::TestRunner::TestFailed(#test, \
213                                                     __FILE__, \
214                                                     __LINE__, \
215                                                     assertMsg.str()); \
216         }                                                                                  \
217     } while (0)
218
219 #define RUNNER_ASSERT(test) RUNNER_ASSERT_MSG(test, "")
220
221 #define RUNNER_FAIL RUNNER_ASSERT(false)
222
223 #define RUNNER_IGNORED_MSG(message) do { std::ostringstream assertMsg; \
224                                          assertMsg << message; \
225                                          throw DPL::Test::TestRunner::Ignored( \
226                                                    assertMsg.str()); \
227 } while (0)
228
229 #endif // DPL_TEST_RUNNER_H