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