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 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 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 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 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