Home | History | Annotate | Download | only in common
      1 #ifndef _TCUTESTHIERARCHYITERATOR_HPP
      2 #define _TCUTESTHIERARCHYITERATOR_HPP
      3 /*-------------------------------------------------------------------------
      4  * drawElements Quality Program Tester Core
      5  * ----------------------------------------
      6  *
      7  * Copyright 2014 The Android Open Source Project
      8  *
      9  * Licensed under the Apache License, Version 2.0 (the "License");
     10  * you may not use this file except in compliance with the License.
     11  * You may obtain a copy of the License at
     12  *
     13  *      http://www.apache.org/licenses/LICENSE-2.0
     14  *
     15  * Unless required by applicable law or agreed to in writing, software
     16  * distributed under the License is distributed on an "AS IS" BASIS,
     17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     18  * See the License for the specific language governing permissions and
     19  * limitations under the License.
     20  *
     21  *//*!
     22  * \file
     23  * \brief Test case hierarchy iterator.
     24  *//*--------------------------------------------------------------------*/
     25 
     26 #include "tcuDefs.hpp"
     27 #include "tcuTestContext.hpp"
     28 #include "tcuTestCase.hpp"
     29 #include "tcuTestPackage.hpp"
     30 
     31 #include <vector>
     32 
     33 namespace tcu
     34 {
     35 
     36 class CommandLine;
     37 
     38 /*--------------------------------------------------------------------*//*!
     39  * \brief Test hierarchy inflater
     40  *
     41  * This interface is used by TestHierarchyIterator to materialize, and clean
     42  * up, test hierarchy on-demand while walking through it.
     43  *//*--------------------------------------------------------------------*/
     44 class TestHierarchyInflater
     45 {
     46 public:
     47 									TestHierarchyInflater	(void);
     48 
     49 	virtual void					enterTestPackage		(TestPackage* testPackage, std::vector<TestNode*>& children) = 0;
     50 	virtual void					leaveTestPackage		(TestPackage* testPackage) = 0;
     51 
     52 	virtual void					enterGroupNode			(TestCaseGroup* testGroup, std::vector<TestNode*>& children) = 0;
     53 	virtual void					leaveGroupNode			(TestCaseGroup* testGroup) = 0;
     54 
     55 protected:
     56 									~TestHierarchyInflater	(void);
     57 };
     58 
     59 // \todo [2015-02-26 pyry] Hierarchy traversal should not depend on TestContext
     60 class DefaultHierarchyInflater : public TestHierarchyInflater
     61 {
     62 public:
     63 									DefaultHierarchyInflater	(TestContext& testCtx);
     64 									~DefaultHierarchyInflater	(void);
     65 
     66 	virtual void					enterTestPackage			(TestPackage* testPackage, std::vector<TestNode*>& children);
     67 	virtual void					leaveTestPackage			(TestPackage* testPackage);
     68 
     69 	virtual void					enterGroupNode				(TestCaseGroup* testGroup, std::vector<TestNode*>& children);
     70 	virtual void					leaveGroupNode				(TestCaseGroup* testGroup);
     71 
     72 protected:
     73 	TestContext&					m_testCtx;
     74 };
     75 
     76 /*--------------------------------------------------------------------*//*!
     77  * \brief Test hierarchy iterator
     78  *
     79  * Test hierarchy iterator allows walking test case hierarchy in depth-first
     80  * order. The walked sub-tree is limited by command line parameters.
     81  *
     82  * Iterator signals current state with getState(), which initally, and after
     83  * each increment (next()) may report one of the following:
     84  *
     85  * STATE_ENTER_NODE: A test node has been entered to for the first time.
     86  *   Node can be queried with getNode() and its full path with getNodePath().
     87  *   For group nodes the iterator will next enter first matching child node.
     88  *   For executable (test case) nodes STATE_LEAVE_NODE will always be reported
     89  *   immediately after entering that node.
     90  *
     91  * STATE_LEAVE_NODE: Iterator is leaving a node. In case of group nodes this
     92  *   means that all child nodes and their children have been processed. For
     93  *   executable nodes the iterator will either move on to the next sibling,
     94  *   or leave the parent group if the reported node was last child of that
     95  *   group.
     96  *
     97  * Root node is never reported, but instead iteration will start on first
     98  * matching test package node, if there is any.
     99  *
    100  * Test hierarchy is created on demand with help of TestHierarchyInflater.
    101  * Upon entering a group node, after STATE_ENTER_NODE has been signaled,
    102  * inflater is called to construct the list of child nodes for that group.
    103  * Upon exiting a group node, before STATE_LEAVE_NODE is called, inflater
    104  * is asked to clean up any resources by calling leaveGroupNode() or
    105  * leaveTestPackage() depending on the type of the node.
    106  *//*--------------------------------------------------------------------*/
    107 class TestHierarchyIterator
    108 {
    109 public:
    110 							TestHierarchyIterator	(TestPackageRoot& rootNode, TestHierarchyInflater& inflater, const CommandLine& cmdLine);
    111 							~TestHierarchyIterator	(void);
    112 
    113 	enum State
    114 	{
    115 		STATE_ENTER_NODE = 0,
    116 		STATE_LEAVE_NODE,
    117 		STATE_FINISHED,
    118 
    119 		STATE_LAST
    120 	};
    121 
    122 	State					getState				(void) const;
    123 
    124 	TestNode*				getNode					(void) const;
    125 	const std::string&		getNodePath				(void) const;
    126 
    127 	void					next					(void);
    128 
    129 private:
    130 	struct NodeIter
    131 	{
    132 		enum State
    133 		{
    134 			STATE_INIT = 0,
    135 			STATE_ENTER,
    136 			STATE_TRAVERSE_CHILDREN,
    137 			STATE_LEAVE,
    138 
    139 			STATE_LAST
    140 		};
    141 
    142 		NodeIter (void)
    143 			: node			(DE_NULL)
    144 			, curChildNdx	(-1)
    145 			, m_state		(STATE_LAST)
    146 		{
    147 		}
    148 
    149 		NodeIter (TestNode* node_)
    150 			: node			(node_)
    151 			, curChildNdx	(-1)
    152 			, m_state		(STATE_INIT)
    153 		{
    154 		}
    155 
    156 		State getState (void) const
    157 		{
    158 			return m_state;
    159 		}
    160 
    161 		void setState (State newState)
    162 		{
    163 			switch (newState)
    164 			{
    165 				case STATE_TRAVERSE_CHILDREN:
    166 					curChildNdx = -1;
    167 					break;
    168 
    169 				default:
    170 					break;
    171 			}
    172 
    173 			m_state = newState;
    174 		}
    175 
    176 		TestNode*				node;
    177 		std::vector<TestNode*>	children;
    178 		int						curChildNdx;
    179 
    180 	private:
    181 		State					m_state;
    182 	};
    183 
    184 							TestHierarchyIterator	(const TestHierarchyIterator&);		// not allowed!
    185 	TestHierarchyIterator&	operator=				(const TestHierarchyIterator&);		// not allowed!
    186 
    187 	bool					matchFolderName			(const std::string& folderName) const;
    188 	bool					matchCaseName			(const std::string& caseName) const;
    189 
    190 	static std::string		buildNodePath			(const std::vector<NodeIter>& nodeStack);
    191 
    192 	TestHierarchyInflater&	m_inflater;
    193 	const CommandLine&		m_cmdLine;
    194 
    195 	// Current session state.
    196 	std::vector<NodeIter>	m_sessionStack;
    197 	std::string				m_nodePath;
    198 };
    199 
    200 } // tcu
    201 
    202 #endif // _TCUTESTHIERARCHYITERATOR_HPP
    203