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