1 #ifndef _TCUTESTCASE_HPP
2 #define _TCUTESTCASE_HPP
3 /*-------------------------------------------------------------------------
4 * drawElements Quality Program Tester Core
5 * ----------------------------------------
6 *
7 * Copyright 2014 The Android Open Source Project
8 *
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
12 *
13 * http://www.apache.org/licenses/LICENSE-2.0
14 *
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
20 *
21 *//*!
22 * \file
23 * \brief Base class for a test case.
24 *//*--------------------------------------------------------------------*/
25
26 #include "tcuDefs.hpp"
27 #include "tcuTestContext.hpp"
28
29 #include <string>
30 #include <vector>
31
32 namespace tcu
33 {
34
35 enum TestNodeType
36 {
37 NODETYPE_ROOT = 0, //!< Root for all test packages.
38 NODETYPE_PACKAGE, //!< Test case package -- same as group, but is omitted from XML dump.
39 NODETYPE_GROUP, //!< Test case container -- cannot be executed.
40 NODETYPE_SELF_VALIDATE, //!< Self-validating test case -- can be executed
41 NODETYPE_PERFORMANCE, //!< Performace test case -- can be executed
42 NODETYPE_CAPABILITY, //!< Capability score case -- can be executed
43 NODETYPE_ACCURACY //!< Accuracy test case -- can be executed
44 };
45
46 enum TestNodeClass
47 {
48 NODECLASS_GROUP = 0, //!< Root or non-leaf in the test hierarchy tree
49 NODECLASS_EXECUTABLE, //!< Non-root leaf in the test hierarchy tree
50
51 NODECLASS_LAST
52 };
53
54 enum TestRunnerType
55 {
56 RUNNERTYPE_ANY = 0u,
57 RUNNERTYPE_NONE = (1u << 0),
58 RUNNERTYPE_AMBER = (1u << 1)
59 };
60
getTestNodeTypeClass(TestNodeType type)61 inline TestNodeClass getTestNodeTypeClass(TestNodeType type)
62 {
63 switch (type)
64 {
65 case NODETYPE_ROOT:
66 return NODECLASS_GROUP;
67 case NODETYPE_PACKAGE:
68 return NODECLASS_GROUP;
69 case NODETYPE_GROUP:
70 return NODECLASS_GROUP;
71 case NODETYPE_SELF_VALIDATE:
72 return NODECLASS_EXECUTABLE;
73 case NODETYPE_PERFORMANCE:
74 return NODECLASS_EXECUTABLE;
75 case NODETYPE_CAPABILITY:
76 return NODECLASS_EXECUTABLE;
77 case NODETYPE_ACCURACY:
78 return NODECLASS_EXECUTABLE;
79 default:
80 DE_ASSERT(false);
81 return NODECLASS_LAST;
82 }
83 }
84
isTestNodeTypeExecutable(TestNodeType type)85 inline bool isTestNodeTypeExecutable(TestNodeType type)
86 {
87 return getTestNodeTypeClass(type) == NODECLASS_EXECUTABLE;
88 }
89
isValidTestCaseNameChar(char c)90 inline bool isValidTestCaseNameChar(char c)
91 {
92 return de::inRange(c, 'a', 'z') || de::inRange(c, 'A', 'Z') || de::inRange(c, '0', '9') || c == '_' || c == '-';
93 }
94
95 class TestCaseGroup;
96 class CaseListFilter;
97
98 /*--------------------------------------------------------------------*//*!
99 * \brief Test case hierarchy node
100 *
101 * Test node forms the backbone of the test case hierarchy. All objects
102 * in the hierarchy are derived from this class.
103 *
104 * Each test node has a type and all except the root node have name and
105 * description. Root and test group nodes have a list of children.
106 *
107 * During test execution TestExecutor iterates the hierarchy. Upon entering
108 * the node (both groups and test cases) init() is called. When exiting the
109 * node deinit() is called respectively.
110 *//*--------------------------------------------------------------------*/
111 class TestNode
112 {
113 public:
114 enum IterateResult
115 {
116 STOP = 0,
117 CONTINUE = 1
118 };
119
120 // Methods.
121 TestNode(TestContext &testCtx, TestNodeType nodeType, const char *name);
122 TestNode(TestContext &testCtx, TestNodeType nodeType, const char *name, const std::vector<TestNode *> &children);
123 virtual ~TestNode(void);
124
getNodeType(void) const125 TestNodeType getNodeType(void) const
126 {
127 return m_nodeType;
128 }
getTestContext(void) const129 TestContext &getTestContext(void) const
130 {
131 return m_testCtx;
132 }
getName(void) const133 const char *getName(void) const
134 {
135 return m_name.c_str();
136 }
137 void getChildren(std::vector<TestNode *> &children) const;
138 void addRootChild(const std::string &groupName, const CaseListFilter *caseListFilter,
139 TestCaseGroup *(*createTestGroup)(tcu::TestContext &testCtx, const std::string &name));
140 void addChild(TestNode *node);
empty() const141 bool empty() const
142 {
143 return m_children.empty();
144 }
145
146 virtual void init(void);
147 virtual void deinit(void);
148 virtual IterateResult iterate(void) = 0;
getRunnerType(void) const149 virtual TestRunnerType getRunnerType(void) const
150 {
151 return RUNNERTYPE_NONE;
152 }
validateRequirements()153 virtual bool validateRequirements()
154 {
155 return true;
156 }
157
158 protected:
159 TestContext &m_testCtx;
160 std::string m_name;
161
162 private:
163 const TestNodeType m_nodeType;
164 std::vector<TestNode *> m_children;
165 bool m_duplicateCheck;
166 };
167
168 /*--------------------------------------------------------------------*//*!
169 * \brief Test case group node
170 *
171 * Test case group implementations must inherit this class. To save resources
172 * during test execution the group must delay creation of any child groups
173 * until init() is called.
174 *
175 * Default deinit() for test group will destroy all child nodes.
176 *//*--------------------------------------------------------------------*/
177 class TestCaseGroup : public TestNode
178 {
179 public:
180 TestCaseGroup(TestContext &testCtx, const char *name);
181 TestCaseGroup(TestContext &testCtx, const char *name, const std::vector<TestNode *> &children);
182
183 // Deprecated constructors
184 TestCaseGroup(TestContext &testCtx, const char *name, const char *description);
185 TestCaseGroup(TestContext &testCtx, const char *name, const char *description,
186 const std::vector<TestNode *> &children);
187
188 virtual ~TestCaseGroup(void);
189
190 virtual IterateResult iterate(void);
191 };
192
193 /*--------------------------------------------------------------------*//*!
194 * \brief Test case class
195 *
196 * Test case implementations must inherit this class.
197 *
198 * Test case objects are usually constructed when TestExecutor enters parent
199 * group. Allocating any non-parameter resources, especially target API objects
200 * must be delayed to init().
201 *
202 * Upon entering the test case TestExecutor calls init(). If initialization
203 * is successful (no exception is thrown) the executor will then call iterate()
204 * until test case returns STOP. After that deinit() will be called.
205 *
206 * Before exiting the execution phase (i.e. at returning STOP from iterate())
207 * the test case must set valid status code to test context (m_testCtx).
208 *
209 * Test case can also signal error condition by throwing an exception. In
210 * that case the framework will set result code and details based on the
211 * exception.
212 *//*--------------------------------------------------------------------*/
213 class TestCase : public TestNode
214 {
215 public:
216 TestCase(TestContext &testCtx, const char *name);
217 TestCase(TestContext &testCtx, TestNodeType nodeType, const char *name);
218
219 // Deprecated constructors
220 TestCase(TestContext &testCtx, const char *name, const char *description);
221 TestCase(TestContext &testCtx, TestNodeType nodeType, const char *name, const char *description);
222
223 virtual ~TestCase(void);
224 };
225
226 class TestStatus
227 {
228 public:
TestStatus(qpTestResult code,const std::string & description)229 TestStatus(qpTestResult code, const std::string &description) : m_code(code), m_description(description)
230 {
231 }
232
isComplete(void) const233 bool isComplete(void) const
234 {
235 return m_code != QP_TEST_RESULT_LAST;
236 }
isFail(void) const237 bool isFail(void) const
238 {
239 return m_code == QP_TEST_RESULT_FAIL;
240 }
getCode(void) const241 qpTestResult getCode(void) const
242 {
243 DE_ASSERT(isComplete());
244 return m_code;
245 }
getDescription(void) const246 const std::string &getDescription(void) const
247 {
248 DE_ASSERT(isComplete());
249 return m_description;
250 }
251
pass(const std::string & description)252 static TestStatus pass(const std::string &description)
253 {
254 return TestStatus(QP_TEST_RESULT_PASS, description);
255 }
fail(const std::string & description)256 static TestStatus fail(const std::string &description)
257 {
258 return TestStatus(QP_TEST_RESULT_FAIL, description);
259 }
incomplete(void)260 static TestStatus incomplete(void)
261 {
262 return TestStatus(QP_TEST_RESULT_LAST, "");
263 }
264
265 private:
266 qpTestResult m_code;
267 std::string m_description;
268 } DE_WARN_UNUSED_TYPE;
269
270 } // namespace tcu
271
272 #endif // _TCUTESTCASE_HPP
273