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 "qpXmlWriter.h"
27
28 #include <fstream>
29
30 namespace tcu
31 {
32
33 using std::string;
34
getNodeTypeName(TestNodeType nodeType)35 static const char* getNodeTypeName (TestNodeType nodeType)
36 {
37 switch (nodeType)
38 {
39 case NODETYPE_SELF_VALIDATE: return "SelfValidate";
40 case NODETYPE_CAPABILITY: return "Capability";
41 case NODETYPE_ACCURACY: return "Accuracy";
42 case NODETYPE_PERFORMANCE: return "Performance";
43 case NODETYPE_GROUP: return "TestGroup";
44 default:
45 DE_ASSERT(false);
46 return DE_NULL;
47 }
48 }
49
50 // Utilities
51
makePackageFilename(const std::string & pattern,const std::string & packageName,const std::string & typeExtension)52 static std::string makePackageFilename (const std::string& pattern, const std::string& packageName, const std::string& typeExtension)
53 {
54 std::map<string, string> args;
55 args["packageName"] = packageName;
56 args["typeExtension"] = typeExtension;
57 return StringTemplate(pattern).specialize(args);
58 }
59
writeXmlCaselists(TestPackageRoot & root,TestContext & testCtx,const tcu::CommandLine & cmdLine)60 void writeXmlCaselists (TestPackageRoot& root, TestContext& testCtx, const tcu::CommandLine& cmdLine)
61 {
62 const char* const filenamePattern = "${packageName}-cases.${typeExtension}"; // \todo [2015-02-27 pyry] Make this command line argument
63 DefaultHierarchyInflater inflater (testCtx);
64 TestHierarchyIterator iter (root, inflater, cmdLine);
65 FILE* curFile = DE_NULL;
66 qpXmlWriter* writer = DE_NULL;
67
68 try
69 {
70 while (iter.getState() != TestHierarchyIterator::STATE_FINISHED)
71 {
72 const TestNode* const node = iter.getNode();
73 const TestNodeType nodeType = node->getNodeType();
74 const bool isEnter = iter.getState() == TestHierarchyIterator::STATE_ENTER_NODE;
75
76 DE_ASSERT(iter.getState() == TestHierarchyIterator::STATE_ENTER_NODE ||
77 iter.getState() == TestHierarchyIterator::STATE_LEAVE_NODE);
78
79 if (nodeType == NODETYPE_PACKAGE)
80 {
81 if (isEnter)
82 {
83 const string filename = makePackageFilename(filenamePattern, node->getName(), "xml");
84 qpXmlAttribute attribs[2];
85 int numAttribs = 0;
86
87 DE_ASSERT(!curFile && !writer);
88
89 print("Writing test cases from '%s' to file '%s'..\n", node->getName(), filename.c_str());
90
91 curFile = fopen(filename.c_str(), "wb");
92 if (!curFile)
93 throw Exception("Failed to open " + filename);
94
95 writer = qpXmlWriter_createFileWriter(curFile, DE_FALSE);
96 if (!writer)
97 throw Exception("Failed to create qpXmlWriter");
98
99 attribs[numAttribs++] = qpSetStringAttrib("PackageName", node->getName());
100 attribs[numAttribs++] = qpSetStringAttrib("Description", node->getDescription());
101 DE_ASSERT(numAttribs <= DE_LENGTH_OF_ARRAY(attribs));
102
103 if (!qpXmlWriter_startDocument(writer) ||
104 !qpXmlWriter_startElement(writer, "TestCaseList", numAttribs, attribs))
105 throw Exception("Failed to start XML document");
106 }
107 else
108 {
109 if (!qpXmlWriter_endElement(writer, "TestCaseList") ||
110 !qpXmlWriter_endDocument(writer))
111 throw Exception("Failed to terminate XML document");
112
113 qpXmlWriter_destroy(writer);
114 fclose(curFile);
115
116 writer = DE_NULL;
117 curFile = DE_NULL;
118 }
119 }
120 else
121 {
122 if (isEnter)
123 {
124 const string caseName = node->getName();
125 const string description = node->getDescription();
126 qpXmlAttribute attribs[3];
127 int numAttribs = 0;
128
129 attribs[numAttribs++] = qpSetStringAttrib("Name", caseName.c_str());
130 attribs[numAttribs++] = qpSetStringAttrib("CaseType", getNodeTypeName(nodeType));
131 attribs[numAttribs++] = qpSetStringAttrib("Description", description.c_str());
132 DE_ASSERT(numAttribs <= DE_LENGTH_OF_ARRAY(attribs));
133
134 if (!qpXmlWriter_startElement(writer, "TestCase", numAttribs, attribs))
135 throw Exception("Writing to case list file failed");
136 }
137 else
138 {
139 if (!qpXmlWriter_endElement(writer, "TestCase"))
140 throw tcu::Exception("Writing to case list file failed");
141 }
142 }
143
144 iter.next();
145 }
146 }
147 catch (...)
148 {
149 if (writer)
150 qpXmlWriter_destroy(writer);
151
152 if (curFile)
153 fclose(curFile);
154
155 throw;
156 }
157
158 DE_ASSERT(!curFile && !writer);
159 }
160
writeTxtCaselists(TestPackageRoot & root,TestContext & testCtx,const tcu::CommandLine & cmdLine)161 void writeTxtCaselists (TestPackageRoot& root, TestContext& testCtx, const tcu::CommandLine& cmdLine)
162 {
163 const char* const filenamePattern = "${packageName}-cases.${typeExtension}"; // \todo [2015-02-27 pyry] Make this command line argument
164 DefaultHierarchyInflater inflater (testCtx);
165 TestHierarchyIterator iter (root, inflater, cmdLine);
166
167 while (iter.getState() != TestHierarchyIterator::STATE_FINISHED)
168 {
169 DE_ASSERT(iter.getState() == TestHierarchyIterator::STATE_ENTER_NODE &&
170 iter.getNode()->getNodeType() == NODETYPE_PACKAGE);
171
172 const char* pkgName = iter.getNode()->getName();
173 const string filename = makePackageFilename(filenamePattern, pkgName, "txt");
174 std::ofstream out (filename.c_str(), std::ios_base::binary);
175
176 if (!out.is_open() || !out.good())
177 throw Exception("Failed to open " + filename);
178
179 print("Writing test cases from '%s' to file '%s'..\n", pkgName, filename.c_str());
180
181 iter.next();
182
183 while (iter.getNode()->getNodeType() != NODETYPE_PACKAGE)
184 {
185 if (iter.getState() == TestHierarchyIterator::STATE_ENTER_NODE)
186 out << (isTestNodeTypeExecutable(iter.getNode()->getNodeType()) ? "TEST" : "GROUP") << ": " << iter.getNodePath() << "\n";
187 iter.next();
188 }
189
190 DE_ASSERT(iter.getState() == TestHierarchyIterator::STATE_LEAVE_NODE &&
191 iter.getNode()->getNodeType() == NODETYPE_PACKAGE);
192 iter.next();
193 }
194 }
195
196 } // tcu
197