1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program Tester Core
3 * ----------------------------------------
4 *
5 * Copyright 2014 The Android Open Source Project
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 *//*!
20 * \file
21 * \brief Base class for a test case.
22 *//*--------------------------------------------------------------------*/
23
24 #include "tcuTestCase.hpp"
25 #include "tcuPlatform.hpp"
26 #include "tcuCommandLine.hpp"
27
28 #include "deString.h"
29
30 namespace tcu
31 {
32
33 using namespace std;
34
35 // TestNode.
36
isValidCaseName(const char * name)37 inline bool isValidCaseName(const char *name)
38 {
39 for (const char *p = name; *p != '\0'; p++)
40 {
41 if (!isValidTestCaseNameChar(*p))
42 return false;
43 }
44 return true;
45 }
46
TestNode(TestContext & testCtx,TestNodeType nodeType,const char * name)47 TestNode::TestNode(TestContext &testCtx, TestNodeType nodeType, const char *name)
48 : m_testCtx(testCtx)
49 , m_name(name)
50 , m_nodeType(nodeType)
51 {
52 DE_ASSERT(isValidCaseName(name));
53 }
54
TestNode(TestContext & testCtx,TestNodeType nodeType,const char * name,const vector<TestNode * > & children)55 TestNode::TestNode(TestContext &testCtx, TestNodeType nodeType, const char *name, const vector<TestNode *> &children)
56 : m_testCtx(testCtx)
57 , m_name(name)
58 , m_nodeType(nodeType)
59 {
60 DE_ASSERT(isValidCaseName(name));
61 for (int i = 0; i < (int)children.size(); i++)
62 addChild(children[i]);
63 }
64
~TestNode(void)65 TestNode::~TestNode(void)
66 {
67 TestNode::deinit();
68 }
69
getChildren(vector<TestNode * > & res) const70 void TestNode::getChildren(vector<TestNode *> &res) const
71 {
72 res.clear();
73 for (int i = 0; i < (int)m_children.size(); i++)
74 res.push_back(m_children[i]);
75 }
76
addRootChild(const std::string & groupName,const CaseListFilter * caseListFilter,TestCaseGroup * (* createTestGroup)(tcu::TestContext & testCtx,const std::string & name))77 void TestNode::addRootChild(const std::string &groupName, const CaseListFilter *caseListFilter,
78 TestCaseGroup *(*createTestGroup)(tcu::TestContext &testCtx, const std::string &name))
79 {
80 // Skip tests not in case list
81 if (caseListFilter && !caseListFilter->checkTestGroupName((m_name + "." + groupName).c_str()))
82 return;
83
84 return addChild(createTestGroup(m_testCtx, groupName));
85 }
86
addChild(TestNode * node)87 void TestNode::addChild(TestNode *node)
88 {
89 // Child names must be unique!
90 // \todo [petri] O(n^2) algorithm, but shouldn't really matter..
91 #if defined(DE_DEBUG)
92 for (int i = 0; i < (int)m_children.size(); i++)
93 {
94 if (deStringEqual(node->getName(), m_children[i]->getName()))
95 throw tcu::InternalError(std::string("Test case with non-unique name '") + node->getName() +
96 "' added to group '" + getName() + "'.");
97 }
98 #endif
99
100 // children only in group nodes
101 DE_ASSERT(getTestNodeTypeClass(m_nodeType) == NODECLASS_GROUP);
102
103 // children must have the same class
104 if (!m_children.empty())
105 DE_ASSERT(getTestNodeTypeClass(m_children.front()->getNodeType()) == getTestNodeTypeClass(node->getNodeType()));
106
107 m_children.push_back(node);
108 }
109
init(void)110 void TestNode::init(void)
111 {
112 }
113
deinit(void)114 void TestNode::deinit(void)
115 {
116 for (int i = 0; i < (int)m_children.size(); i++)
117 delete m_children[i];
118 m_children.clear();
119 }
120
121 // TestCaseGroup
122
TestCaseGroup(TestContext & testCtx,const char * name)123 TestCaseGroup::TestCaseGroup(TestContext &testCtx, const char *name) : TestNode(testCtx, NODETYPE_GROUP, name)
124 {
125 }
126
TestCaseGroup(TestContext & testCtx,const char * name,const vector<TestNode * > & children)127 TestCaseGroup::TestCaseGroup(TestContext &testCtx, const char *name, const vector<TestNode *> &children)
128 : TestNode(testCtx, NODETYPE_GROUP, name, children)
129 {
130 }
131
132 // Deprecated constructor with an ignored description argument. These shouldn't really be used
133 // in new code but are retained to avoid changing every test group construction at once.
TestCaseGroup(TestContext & testCtx,const char * name,const char * description)134 TestCaseGroup::TestCaseGroup(TestContext &testCtx, const char *name, const char *description)
135 : TestCaseGroup(testCtx, name)
136 {
137 DE_UNREF(description);
138 }
139
TestCaseGroup(TestContext & testCtx,const char * name,const char * description,const vector<TestNode * > & children)140 TestCaseGroup::TestCaseGroup(TestContext &testCtx, const char *name, const char *description,
141 const vector<TestNode *> &children)
142 : TestCaseGroup(testCtx, name, children)
143 {
144 DE_UNREF(description);
145 }
146
~TestCaseGroup(void)147 TestCaseGroup::~TestCaseGroup(void)
148 {
149 }
150
iterate(void)151 TestCase::IterateResult TestCaseGroup::iterate(void)
152 {
153 DE_ASSERT(false); // should never be here!
154 throw InternalError("TestCaseGroup::iterate() called!", "", __FILE__, __LINE__);
155 }
156
157 // TestCase
158
TestCase(TestContext & testCtx,const char * name)159 TestCase::TestCase(TestContext &testCtx, const char *name) : TestNode(testCtx, NODETYPE_SELF_VALIDATE, name)
160 {
161 }
162
TestCase(TestContext & testCtx,TestNodeType nodeType,const char * name)163 TestCase::TestCase(TestContext &testCtx, TestNodeType nodeType, const char *name) : TestNode(testCtx, nodeType, name)
164 {
165 DE_ASSERT(isTestNodeTypeExecutable(nodeType));
166 }
167
168 // Deprecated constructor with an ignored description argument. These shouldn't really be used
169 // in new code but are retained to avoid changing every test case construction at once.
TestCase(TestContext & testCtx,const char * name,const char * description)170 TestCase::TestCase(TestContext &testCtx, const char *name, const char *description) : TestCase(testCtx, name)
171 {
172 DE_UNREF(description);
173 }
174
TestCase(TestContext & testCtx,TestNodeType nodeType,const char * name,const char * description)175 TestCase::TestCase(TestContext &testCtx, TestNodeType nodeType, const char *name, const char *description)
176 : TestCase(testCtx, nodeType, name)
177 {
178 DE_UNREF(description);
179 }
180
~TestCase(void)181 TestCase::~TestCase(void)
182 {
183 }
184
185 } // namespace tcu
186