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 };
166
167 /*--------------------------------------------------------------------*//*!
168 * \brief Test case group node
169 *
170 * Test case group implementations must inherit this class. To save resources
171 * during test execution the group must delay creation of any child groups
172 * until init() is called.
173 *
174 * Default deinit() for test group will destroy all child nodes.
175 *//*--------------------------------------------------------------------*/
176 class TestCaseGroup : public TestNode
177 {
178 public:
179 TestCaseGroup(TestContext &testCtx, const char *name);
180 TestCaseGroup(TestContext &testCtx, const char *name, const std::vector<TestNode *> &children);
181
182 // Deprecated constructors
183 TestCaseGroup(TestContext &testCtx, const char *name, const char *description);
184 TestCaseGroup(TestContext &testCtx, const char *name, const char *description,
185 const std::vector<TestNode *> &children);
186
187 virtual ~TestCaseGroup(void);
188
189 virtual IterateResult iterate(void);
190 };
191
192 /*--------------------------------------------------------------------*//*!
193 * \brief Test case class
194 *
195 * Test case implementations must inherit this class.
196 *
197 * Test case objects are usually constructed when TestExecutor enters parent
198 * group. Allocating any non-parameter resources, especially target API objects
199 * must be delayed to init().
200 *
201 * Upon entering the test case TestExecutor calls init(). If initialization
202 * is successful (no exception is thrown) the executor will then call iterate()
203 * until test case returns STOP. After that deinit() will be called.
204 *
205 * Before exiting the execution phase (i.e. at returning STOP from iterate())
206 * the test case must set valid status code to test context (m_testCtx).
207 *
208 * Test case can also signal error condition by throwing an exception. In
209 * that case the framework will set result code and details based on the
210 * exception.
211 *//*--------------------------------------------------------------------*/
212 class TestCase : public TestNode
213 {
214 public:
215 TestCase(TestContext &testCtx, const char *name);
216 TestCase(TestContext &testCtx, TestNodeType nodeType, const char *name);
217
218 // Deprecated constructors
219 TestCase(TestContext &testCtx, const char *name, const char *description);
220 TestCase(TestContext &testCtx, TestNodeType nodeType, const char *name, const char *description);
221
222 virtual ~TestCase(void);
223 };
224
225 class TestStatus
226 {
227 public:
TestStatus(qpTestResult code,const std::string & description)228 TestStatus(qpTestResult code, const std::string &description) : m_code(code), m_description(description)
229 {
230 }
231
isComplete(void) const232 bool isComplete(void) const
233 {
234 return m_code != QP_TEST_RESULT_LAST;
235 }
isFail(void) const236 bool isFail(void) const
237 {
238 return m_code == QP_TEST_RESULT_FAIL;
239 }
getCode(void) const240 qpTestResult getCode(void) const
241 {
242 DE_ASSERT(isComplete());
243 return m_code;
244 }
getDescription(void) const245 const std::string &getDescription(void) const
246 {
247 DE_ASSERT(isComplete());
248 return m_description;
249 }
250
pass(const std::string & description)251 static TestStatus pass(const std::string &description)
252 {
253 return TestStatus(QP_TEST_RESULT_PASS, description);
254 }
fail(const std::string & description)255 static TestStatus fail(const std::string &description)
256 {
257 return TestStatus(QP_TEST_RESULT_FAIL, description);
258 }
incomplete(void)259 static TestStatus incomplete(void)
260 {
261 return TestStatus(QP_TEST_RESULT_LAST, "");
262 }
263
264 private:
265 qpTestResult m_code;
266 std::string m_description;
267 } DE_WARN_UNUSED_TYPE;
268
269 } // namespace tcu
270
271 #endif // _TCUTESTCASE_HPP
272