Home | History | Annotate | Download | only in common
      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
    218