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)
94 // Init traverse state and "seek" to first reportable node.
95 NodeIter iter(&rootNode);
96 iter.setState(NodeIter::STATE_ENTER); // Root is never reported
97 m_sessionStack.push_back(iter);
101 TestHierarchyIterator::~TestHierarchyIterator (void)
103 // Tear down inflated nodes in m_sessionStack
104 for (vector<NodeIter>::reverse_iterator iter = m_sessionStack.rbegin(); iter != m_sessionStack.rend(); ++iter)
106 TestNode* const node = iter->node;
107 const TestNodeType nodeType = node->getNodeType();
111 case NODETYPE_ROOT: /* root is not de-initialized */ break;
112 case NODETYPE_PACKAGE: m_inflater.leaveTestPackage(static_cast<TestPackage*>(node)); break;
113 case NODETYPE_GROUP: m_inflater.leaveGroupNode(static_cast<TestCaseGroup*>(node)); break;
120 TestHierarchyIterator::State TestHierarchyIterator::getState (void) const
122 if (!m_sessionStack.empty())
124 const NodeIter& iter = m_sessionStack.back();
126 DE_ASSERT(iter.getState() == NodeIter::STATE_ENTER ||
127 iter.getState() == NodeIter::STATE_LEAVE);
129 return iter.getState() == NodeIter::STATE_ENTER ? STATE_ENTER_NODE : STATE_LEAVE_NODE;
132 return STATE_FINISHED;
135 TestNode* TestHierarchyIterator::getNode (void) const
137 DE_ASSERT(getState() != STATE_FINISHED);
138 return m_sessionStack.back().node;
141 const std::string& TestHierarchyIterator::getNodePath (void) const
143 DE_ASSERT(getState() != STATE_FINISHED);
147 std::string TestHierarchyIterator::buildNodePath (const vector<NodeIter>& nodeStack)
150 for (size_t ndx = 1; ndx < nodeStack.size(); ndx++)
152 const NodeIter& iter = nodeStack[ndx];
153 if (ndx > 1) // ignore root package
155 nodePath += iter.node->getName();
160 void TestHierarchyIterator::next (void)
162 while (!m_sessionStack.empty())
164 NodeIter& iter = m_sessionStack.back();
165 TestNode* const node = iter.node;
166 const bool isLeaf = isTestNodeTypeExecutable(node->getNodeType());
168 switch (iter.getState())
170 case NodeIter::STATE_INIT:
172 const std::string nodePath = buildNodePath(m_sessionStack);
174 // Return to parent if name doesn't match filter.
175 if (!(isLeaf ? m_caseListFilter.checkTestCaseName(nodePath.c_str()) : m_caseListFilter.checkTestGroupName(nodePath.c_str())))
177 m_sessionStack.pop_back();
181 m_nodePath = nodePath;
182 iter.setState(NodeIter::STATE_ENTER);
183 return; // Yield enter event
186 case NodeIter::STATE_ENTER:
190 iter.setState(NodeIter::STATE_LEAVE);
191 return; // Yield leave event
195 iter.setState(NodeIter::STATE_TRAVERSE_CHILDREN);
196 iter.children.clear();
198 switch (node->getNodeType())
200 case NODETYPE_ROOT: static_cast<TestPackageRoot*>(node)->getChildren(iter.children); break;
201 case NODETYPE_PACKAGE: m_inflater.enterTestPackage(static_cast<TestPackage*>(node), iter.children); break;
202 case NODETYPE_GROUP: m_inflater.enterGroupNode(static_cast<TestCaseGroup*>(node), iter.children); break;
211 case NodeIter::STATE_TRAVERSE_CHILDREN:
213 int numChildren = (int)iter.children.size();
214 if (++iter.curChildNdx < numChildren)
216 // Push child to stack.
217 TestNode* childNode = iter.children[iter.curChildNdx];
218 m_sessionStack.push_back(NodeIter(childNode));
222 iter.setState(NodeIter::STATE_LEAVE);
223 if (node->getNodeType() != NODETYPE_ROOT)
224 return; // Yield leave event
230 case NodeIter::STATE_LEAVE:
235 switch (node->getNodeType())
237 case NODETYPE_ROOT: /* root is not de-initialized */ break;
238 case NODETYPE_PACKAGE: m_inflater.leaveTestPackage(static_cast<TestPackage*>(node)); break;
239 case NODETYPE_GROUP: m_inflater.leaveGroupNode(static_cast<TestCaseGroup*>(node)); break;
245 m_sessionStack.pop_back();
246 m_nodePath = buildNodePath(m_sessionStack);
256 DE_ASSERT(m_sessionStack.empty() && getState() == STATE_FINISHED);