Merge "Relax line width verification in primitive bbox tests" into nougat-cts-dev
[platform/upstream/VK-GL-CTS.git] / framework / common / tcuTestHierarchyUtil.cpp
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program Tester Core
3  * ----------------------------------------
4  *
5  * Copyright 2014 The Android Open Source Project
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Test hierarchy utilities.
22  *//*--------------------------------------------------------------------*/
23
24 #include "tcuTestHierarchyUtil.hpp"
25 #include "tcuStringTemplate.hpp"
26 #include "tcuCommandLine.hpp"
27
28 #include "qpXmlWriter.h"
29
30 #include <fstream>
31
32 namespace tcu
33 {
34
35 using std::string;
36
37 static const char* getNodeTypeName (TestNodeType nodeType)
38 {
39         switch (nodeType)
40         {
41                 case NODETYPE_SELF_VALIDATE:    return "SelfValidate";
42                 case NODETYPE_CAPABILITY:               return "Capability";
43                 case NODETYPE_ACCURACY:                 return "Accuracy";
44                 case NODETYPE_PERFORMANCE:              return "Performance";
45                 case NODETYPE_GROUP:                    return "TestGroup";
46                 default:
47                         DE_ASSERT(false);
48                         return DE_NULL;
49         }
50 }
51
52 // Utilities
53
54 static std::string makePackageFilename (const std::string& pattern, const std::string& packageName, const std::string& typeExtension)
55 {
56         std::map<string, string> args;
57         args["packageName"]             = packageName;
58         args["typeExtension"]   = typeExtension;
59         return StringTemplate(pattern).specialize(args);
60 }
61
62 static void writeXmlCaselist (TestHierarchyIterator& iter, qpXmlWriter* writer)
63 {
64         DE_ASSERT(iter.getState() == TestHierarchyIterator::STATE_ENTER_NODE &&
65                           iter.getNode()->getNodeType() == NODETYPE_PACKAGE);
66
67         {
68                 const TestNode* node            = iter.getNode();
69                 qpXmlAttribute  attribs[2];
70                 int                             numAttribs      = 0;
71                 attribs[numAttribs++] = qpSetStringAttrib("PackageName", node->getName());
72                 attribs[numAttribs++] = qpSetStringAttrib("Description", node->getDescription());
73                 DE_ASSERT(numAttribs <= DE_LENGTH_OF_ARRAY(attribs));
74
75                 if (!qpXmlWriter_startDocument(writer) ||
76                         !qpXmlWriter_startElement(writer, "TestCaseList", numAttribs, attribs))
77                         throw Exception("Failed to start XML document");
78         }
79
80         iter.next();
81
82         while (iter.getNode()->getNodeType() != NODETYPE_PACKAGE)
83         {
84                 const TestNode* const   node            = iter.getNode();
85                 const TestNodeType              nodeType        = node->getNodeType();
86                 const bool                              isEnter         = iter.getState() == TestHierarchyIterator::STATE_ENTER_NODE;
87
88                 DE_ASSERT(iter.getState() == TestHierarchyIterator::STATE_ENTER_NODE ||
89                                   iter.getState() == TestHierarchyIterator::STATE_LEAVE_NODE);
90                 {
91                         if (isEnter)
92                         {
93                                 const string    caseName        = node->getName();
94                                 const string    description     = node->getDescription();
95                                 qpXmlAttribute  attribs[3];
96                                 int                             numAttribs = 0;
97
98                                 attribs[numAttribs++] = qpSetStringAttrib("Name",                       caseName.c_str());
99                                 attribs[numAttribs++] = qpSetStringAttrib("CaseType",           getNodeTypeName(nodeType));
100                                 attribs[numAttribs++] = qpSetStringAttrib("Description",        description.c_str());
101                                 DE_ASSERT(numAttribs <= DE_LENGTH_OF_ARRAY(attribs));
102
103                                 if (!qpXmlWriter_startElement(writer, "TestCase", numAttribs, attribs))
104                                         throw Exception("Writing to case list file failed");
105                         }
106                         else
107                         {
108                                 if (!qpXmlWriter_endElement(writer, "TestCase"))
109                                         throw tcu::Exception("Writing to case list file failed");
110                         }
111                 }
112
113                 iter.next();
114         }
115
116         // This could be done in catch, but the file is corrupt at that point anyways.
117         if (!qpXmlWriter_endElement(writer, "TestCaseList") ||
118                 !qpXmlWriter_endDocument(writer))
119                 throw Exception("Failed to terminate XML document");
120 }
121
122 /*--------------------------------------------------------------------*//*!
123  * \brief Export the test list of each package into a separate XML file.
124  *//*--------------------------------------------------------------------*/
125 void writeXmlCaselistsToFiles (TestPackageRoot& root, TestContext& testCtx, const CommandLine& cmdLine)
126 {
127         DefaultHierarchyInflater        inflater                (testCtx);
128         TestHierarchyIterator           iter                    (root, inflater, cmdLine);
129         const char* const                       filenamePattern = cmdLine.getCaseListExportFile();
130
131         while (iter.getState() != TestHierarchyIterator::STATE_FINISHED)
132         {
133                 const TestNode* node            = iter.getNode();
134                 const char*             pkgName         = node->getName();
135                 const string    filename        = makePackageFilename(filenamePattern, pkgName, "xml");
136
137                 DE_ASSERT(iter.getState() == TestHierarchyIterator::STATE_ENTER_NODE &&
138                                   node->getNodeType() == NODETYPE_PACKAGE);
139
140                 FILE*                   file    = DE_NULL;
141                 qpXmlWriter*    writer  = DE_NULL;
142
143                 try
144                 {
145                         file = fopen(filename.c_str(), "wb");
146                         if (!file)
147                                 throw Exception("Failed to open " + filename);
148
149                         writer = qpXmlWriter_createFileWriter(file, DE_FALSE, DE_FALSE);
150                         if (!writer)
151                                 throw Exception("XML writer creation failed");
152
153                         print("Writing test cases from '%s' to file '%s'..\n", pkgName, filename.c_str());
154
155                         writeXmlCaselist(iter, writer);
156
157                         qpXmlWriter_destroy(writer);
158                         writer = DE_NULL;
159
160                         fclose(file);
161                         file = DE_NULL;
162                 }
163                 catch (...)
164                 {
165                         if (writer)
166                                 qpXmlWriter_destroy(writer);
167                         if (file)
168                                 fclose(file);
169                         throw;
170                 }
171
172                 DE_ASSERT(iter.getState() == TestHierarchyIterator::STATE_LEAVE_NODE &&
173                                   iter.getNode()->getNodeType() == NODETYPE_PACKAGE);
174                 iter.next();
175         }
176 }
177
178 /*--------------------------------------------------------------------*//*!
179  * \brief Export the test list of each package into a separate ascii file.
180  *//*--------------------------------------------------------------------*/
181 void writeTxtCaselistsToFiles (TestPackageRoot& root, TestContext& testCtx, const CommandLine& cmdLine)
182 {
183         DefaultHierarchyInflater        inflater                (testCtx);
184         TestHierarchyIterator           iter                    (root, inflater, cmdLine);
185         const char* const                       filenamePattern = cmdLine.getCaseListExportFile();
186
187         while (iter.getState() != TestHierarchyIterator::STATE_FINISHED)
188         {
189                 const TestNode* node            = iter.getNode();
190                 const char*             pkgName         = node->getName();
191                 const string    filename        = makePackageFilename(filenamePattern, pkgName, "txt");
192
193                 DE_ASSERT(iter.getState() == TestHierarchyIterator::STATE_ENTER_NODE &&
194                                   node->getNodeType() == NODETYPE_PACKAGE);
195
196                 std::ofstream out(filename.c_str(), std::ios_base::binary);
197                 if (!out.is_open() || !out.good())
198                         throw Exception("Failed to open " + filename);
199
200                 print("Writing test cases from '%s' to file '%s'..\n", pkgName, filename.c_str());
201
202                 iter.next();
203
204                 while (iter.getNode()->getNodeType() != NODETYPE_PACKAGE)
205                 {
206                         if (iter.getState() == TestHierarchyIterator::STATE_ENTER_NODE)
207                                 out << (isTestNodeTypeExecutable(iter.getNode()->getNodeType()) ? "TEST" : "GROUP") << ": " << iter.getNodePath() << "\n";
208                         iter.next();
209                 }
210
211                 DE_ASSERT(iter.getState() == TestHierarchyIterator::STATE_LEAVE_NODE &&
212                                   iter.getNode()->getNodeType() == NODETYPE_PACKAGE);
213                 iter.next();
214         }
215 }
216
217 } // tcu