• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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