1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker * Vulkan CTS Framework
3*35238bceSAndroid Build Coastguard Worker * --------------------
4*35238bceSAndroid Build Coastguard Worker *
5*35238bceSAndroid Build Coastguard Worker * Copyright (c) 2020 The Khronos Group Inc.
6*35238bceSAndroid Build Coastguard Worker *
7*35238bceSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
8*35238bceSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
9*35238bceSAndroid Build Coastguard Worker * You may obtain a copy of the License at
10*35238bceSAndroid Build Coastguard Worker *
11*35238bceSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
12*35238bceSAndroid Build Coastguard Worker *
13*35238bceSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
14*35238bceSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
15*35238bceSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16*35238bceSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
17*35238bceSAndroid Build Coastguard Worker * limitations under the License.
18*35238bceSAndroid Build Coastguard Worker *
19*35238bceSAndroid Build Coastguard Worker *//*!
20*35238bceSAndroid Build Coastguard Worker * \file
21*35238bceSAndroid Build Coastguard Worker * \brief Waiver mechanism implementation.
22*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker
24*35238bceSAndroid Build Coastguard Worker #include "tcuWaiverUtil.hpp"
25*35238bceSAndroid Build Coastguard Worker #include <fstream>
26*35238bceSAndroid Build Coastguard Worker #include <iostream>
27*35238bceSAndroid Build Coastguard Worker #include <sstream>
28*35238bceSAndroid Build Coastguard Worker #include <iomanip>
29*35238bceSAndroid Build Coastguard Worker #include "deString.h"
30*35238bceSAndroid Build Coastguard Worker #include "deStringUtil.hpp"
31*35238bceSAndroid Build Coastguard Worker #include "xeXMLParser.hpp"
32*35238bceSAndroid Build Coastguard Worker #include "tcuCommandLine.hpp"
33*35238bceSAndroid Build Coastguard Worker
34*35238bceSAndroid Build Coastguard Worker namespace tcu
35*35238bceSAndroid Build Coastguard Worker {
36*35238bceSAndroid Build Coastguard Worker
SessionInfo(uint32_t vendorId,uint32_t deviceId,const std::string & deviceName,const std::string & cmdLine)37*35238bceSAndroid Build Coastguard Worker SessionInfo::SessionInfo(uint32_t vendorId, uint32_t deviceId, const std::string &deviceName,
38*35238bceSAndroid Build Coastguard Worker const std::string &cmdLine)
39*35238bceSAndroid Build Coastguard Worker : m_cmdLine(cmdLine)
40*35238bceSAndroid Build Coastguard Worker {
41*35238bceSAndroid Build Coastguard Worker m_info << std::hex << "#sessionInfo vendorID 0x" << vendorId << "\n"
42*35238bceSAndroid Build Coastguard Worker << "#sessionInfo deviceID 0x" << deviceId << "\n"
43*35238bceSAndroid Build Coastguard Worker << "#sessionInfo deviceName " << deviceName << "\n";
44*35238bceSAndroid Build Coastguard Worker }
45*35238bceSAndroid Build Coastguard Worker
SessionInfo(std::string vendor,std::string renderer,const std::string & cmdLine)46*35238bceSAndroid Build Coastguard Worker SessionInfo::SessionInfo(std::string vendor, std::string renderer, const std::string &cmdLine) : m_cmdLine(cmdLine)
47*35238bceSAndroid Build Coastguard Worker {
48*35238bceSAndroid Build Coastguard Worker m_info << "#sessionInfo vendor \"" << vendor << "\"\n"
49*35238bceSAndroid Build Coastguard Worker << "#sessionInfo renderer \"" << renderer << "\"\n";
50*35238bceSAndroid Build Coastguard Worker }
51*35238bceSAndroid Build Coastguard Worker
get()52*35238bceSAndroid Build Coastguard Worker std::string SessionInfo::get()
53*35238bceSAndroid Build Coastguard Worker {
54*35238bceSAndroid Build Coastguard Worker if (!m_waiverUrls.empty())
55*35238bceSAndroid Build Coastguard Worker {
56*35238bceSAndroid Build Coastguard Worker m_info << "#sessionInfo waiverUrls \"" << m_waiverUrls << "\"\n";
57*35238bceSAndroid Build Coastguard Worker m_waiverUrls.clear();
58*35238bceSAndroid Build Coastguard Worker }
59*35238bceSAndroid Build Coastguard Worker if (!m_cmdLine.empty())
60*35238bceSAndroid Build Coastguard Worker {
61*35238bceSAndroid Build Coastguard Worker m_info << "#sessionInfo commandLineParameters \"" << m_cmdLine << "\"\n";
62*35238bceSAndroid Build Coastguard Worker m_cmdLine.clear();
63*35238bceSAndroid Build Coastguard Worker }
64*35238bceSAndroid Build Coastguard Worker return m_info.str();
65*35238bceSAndroid Build Coastguard Worker }
66*35238bceSAndroid Build Coastguard Worker
67*35238bceSAndroid Build Coastguard Worker // Base class for GL and VK waiver tree builders
68*35238bceSAndroid Build Coastguard Worker class WaiverTreeBuilder
69*35238bceSAndroid Build Coastguard Worker {
70*35238bceSAndroid Build Coastguard Worker public:
71*35238bceSAndroid Build Coastguard Worker typedef WaiverUtil::WaiverComponent WaiverComponent;
72*35238bceSAndroid Build Coastguard Worker
73*35238bceSAndroid Build Coastguard Worker public:
74*35238bceSAndroid Build Coastguard Worker WaiverTreeBuilder(const std::string &waiverFile, const std::string &packageName, const char *vendorTag,
75*35238bceSAndroid Build Coastguard Worker const char *deviceTag, SessionInfo &sessionInfo, std::vector<WaiverComponent> &waiverTree);
76*35238bceSAndroid Build Coastguard Worker
77*35238bceSAndroid Build Coastguard Worker virtual ~WaiverTreeBuilder();
78*35238bceSAndroid Build Coastguard Worker
79*35238bceSAndroid Build Coastguard Worker void build(void);
80*35238bceSAndroid Build Coastguard Worker
81*35238bceSAndroid Build Coastguard Worker protected:
82*35238bceSAndroid Build Coastguard Worker // structure representing component during tree construction
83*35238bceSAndroid Build Coastguard Worker struct BuilComponent
84*35238bceSAndroid Build Coastguard Worker {
85*35238bceSAndroid Build Coastguard Worker std::string name;
86*35238bceSAndroid Build Coastguard Worker uint32_t parentIndex; // index in allComponents vector
87*35238bceSAndroid Build Coastguard Worker std::vector<uint32_t> childrenIndex; // index in allComponents vector
88*35238bceSAndroid Build Coastguard Worker
BuilComponenttcu::WaiverTreeBuilder::BuilComponent89*35238bceSAndroid Build Coastguard Worker BuilComponent(std::string n, uint32_t p) : name(std::move(n)), parentIndex(p)
90*35238bceSAndroid Build Coastguard Worker {
91*35238bceSAndroid Build Coastguard Worker }
92*35238bceSAndroid Build Coastguard Worker };
93*35238bceSAndroid Build Coastguard Worker
94*35238bceSAndroid Build Coastguard Worker // parse waiver.xml and read list of waived tests defined
95*35238bceSAndroid Build Coastguard Worker // specificly for current device id and current vendor id
96*35238bceSAndroid Build Coastguard Worker void readWaivedTestsFromXML(void);
97*35238bceSAndroid Build Coastguard Worker
98*35238bceSAndroid Build Coastguard Worker // use list of paths to build a temporary tree which
99*35238bceSAndroid Build Coastguard Worker // consists of BuilComponents that help with tree construction
100*35238bceSAndroid Build Coastguard Worker void buildTreeFromPathList(void);
101*35238bceSAndroid Build Coastguard Worker
102*35238bceSAndroid Build Coastguard Worker // use temporary tree to create final tree containing
103*35238bceSAndroid Build Coastguard Worker // only things that are needed during searches
104*35238bceSAndroid Build Coastguard Worker void constructFinalTree(void);
105*35238bceSAndroid Build Coastguard Worker
106*35238bceSAndroid Build Coastguard Worker // helper methods used to identify if proper waiver for vendor was found
107*35238bceSAndroid Build Coastguard Worker virtual bool matchVendor(const std::string &vendor) const = 0;
108*35238bceSAndroid Build Coastguard Worker
109*35238bceSAndroid Build Coastguard Worker // helper methods used after waiver for current vendor was found to check
110*35238bceSAndroid Build Coastguard Worker // if it is defined also for currend deviceId/renderer
111*35238bceSAndroid Build Coastguard Worker virtual bool matchDevice(const std::string &device) const = 0;
112*35238bceSAndroid Build Coastguard Worker
113*35238bceSAndroid Build Coastguard Worker // helper method used in buildTreeFromPathList; returns index
114*35238bceSAndroid Build Coastguard Worker // of component having same ancestors as the component specified
115*35238bceSAndroid Build Coastguard Worker // in the argument or 0 when build tree does not include this component
116*35238bceSAndroid Build Coastguard Worker uint32_t findComponentInBuildTree(const std::vector<std::string> &pathComponents, uint32_t index) const;
117*35238bceSAndroid Build Coastguard Worker
118*35238bceSAndroid Build Coastguard Worker private:
119*35238bceSAndroid Build Coastguard Worker const std::string &m_waiverFile;
120*35238bceSAndroid Build Coastguard Worker const std::string &m_packageName;
121*35238bceSAndroid Build Coastguard Worker
122*35238bceSAndroid Build Coastguard Worker const char *m_vendorTag;
123*35238bceSAndroid Build Coastguard Worker const char *m_deviceTag;
124*35238bceSAndroid Build Coastguard Worker
125*35238bceSAndroid Build Coastguard Worker // helper attributes used during construction
126*35238bceSAndroid Build Coastguard Worker std::vector<std::string> m_testList;
127*35238bceSAndroid Build Coastguard Worker std::vector<BuilComponent> m_buildTree;
128*35238bceSAndroid Build Coastguard Worker
129*35238bceSAndroid Build Coastguard Worker // reference to object containing information about used waivers
130*35238bceSAndroid Build Coastguard Worker SessionInfo &m_sessionInfo;
131*35238bceSAndroid Build Coastguard Worker
132*35238bceSAndroid Build Coastguard Worker // reference to vector containing final tree
133*35238bceSAndroid Build Coastguard Worker std::vector<WaiverComponent> &m_finalTree;
134*35238bceSAndroid Build Coastguard Worker };
135*35238bceSAndroid Build Coastguard Worker
WaiverTreeBuilder(const std::string & waiverFile,const std::string & packageName,const char * vendorTag,const char * deviceTag,SessionInfo & sessionInfo,std::vector<WaiverComponent> & waiverTree)136*35238bceSAndroid Build Coastguard Worker WaiverTreeBuilder::WaiverTreeBuilder(const std::string &waiverFile, const std::string &packageName,
137*35238bceSAndroid Build Coastguard Worker const char *vendorTag, const char *deviceTag, SessionInfo &sessionInfo,
138*35238bceSAndroid Build Coastguard Worker std::vector<WaiverComponent> &waiverTree)
139*35238bceSAndroid Build Coastguard Worker : m_waiverFile(waiverFile)
140*35238bceSAndroid Build Coastguard Worker , m_packageName(packageName)
141*35238bceSAndroid Build Coastguard Worker , m_vendorTag(vendorTag)
142*35238bceSAndroid Build Coastguard Worker , m_deviceTag(deviceTag)
143*35238bceSAndroid Build Coastguard Worker , m_sessionInfo(sessionInfo)
144*35238bceSAndroid Build Coastguard Worker , m_finalTree(waiverTree)
145*35238bceSAndroid Build Coastguard Worker {
146*35238bceSAndroid Build Coastguard Worker }
147*35238bceSAndroid Build Coastguard Worker
~WaiverTreeBuilder()148*35238bceSAndroid Build Coastguard Worker WaiverTreeBuilder::~WaiverTreeBuilder()
149*35238bceSAndroid Build Coastguard Worker {
150*35238bceSAndroid Build Coastguard Worker }
151*35238bceSAndroid Build Coastguard Worker
build(void)152*35238bceSAndroid Build Coastguard Worker void WaiverTreeBuilder::build(void)
153*35238bceSAndroid Build Coastguard Worker {
154*35238bceSAndroid Build Coastguard Worker readWaivedTestsFromXML();
155*35238bceSAndroid Build Coastguard Worker buildTreeFromPathList();
156*35238bceSAndroid Build Coastguard Worker constructFinalTree();
157*35238bceSAndroid Build Coastguard Worker }
158*35238bceSAndroid Build Coastguard Worker
readWaivedTestsFromXML()159*35238bceSAndroid Build Coastguard Worker void WaiverTreeBuilder::readWaivedTestsFromXML()
160*35238bceSAndroid Build Coastguard Worker {
161*35238bceSAndroid Build Coastguard Worker std::ifstream iStream(m_waiverFile);
162*35238bceSAndroid Build Coastguard Worker if (!iStream.is_open())
163*35238bceSAndroid Build Coastguard Worker return;
164*35238bceSAndroid Build Coastguard Worker
165*35238bceSAndroid Build Coastguard Worker // get whole waiver file content
166*35238bceSAndroid Build Coastguard Worker std::stringstream buffer;
167*35238bceSAndroid Build Coastguard Worker buffer << iStream.rdbuf();
168*35238bceSAndroid Build Coastguard Worker std::string wholeContent = buffer.str();
169*35238bceSAndroid Build Coastguard Worker
170*35238bceSAndroid Build Coastguard Worker // feed parser with xml content
171*35238bceSAndroid Build Coastguard Worker xe::xml::Parser xmlParser;
172*35238bceSAndroid Build Coastguard Worker xmlParser.feed(reinterpret_cast<const uint8_t *>(wholeContent.c_str()), static_cast<int>(wholeContent.size()));
173*35238bceSAndroid Build Coastguard Worker xmlParser.advance();
174*35238bceSAndroid Build Coastguard Worker
175*35238bceSAndroid Build Coastguard Worker // first we find matching vendor, then search for matching device/renderer and then memorize cases
176*35238bceSAndroid Build Coastguard Worker bool vendorFound = false;
177*35238bceSAndroid Build Coastguard Worker bool deviceFound = false;
178*35238bceSAndroid Build Coastguard Worker bool scanDevice = false;
179*35238bceSAndroid Build Coastguard Worker bool memorizeCase = false;
180*35238bceSAndroid Build Coastguard Worker std::string waiverUrl;
181*35238bceSAndroid Build Coastguard Worker std::vector<std::string> waiverTestList;
182*35238bceSAndroid Build Coastguard Worker
183*35238bceSAndroid Build Coastguard Worker while (true)
184*35238bceSAndroid Build Coastguard Worker {
185*35238bceSAndroid Build Coastguard Worker // we are grabing elements one by one - depth-first traversal in pre-order
186*35238bceSAndroid Build Coastguard Worker xe::xml::Element currElement = xmlParser.getElement();
187*35238bceSAndroid Build Coastguard Worker
188*35238bceSAndroid Build Coastguard Worker // stop if there is parsing error or we didnt found
189*35238bceSAndroid Build Coastguard Worker // waiver for current vendor id and device id/renderer
190*35238bceSAndroid Build Coastguard Worker if (currElement == xe::xml::ELEMENT_INCOMPLETE || currElement == xe::xml::ELEMENT_END_OF_STRING)
191*35238bceSAndroid Build Coastguard Worker break;
192*35238bceSAndroid Build Coastguard Worker
193*35238bceSAndroid Build Coastguard Worker const char *elemName = xmlParser.getElementName();
194*35238bceSAndroid Build Coastguard Worker switch (currElement)
195*35238bceSAndroid Build Coastguard Worker {
196*35238bceSAndroid Build Coastguard Worker case xe::xml::ELEMENT_START:
197*35238bceSAndroid Build Coastguard Worker if (vendorFound)
198*35238bceSAndroid Build Coastguard Worker {
199*35238bceSAndroid Build Coastguard Worker if (!deviceFound)
200*35238bceSAndroid Build Coastguard Worker {
201*35238bceSAndroid Build Coastguard Worker // if we found proper vendor and are reading deviceIds/rendererers list then allow it
202*35238bceSAndroid Build Coastguard Worker scanDevice = deStringEqual(elemName, m_deviceTag); // e.g. "d"
203*35238bceSAndroid Build Coastguard Worker if (scanDevice)
204*35238bceSAndroid Build Coastguard Worker break;
205*35238bceSAndroid Build Coastguard Worker }
206*35238bceSAndroid Build Coastguard Worker
207*35238bceSAndroid Build Coastguard Worker // if we found waiver for current vendor and are reading test case names then allow it
208*35238bceSAndroid Build Coastguard Worker memorizeCase = deStringEqual(elemName, "t");
209*35238bceSAndroid Build Coastguard Worker break;
210*35238bceSAndroid Build Coastguard Worker }
211*35238bceSAndroid Build Coastguard Worker
212*35238bceSAndroid Build Coastguard Worker // we are searching for waiver definition for current vendor, till we find
213*35238bceSAndroid Build Coastguard Worker // it we skip everythingh; we also skip tags that we don't need eg. description
214*35238bceSAndroid Build Coastguard Worker if (!deStringEqual(elemName, "waiver"))
215*35238bceSAndroid Build Coastguard Worker break;
216*35238bceSAndroid Build Coastguard Worker
217*35238bceSAndroid Build Coastguard Worker // we found waiver tag, check if it is deffined for current vendor
218*35238bceSAndroid Build Coastguard Worker waiverTestList.clear();
219*35238bceSAndroid Build Coastguard Worker if (xmlParser.hasAttribute(m_vendorTag))
220*35238bceSAndroid Build Coastguard Worker {
221*35238bceSAndroid Build Coastguard Worker vendorFound = matchVendor(xmlParser.getAttribute(m_vendorTag));
222*35238bceSAndroid Build Coastguard Worker // if waiver vendor matches current one then memorize waiver url
223*35238bceSAndroid Build Coastguard Worker // it will be needed when deviceId/renderer will match current one
224*35238bceSAndroid Build Coastguard Worker if (vendorFound)
225*35238bceSAndroid Build Coastguard Worker waiverUrl = xmlParser.getAttribute("url");
226*35238bceSAndroid Build Coastguard Worker }
227*35238bceSAndroid Build Coastguard Worker break;
228*35238bceSAndroid Build Coastguard Worker
229*35238bceSAndroid Build Coastguard Worker case xe::xml::ELEMENT_DATA:
230*35238bceSAndroid Build Coastguard Worker if (scanDevice)
231*35238bceSAndroid Build Coastguard Worker {
232*35238bceSAndroid Build Coastguard Worker // check if device read from xml matches current device/renderer
233*35238bceSAndroid Build Coastguard Worker std::string waivedDevice;
234*35238bceSAndroid Build Coastguard Worker xmlParser.getDataStr(waivedDevice);
235*35238bceSAndroid Build Coastguard Worker deviceFound = matchDevice(waivedDevice);
236*35238bceSAndroid Build Coastguard Worker }
237*35238bceSAndroid Build Coastguard Worker else if (memorizeCase)
238*35238bceSAndroid Build Coastguard Worker {
239*35238bceSAndroid Build Coastguard Worker // memorize whats betwean <t></t> tags when case name starts with current package name
240*35238bceSAndroid Build Coastguard Worker // note: waiver tree is constructed per package
241*35238bceSAndroid Build Coastguard Worker std::string waivedCaseName;
242*35238bceSAndroid Build Coastguard Worker xmlParser.getDataStr(waivedCaseName);
243*35238bceSAndroid Build Coastguard Worker if (waivedCaseName.find(m_packageName) == 0)
244*35238bceSAndroid Build Coastguard Worker waiverTestList.push_back(waivedCaseName);
245*35238bceSAndroid Build Coastguard Worker }
246*35238bceSAndroid Build Coastguard Worker break;
247*35238bceSAndroid Build Coastguard Worker
248*35238bceSAndroid Build Coastguard Worker case xe::xml::ELEMENT_END:
249*35238bceSAndroid Build Coastguard Worker memorizeCase = false;
250*35238bceSAndroid Build Coastguard Worker scanDevice = false;
251*35238bceSAndroid Build Coastguard Worker if (deStringEqual(elemName, "waiver"))
252*35238bceSAndroid Build Coastguard Worker {
253*35238bceSAndroid Build Coastguard Worker // when we found proper waiver we can copy memorized cases and update waiver info
254*35238bceSAndroid Build Coastguard Worker if (vendorFound && deviceFound)
255*35238bceSAndroid Build Coastguard Worker {
256*35238bceSAndroid Build Coastguard Worker DE_ASSERT(m_testList.empty() || waiverUrl.empty());
257*35238bceSAndroid Build Coastguard Worker
258*35238bceSAndroid Build Coastguard Worker std::string &urls = m_sessionInfo.m_waiverUrls;
259*35238bceSAndroid Build Coastguard Worker m_testList.insert(m_testList.end(), waiverTestList.begin(), waiverTestList.end());
260*35238bceSAndroid Build Coastguard Worker
261*35238bceSAndroid Build Coastguard Worker // if m_waiverUrls is not empty then we found another waiver
262*35238bceSAndroid Build Coastguard Worker // definition that should be applyed for this device; we need to
263*35238bceSAndroid Build Coastguard Worker // add space to urls attribute to separate new url from previous one
264*35238bceSAndroid Build Coastguard Worker if (!urls.empty())
265*35238bceSAndroid Build Coastguard Worker urls.append(" ");
266*35238bceSAndroid Build Coastguard Worker urls.append(waiverUrl);
267*35238bceSAndroid Build Coastguard Worker }
268*35238bceSAndroid Build Coastguard Worker vendorFound = false;
269*35238bceSAndroid Build Coastguard Worker deviceFound = false;
270*35238bceSAndroid Build Coastguard Worker }
271*35238bceSAndroid Build Coastguard Worker break;
272*35238bceSAndroid Build Coastguard Worker
273*35238bceSAndroid Build Coastguard Worker default:
274*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
275*35238bceSAndroid Build Coastguard Worker }
276*35238bceSAndroid Build Coastguard Worker
277*35238bceSAndroid Build Coastguard Worker xmlParser.advance();
278*35238bceSAndroid Build Coastguard Worker }
279*35238bceSAndroid Build Coastguard Worker }
280*35238bceSAndroid Build Coastguard Worker
findComponentInBuildTree(const std::vector<std::string> & pathComponents,uint32_t index) const281*35238bceSAndroid Build Coastguard Worker uint32_t WaiverTreeBuilder::findComponentInBuildTree(const std::vector<std::string> &pathComponents,
282*35238bceSAndroid Build Coastguard Worker uint32_t index) const
283*35238bceSAndroid Build Coastguard Worker {
284*35238bceSAndroid Build Coastguard Worker const std::string &checkedName = pathComponents[index];
285*35238bceSAndroid Build Coastguard Worker
286*35238bceSAndroid Build Coastguard Worker // check if same component is already in the build tree; we start from 1 - skiping root
287*35238bceSAndroid Build Coastguard Worker for (uint32_t componentIndex = 1; componentIndex < m_buildTree.size(); ++componentIndex)
288*35238bceSAndroid Build Coastguard Worker {
289*35238bceSAndroid Build Coastguard Worker const BuilComponent &componentInTree = m_buildTree[componentIndex];
290*35238bceSAndroid Build Coastguard Worker if (componentInTree.name != checkedName)
291*35238bceSAndroid Build Coastguard Worker continue;
292*35238bceSAndroid Build Coastguard Worker
293*35238bceSAndroid Build Coastguard Worker // names match so we need to make sure that all their ancestors match too;
294*35238bceSAndroid Build Coastguard Worker uint32_t reverseLevel = index;
295*35238bceSAndroid Build Coastguard Worker uint32_t ancestorInTreeIndex = componentInTree.parentIndex;
296*35238bceSAndroid Build Coastguard Worker
297*35238bceSAndroid Build Coastguard Worker // if this component is the next after root then there is no ancestors to check
298*35238bceSAndroid Build Coastguard Worker if (reverseLevel == 1)
299*35238bceSAndroid Build Coastguard Worker return componentIndex;
300*35238bceSAndroid Build Coastguard Worker
301*35238bceSAndroid Build Coastguard Worker while (--reverseLevel > 0)
302*35238bceSAndroid Build Coastguard Worker {
303*35238bceSAndroid Build Coastguard Worker // names dont match - we can move to searching other build tree items
304*35238bceSAndroid Build Coastguard Worker if (pathComponents[reverseLevel] != m_buildTree[ancestorInTreeIndex].name)
305*35238bceSAndroid Build Coastguard Worker break;
306*35238bceSAndroid Build Coastguard Worker
307*35238bceSAndroid Build Coastguard Worker // when previous path component matches ancestor name then we need do check earlier path component
308*35238bceSAndroid Build Coastguard Worker ancestorInTreeIndex = m_buildTree[ancestorInTreeIndex].parentIndex;
309*35238bceSAndroid Build Coastguard Worker
310*35238bceSAndroid Build Coastguard Worker // we reached root
311*35238bceSAndroid Build Coastguard Worker if (ancestorInTreeIndex == 0)
312*35238bceSAndroid Build Coastguard Worker {
313*35238bceSAndroid Build Coastguard Worker // if next level would be root then ancestors match
314*35238bceSAndroid Build Coastguard Worker if (reverseLevel == 1)
315*35238bceSAndroid Build Coastguard Worker return componentIndex;
316*35238bceSAndroid Build Coastguard Worker // if next level is not root then ancestors dont match
317*35238bceSAndroid Build Coastguard Worker break;
318*35238bceSAndroid Build Coastguard Worker }
319*35238bceSAndroid Build Coastguard Worker }
320*35238bceSAndroid Build Coastguard Worker }
321*35238bceSAndroid Build Coastguard Worker
322*35238bceSAndroid Build Coastguard Worker // searched path component is not in the tree
323*35238bceSAndroid Build Coastguard Worker return 0;
324*35238bceSAndroid Build Coastguard Worker }
325*35238bceSAndroid Build Coastguard Worker
buildTreeFromPathList(void)326*35238bceSAndroid Build Coastguard Worker void WaiverTreeBuilder::buildTreeFromPathList(void)
327*35238bceSAndroid Build Coastguard Worker {
328*35238bceSAndroid Build Coastguard Worker if (m_testList.empty())
329*35238bceSAndroid Build Coastguard Worker return;
330*35238bceSAndroid Build Coastguard Worker
331*35238bceSAndroid Build Coastguard Worker uint32_t parentIndex = 0;
332*35238bceSAndroid Build Coastguard Worker
333*35238bceSAndroid Build Coastguard Worker // construct root node
334*35238bceSAndroid Build Coastguard Worker m_buildTree.emplace_back("root", 0);
335*35238bceSAndroid Build Coastguard Worker
336*35238bceSAndroid Build Coastguard Worker for (const auto &path : m_testList)
337*35238bceSAndroid Build Coastguard Worker {
338*35238bceSAndroid Build Coastguard Worker const std::vector<std::string> pathComponents = de::splitString(path, '.');
339*35238bceSAndroid Build Coastguard Worker
340*35238bceSAndroid Build Coastguard Worker // first component is parented to root
341*35238bceSAndroid Build Coastguard Worker parentIndex = 0;
342*35238bceSAndroid Build Coastguard Worker
343*35238bceSAndroid Build Coastguard Worker // iterate over all components of current path, but skip first one (e.g. "dEQP-VK", "KHR-GLES31")
344*35238bceSAndroid Build Coastguard Worker for (uint32_t level = 1; level < pathComponents.size(); ++level)
345*35238bceSAndroid Build Coastguard Worker {
346*35238bceSAndroid Build Coastguard Worker // check if same component is already in the tree and we dont need to add it
347*35238bceSAndroid Build Coastguard Worker uint32_t componentIndex = findComponentInBuildTree(pathComponents, level);
348*35238bceSAndroid Build Coastguard Worker if (componentIndex)
349*35238bceSAndroid Build Coastguard Worker {
350*35238bceSAndroid Build Coastguard Worker parentIndex = componentIndex;
351*35238bceSAndroid Build Coastguard Worker continue;
352*35238bceSAndroid Build Coastguard Worker }
353*35238bceSAndroid Build Coastguard Worker
354*35238bceSAndroid Build Coastguard Worker // component is not in the tree, add it
355*35238bceSAndroid Build Coastguard Worker const std::string componentName = pathComponents[level];
356*35238bceSAndroid Build Coastguard Worker m_buildTree.emplace_back(componentName, parentIndex);
357*35238bceSAndroid Build Coastguard Worker
358*35238bceSAndroid Build Coastguard Worker // add current component as a child to its parent and assume
359*35238bceSAndroid Build Coastguard Worker // that this component will be parent of next component
360*35238bceSAndroid Build Coastguard Worker componentIndex = static_cast<uint32_t>(m_buildTree.size() - 1);
361*35238bceSAndroid Build Coastguard Worker m_buildTree[parentIndex].childrenIndex.push_back(componentIndex);
362*35238bceSAndroid Build Coastguard Worker parentIndex = componentIndex;
363*35238bceSAndroid Build Coastguard Worker }
364*35238bceSAndroid Build Coastguard Worker }
365*35238bceSAndroid Build Coastguard Worker }
366*35238bceSAndroid Build Coastguard Worker
constructFinalTree(void)367*35238bceSAndroid Build Coastguard Worker void WaiverTreeBuilder::constructFinalTree(void)
368*35238bceSAndroid Build Coastguard Worker {
369*35238bceSAndroid Build Coastguard Worker if (m_buildTree.empty())
370*35238bceSAndroid Build Coastguard Worker return;
371*35238bceSAndroid Build Coastguard Worker
372*35238bceSAndroid Build Coastguard Worker // translate vector of BuilComponents to vector of WaiverComponents
373*35238bceSAndroid Build Coastguard Worker m_finalTree.resize(m_buildTree.size());
374*35238bceSAndroid Build Coastguard Worker for (uint32_t i = 0; i < m_finalTree.size(); ++i)
375*35238bceSAndroid Build Coastguard Worker {
376*35238bceSAndroid Build Coastguard Worker BuilComponent &buildCmponent = m_buildTree[i];
377*35238bceSAndroid Build Coastguard Worker WaiverComponent &waiverComponent = m_finalTree[i];
378*35238bceSAndroid Build Coastguard Worker
379*35238bceSAndroid Build Coastguard Worker waiverComponent.name = std::move(buildCmponent.name);
380*35238bceSAndroid Build Coastguard Worker waiverComponent.children.resize(buildCmponent.childrenIndex.size());
381*35238bceSAndroid Build Coastguard Worker
382*35238bceSAndroid Build Coastguard Worker // set pointers for children
383*35238bceSAndroid Build Coastguard Worker for (uint32_t j = 0; j < buildCmponent.childrenIndex.size(); ++j)
384*35238bceSAndroid Build Coastguard Worker {
385*35238bceSAndroid Build Coastguard Worker uint32_t childIndexInTree = buildCmponent.childrenIndex[j];
386*35238bceSAndroid Build Coastguard Worker waiverComponent.children[j] = &m_finalTree[childIndexInTree];
387*35238bceSAndroid Build Coastguard Worker }
388*35238bceSAndroid Build Coastguard Worker }
389*35238bceSAndroid Build Coastguard Worker }
390*35238bceSAndroid Build Coastguard Worker
391*35238bceSAndroid Build Coastguard Worker // Class that builds a tree out of waiver definitions for OpenGL tests.
392*35238bceSAndroid Build Coastguard Worker // Most of functionalities are shared betwean VK and GL builders and they
393*35238bceSAndroid Build Coastguard Worker // were extracted to WaiverTreeBuilder base class.
394*35238bceSAndroid Build Coastguard Worker class GLWaiverTreeBuilder : public WaiverTreeBuilder
395*35238bceSAndroid Build Coastguard Worker {
396*35238bceSAndroid Build Coastguard Worker public:
397*35238bceSAndroid Build Coastguard Worker GLWaiverTreeBuilder(const std::string &waiverFile, const std::string &packageName, const std::string ¤tVendor,
398*35238bceSAndroid Build Coastguard Worker const std::string ¤tRenderer, SessionInfo &sessionInfo,
399*35238bceSAndroid Build Coastguard Worker std::vector<WaiverComponent> &waiverTree);
400*35238bceSAndroid Build Coastguard Worker
401*35238bceSAndroid Build Coastguard Worker bool matchVendor(const std::string &vendor) const override;
402*35238bceSAndroid Build Coastguard Worker bool matchDevice(const std::string &device) const override;
403*35238bceSAndroid Build Coastguard Worker
404*35238bceSAndroid Build Coastguard Worker private:
405*35238bceSAndroid Build Coastguard Worker const std::string m_currentVendor;
406*35238bceSAndroid Build Coastguard Worker const std::string m_currentRenderer;
407*35238bceSAndroid Build Coastguard Worker };
408*35238bceSAndroid Build Coastguard Worker
GLWaiverTreeBuilder(const std::string & waiverFile,const std::string & packageName,const std::string & currentVendor,const std::string & currentRenderer,SessionInfo & sessionInfo,std::vector<WaiverComponent> & waiverTree)409*35238bceSAndroid Build Coastguard Worker GLWaiverTreeBuilder::GLWaiverTreeBuilder(const std::string &waiverFile, const std::string &packageName,
410*35238bceSAndroid Build Coastguard Worker const std::string ¤tVendor, const std::string ¤tRenderer,
411*35238bceSAndroid Build Coastguard Worker SessionInfo &sessionInfo, std::vector<WaiverComponent> &waiverTree)
412*35238bceSAndroid Build Coastguard Worker : WaiverTreeBuilder(waiverFile, packageName, "vendor", "r", sessionInfo, waiverTree)
413*35238bceSAndroid Build Coastguard Worker , m_currentVendor(currentVendor)
414*35238bceSAndroid Build Coastguard Worker , m_currentRenderer(currentRenderer)
415*35238bceSAndroid Build Coastguard Worker {
416*35238bceSAndroid Build Coastguard Worker }
417*35238bceSAndroid Build Coastguard Worker
matchVendor(const std::string & vendor) const418*35238bceSAndroid Build Coastguard Worker bool GLWaiverTreeBuilder::matchVendor(const std::string &vendor) const
419*35238bceSAndroid Build Coastguard Worker {
420*35238bceSAndroid Build Coastguard Worker return tcu::matchWildcards(vendor.cbegin(), vendor.cend(), m_currentVendor.cbegin(), m_currentVendor.cend(), false);
421*35238bceSAndroid Build Coastguard Worker }
422*35238bceSAndroid Build Coastguard Worker
matchDevice(const std::string & device) const423*35238bceSAndroid Build Coastguard Worker bool GLWaiverTreeBuilder::matchDevice(const std::string &device) const
424*35238bceSAndroid Build Coastguard Worker {
425*35238bceSAndroid Build Coastguard Worker // make sure that renderer name in .xml is not within "", those extra characters should be removed
426*35238bceSAndroid Build Coastguard Worker DE_ASSERT(device[0] != '\"');
427*35238bceSAndroid Build Coastguard Worker
428*35238bceSAndroid Build Coastguard Worker return tcu::matchWildcards(device.cbegin(), device.cend(), m_currentRenderer.cbegin(), m_currentRenderer.cend(),
429*35238bceSAndroid Build Coastguard Worker false);
430*35238bceSAndroid Build Coastguard Worker }
431*35238bceSAndroid Build Coastguard Worker
432*35238bceSAndroid Build Coastguard Worker // Class that builds a tree out of waiver definitions for Vulkan tests.
433*35238bceSAndroid Build Coastguard Worker // Most of functionalities are shared betwean VK and GL builders and they
434*35238bceSAndroid Build Coastguard Worker // were extracted to WaiverTreeBuilder base class.
435*35238bceSAndroid Build Coastguard Worker class VKWaiverTreeBuilder : public WaiverTreeBuilder
436*35238bceSAndroid Build Coastguard Worker {
437*35238bceSAndroid Build Coastguard Worker public:
438*35238bceSAndroid Build Coastguard Worker VKWaiverTreeBuilder(const std::string &waiverFile, const std::string &packageName, const uint32_t currentVendor,
439*35238bceSAndroid Build Coastguard Worker const uint32_t currentRenderer, SessionInfo &sessionInfo,
440*35238bceSAndroid Build Coastguard Worker std::vector<WaiverComponent> &waiverTree);
441*35238bceSAndroid Build Coastguard Worker
442*35238bceSAndroid Build Coastguard Worker bool matchVendor(const std::string &vendor) const override;
443*35238bceSAndroid Build Coastguard Worker bool matchDevice(const std::string &device) const override;
444*35238bceSAndroid Build Coastguard Worker
445*35238bceSAndroid Build Coastguard Worker private:
446*35238bceSAndroid Build Coastguard Worker const uint32_t m_currentVendorId;
447*35238bceSAndroid Build Coastguard Worker const uint32_t m_currentDeviceId;
448*35238bceSAndroid Build Coastguard Worker };
449*35238bceSAndroid Build Coastguard Worker
VKWaiverTreeBuilder(const std::string & waiverFile,const std::string & packageName,const uint32_t currentVendor,const uint32_t currentRenderer,SessionInfo & sessionInfo,std::vector<WaiverComponent> & waiverTree)450*35238bceSAndroid Build Coastguard Worker VKWaiverTreeBuilder::VKWaiverTreeBuilder(const std::string &waiverFile, const std::string &packageName,
451*35238bceSAndroid Build Coastguard Worker const uint32_t currentVendor, const uint32_t currentRenderer,
452*35238bceSAndroid Build Coastguard Worker SessionInfo &sessionInfo, std::vector<WaiverComponent> &waiverTree)
453*35238bceSAndroid Build Coastguard Worker : WaiverTreeBuilder(waiverFile, packageName, "vendorId", "d", sessionInfo, waiverTree)
454*35238bceSAndroid Build Coastguard Worker , m_currentVendorId(currentVendor)
455*35238bceSAndroid Build Coastguard Worker , m_currentDeviceId(currentRenderer)
456*35238bceSAndroid Build Coastguard Worker {
457*35238bceSAndroid Build Coastguard Worker }
458*35238bceSAndroid Build Coastguard Worker
matchVendor(const std::string & vendor) const459*35238bceSAndroid Build Coastguard Worker bool VKWaiverTreeBuilder::matchVendor(const std::string &vendor) const
460*35238bceSAndroid Build Coastguard Worker {
461*35238bceSAndroid Build Coastguard Worker return (m_currentVendorId == static_cast<uint32_t>(std::stoul(vendor, 0, 0)));
462*35238bceSAndroid Build Coastguard Worker }
463*35238bceSAndroid Build Coastguard Worker
matchDevice(const std::string & device) const464*35238bceSAndroid Build Coastguard Worker bool VKWaiverTreeBuilder::matchDevice(const std::string &device) const
465*35238bceSAndroid Build Coastguard Worker {
466*35238bceSAndroid Build Coastguard Worker return (m_currentDeviceId == static_cast<uint32_t>(std::stoul(device, 0, 0)));
467*35238bceSAndroid Build Coastguard Worker }
468*35238bceSAndroid Build Coastguard Worker
setup(const std::string waiverFile,std::string packageName,uint32_t vendorId,uint32_t deviceId,SessionInfo & sessionInfo)469*35238bceSAndroid Build Coastguard Worker void WaiverUtil::setup(const std::string waiverFile, std::string packageName, uint32_t vendorId, uint32_t deviceId,
470*35238bceSAndroid Build Coastguard Worker SessionInfo &sessionInfo)
471*35238bceSAndroid Build Coastguard Worker {
472*35238bceSAndroid Build Coastguard Worker VKWaiverTreeBuilder(waiverFile, packageName, vendorId, deviceId, sessionInfo, m_waiverTree).build();
473*35238bceSAndroid Build Coastguard Worker }
474*35238bceSAndroid Build Coastguard Worker
setup(const std::string waiverFile,std::string packageName,std::string vendor,std::string renderer,SessionInfo & sessionInfo)475*35238bceSAndroid Build Coastguard Worker void WaiverUtil::setup(const std::string waiverFile, std::string packageName, std::string vendor, std::string renderer,
476*35238bceSAndroid Build Coastguard Worker SessionInfo &sessionInfo)
477*35238bceSAndroid Build Coastguard Worker {
478*35238bceSAndroid Build Coastguard Worker GLWaiverTreeBuilder(waiverFile, packageName, vendor, renderer, sessionInfo, m_waiverTree).build();
479*35238bceSAndroid Build Coastguard Worker }
480*35238bceSAndroid Build Coastguard Worker
isOnWaiverList(const std::string & casePath) const481*35238bceSAndroid Build Coastguard Worker bool WaiverUtil::isOnWaiverList(const std::string &casePath) const
482*35238bceSAndroid Build Coastguard Worker {
483*35238bceSAndroid Build Coastguard Worker if (m_waiverTree.empty())
484*35238bceSAndroid Build Coastguard Worker return false;
485*35238bceSAndroid Build Coastguard Worker
486*35238bceSAndroid Build Coastguard Worker // skip root e.g. "dEQP-VK"
487*35238bceSAndroid Build Coastguard Worker size_t firstDotPos = casePath.find('.');
488*35238bceSAndroid Build Coastguard Worker std::string::const_iterator componentStart = casePath.cbegin() + firstDotPos + 1;
489*35238bceSAndroid Build Coastguard Worker std::string::const_iterator componentEnd = componentStart;
490*35238bceSAndroid Build Coastguard Worker std::string::const_iterator pathEnd = casePath.cend();
491*35238bceSAndroid Build Coastguard Worker const WaiverComponent *waiverComponent = m_waiverTree.data();
492*35238bceSAndroid Build Coastguard Worker
493*35238bceSAndroid Build Coastguard Worker // check path component by component
494*35238bceSAndroid Build Coastguard Worker while (true)
495*35238bceSAndroid Build Coastguard Worker {
496*35238bceSAndroid Build Coastguard Worker // find the last character of next component
497*35238bceSAndroid Build Coastguard Worker ++componentEnd;
498*35238bceSAndroid Build Coastguard Worker for (; componentEnd < pathEnd; ++componentEnd)
499*35238bceSAndroid Build Coastguard Worker {
500*35238bceSAndroid Build Coastguard Worker if (*componentEnd == '.')
501*35238bceSAndroid Build Coastguard Worker break;
502*35238bceSAndroid Build Coastguard Worker }
503*35238bceSAndroid Build Coastguard Worker
504*35238bceSAndroid Build Coastguard Worker // check if one of children has the same component name
505*35238bceSAndroid Build Coastguard Worker for (const auto &c : waiverComponent->children)
506*35238bceSAndroid Build Coastguard Worker {
507*35238bceSAndroid Build Coastguard Worker bool matchFound =
508*35238bceSAndroid Build Coastguard Worker tcu::matchWildcards(c->name.cbegin(), c->name.cend(), componentStart, componentEnd, false);
509*35238bceSAndroid Build Coastguard Worker
510*35238bceSAndroid Build Coastguard Worker // current waiver component matches curent path component - go to next component
511*35238bceSAndroid Build Coastguard Worker if (matchFound)
512*35238bceSAndroid Build Coastguard Worker {
513*35238bceSAndroid Build Coastguard Worker waiverComponent = c;
514*35238bceSAndroid Build Coastguard Worker break;
515*35238bceSAndroid Build Coastguard Worker }
516*35238bceSAndroid Build Coastguard Worker }
517*35238bceSAndroid Build Coastguard Worker
518*35238bceSAndroid Build Coastguard Worker // we checked all components - if our pattern was a leaf then this test should be waived
519*35238bceSAndroid Build Coastguard Worker if (componentEnd == pathEnd)
520*35238bceSAndroid Build Coastguard Worker return waiverComponent->children.empty();
521*35238bceSAndroid Build Coastguard Worker
522*35238bceSAndroid Build Coastguard Worker // go to next test path component
523*35238bceSAndroid Build Coastguard Worker componentStart = componentEnd + 1;
524*35238bceSAndroid Build Coastguard Worker }
525*35238bceSAndroid Build Coastguard Worker return false;
526*35238bceSAndroid Build Coastguard Worker }
527*35238bceSAndroid Build Coastguard Worker
528*35238bceSAndroid Build Coastguard Worker } // namespace tcu
529