1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program Tester Core
3 * ----------------------------------------
5 * Copyright 2014 The Android Open Source Project
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 * \brief Test case hierarchy iterator.
22 *//*--------------------------------------------------------------------*/
24 #include "tcuTestHierarchyIterator.hpp"
25 #include "tcuCommandLine.hpp"
33 // TestHierarchyInflater
35 TestHierarchyInflater::TestHierarchyInflater (void)
39 TestHierarchyInflater::~TestHierarchyInflater (void)
43 // DefaultHierarchyInflater
45 DefaultHierarchyInflater::DefaultHierarchyInflater (TestContext& testCtx)
50 DefaultHierarchyInflater::~DefaultHierarchyInflater (void)
54 void DefaultHierarchyInflater::enterTestPackage (TestPackage* testPackage, vector<TestNode*>& children)
57 Archive* const pkgArchive = testPackage->getArchive();
60 m_testCtx.setCurrentArchive(*pkgArchive);
62 m_testCtx.setCurrentArchive(m_testCtx.getRootArchive());
66 testPackage->getChildren(children);
69 void DefaultHierarchyInflater::leaveTestPackage (TestPackage* testPackage)
71 m_testCtx.setCurrentArchive(m_testCtx.getRootArchive());
72 testPackage->deinit();
75 void DefaultHierarchyInflater::enterGroupNode (TestCaseGroup* testGroup, vector<TestNode*>& children)
78 testGroup->getChildren(children);
81 void DefaultHierarchyInflater::leaveGroupNode (TestCaseGroup* testGroup)
86 // TestHierarchyIterator
88 TestHierarchyIterator::TestHierarchyIterator (TestPackageRoot& rootNode,
89 TestHierarchyInflater& inflater,
90 const CaseListFilter& caseListFilter)
91 : m_inflater (inflater)
92 , m_caseListFilter (caseListFilter)
95 // Init traverse state and "seek" to first reportable node.
96 NodeIter iter(&rootNode);
97 iter.setState(NodeIter::NISTATE_ENTER); // Root is never reported
98 m_sessionStack.push_back(iter);
102 TestHierarchyIterator::~TestHierarchyIterator (void)
104 // Tear down inflated nodes in m_sessionStack
105 for (vector<NodeIter>::reverse_iterator iter = m_sessionStack.rbegin(); iter != m_sessionStack.rend(); ++iter)
107 TestNode* const node = iter->node;
108 const TestNodeType nodeType = node->getNodeType();
112 case NODETYPE_ROOT: /* root is not de-initialized */ break;
113 case NODETYPE_PACKAGE: m_inflater.leaveTestPackage(static_cast<TestPackage*>(node)); break;
114 case NODETYPE_GROUP: m_inflater.leaveGroupNode(static_cast<TestCaseGroup*>(node)); break;
121 TestHierarchyIterator::State TestHierarchyIterator::getState (void) const
123 if (!m_sessionStack.empty())
125 const NodeIter& iter = m_sessionStack.back();
127 DE_ASSERT(iter.getState() == NodeIter::NISTATE_ENTER ||
128 iter.getState() == NodeIter::NISTATE_LEAVE);
130 return iter.getState() == NodeIter::NISTATE_ENTER ? STATE_ENTER_NODE : STATE_LEAVE_NODE;
133 return STATE_FINISHED;
136 TestNode* TestHierarchyIterator::getNode (void) const
138 DE_ASSERT(getState() != STATE_FINISHED);
139 return m_sessionStack.back().node;
142 const std::string& TestHierarchyIterator::getNodePath (void) const
144 DE_ASSERT(getState() != STATE_FINISHED);
148 std::string TestHierarchyIterator::buildNodePath (const vector<NodeIter>& nodeStack)
151 for (size_t ndx = 1; ndx < nodeStack.size(); ndx++)
153 const NodeIter& iter = nodeStack[ndx];
154 if (ndx > 1) // ignore root package
156 nodePath += iter.node->getName();
161 void TestHierarchyIterator::next (void)
163 while (!m_sessionStack.empty())
165 NodeIter& iter = m_sessionStack.back();
166 TestNode* const node = iter.node;
167 const bool isLeaf = isTestNodeTypeExecutable(node->getNodeType());
169 switch (iter.getState())
171 case NodeIter::NISTATE_INIT:
173 const std::string nodePath = buildNodePath(m_sessionStack);
175 // Return to parent if name doesn't match filter.
176 if (!(isLeaf ? m_caseListFilter.checkTestCaseName(nodePath.c_str()) : m_caseListFilter.checkTestGroupName(nodePath.c_str())))
178 m_sessionStack.pop_back();
182 m_nodePath = nodePath;
183 iter.setState(NodeIter::NISTATE_ENTER);
184 return; // Yield enter event
187 case NodeIter::NISTATE_ENTER:
191 iter.setState(NodeIter::NISTATE_LEAVE);
192 return; // Yield leave event
196 iter.setState(NodeIter::NISTATE_TRAVERSE_CHILDREN);
197 iter.children.clear();
199 switch (node->getNodeType())
201 case NODETYPE_ROOT: static_cast<TestPackageRoot*>(node)->getChildren(iter.children); break;
202 case NODETYPE_PACKAGE: m_inflater.enterTestPackage(static_cast<TestPackage*>(node), iter.children); break;
203 case NODETYPE_GROUP: m_inflater.enterGroupNode(static_cast<TestCaseGroup*>(node), iter.children); break;
212 case NodeIter::NISTATE_TRAVERSE_CHILDREN:
214 int numChildren = (int)iter.children.size();
215 if (++iter.curChildNdx < numChildren)
217 // Push child to stack.
218 TestNode* childNode = iter.children[iter.curChildNdx];
220 // Check whether this is a bottom-level group (child is executable)
221 // and whether that group should be filtered out.
222 if ( isTestNodeTypeExecutable(childNode->getNodeType()) )
224 const std::string testName = m_nodePath + "." + childNode->getName();
225 if(!m_caseListFilter.checkCaseFraction(m_groupNumber, testName))
228 m_sessionStack.push_back(NodeIter(childNode));
232 iter.setState(NodeIter::NISTATE_LEAVE);
233 if (node->getNodeType() != NODETYPE_ROOT)
234 return; // Yield leave event
240 case NodeIter::NISTATE_LEAVE:
245 switch (node->getNodeType())
247 case NODETYPE_ROOT: /* root is not de-initialized */ break;
248 case NODETYPE_PACKAGE: m_inflater.leaveTestPackage(static_cast<TestPackage*>(node)); break;
249 case NODETYPE_GROUP: m_inflater.leaveGroupNode(static_cast<TestCaseGroup*>(node)); break;
256 m_sessionStack.pop_back();
257 m_nodePath = buildNodePath(m_sessionStack);
267 DE_ASSERT(m_sessionStack.empty() && getState() == STATE_FINISHED);