2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
19 * @author Lukasz Wrzosek (l.wrzosek@samsung.com)
21 * @brief This file is the header file of test runner
23 #ifndef DPL_TEST_RUNNER_H
24 #define DPL_TEST_RUNNER_H
26 #include <dpl/singleton.h>
27 #include <dpl/availability.h>
28 #include <dpl/atomic.h>
29 #include <dpl/test/test_results_collector.h>
42 typedef std::map<std::string, TestResultsCollectorBasePtr>
43 TestResultsCollectors;
44 TestResultsCollectors m_collectors;
46 std::string m_startTestId;
51 m_currentTestCase(NULL)
53 , m_allowChildLogs(false)
56 void beginPerformanceTestTime(std::chrono::system_clock::duration maxTimeInMicroseconds);
57 void endPerformanceTestTime();
58 void getCurrentTestCasePerformanceResult(bool& isPerformanceTest,
59 std::chrono::system_clock::duration& result,
60 std::chrono::system_clock::duration& resultMax);
61 void setCurrentTestCasePerformanceResult(bool isPerformanceTest,
62 std::chrono::system_clock::duration result,
63 std::chrono::system_clock::duration resultMax);
65 typedef void (*TestCase)();
73 bool m_isPerformanceTest;
74 std::chrono::system_clock::time_point m_performanceTestStartTime;
75 std::chrono::system_clock::duration m_performanceTestDurationTime;
76 std::chrono::system_clock::duration m_performanceMaxTime;
78 bool operator <(const TestCaseStruct &other) const
80 return name < other.name;
83 bool operator ==(const TestCaseStruct &other) const
85 return name == other.name;
88 TestCaseStruct(const std::string &n, TestCase p) :
91 m_isPerformanceTest(false)
95 typedef std::list<TestCaseStruct> TestCaseStructList;
96 typedef std::map<std::string, TestCaseStructList> TestCaseGroupMap;
97 TestCaseGroupMap m_testGroups;
99 TestCaseStruct * m_currentTestCase;
101 typedef std::set<std::string> SelectedTestNameSet;
102 SelectedTestNameSet m_selectedTestNamesSet;
103 typedef std::set<std::string> SelectedTestGroupSet;
104 SelectedTestGroupSet m_selectedTestGroupSet;
105 std::string m_currentGroup;
107 DPL::Atomic m_totalAssertions;
109 // Terminate without any logs.
110 // Some test requires to call fork function.
111 // Child process must not produce any logs and should die quietly.
113 bool m_allowChildLogs;
116 void InvalidArgs(const std::string& message = "Invalid arguments!");
119 bool filterGroupsByXmls(const std::vector<std::string> & files);
120 bool filterByXML(std::map<std::string, bool> & casesMap);
121 void normalizeXMLTag(std::string& str, const std::string& testcase);
123 enum Status { FAILED, IGNORED, PASS };
125 Status RunTestCase(const TestCaseStruct& testCase);
127 void setCurrentTestCase(TestCaseStruct* testCase);
128 TestCaseStruct *getCurrentTestCase();
132 void CollectResult(const std::string& id,
133 const std::string& description,
134 const TestResultsCollectorBase::FailStatus::Type status
135 = TestResultsCollectorBase::FailStatus::NONE,
136 const std::string& reason = std::string(),
137 const bool& isPerformanceTest = false,
138 const std::chrono::system_clock::duration& performanceTime = std::chrono::microseconds::zero(),
139 const std::chrono::system_clock::duration& performanceMaxTime = std::chrono::microseconds::zero());
145 std::string m_message;
151 //! \brief Failed test message creator
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,
160 const std::string &aMessage);
162 TestFailed(const std::string &message);
164 std::string GetMessage() const
173 std::string m_message;
179 Ignored(const std::string &message) :
183 std::string GetMessage() const
189 void MarkAssertion();
191 void RegisterTest(const char *testName, TestCase proc);
192 void InitGroup(const char* name);
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).
200 bool GetAllowChildLogs();
203 typedef DPL::Singleton<TestRunner> TestRunnerSingleton;
207 #define RUNNER_TEST_GROUP_INIT(GroupName) \
208 static int Static##GroupName##Init() \
210 DPL::Test::TestRunnerSingleton::Instance().InitGroup(#GroupName); \
213 const int DPL_UNUSED Static##GroupName##InitVar = \
214 Static##GroupName##Init();
216 #define RUNNER_TEST(Proc) \
218 static int Static##Proc##Init() \
220 DPL::Test::TestRunnerSingleton::Instance().RegisterTest(#Proc, &Proc); \
223 const int DPL_UNUSED Static##Proc##InitVar = Static##Proc##Init(); \
226 //! \brief Returns base name for path
228 #define RUNNER_ASSERT_MSG(test, message) \
231 DPL::Test::TestRunnerSingleton::Instance().MarkAssertion(); \
235 std::ostringstream assertMsg; \
236 assertMsg << message; \
237 throw DPL::Test::TestRunner::TestFailed(#test, \
244 #define RUNNER_ASSERT(test) RUNNER_ASSERT_MSG(test, "")
246 #define RUNNER_FAIL RUNNER_ASSERT(false)
248 #define RUNNER_IGNORED_MSG(message) do { std::ostringstream assertMsg; \
249 assertMsg << message; \
250 throw DPL::Test::TestRunner::Ignored( \
255 * Use these macros to do the time measurement. The first macro will start time measurement,
256 * the second will gather the result. These macros can be used only once per test-case.
257 * The result of time measurement will be displayed only if the test will pass.
258 * Notice that these macros will work only if will be used in parent process. If these
259 * macros will be used in child process then there will be no time measure results printed.
260 * This macro in multiprocess tests has effect only if used in parent process. This macro
261 * used in child process in multiprocess test has no effect.
262 * The precision of measurement is 1 microsecond - the smallest time value that can be
263 * measured is 0.000001s.
264 * The time measure results will be printed only specific output format:
269 * In TAP format performance result will not be displayed.
271 #define RUNNER_PERF_TEST_BEGIN(maxTime) \
273 DPL::Test::TestRunnerSingleton::Instance().beginPerformanceTestTime( \
274 std::chrono::microseconds{static_cast<long long int>(maxTime*1000000.0)}); \
277 #define RUNNER_PERF_TEST_END() \
279 DPL::Test::TestRunnerSingleton::Instance().endPerformanceTestTime(); \
282 #endif // DPL_TEST_RUNNER_H