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