• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 Test case hierarchy iterator.
22  *//*--------------------------------------------------------------------*/
23 
24 #include "tcuTestHierarchyIterator.hpp"
25 #include "tcuCommandLine.hpp"
26 
27 namespace tcu
28 {
29 
30 using std::string;
31 using std::vector;
32 
33 // TestHierarchyInflater
34 
TestHierarchyInflater(void)35 TestHierarchyInflater::TestHierarchyInflater (void)
36 {
37 }
38 
~TestHierarchyInflater(void)39 TestHierarchyInflater::~TestHierarchyInflater (void)
40 {
41 }
42 
43 // DefaultHierarchyInflater
44 
DefaultHierarchyInflater(TestContext & testCtx)45 DefaultHierarchyInflater::DefaultHierarchyInflater (TestContext& testCtx)
46 	: m_testCtx(testCtx)
47 {
48 }
49 
~DefaultHierarchyInflater(void)50 DefaultHierarchyInflater::~DefaultHierarchyInflater (void)
51 {
52 }
53 
enterTestPackage(TestPackage * testPackage,vector<TestNode * > & children)54 void DefaultHierarchyInflater::enterTestPackage (TestPackage* testPackage, vector<TestNode*>& children)
55 {
56 	{
57 		Archive* const	pkgArchive	= testPackage->getArchive();
58 
59 		if (pkgArchive)
60 			m_testCtx.setCurrentArchive(*pkgArchive);
61 		else
62 			m_testCtx.setCurrentArchive(m_testCtx.getRootArchive());
63 	}
64 
65 	testPackage->init();
66 	testPackage->getChildren(children);
67 }
68 
leaveTestPackage(TestPackage * testPackage)69 void DefaultHierarchyInflater::leaveTestPackage (TestPackage* testPackage)
70 {
71 	m_testCtx.setCurrentArchive(m_testCtx.getRootArchive());
72 	testPackage->deinit();
73 }
74 
enterGroupNode(TestCaseGroup * testGroup,vector<TestNode * > & children)75 void DefaultHierarchyInflater::enterGroupNode (TestCaseGroup* testGroup, vector<TestNode*>& children)
76 {
77 	testGroup->init();
78 	testGroup->getChildren(children);
79 }
80 
leaveGroupNode(TestCaseGroup * testGroup)81 void DefaultHierarchyInflater::leaveGroupNode (TestCaseGroup* testGroup)
82 {
83 	testGroup->deinit();
84 }
85 
86 // TestHierarchyIterator
87 
TestHierarchyIterator(TestPackageRoot & rootNode,TestHierarchyInflater & inflater,const CaseListFilter & caseListFilter)88 TestHierarchyIterator::TestHierarchyIterator (TestPackageRoot&			rootNode,
89 											  TestHierarchyInflater&	inflater,
90 											  const CaseListFilter&		caseListFilter)
91 	: m_inflater		(inflater)
92 	, m_caseListFilter	(caseListFilter)
93 {
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);
98 	next();
99 }
100 
~TestHierarchyIterator(void)101 TestHierarchyIterator::~TestHierarchyIterator (void)
102 {
103 	// Tear down inflated nodes in m_sessionStack
104 	for (vector<NodeIter>::reverse_iterator iter = m_sessionStack.rbegin(); iter != m_sessionStack.rend(); ++iter)
105 	{
106 		TestNode* const		node		= iter->node;
107 		const TestNodeType	nodeType	= node->getNodeType();
108 
109 		switch (nodeType)
110 		{
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;
114 			default:
115 				break;
116 		}
117 	}
118 }
119 
getState(void) const120 TestHierarchyIterator::State TestHierarchyIterator::getState (void) const
121 {
122 	if (!m_sessionStack.empty())
123 	{
124 		const NodeIter&	iter	= m_sessionStack.back();
125 
126 		DE_ASSERT(iter.getState() == NodeIter::STATE_ENTER ||
127 				  iter.getState() == NodeIter::STATE_LEAVE);
128 
129 		return iter.getState() == NodeIter::STATE_ENTER ? STATE_ENTER_NODE : STATE_LEAVE_NODE;
130 	}
131 	else
132 		return STATE_FINISHED;
133 }
134 
getNode(void) const135 TestNode* TestHierarchyIterator::getNode (void) const
136 {
137 	DE_ASSERT(getState() != STATE_FINISHED);
138 	return m_sessionStack.back().node;
139 }
140 
getNodePath(void) const141 const std::string& TestHierarchyIterator::getNodePath (void) const
142 {
143 	DE_ASSERT(getState() != STATE_FINISHED);
144 	return m_nodePath;
145 }
146 
buildNodePath(const vector<NodeIter> & nodeStack)147 std::string TestHierarchyIterator::buildNodePath (const vector<NodeIter>& nodeStack)
148 {
149 	string nodePath;
150 	for (size_t ndx = 1; ndx < nodeStack.size(); ndx++)
151 	{
152 		const NodeIter& iter = nodeStack[ndx];
153 		if (ndx > 1) // ignore root package
154 			nodePath += ".";
155 		nodePath += iter.node->getName();
156 	}
157 	return nodePath;
158 }
159 
next(void)160 void TestHierarchyIterator::next (void)
161 {
162 	while (!m_sessionStack.empty())
163 	{
164 		NodeIter&			iter		= m_sessionStack.back();
165 		TestNode* const		node		= iter.node;
166 		const bool			isLeaf		= isTestNodeTypeExecutable(node->getNodeType());
167 
168 		switch (iter.getState())
169 		{
170 			case NodeIter::STATE_INIT:
171 			{
172 				const std::string nodePath = buildNodePath(m_sessionStack);
173 
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())))
176 				{
177 					m_sessionStack.pop_back();
178 					break;
179 				}
180 
181 				m_nodePath = nodePath;
182 				iter.setState(NodeIter::STATE_ENTER);
183 				return; // Yield enter event
184 			}
185 
186 			case NodeIter::STATE_ENTER:
187 			{
188 				if (isLeaf)
189 				{
190 					iter.setState(NodeIter::STATE_LEAVE);
191 					return; // Yield leave event
192 				}
193 				else
194 				{
195 					iter.setState(NodeIter::STATE_TRAVERSE_CHILDREN);
196 					iter.children.clear();
197 
198 					switch (node->getNodeType())
199 					{
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;
203 						default:
204 							DE_ASSERT(false);
205 					}
206 				}
207 
208 				break;
209 			}
210 
211 			case NodeIter::STATE_TRAVERSE_CHILDREN:
212 			{
213 				int numChildren = (int)iter.children.size();
214 				if (++iter.curChildNdx < numChildren)
215 				{
216 					// Push child to stack.
217 					TestNode* childNode = iter.children[iter.curChildNdx];
218 					m_sessionStack.push_back(NodeIter(childNode));
219 				}
220 				else
221 				{
222 					iter.setState(NodeIter::STATE_LEAVE);
223 					if (node->getNodeType() != NODETYPE_ROOT)
224 						return; // Yield leave event
225 				}
226 
227 				break;
228 			}
229 
230 			case NodeIter::STATE_LEAVE:
231 			{
232 				// Leave node.
233 				if (!isLeaf)
234 				{
235 					switch (node->getNodeType())
236 					{
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;
240 						default:
241 							DE_ASSERT(false);
242 					}
243 				}
244 
245 				m_sessionStack.pop_back();
246 				m_nodePath = buildNodePath(m_sessionStack);
247 				break;
248 			}
249 
250 			default:
251 				DE_ASSERT(false);
252 				return;
253 		}
254 	}
255 
256 	DE_ASSERT(m_sessionStack.empty() && getState() == STATE_FINISHED);
257 }
258 
259 } // tcu
260