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 CaseListFilter; 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 CaseListFilter& caseListFilter); 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 NISTATE_INIT = 0, 135 NISTATE_ENTER, 136 NISTATE_TRAVERSE_CHILDREN, 137 NISTATE_LEAVE, 138 139 NISTATE_LAST 140 }; 141 NodeItertcu::TestHierarchyIterator::NodeIter142 NodeIter (void) 143 : node (DE_NULL) 144 , curChildNdx (-1) 145 , m_state (NISTATE_LAST) 146 { 147 } 148 NodeItertcu::TestHierarchyIterator::NodeIter149 NodeIter (TestNode* node_) 150 : node (node_) 151 , curChildNdx (-1) 152 , m_state (NISTATE_INIT) 153 { 154 } 155 getStatetcu::TestHierarchyIterator::NodeIter156 State getState (void) const 157 { 158 return m_state; 159 } 160 setStatetcu::TestHierarchyIterator::NodeIter161 void setState (State newState) 162 { 163 switch (newState) 164 { 165 case NISTATE_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 CaseListFilter& m_caseListFilter; 194 195 // Current session state. 196 std::vector<NodeIter> m_sessionStack; 197 std::string m_nodePath; 198 199 // Counter that increments by one for each bottom-level test group 200 int m_groupNumber; 201 }; 202 203 } // tcu 204 205 #endif // _TCUTESTHIERARCHYITERATOR_HPP 206