xref: /aosp_15_r20/external/deqp/executor/xeTestCase.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker  * drawElements Quality Program Test Executor
3*35238bceSAndroid Build Coastguard Worker  * ------------------------------------------
4*35238bceSAndroid Build Coastguard Worker  *
5*35238bceSAndroid Build Coastguard Worker  * Copyright 2014 The Android Open Source Project
6*35238bceSAndroid Build Coastguard Worker  *
7*35238bceSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
8*35238bceSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
9*35238bceSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
10*35238bceSAndroid Build Coastguard Worker  *
11*35238bceSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
12*35238bceSAndroid Build Coastguard Worker  *
13*35238bceSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
14*35238bceSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
15*35238bceSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16*35238bceSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
17*35238bceSAndroid Build Coastguard Worker  * limitations under the License.
18*35238bceSAndroid Build Coastguard Worker  *
19*35238bceSAndroid Build Coastguard Worker  *//*!
20*35238bceSAndroid Build Coastguard Worker  * \file
21*35238bceSAndroid Build Coastguard Worker  * \brief Test case.
22*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker 
24*35238bceSAndroid Build Coastguard Worker #include "xeTestCase.hpp"
25*35238bceSAndroid Build Coastguard Worker 
26*35238bceSAndroid Build Coastguard Worker using std::vector;
27*35238bceSAndroid Build Coastguard Worker 
28*35238bceSAndroid Build Coastguard Worker namespace xe
29*35238bceSAndroid Build Coastguard Worker {
30*35238bceSAndroid Build Coastguard Worker 
getTestCaseTypeName(TestCaseType caseType)31*35238bceSAndroid Build Coastguard Worker const char *getTestCaseTypeName(TestCaseType caseType)
32*35238bceSAndroid Build Coastguard Worker {
33*35238bceSAndroid Build Coastguard Worker     switch (caseType)
34*35238bceSAndroid Build Coastguard Worker     {
35*35238bceSAndroid Build Coastguard Worker     case TESTCASETYPE_SELF_VALIDATE:
36*35238bceSAndroid Build Coastguard Worker         return "SelfValidate";
37*35238bceSAndroid Build Coastguard Worker     case TESTCASETYPE_CAPABILITY:
38*35238bceSAndroid Build Coastguard Worker         return "Capability";
39*35238bceSAndroid Build Coastguard Worker     case TESTCASETYPE_ACCURACY:
40*35238bceSAndroid Build Coastguard Worker         return "Accuracy";
41*35238bceSAndroid Build Coastguard Worker     case TESTCASETYPE_PERFORMANCE:
42*35238bceSAndroid Build Coastguard Worker         return "Performance";
43*35238bceSAndroid Build Coastguard Worker     default:
44*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
45*35238bceSAndroid Build Coastguard Worker         return DE_NULL;
46*35238bceSAndroid Build Coastguard Worker     }
47*35238bceSAndroid Build Coastguard Worker }
48*35238bceSAndroid Build Coastguard Worker 
getFirstComponentLength(const char * path)49*35238bceSAndroid Build Coastguard Worker static inline int getFirstComponentLength(const char *path)
50*35238bceSAndroid Build Coastguard Worker {
51*35238bceSAndroid Build Coastguard Worker     int compLen = 0;
52*35238bceSAndroid Build Coastguard Worker     while (path[compLen] != 0 && path[compLen] != '.')
53*35238bceSAndroid Build Coastguard Worker         compLen++;
54*35238bceSAndroid Build Coastguard Worker     return compLen;
55*35238bceSAndroid Build Coastguard Worker }
56*35238bceSAndroid Build Coastguard Worker 
compareNameToPathComponent(const char * name,const char * path,int compLen)57*35238bceSAndroid Build Coastguard Worker static bool compareNameToPathComponent(const char *name, const char *path, int compLen)
58*35238bceSAndroid Build Coastguard Worker {
59*35238bceSAndroid Build Coastguard Worker     for (int pos = 0; pos < compLen; pos++)
60*35238bceSAndroid Build Coastguard Worker     {
61*35238bceSAndroid Build Coastguard Worker         if (name[pos] != path[pos])
62*35238bceSAndroid Build Coastguard Worker             return false;
63*35238bceSAndroid Build Coastguard Worker     }
64*35238bceSAndroid Build Coastguard Worker 
65*35238bceSAndroid Build Coastguard Worker     if (name[compLen] != 0)
66*35238bceSAndroid Build Coastguard Worker         return false;
67*35238bceSAndroid Build Coastguard Worker 
68*35238bceSAndroid Build Coastguard Worker     return true;
69*35238bceSAndroid Build Coastguard Worker }
70*35238bceSAndroid Build Coastguard Worker 
splitPath(const char * path,std::vector<std::string> & components)71*35238bceSAndroid Build Coastguard Worker static void splitPath(const char *path, std::vector<std::string> &components)
72*35238bceSAndroid Build Coastguard Worker {
73*35238bceSAndroid Build Coastguard Worker     std::string pathStr(path);
74*35238bceSAndroid Build Coastguard Worker     int compStart = 0;
75*35238bceSAndroid Build Coastguard Worker 
76*35238bceSAndroid Build Coastguard Worker     for (int pos = 0; pos < (int)pathStr.length(); pos++)
77*35238bceSAndroid Build Coastguard Worker     {
78*35238bceSAndroid Build Coastguard Worker         if (pathStr[pos] == '.')
79*35238bceSAndroid Build Coastguard Worker         {
80*35238bceSAndroid Build Coastguard Worker             components.push_back(pathStr.substr(compStart, pos - compStart));
81*35238bceSAndroid Build Coastguard Worker             compStart = pos + 1;
82*35238bceSAndroid Build Coastguard Worker         }
83*35238bceSAndroid Build Coastguard Worker     }
84*35238bceSAndroid Build Coastguard Worker 
85*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(compStart < (int)pathStr.length());
86*35238bceSAndroid Build Coastguard Worker     components.push_back(pathStr.substr(compStart));
87*35238bceSAndroid Build Coastguard Worker }
88*35238bceSAndroid Build Coastguard Worker 
89*35238bceSAndroid Build Coastguard Worker // TestNode
90*35238bceSAndroid Build Coastguard Worker 
TestNode(TestGroup * parent,TestNodeType nodeType,const char * name)91*35238bceSAndroid Build Coastguard Worker TestNode::TestNode(TestGroup *parent, TestNodeType nodeType, const char *name)
92*35238bceSAndroid Build Coastguard Worker     : m_parent(parent)
93*35238bceSAndroid Build Coastguard Worker     , m_nodeType(nodeType)
94*35238bceSAndroid Build Coastguard Worker     , m_name(name)
95*35238bceSAndroid Build Coastguard Worker {
96*35238bceSAndroid Build Coastguard Worker     if (m_parent)
97*35238bceSAndroid Build Coastguard Worker     {
98*35238bceSAndroid Build Coastguard Worker         // Verify that the name is unique.
99*35238bceSAndroid Build Coastguard Worker         if (parent->m_childNames.find(name) != parent->m_childNames.end())
100*35238bceSAndroid Build Coastguard Worker             throw Error(std::string("Duplicate node '") + name + "' in '" + parent->getFullPath());
101*35238bceSAndroid Build Coastguard Worker 
102*35238bceSAndroid Build Coastguard Worker         m_parent->m_children.push_back(this);
103*35238bceSAndroid Build Coastguard Worker         m_parent->m_childNames.insert(name);
104*35238bceSAndroid Build Coastguard Worker     }
105*35238bceSAndroid Build Coastguard Worker }
106*35238bceSAndroid Build Coastguard Worker 
getFullPath(std::string & dst) const107*35238bceSAndroid Build Coastguard Worker void TestNode::getFullPath(std::string &dst) const
108*35238bceSAndroid Build Coastguard Worker {
109*35238bceSAndroid Build Coastguard Worker     dst.clear();
110*35238bceSAndroid Build Coastguard Worker 
111*35238bceSAndroid Build Coastguard Worker     int nameLen             = 0;
112*35238bceSAndroid Build Coastguard Worker     const TestNode *curNode = this;
113*35238bceSAndroid Build Coastguard Worker 
114*35238bceSAndroid Build Coastguard Worker     for (;;)
115*35238bceSAndroid Build Coastguard Worker     {
116*35238bceSAndroid Build Coastguard Worker         nameLen += (int)curNode->m_name.length();
117*35238bceSAndroid Build Coastguard Worker 
118*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(curNode->m_parent);
119*35238bceSAndroid Build Coastguard Worker         if (curNode->m_parent->getNodeType() != TESTNODETYPE_ROOT)
120*35238bceSAndroid Build Coastguard Worker         {
121*35238bceSAndroid Build Coastguard Worker             nameLen += 1;
122*35238bceSAndroid Build Coastguard Worker             curNode = curNode->m_parent;
123*35238bceSAndroid Build Coastguard Worker         }
124*35238bceSAndroid Build Coastguard Worker         else
125*35238bceSAndroid Build Coastguard Worker             break;
126*35238bceSAndroid Build Coastguard Worker     }
127*35238bceSAndroid Build Coastguard Worker 
128*35238bceSAndroid Build Coastguard Worker     dst.resize(nameLen);
129*35238bceSAndroid Build Coastguard Worker 
130*35238bceSAndroid Build Coastguard Worker     curNode = this;
131*35238bceSAndroid Build Coastguard Worker     int pos = nameLen;
132*35238bceSAndroid Build Coastguard Worker 
133*35238bceSAndroid Build Coastguard Worker     for (;;)
134*35238bceSAndroid Build Coastguard Worker     {
135*35238bceSAndroid Build Coastguard Worker         std::copy(curNode->m_name.begin(), curNode->m_name.end(), dst.begin() + (pos - curNode->m_name.length()));
136*35238bceSAndroid Build Coastguard Worker         pos -= (int)curNode->m_name.length();
137*35238bceSAndroid Build Coastguard Worker 
138*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(curNode->m_parent);
139*35238bceSAndroid Build Coastguard Worker         if (curNode->m_parent->getNodeType() != TESTNODETYPE_ROOT)
140*35238bceSAndroid Build Coastguard Worker         {
141*35238bceSAndroid Build Coastguard Worker             dst[--pos] = '.';
142*35238bceSAndroid Build Coastguard Worker             curNode    = curNode->m_parent;
143*35238bceSAndroid Build Coastguard Worker         }
144*35238bceSAndroid Build Coastguard Worker         else
145*35238bceSAndroid Build Coastguard Worker             break;
146*35238bceSAndroid Build Coastguard Worker     }
147*35238bceSAndroid Build Coastguard Worker }
148*35238bceSAndroid Build Coastguard Worker 
find(const char * path) const149*35238bceSAndroid Build Coastguard Worker const TestNode *TestNode::find(const char *path) const
150*35238bceSAndroid Build Coastguard Worker {
151*35238bceSAndroid Build Coastguard Worker     if (m_nodeType == TESTNODETYPE_ROOT)
152*35238bceSAndroid Build Coastguard Worker     {
153*35238bceSAndroid Build Coastguard Worker         // Don't need to consider current node.
154*35238bceSAndroid Build Coastguard Worker         return static_cast<const TestGroup *>(this)->findChildNode(path);
155*35238bceSAndroid Build Coastguard Worker     }
156*35238bceSAndroid Build Coastguard Worker     else
157*35238bceSAndroid Build Coastguard Worker     {
158*35238bceSAndroid Build Coastguard Worker         // Check if first component matches this node.
159*35238bceSAndroid Build Coastguard Worker         int compLen = getFirstComponentLength(path);
160*35238bceSAndroid Build Coastguard Worker         XE_CHECK(compLen > 0);
161*35238bceSAndroid Build Coastguard Worker 
162*35238bceSAndroid Build Coastguard Worker         if (compareNameToPathComponent(getName(), path, compLen))
163*35238bceSAndroid Build Coastguard Worker         {
164*35238bceSAndroid Build Coastguard Worker             if (path[compLen] == 0)
165*35238bceSAndroid Build Coastguard Worker                 return this;
166*35238bceSAndroid Build Coastguard Worker             else if (getNodeType() == TESTNODETYPE_GROUP)
167*35238bceSAndroid Build Coastguard Worker                 return static_cast<const TestGroup *>(this)->findChildNode(path + compLen + 1);
168*35238bceSAndroid Build Coastguard Worker             else
169*35238bceSAndroid Build Coastguard Worker                 return DE_NULL;
170*35238bceSAndroid Build Coastguard Worker         }
171*35238bceSAndroid Build Coastguard Worker         else
172*35238bceSAndroid Build Coastguard Worker             return DE_NULL;
173*35238bceSAndroid Build Coastguard Worker     }
174*35238bceSAndroid Build Coastguard Worker }
175*35238bceSAndroid Build Coastguard Worker 
find(const char * path)176*35238bceSAndroid Build Coastguard Worker TestNode *TestNode::find(const char *path)
177*35238bceSAndroid Build Coastguard Worker {
178*35238bceSAndroid Build Coastguard Worker     return const_cast<TestNode *>(const_cast<const TestNode *>(this)->find(path));
179*35238bceSAndroid Build Coastguard Worker }
180*35238bceSAndroid Build Coastguard Worker 
181*35238bceSAndroid Build Coastguard Worker // TestGroup
182*35238bceSAndroid Build Coastguard Worker 
TestGroup(TestGroup * parent,TestNodeType nodeType,const char * name)183*35238bceSAndroid Build Coastguard Worker TestGroup::TestGroup(TestGroup *parent, TestNodeType nodeType, const char *name) : TestNode(parent, nodeType, name)
184*35238bceSAndroid Build Coastguard Worker {
185*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(nodeType == TESTNODETYPE_GROUP || nodeType == TESTNODETYPE_ROOT);
186*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(!parent == (nodeType == TESTNODETYPE_ROOT));
187*35238bceSAndroid Build Coastguard Worker }
188*35238bceSAndroid Build Coastguard Worker 
~TestGroup(void)189*35238bceSAndroid Build Coastguard Worker TestGroup::~TestGroup(void)
190*35238bceSAndroid Build Coastguard Worker {
191*35238bceSAndroid Build Coastguard Worker     for (std::vector<TestNode *>::iterator i = m_children.begin(); i != m_children.end(); i++)
192*35238bceSAndroid Build Coastguard Worker         delete *i;
193*35238bceSAndroid Build Coastguard Worker }
194*35238bceSAndroid Build Coastguard Worker 
createGroup(const char * name)195*35238bceSAndroid Build Coastguard Worker TestGroup *TestGroup::createGroup(const char *name)
196*35238bceSAndroid Build Coastguard Worker {
197*35238bceSAndroid Build Coastguard Worker     return new TestGroup(this, TESTNODETYPE_GROUP, name);
198*35238bceSAndroid Build Coastguard Worker }
199*35238bceSAndroid Build Coastguard Worker 
createCase(TestCaseType caseType,const char * name)200*35238bceSAndroid Build Coastguard Worker TestCase *TestGroup::createCase(TestCaseType caseType, const char *name)
201*35238bceSAndroid Build Coastguard Worker {
202*35238bceSAndroid Build Coastguard Worker     return TestCase::createAsChild(this, caseType, name);
203*35238bceSAndroid Build Coastguard Worker }
204*35238bceSAndroid Build Coastguard Worker 
findChildNode(const char * path) const205*35238bceSAndroid Build Coastguard Worker const TestNode *TestGroup::findChildNode(const char *path) const
206*35238bceSAndroid Build Coastguard Worker {
207*35238bceSAndroid Build Coastguard Worker     int compLen = getFirstComponentLength(path);
208*35238bceSAndroid Build Coastguard Worker     XE_CHECK(compLen > 0);
209*35238bceSAndroid Build Coastguard Worker 
210*35238bceSAndroid Build Coastguard Worker     // Try to find matching children.
211*35238bceSAndroid Build Coastguard Worker     const TestNode *matchingNode = DE_NULL;
212*35238bceSAndroid Build Coastguard Worker     for (vector<TestNode *>::const_iterator iter = m_children.begin(); iter != m_children.end(); iter++)
213*35238bceSAndroid Build Coastguard Worker     {
214*35238bceSAndroid Build Coastguard Worker         if (compareNameToPathComponent((*iter)->getName(), path, compLen))
215*35238bceSAndroid Build Coastguard Worker         {
216*35238bceSAndroid Build Coastguard Worker             matchingNode = *iter;
217*35238bceSAndroid Build Coastguard Worker             break;
218*35238bceSAndroid Build Coastguard Worker         }
219*35238bceSAndroid Build Coastguard Worker     }
220*35238bceSAndroid Build Coastguard Worker 
221*35238bceSAndroid Build Coastguard Worker     if (matchingNode)
222*35238bceSAndroid Build Coastguard Worker     {
223*35238bceSAndroid Build Coastguard Worker         if (path[compLen] == 0)
224*35238bceSAndroid Build Coastguard Worker             return matchingNode; // Last element in path, return matching node.
225*35238bceSAndroid Build Coastguard Worker         else if (matchingNode->getNodeType() == TESTNODETYPE_GROUP)
226*35238bceSAndroid Build Coastguard Worker             return static_cast<const TestGroup *>(matchingNode)->findChildNode(path + compLen + 1);
227*35238bceSAndroid Build Coastguard Worker         else
228*35238bceSAndroid Build Coastguard Worker             return DE_NULL;
229*35238bceSAndroid Build Coastguard Worker     }
230*35238bceSAndroid Build Coastguard Worker     else
231*35238bceSAndroid Build Coastguard Worker         return DE_NULL;
232*35238bceSAndroid Build Coastguard Worker }
233*35238bceSAndroid Build Coastguard Worker 
234*35238bceSAndroid Build Coastguard Worker // TestRoot
235*35238bceSAndroid Build Coastguard Worker 
TestRoot(void)236*35238bceSAndroid Build Coastguard Worker TestRoot::TestRoot(void) : TestGroup(DE_NULL, TESTNODETYPE_ROOT, "")
237*35238bceSAndroid Build Coastguard Worker {
238*35238bceSAndroid Build Coastguard Worker }
239*35238bceSAndroid Build Coastguard Worker 
240*35238bceSAndroid Build Coastguard Worker // TestCase
241*35238bceSAndroid Build Coastguard Worker 
createAsChild(TestGroup * parent,TestCaseType caseType,const char * name)242*35238bceSAndroid Build Coastguard Worker TestCase *TestCase::createAsChild(TestGroup *parent, TestCaseType caseType, const char *name)
243*35238bceSAndroid Build Coastguard Worker {
244*35238bceSAndroid Build Coastguard Worker     return new TestCase(parent, caseType, name);
245*35238bceSAndroid Build Coastguard Worker }
246*35238bceSAndroid Build Coastguard Worker 
TestCase(TestGroup * parent,TestCaseType caseType,const char * name)247*35238bceSAndroid Build Coastguard Worker TestCase::TestCase(TestGroup *parent, TestCaseType caseType, const char *name)
248*35238bceSAndroid Build Coastguard Worker     : TestNode(parent, TESTNODETYPE_TEST_CASE, name)
249*35238bceSAndroid Build Coastguard Worker     , m_caseType(caseType)
250*35238bceSAndroid Build Coastguard Worker {
251*35238bceSAndroid Build Coastguard Worker }
252*35238bceSAndroid Build Coastguard Worker 
~TestCase(void)253*35238bceSAndroid Build Coastguard Worker TestCase::~TestCase(void)
254*35238bceSAndroid Build Coastguard Worker {
255*35238bceSAndroid Build Coastguard Worker }
256*35238bceSAndroid Build Coastguard Worker 
257*35238bceSAndroid Build Coastguard Worker // TestHierarchyBuilder helpers
258*35238bceSAndroid Build Coastguard Worker 
addChildGroupsToMap(std::map<std::string,TestGroup * > & groupMap,TestGroup * group)259*35238bceSAndroid Build Coastguard Worker void addChildGroupsToMap(std::map<std::string, TestGroup *> &groupMap, TestGroup *group)
260*35238bceSAndroid Build Coastguard Worker {
261*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < group->getNumChildren(); ndx++)
262*35238bceSAndroid Build Coastguard Worker     {
263*35238bceSAndroid Build Coastguard Worker         TestNode *node = group->getChild(ndx);
264*35238bceSAndroid Build Coastguard Worker         if (node->getNodeType() == TESTNODETYPE_GROUP)
265*35238bceSAndroid Build Coastguard Worker         {
266*35238bceSAndroid Build Coastguard Worker             TestGroup *childGroup = static_cast<TestGroup *>(node);
267*35238bceSAndroid Build Coastguard Worker             std::string fullPath;
268*35238bceSAndroid Build Coastguard Worker             childGroup->getFullPath(fullPath);
269*35238bceSAndroid Build Coastguard Worker 
270*35238bceSAndroid Build Coastguard Worker             groupMap.insert(std::make_pair(fullPath, childGroup));
271*35238bceSAndroid Build Coastguard Worker             addChildGroupsToMap(groupMap, childGroup);
272*35238bceSAndroid Build Coastguard Worker         }
273*35238bceSAndroid Build Coastguard Worker     }
274*35238bceSAndroid Build Coastguard Worker }
275*35238bceSAndroid Build Coastguard Worker 
276*35238bceSAndroid Build Coastguard Worker // TestHierarchyBuilder
277*35238bceSAndroid Build Coastguard Worker 
TestHierarchyBuilder(TestRoot * root)278*35238bceSAndroid Build Coastguard Worker TestHierarchyBuilder::TestHierarchyBuilder(TestRoot *root) : m_root(root)
279*35238bceSAndroid Build Coastguard Worker {
280*35238bceSAndroid Build Coastguard Worker     addChildGroupsToMap(m_groupMap, root);
281*35238bceSAndroid Build Coastguard Worker }
282*35238bceSAndroid Build Coastguard Worker 
~TestHierarchyBuilder(void)283*35238bceSAndroid Build Coastguard Worker TestHierarchyBuilder::~TestHierarchyBuilder(void)
284*35238bceSAndroid Build Coastguard Worker {
285*35238bceSAndroid Build Coastguard Worker }
286*35238bceSAndroid Build Coastguard Worker 
createCase(const char * path,TestCaseType caseType)287*35238bceSAndroid Build Coastguard Worker TestCase *TestHierarchyBuilder::createCase(const char *path, TestCaseType caseType)
288*35238bceSAndroid Build Coastguard Worker {
289*35238bceSAndroid Build Coastguard Worker     // \todo [2012-09-05 pyry] This can be done with less string manipulations.
290*35238bceSAndroid Build Coastguard Worker     std::vector<std::string> components;
291*35238bceSAndroid Build Coastguard Worker     splitPath(path, components);
292*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(!components.empty());
293*35238bceSAndroid Build Coastguard Worker 
294*35238bceSAndroid Build Coastguard Worker     // Create all parents if necessary.
295*35238bceSAndroid Build Coastguard Worker     TestGroup *curGroup = m_root;
296*35238bceSAndroid Build Coastguard Worker     std::string curGroupPath;
297*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < (int)components.size() - 1; ndx++)
298*35238bceSAndroid Build Coastguard Worker     {
299*35238bceSAndroid Build Coastguard Worker         if (!curGroupPath.empty())
300*35238bceSAndroid Build Coastguard Worker             curGroupPath += ".";
301*35238bceSAndroid Build Coastguard Worker         curGroupPath += components[ndx];
302*35238bceSAndroid Build Coastguard Worker 
303*35238bceSAndroid Build Coastguard Worker         std::map<std::string, TestGroup *>::const_iterator groupPos = m_groupMap.find(curGroupPath);
304*35238bceSAndroid Build Coastguard Worker         if (groupPos == m_groupMap.end())
305*35238bceSAndroid Build Coastguard Worker         {
306*35238bceSAndroid Build Coastguard Worker             TestGroup *newGroup = curGroup->createGroup(components[ndx].c_str());
307*35238bceSAndroid Build Coastguard Worker             m_groupMap.insert(std::make_pair(curGroupPath, newGroup));
308*35238bceSAndroid Build Coastguard Worker             curGroup = newGroup;
309*35238bceSAndroid Build Coastguard Worker         }
310*35238bceSAndroid Build Coastguard Worker         else
311*35238bceSAndroid Build Coastguard Worker             curGroup = groupPos->second;
312*35238bceSAndroid Build Coastguard Worker     }
313*35238bceSAndroid Build Coastguard Worker 
314*35238bceSAndroid Build Coastguard Worker     return curGroup->createCase(caseType, components.back().c_str());
315*35238bceSAndroid Build Coastguard Worker }
316*35238bceSAndroid Build Coastguard Worker 
317*35238bceSAndroid Build Coastguard Worker // TestSet helpers
318*35238bceSAndroid Build Coastguard Worker 
addNodeAndParents(std::set<const TestNode * > & nodeSet,const TestNode * node)319*35238bceSAndroid Build Coastguard Worker static void addNodeAndParents(std::set<const TestNode *> &nodeSet, const TestNode *node)
320*35238bceSAndroid Build Coastguard Worker {
321*35238bceSAndroid Build Coastguard Worker     while (node != DE_NULL)
322*35238bceSAndroid Build Coastguard Worker     {
323*35238bceSAndroid Build Coastguard Worker         nodeSet.insert(node);
324*35238bceSAndroid Build Coastguard Worker         node = node->getParent();
325*35238bceSAndroid Build Coastguard Worker     }
326*35238bceSAndroid Build Coastguard Worker }
327*35238bceSAndroid Build Coastguard Worker 
addChildren(std::set<const TestNode * > & nodeSet,const TestGroup * group)328*35238bceSAndroid Build Coastguard Worker static void addChildren(std::set<const TestNode *> &nodeSet, const TestGroup *group)
329*35238bceSAndroid Build Coastguard Worker {
330*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < group->getNumChildren(); ndx++)
331*35238bceSAndroid Build Coastguard Worker     {
332*35238bceSAndroid Build Coastguard Worker         const TestNode *child = group->getChild(ndx);
333*35238bceSAndroid Build Coastguard Worker         nodeSet.insert(child);
334*35238bceSAndroid Build Coastguard Worker 
335*35238bceSAndroid Build Coastguard Worker         if (child->getNodeType() == TESTNODETYPE_GROUP)
336*35238bceSAndroid Build Coastguard Worker             addChildren(nodeSet, static_cast<const TestGroup *>(child));
337*35238bceSAndroid Build Coastguard Worker     }
338*35238bceSAndroid Build Coastguard Worker }
339*35238bceSAndroid Build Coastguard Worker 
removeChildren(std::set<const TestNode * > & nodeSet,const TestGroup * group)340*35238bceSAndroid Build Coastguard Worker static void removeChildren(std::set<const TestNode *> &nodeSet, const TestGroup *group)
341*35238bceSAndroid Build Coastguard Worker {
342*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < group->getNumChildren(); ndx++)
343*35238bceSAndroid Build Coastguard Worker     {
344*35238bceSAndroid Build Coastguard Worker         const TestNode *child = group->getChild(ndx);
345*35238bceSAndroid Build Coastguard Worker         nodeSet.erase(child);
346*35238bceSAndroid Build Coastguard Worker 
347*35238bceSAndroid Build Coastguard Worker         if (child->getNodeType() == TESTNODETYPE_GROUP)
348*35238bceSAndroid Build Coastguard Worker             removeChildren(nodeSet, static_cast<const TestGroup *>(child));
349*35238bceSAndroid Build Coastguard Worker     }
350*35238bceSAndroid Build Coastguard Worker }
351*35238bceSAndroid Build Coastguard Worker 
hasChildrenInSet(const std::set<const TestNode * > & nodeSet,const TestGroup * group)352*35238bceSAndroid Build Coastguard Worker static bool hasChildrenInSet(const std::set<const TestNode *> &nodeSet, const TestGroup *group)
353*35238bceSAndroid Build Coastguard Worker {
354*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < group->getNumChildren(); ndx++)
355*35238bceSAndroid Build Coastguard Worker     {
356*35238bceSAndroid Build Coastguard Worker         if (nodeSet.find(group->getChild(ndx)) != nodeSet.end())
357*35238bceSAndroid Build Coastguard Worker             return true;
358*35238bceSAndroid Build Coastguard Worker     }
359*35238bceSAndroid Build Coastguard Worker     return false;
360*35238bceSAndroid Build Coastguard Worker }
361*35238bceSAndroid Build Coastguard Worker 
removeEmptyGroups(std::set<const TestNode * > & nodeSet,const TestGroup * group)362*35238bceSAndroid Build Coastguard Worker static void removeEmptyGroups(std::set<const TestNode *> &nodeSet, const TestGroup *group)
363*35238bceSAndroid Build Coastguard Worker {
364*35238bceSAndroid Build Coastguard Worker     if (!hasChildrenInSet(nodeSet, group))
365*35238bceSAndroid Build Coastguard Worker     {
366*35238bceSAndroid Build Coastguard Worker         nodeSet.erase(group);
367*35238bceSAndroid Build Coastguard Worker         if (group->getParent() != DE_NULL)
368*35238bceSAndroid Build Coastguard Worker             removeEmptyGroups(nodeSet, group->getParent());
369*35238bceSAndroid Build Coastguard Worker     }
370*35238bceSAndroid Build Coastguard Worker }
371*35238bceSAndroid Build Coastguard Worker 
372*35238bceSAndroid Build Coastguard Worker // TestSet
373*35238bceSAndroid Build Coastguard Worker 
add(const TestNode * node)374*35238bceSAndroid Build Coastguard Worker void TestSet::add(const TestNode *node)
375*35238bceSAndroid Build Coastguard Worker {
376*35238bceSAndroid Build Coastguard Worker     if (node->getNodeType() == TESTNODETYPE_TEST_CASE)
377*35238bceSAndroid Build Coastguard Worker         addCase(static_cast<const TestCase *>(node));
378*35238bceSAndroid Build Coastguard Worker     else
379*35238bceSAndroid Build Coastguard Worker     {
380*35238bceSAndroid Build Coastguard Worker         XE_CHECK(node->getNodeType() == TESTNODETYPE_GROUP || node->getNodeType() == TESTNODETYPE_ROOT);
381*35238bceSAndroid Build Coastguard Worker         addGroup(static_cast<const TestGroup *>(node));
382*35238bceSAndroid Build Coastguard Worker     }
383*35238bceSAndroid Build Coastguard Worker }
384*35238bceSAndroid Build Coastguard Worker 
addCase(const TestCase * testCase)385*35238bceSAndroid Build Coastguard Worker void TestSet::addCase(const TestCase *testCase)
386*35238bceSAndroid Build Coastguard Worker {
387*35238bceSAndroid Build Coastguard Worker     addNodeAndParents(m_set, testCase);
388*35238bceSAndroid Build Coastguard Worker }
389*35238bceSAndroid Build Coastguard Worker 
addGroup(const TestGroup * testGroup)390*35238bceSAndroid Build Coastguard Worker void TestSet::addGroup(const TestGroup *testGroup)
391*35238bceSAndroid Build Coastguard Worker {
392*35238bceSAndroid Build Coastguard Worker     addNodeAndParents(m_set, testGroup);
393*35238bceSAndroid Build Coastguard Worker     addChildren(m_set, testGroup);
394*35238bceSAndroid Build Coastguard Worker }
395*35238bceSAndroid Build Coastguard Worker 
remove(const TestNode * node)396*35238bceSAndroid Build Coastguard Worker void TestSet::remove(const TestNode *node)
397*35238bceSAndroid Build Coastguard Worker {
398*35238bceSAndroid Build Coastguard Worker     if (node->getNodeType() == TESTNODETYPE_TEST_CASE)
399*35238bceSAndroid Build Coastguard Worker         removeCase(static_cast<const TestCase *>(node));
400*35238bceSAndroid Build Coastguard Worker     else
401*35238bceSAndroid Build Coastguard Worker     {
402*35238bceSAndroid Build Coastguard Worker         XE_CHECK(node->getNodeType() == TESTNODETYPE_GROUP || node->getNodeType() == TESTNODETYPE_ROOT);
403*35238bceSAndroid Build Coastguard Worker         removeGroup(static_cast<const TestGroup *>(node));
404*35238bceSAndroid Build Coastguard Worker     }
405*35238bceSAndroid Build Coastguard Worker }
406*35238bceSAndroid Build Coastguard Worker 
removeCase(const TestCase * testCase)407*35238bceSAndroid Build Coastguard Worker void TestSet::removeCase(const TestCase *testCase)
408*35238bceSAndroid Build Coastguard Worker {
409*35238bceSAndroid Build Coastguard Worker     if (m_set.find(testCase) != m_set.end())
410*35238bceSAndroid Build Coastguard Worker     {
411*35238bceSAndroid Build Coastguard Worker         m_set.erase(testCase);
412*35238bceSAndroid Build Coastguard Worker         removeEmptyGroups(m_set, testCase->getParent());
413*35238bceSAndroid Build Coastguard Worker     }
414*35238bceSAndroid Build Coastguard Worker }
415*35238bceSAndroid Build Coastguard Worker 
removeGroup(const TestGroup * testGroup)416*35238bceSAndroid Build Coastguard Worker void TestSet::removeGroup(const TestGroup *testGroup)
417*35238bceSAndroid Build Coastguard Worker {
418*35238bceSAndroid Build Coastguard Worker     if (m_set.find(testGroup) != m_set.end())
419*35238bceSAndroid Build Coastguard Worker     {
420*35238bceSAndroid Build Coastguard Worker         m_set.erase(testGroup);
421*35238bceSAndroid Build Coastguard Worker         removeChildren(m_set, testGroup);
422*35238bceSAndroid Build Coastguard Worker         if (testGroup->getParent() != DE_NULL)
423*35238bceSAndroid Build Coastguard Worker             removeEmptyGroups(m_set, testGroup->getParent());
424*35238bceSAndroid Build Coastguard Worker     }
425*35238bceSAndroid Build Coastguard Worker }
426*35238bceSAndroid Build Coastguard Worker 
427*35238bceSAndroid Build Coastguard Worker // ConstTestNodeIterator
428*35238bceSAndroid Build Coastguard Worker 
ConstTestNodeIterator(const TestNode * root)429*35238bceSAndroid Build Coastguard Worker ConstTestNodeIterator::ConstTestNodeIterator(const TestNode *root) : m_root(root)
430*35238bceSAndroid Build Coastguard Worker {
431*35238bceSAndroid Build Coastguard Worker }
432*35238bceSAndroid Build Coastguard Worker 
begin(const TestNode * root)433*35238bceSAndroid Build Coastguard Worker ConstTestNodeIterator ConstTestNodeIterator::begin(const TestNode *root)
434*35238bceSAndroid Build Coastguard Worker {
435*35238bceSAndroid Build Coastguard Worker     ConstTestNodeIterator iter(root);
436*35238bceSAndroid Build Coastguard Worker     iter.m_iterStack.push_back(GroupState(DE_NULL));
437*35238bceSAndroid Build Coastguard Worker     return iter;
438*35238bceSAndroid Build Coastguard Worker }
439*35238bceSAndroid Build Coastguard Worker 
end(const TestNode * root)440*35238bceSAndroid Build Coastguard Worker ConstTestNodeIterator ConstTestNodeIterator::end(const TestNode *root)
441*35238bceSAndroid Build Coastguard Worker {
442*35238bceSAndroid Build Coastguard Worker     DE_UNREF(root);
443*35238bceSAndroid Build Coastguard Worker     return ConstTestNodeIterator(root);
444*35238bceSAndroid Build Coastguard Worker }
445*35238bceSAndroid Build Coastguard Worker 
operator ++(void)446*35238bceSAndroid Build Coastguard Worker ConstTestNodeIterator &ConstTestNodeIterator::operator++(void)
447*35238bceSAndroid Build Coastguard Worker {
448*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(!m_iterStack.empty());
449*35238bceSAndroid Build Coastguard Worker 
450*35238bceSAndroid Build Coastguard Worker     const TestNode *curNode  = **this;
451*35238bceSAndroid Build Coastguard Worker     TestNodeType curNodeType = curNode->getNodeType();
452*35238bceSAndroid Build Coastguard Worker 
453*35238bceSAndroid Build Coastguard Worker     if ((curNodeType == TESTNODETYPE_GROUP || curNodeType == TESTNODETYPE_ROOT) &&
454*35238bceSAndroid Build Coastguard Worker         static_cast<const TestGroup *>(curNode)->getNumChildren() > 0)
455*35238bceSAndroid Build Coastguard Worker     {
456*35238bceSAndroid Build Coastguard Worker         m_iterStack.push_back(GroupState(static_cast<const TestGroup *>(curNode)));
457*35238bceSAndroid Build Coastguard Worker     }
458*35238bceSAndroid Build Coastguard Worker     else
459*35238bceSAndroid Build Coastguard Worker     {
460*35238bceSAndroid Build Coastguard Worker         for (;;)
461*35238bceSAndroid Build Coastguard Worker         {
462*35238bceSAndroid Build Coastguard Worker             const TestGroup *group = m_iterStack.back().group;
463*35238bceSAndroid Build Coastguard Worker             int &childNdx          = m_iterStack.back().childNdx;
464*35238bceSAndroid Build Coastguard Worker             int numChildren        = group ? group->getNumChildren() : 1;
465*35238bceSAndroid Build Coastguard Worker 
466*35238bceSAndroid Build Coastguard Worker             childNdx += 1;
467*35238bceSAndroid Build Coastguard Worker             if (childNdx == numChildren)
468*35238bceSAndroid Build Coastguard Worker             {
469*35238bceSAndroid Build Coastguard Worker                 m_iterStack.pop_back();
470*35238bceSAndroid Build Coastguard Worker                 if (m_iterStack.empty())
471*35238bceSAndroid Build Coastguard Worker                     break;
472*35238bceSAndroid Build Coastguard Worker             }
473*35238bceSAndroid Build Coastguard Worker             else
474*35238bceSAndroid Build Coastguard Worker                 break;
475*35238bceSAndroid Build Coastguard Worker         }
476*35238bceSAndroid Build Coastguard Worker     }
477*35238bceSAndroid Build Coastguard Worker 
478*35238bceSAndroid Build Coastguard Worker     return *this;
479*35238bceSAndroid Build Coastguard Worker }
480*35238bceSAndroid Build Coastguard Worker 
operator ++(int)481*35238bceSAndroid Build Coastguard Worker ConstTestNodeIterator ConstTestNodeIterator::operator++(int)
482*35238bceSAndroid Build Coastguard Worker {
483*35238bceSAndroid Build Coastguard Worker     ConstTestNodeIterator copy(*this);
484*35238bceSAndroid Build Coastguard Worker     ++(*this);
485*35238bceSAndroid Build Coastguard Worker     return copy;
486*35238bceSAndroid Build Coastguard Worker }
487*35238bceSAndroid Build Coastguard Worker 
operator *(void) const488*35238bceSAndroid Build Coastguard Worker const TestNode *ConstTestNodeIterator::operator*(void) const
489*35238bceSAndroid Build Coastguard Worker {
490*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(!m_iterStack.empty());
491*35238bceSAndroid Build Coastguard Worker     if (m_iterStack.size() == 1)
492*35238bceSAndroid Build Coastguard Worker     {
493*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(m_iterStack[0].group == DE_NULL && m_iterStack[0].childNdx == 0);
494*35238bceSAndroid Build Coastguard Worker         return m_root;
495*35238bceSAndroid Build Coastguard Worker     }
496*35238bceSAndroid Build Coastguard Worker     else
497*35238bceSAndroid Build Coastguard Worker         return m_iterStack.back().group->getChild(m_iterStack.back().childNdx);
498*35238bceSAndroid Build Coastguard Worker }
499*35238bceSAndroid Build Coastguard Worker 
operator !=(const ConstTestNodeIterator & other) const500*35238bceSAndroid Build Coastguard Worker bool ConstTestNodeIterator::operator!=(const ConstTestNodeIterator &other) const
501*35238bceSAndroid Build Coastguard Worker {
502*35238bceSAndroid Build Coastguard Worker     return m_root != other.m_root || m_iterStack != other.m_iterStack;
503*35238bceSAndroid Build Coastguard Worker }
504*35238bceSAndroid Build Coastguard Worker 
505*35238bceSAndroid Build Coastguard Worker } // namespace xe
506