xref: /aosp_15_r20/external/deqp/framework/common/tcuTestHierarchyIterator.hpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
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