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, 111 const CaseListFilter &caseListFilter); 112 ~TestHierarchyIterator(void); 113 114 enum State 115 { 116 STATE_ENTER_NODE = 0, 117 STATE_LEAVE_NODE, 118 STATE_FINISHED, 119 120 STATE_LAST 121 }; 122 123 State getState(void) const; 124 125 TestNode *getNode(void) const; 126 const std::string &getNodePath(void) const; 127 128 void next(void); 129 130 private: 131 struct NodeIter 132 { 133 enum State 134 { 135 NISTATE_INIT = 0, 136 NISTATE_ENTER, 137 NISTATE_TRAVERSE_CHILDREN, 138 NISTATE_LEAVE, 139 140 NISTATE_LAST 141 }; 142 NodeItertcu::TestHierarchyIterator::NodeIter143 NodeIter(void) : node(DE_NULL), curChildNdx(-1), m_state(NISTATE_LAST) 144 { 145 } 146 NodeItertcu::TestHierarchyIterator::NodeIter147 NodeIter(TestNode *node_) : node(node_), curChildNdx(-1), m_state(NISTATE_INIT) 148 { 149 } 150 getStatetcu::TestHierarchyIterator::NodeIter151 State getState(void) const 152 { 153 return m_state; 154 } 155 setStatetcu::TestHierarchyIterator::NodeIter156 void setState(State newState) 157 { 158 switch (newState) 159 { 160 case NISTATE_TRAVERSE_CHILDREN: 161 curChildNdx = -1; 162 break; 163 164 default: 165 break; 166 } 167 168 m_state = newState; 169 } 170 171 TestNode *node; 172 std::vector<TestNode *> children; 173 int curChildNdx; 174 175 private: 176 State m_state; 177 }; 178 179 TestHierarchyIterator(const TestHierarchyIterator &); // not allowed! 180 TestHierarchyIterator &operator=(const TestHierarchyIterator &); // not allowed! 181 182 bool matchFolderName(const std::string &folderName) const; 183 bool matchCaseName(const std::string &caseName) const; 184 185 static std::string buildNodePath(const std::vector<NodeIter> &nodeStack); 186 187 TestHierarchyInflater &m_inflater; 188 const CaseListFilter &m_caseListFilter; 189 190 // Current session state. 191 std::vector<NodeIter> m_sessionStack; 192 std::string m_nodePath; 193 194 // Counter that increments by one for each bottom-level test group 195 int m_groupNumber; 196 }; 197 198 } // namespace tcu 199 200 #endif // _TCUTESTHIERARCHYITERATOR_HPP 201