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, TestCaseGroup* (*createTestGroup)(tcu::TestContext& testCtx, const std::string& name))
78 {
79 // Skip tests not in case list
80 if (caseListFilter && !caseListFilter->checkTestGroupName((m_name + "." + groupName).c_str()))
81 return;
82
83 return addChild(createTestGroup(m_testCtx, groupName));
84 }
85
addChild(TestNode * node)86 void TestNode::addChild (TestNode* node)
87 {
88 // Child names must be unique!
89 // \todo [petri] O(n^2) algorithm, but shouldn't really matter..
90 #if defined(DE_DEBUG)
91 for (int i = 0; i < (int)m_children.size(); i++)
92 {
93 if (deStringEqual(node->getName(), m_children[i]->getName()))
94 throw tcu::InternalError(std::string("Test case with non-unique name '") + node->getName() + "' added to group '" + getName() + "'.");
95 }
96 #endif
97
98 // children only in group nodes
99 DE_ASSERT(getTestNodeTypeClass(m_nodeType) == NODECLASS_GROUP);
100
101 // children must have the same class
102 if (!m_children.empty())
103 DE_ASSERT(getTestNodeTypeClass(m_children.front()->getNodeType()) == getTestNodeTypeClass(node->getNodeType()));
104
105 m_children.push_back(node);
106 }
107
init(void)108 void TestNode::init (void)
109 {
110 }
111
deinit(void)112 void TestNode::deinit (void)
113 {
114 for (int i = 0; i < (int)m_children.size(); i++)
115 delete m_children[i];
116 m_children.clear();
117 }
118
119 // TestCaseGroup
120
TestCaseGroup(TestContext & testCtx,const char * name)121 TestCaseGroup::TestCaseGroup (TestContext& testCtx, const char* name)
122 : TestNode(testCtx, NODETYPE_GROUP, name)
123 {
124 }
125
TestCaseGroup(TestContext & testCtx,const char * name,const vector<TestNode * > & children)126 TestCaseGroup::TestCaseGroup (TestContext& testCtx, const char* name, const vector<TestNode*>& children)
127 : TestNode(testCtx, NODETYPE_GROUP, name, children)
128 {
129 }
130
131 // Deprecated constructor with an ignored description argument. These shouldn't really be used
132 // in new code but are retained to avoid changing every test group construction at once.
TestCaseGroup(TestContext & testCtx,const char * name,const char * description)133 TestCaseGroup::TestCaseGroup (TestContext& testCtx, const char* name, const char* description)
134 : TestCaseGroup(testCtx, name)
135 {
136 DE_UNREF(description);
137 }
138
TestCaseGroup(TestContext & testCtx,const char * name,const char * description,const vector<TestNode * > & children)139 TestCaseGroup::TestCaseGroup (TestContext& testCtx, const char* name, const char* description, const vector<TestNode*>& children)
140 : TestCaseGroup(testCtx, name, children)
141 {
142 DE_UNREF(description);
143 }
144
~TestCaseGroup(void)145 TestCaseGroup::~TestCaseGroup (void)
146 {
147 }
148
iterate(void)149 TestCase::IterateResult TestCaseGroup::iterate (void)
150 {
151 DE_ASSERT(DE_FALSE); // should never be here!
152 throw InternalError("TestCaseGroup::iterate() called!", "", __FILE__, __LINE__);
153 }
154
155 // TestCase
156
TestCase(TestContext & testCtx,const char * name)157 TestCase::TestCase (TestContext& testCtx, const char* name)
158 : TestNode(testCtx, NODETYPE_SELF_VALIDATE, name)
159 {
160 }
161
TestCase(TestContext & testCtx,TestNodeType nodeType,const char * name)162 TestCase::TestCase (TestContext& testCtx, TestNodeType nodeType, const char* name)
163 : 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)
171 : TestCase(testCtx, name)
172 {
173 DE_UNREF(description);
174 }
175
TestCase(TestContext & testCtx,TestNodeType nodeType,const char * name,const char * description)176 TestCase::TestCase (TestContext& testCtx, TestNodeType nodeType, const char* name, const char* description)
177 : TestCase(testCtx, nodeType, name)
178 {
179 DE_UNREF(description);
180 }
181
~TestCase(void)182 TestCase::~TestCase (void)
183 {
184 }
185
186 } // tcu
187