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