xref: /aosp_15_r20/external/deqp/framework/common/tcuTestHierarchyUtil.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker  * drawElements Quality Program Tester Core
3*35238bceSAndroid Build Coastguard Worker  * ----------------------------------------
4*35238bceSAndroid Build Coastguard Worker  *
5*35238bceSAndroid Build Coastguard Worker  * Copyright 2014 The Android Open Source Project
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 Test hierarchy utilities.
22*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker 
24*35238bceSAndroid Build Coastguard Worker #include "tcuTestHierarchyUtil.hpp"
25*35238bceSAndroid Build Coastguard Worker #include "tcuStringTemplate.hpp"
26*35238bceSAndroid Build Coastguard Worker #include "tcuCommandLine.hpp"
27*35238bceSAndroid Build Coastguard Worker 
28*35238bceSAndroid Build Coastguard Worker #include "qpXmlWriter.h"
29*35238bceSAndroid Build Coastguard Worker 
30*35238bceSAndroid Build Coastguard Worker #include <fstream>
31*35238bceSAndroid Build Coastguard Worker 
32*35238bceSAndroid Build Coastguard Worker namespace tcu
33*35238bceSAndroid Build Coastguard Worker {
34*35238bceSAndroid Build Coastguard Worker 
35*35238bceSAndroid Build Coastguard Worker using std::string;
36*35238bceSAndroid Build Coastguard Worker 
getNodeTypeName(TestNodeType nodeType)37*35238bceSAndroid Build Coastguard Worker static const char *getNodeTypeName(TestNodeType nodeType)
38*35238bceSAndroid Build Coastguard Worker {
39*35238bceSAndroid Build Coastguard Worker     switch (nodeType)
40*35238bceSAndroid Build Coastguard Worker     {
41*35238bceSAndroid Build Coastguard Worker     case NODETYPE_SELF_VALIDATE:
42*35238bceSAndroid Build Coastguard Worker         return "SelfValidate";
43*35238bceSAndroid Build Coastguard Worker     case NODETYPE_CAPABILITY:
44*35238bceSAndroid Build Coastguard Worker         return "Capability";
45*35238bceSAndroid Build Coastguard Worker     case NODETYPE_ACCURACY:
46*35238bceSAndroid Build Coastguard Worker         return "Accuracy";
47*35238bceSAndroid Build Coastguard Worker     case NODETYPE_PERFORMANCE:
48*35238bceSAndroid Build Coastguard Worker         return "Performance";
49*35238bceSAndroid Build Coastguard Worker     case NODETYPE_GROUP:
50*35238bceSAndroid Build Coastguard Worker         return "TestGroup";
51*35238bceSAndroid Build Coastguard Worker     default:
52*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
53*35238bceSAndroid Build Coastguard Worker         return DE_NULL;
54*35238bceSAndroid Build Coastguard Worker     }
55*35238bceSAndroid Build Coastguard Worker }
56*35238bceSAndroid Build Coastguard Worker 
57*35238bceSAndroid Build Coastguard Worker // Utilities
58*35238bceSAndroid Build Coastguard Worker 
makePackageFilename(const std::string & pattern,const std::string & packageName,const std::string & typeExtension)59*35238bceSAndroid Build Coastguard Worker static std::string makePackageFilename(const std::string &pattern, const std::string &packageName,
60*35238bceSAndroid Build Coastguard Worker                                        const std::string &typeExtension)
61*35238bceSAndroid Build Coastguard Worker {
62*35238bceSAndroid Build Coastguard Worker     std::map<string, string> args;
63*35238bceSAndroid Build Coastguard Worker     args["packageName"]   = packageName;
64*35238bceSAndroid Build Coastguard Worker     args["typeExtension"] = typeExtension;
65*35238bceSAndroid Build Coastguard Worker     return StringTemplate(pattern).specialize(args);
66*35238bceSAndroid Build Coastguard Worker }
67*35238bceSAndroid Build Coastguard Worker 
writeXmlCaselist(TestHierarchyIterator & iter,qpXmlWriter * writer)68*35238bceSAndroid Build Coastguard Worker static void writeXmlCaselist(TestHierarchyIterator &iter, qpXmlWriter *writer)
69*35238bceSAndroid Build Coastguard Worker {
70*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(iter.getState() == TestHierarchyIterator::STATE_ENTER_NODE &&
71*35238bceSAndroid Build Coastguard Worker               iter.getNode()->getNodeType() == NODETYPE_PACKAGE);
72*35238bceSAndroid Build Coastguard Worker 
73*35238bceSAndroid Build Coastguard Worker     {
74*35238bceSAndroid Build Coastguard Worker         const TestNode *node = iter.getNode();
75*35238bceSAndroid Build Coastguard Worker         qpXmlAttribute attribs[1];
76*35238bceSAndroid Build Coastguard Worker         int numAttribs        = 0;
77*35238bceSAndroid Build Coastguard Worker         attribs[numAttribs++] = qpSetStringAttrib("PackageName", node->getName());
78*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(numAttribs <= DE_LENGTH_OF_ARRAY(attribs));
79*35238bceSAndroid Build Coastguard Worker 
80*35238bceSAndroid Build Coastguard Worker         if (!qpXmlWriter_startDocument(writer, true) ||
81*35238bceSAndroid Build Coastguard Worker             !qpXmlWriter_startElement(writer, "TestCaseList", numAttribs, attribs))
82*35238bceSAndroid Build Coastguard Worker             throw Exception("Failed to start XML document");
83*35238bceSAndroid Build Coastguard Worker     }
84*35238bceSAndroid Build Coastguard Worker 
85*35238bceSAndroid Build Coastguard Worker     iter.next();
86*35238bceSAndroid Build Coastguard Worker 
87*35238bceSAndroid Build Coastguard Worker     while (iter.getNode()->getNodeType() != NODETYPE_PACKAGE)
88*35238bceSAndroid Build Coastguard Worker     {
89*35238bceSAndroid Build Coastguard Worker         const TestNode *const node  = iter.getNode();
90*35238bceSAndroid Build Coastguard Worker         const TestNodeType nodeType = node->getNodeType();
91*35238bceSAndroid Build Coastguard Worker         const bool isEnter          = iter.getState() == TestHierarchyIterator::STATE_ENTER_NODE;
92*35238bceSAndroid Build Coastguard Worker 
93*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(iter.getState() == TestHierarchyIterator::STATE_ENTER_NODE ||
94*35238bceSAndroid Build Coastguard Worker                   iter.getState() == TestHierarchyIterator::STATE_LEAVE_NODE);
95*35238bceSAndroid Build Coastguard Worker         {
96*35238bceSAndroid Build Coastguard Worker             if (isEnter)
97*35238bceSAndroid Build Coastguard Worker             {
98*35238bceSAndroid Build Coastguard Worker                 const string caseName = node->getName();
99*35238bceSAndroid Build Coastguard Worker                 qpXmlAttribute attribs[2];
100*35238bceSAndroid Build Coastguard Worker                 int numAttribs = 0;
101*35238bceSAndroid Build Coastguard Worker 
102*35238bceSAndroid Build Coastguard Worker                 attribs[numAttribs++] = qpSetStringAttrib("Name", caseName.c_str());
103*35238bceSAndroid Build Coastguard Worker                 attribs[numAttribs++] = qpSetStringAttrib("CaseType", getNodeTypeName(nodeType));
104*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(numAttribs <= DE_LENGTH_OF_ARRAY(attribs));
105*35238bceSAndroid Build Coastguard Worker 
106*35238bceSAndroid Build Coastguard Worker                 if (!qpXmlWriter_startElement(writer, "TestCase", numAttribs, attribs))
107*35238bceSAndroid Build Coastguard Worker                     throw Exception("Writing to case list file failed");
108*35238bceSAndroid Build Coastguard Worker             }
109*35238bceSAndroid Build Coastguard Worker             else
110*35238bceSAndroid Build Coastguard Worker             {
111*35238bceSAndroid Build Coastguard Worker                 if (!qpXmlWriter_endElement(writer, "TestCase"))
112*35238bceSAndroid Build Coastguard Worker                     throw tcu::Exception("Writing to case list file failed");
113*35238bceSAndroid Build Coastguard Worker             }
114*35238bceSAndroid Build Coastguard Worker         }
115*35238bceSAndroid Build Coastguard Worker 
116*35238bceSAndroid Build Coastguard Worker         iter.next();
117*35238bceSAndroid Build Coastguard Worker     }
118*35238bceSAndroid Build Coastguard Worker 
119*35238bceSAndroid Build Coastguard Worker     // This could be done in catch, but the file is corrupt at that point anyways.
120*35238bceSAndroid Build Coastguard Worker     if (!qpXmlWriter_endElement(writer, "TestCaseList") || !qpXmlWriter_endDocument(writer))
121*35238bceSAndroid Build Coastguard Worker         throw Exception("Failed to terminate XML document");
122*35238bceSAndroid Build Coastguard Worker }
123*35238bceSAndroid Build Coastguard Worker 
124*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
125*35238bceSAndroid Build Coastguard Worker  * \brief Export the test list of each package into a separate XML file.
126*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
writeXmlCaselistsToFiles(TestPackageRoot & root,TestContext & testCtx,const CommandLine & cmdLine)127*35238bceSAndroid Build Coastguard Worker void writeXmlCaselistsToFiles(TestPackageRoot &root, TestContext &testCtx, const CommandLine &cmdLine)
128*35238bceSAndroid Build Coastguard Worker {
129*35238bceSAndroid Build Coastguard Worker     DefaultHierarchyInflater inflater(testCtx);
130*35238bceSAndroid Build Coastguard Worker     de::MovePtr<const CaseListFilter> caseListFilter(
131*35238bceSAndroid Build Coastguard Worker         testCtx.getCommandLine().createCaseListFilter(testCtx.getArchive()));
132*35238bceSAndroid Build Coastguard Worker 
133*35238bceSAndroid Build Coastguard Worker     TestHierarchyIterator iter(root, inflater, *caseListFilter);
134*35238bceSAndroid Build Coastguard Worker     const char *const filenamePattern = cmdLine.getCaseListExportFile();
135*35238bceSAndroid Build Coastguard Worker 
136*35238bceSAndroid Build Coastguard Worker     while (iter.getState() != TestHierarchyIterator::STATE_FINISHED)
137*35238bceSAndroid Build Coastguard Worker     {
138*35238bceSAndroid Build Coastguard Worker         const TestNode *node  = iter.getNode();
139*35238bceSAndroid Build Coastguard Worker         const char *pkgName   = node->getName();
140*35238bceSAndroid Build Coastguard Worker         const string filename = makePackageFilename(filenamePattern, pkgName, "xml");
141*35238bceSAndroid Build Coastguard Worker 
142*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(iter.getState() == TestHierarchyIterator::STATE_ENTER_NODE &&
143*35238bceSAndroid Build Coastguard Worker                   node->getNodeType() == NODETYPE_PACKAGE);
144*35238bceSAndroid Build Coastguard Worker 
145*35238bceSAndroid Build Coastguard Worker         FILE *file          = DE_NULL;
146*35238bceSAndroid Build Coastguard Worker         qpXmlWriter *writer = DE_NULL;
147*35238bceSAndroid Build Coastguard Worker 
148*35238bceSAndroid Build Coastguard Worker         try
149*35238bceSAndroid Build Coastguard Worker         {
150*35238bceSAndroid Build Coastguard Worker             file = fopen(filename.c_str(), "wb");
151*35238bceSAndroid Build Coastguard Worker             if (!file)
152*35238bceSAndroid Build Coastguard Worker                 throw Exception("Failed to open " + filename);
153*35238bceSAndroid Build Coastguard Worker 
154*35238bceSAndroid Build Coastguard Worker             writer = qpXmlWriter_createFileWriter(file, false, false);
155*35238bceSAndroid Build Coastguard Worker             if (!writer)
156*35238bceSAndroid Build Coastguard Worker                 throw Exception("XML writer creation failed");
157*35238bceSAndroid Build Coastguard Worker 
158*35238bceSAndroid Build Coastguard Worker             print("Writing test cases from '%s' to file '%s'..\n", pkgName, filename.c_str());
159*35238bceSAndroid Build Coastguard Worker 
160*35238bceSAndroid Build Coastguard Worker             writeXmlCaselist(iter, writer);
161*35238bceSAndroid Build Coastguard Worker 
162*35238bceSAndroid Build Coastguard Worker             qpXmlWriter_destroy(writer);
163*35238bceSAndroid Build Coastguard Worker             writer = DE_NULL;
164*35238bceSAndroid Build Coastguard Worker 
165*35238bceSAndroid Build Coastguard Worker             fclose(file);
166*35238bceSAndroid Build Coastguard Worker             file = DE_NULL;
167*35238bceSAndroid Build Coastguard Worker         }
168*35238bceSAndroid Build Coastguard Worker         catch (...)
169*35238bceSAndroid Build Coastguard Worker         {
170*35238bceSAndroid Build Coastguard Worker             if (writer)
171*35238bceSAndroid Build Coastguard Worker                 qpXmlWriter_destroy(writer);
172*35238bceSAndroid Build Coastguard Worker             if (file)
173*35238bceSAndroid Build Coastguard Worker                 fclose(file);
174*35238bceSAndroid Build Coastguard Worker             throw;
175*35238bceSAndroid Build Coastguard Worker         }
176*35238bceSAndroid Build Coastguard Worker 
177*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(iter.getState() == TestHierarchyIterator::STATE_LEAVE_NODE &&
178*35238bceSAndroid Build Coastguard Worker                   iter.getNode()->getNodeType() == NODETYPE_PACKAGE);
179*35238bceSAndroid Build Coastguard Worker         iter.next();
180*35238bceSAndroid Build Coastguard Worker     }
181*35238bceSAndroid Build Coastguard Worker }
182*35238bceSAndroid Build Coastguard Worker 
183*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
184*35238bceSAndroid Build Coastguard Worker  * \brief Export the test list of each package into a separate ascii file.
185*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
writeTxtCaselistsToFiles(TestPackageRoot & root,TestContext & testCtx,const CommandLine & cmdLine)186*35238bceSAndroid Build Coastguard Worker void writeTxtCaselistsToFiles(TestPackageRoot &root, TestContext &testCtx, const CommandLine &cmdLine)
187*35238bceSAndroid Build Coastguard Worker {
188*35238bceSAndroid Build Coastguard Worker     DefaultHierarchyInflater inflater(testCtx);
189*35238bceSAndroid Build Coastguard Worker     de::MovePtr<const CaseListFilter> caseListFilter(
190*35238bceSAndroid Build Coastguard Worker         testCtx.getCommandLine().createCaseListFilter(testCtx.getArchive()));
191*35238bceSAndroid Build Coastguard Worker 
192*35238bceSAndroid Build Coastguard Worker     TestHierarchyIterator iter(root, inflater, *caseListFilter);
193*35238bceSAndroid Build Coastguard Worker     const char *const filenamePattern = cmdLine.getCaseListExportFile();
194*35238bceSAndroid Build Coastguard Worker 
195*35238bceSAndroid Build Coastguard Worker     while (iter.getState() != TestHierarchyIterator::STATE_FINISHED)
196*35238bceSAndroid Build Coastguard Worker     {
197*35238bceSAndroid Build Coastguard Worker         const TestNode *node  = iter.getNode();
198*35238bceSAndroid Build Coastguard Worker         const char *pkgName   = node->getName();
199*35238bceSAndroid Build Coastguard Worker         const string filename = makePackageFilename(filenamePattern, pkgName, "txt");
200*35238bceSAndroid Build Coastguard Worker 
201*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(iter.getState() == TestHierarchyIterator::STATE_ENTER_NODE &&
202*35238bceSAndroid Build Coastguard Worker                   node->getNodeType() == NODETYPE_PACKAGE);
203*35238bceSAndroid Build Coastguard Worker 
204*35238bceSAndroid Build Coastguard Worker         std::ofstream out(filename.c_str(), std::ios_base::binary);
205*35238bceSAndroid Build Coastguard Worker         if (!out.is_open() || !out.good())
206*35238bceSAndroid Build Coastguard Worker             throw Exception("Failed to open " + filename);
207*35238bceSAndroid Build Coastguard Worker 
208*35238bceSAndroid Build Coastguard Worker         print("Writing test cases from '%s' to file '%s'..\n", pkgName, filename.c_str());
209*35238bceSAndroid Build Coastguard Worker 
210*35238bceSAndroid Build Coastguard Worker         try
211*35238bceSAndroid Build Coastguard Worker         {
212*35238bceSAndroid Build Coastguard Worker             iter.next();
213*35238bceSAndroid Build Coastguard Worker         }
214*35238bceSAndroid Build Coastguard Worker         catch (const tcu::NotSupportedError &)
215*35238bceSAndroid Build Coastguard Worker         {
216*35238bceSAndroid Build Coastguard Worker             return;
217*35238bceSAndroid Build Coastguard Worker         }
218*35238bceSAndroid Build Coastguard Worker 
219*35238bceSAndroid Build Coastguard Worker         while (iter.getNode()->getNodeType() != NODETYPE_PACKAGE)
220*35238bceSAndroid Build Coastguard Worker         {
221*35238bceSAndroid Build Coastguard Worker             if (iter.getState() == TestHierarchyIterator::STATE_ENTER_NODE)
222*35238bceSAndroid Build Coastguard Worker                 out << (isTestNodeTypeExecutable(iter.getNode()->getNodeType()) ? "TEST" : "GROUP") << ": "
223*35238bceSAndroid Build Coastguard Worker                     << iter.getNodePath() << "\n";
224*35238bceSAndroid Build Coastguard Worker             iter.next();
225*35238bceSAndroid Build Coastguard Worker         }
226*35238bceSAndroid Build Coastguard Worker 
227*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(iter.getState() == TestHierarchyIterator::STATE_LEAVE_NODE &&
228*35238bceSAndroid Build Coastguard Worker                   iter.getNode()->getNodeType() == NODETYPE_PACKAGE);
229*35238bceSAndroid Build Coastguard Worker         iter.next();
230*35238bceSAndroid Build Coastguard Worker     }
231*35238bceSAndroid Build Coastguard Worker }
232*35238bceSAndroid Build Coastguard Worker 
233*35238bceSAndroid Build Coastguard Worker } // namespace tcu
234