xref: /aosp_15_r20/external/deqp/framework/common/tcuTestCase.hpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
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