1 /*------------------------------------------------------------------------- 2 * drawElements Quality Program Test Executor 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 Batch result to JUnit report conversion tool. 22 *//*--------------------------------------------------------------------*/ 23 24 #include "xeTestLogParser.hpp" 25 #include "xeTestResultParser.hpp" 26 #include "xeXMLWriter.hpp" 27 #include "deFilePath.hpp" 28 #include "deString.h" 29 #include "deStringUtil.hpp" 30 31 #include <vector> 32 #include <string> 33 #include <map> 34 #include <cstdio> 35 #include <fstream> 36 37 using std::vector; 38 using std::string; 39 using std::map; 40 41 struct CommandLine 42 { 43 CommandLine (void) 44 { 45 } 46 47 std::string batchResultFile; 48 std::string outputFile; 49 }; 50 51 static void printHelp (const char* binName) 52 { 53 printf("%s: [testlog] [output file]\n", binName); 54 } 55 56 static void parseCommandLine (CommandLine& cmdLine, int argc, const char* const* argv) 57 { 58 if (argc != 3) 59 throw xe::Error("Expected input and output paths"); 60 61 cmdLine.batchResultFile = argv[argc-2]; 62 cmdLine.outputFile = argv[argc-1]; 63 } 64 65 static void parseBatchResult (xe::TestLogParser& parser, const char* filename) 66 { 67 std::ifstream in (filename, std::ios_base::binary); 68 deUint8 buf[2048]; 69 70 for (;;) 71 { 72 in.read((char*)&buf[0], sizeof(buf)); 73 int numRead = (int)in.gcount(); 74 75 if (numRead > 0) 76 parser.parse(&buf[0], numRead); 77 78 if (numRead < (int)sizeof(buf)) 79 break; 80 } 81 } 82 83 class ResultToJUnitHandler : public xe::TestLogHandler 84 { 85 public: 86 ResultToJUnitHandler (xe::xml::Writer& writer) 87 : m_writer(writer) 88 { 89 } 90 91 void setSessionInfo (const xe::SessionInfo&) 92 { 93 } 94 95 xe::TestCaseResultPtr startTestCaseResult (const char* casePath) 96 { 97 return xe::TestCaseResultPtr(new xe::TestCaseResultData(casePath)); 98 } 99 100 void testCaseResultUpdated (const xe::TestCaseResultPtr&) 101 { 102 } 103 104 void testCaseResultComplete (const xe::TestCaseResultPtr& resultData) 105 { 106 using xe::xml::Writer; 107 108 xe::TestCaseResult result; 109 110 xe::parseTestCaseResultFromData(&m_resultParser, &result, *resultData.get()); 111 112 // Split group and case names. 113 size_t sepPos = result.casePath.find_last_of('.'); 114 std::string caseName = result.casePath.substr(sepPos+1); 115 std::string groupName = result.casePath.substr(0, sepPos); 116 117 // Write result. 118 m_writer << Writer::BeginElement("testcase") 119 << Writer::Attribute("name", caseName) 120 << Writer::Attribute("classname", groupName); 121 122 if (result.statusCode != xe::TESTSTATUSCODE_PASS) 123 m_writer << Writer::BeginElement("failure") 124 << Writer::Attribute("type", xe::getTestStatusCodeName(result.statusCode)) 125 << result.statusDetails 126 << Writer::EndElement; 127 128 m_writer << Writer::EndElement; 129 } 130 131 private: 132 xe::xml::Writer& m_writer; 133 xe::TestResultParser m_resultParser; 134 }; 135 136 static void batchResultToJUnitReport (const char* batchResultFilename, const char* dstFileName) 137 { 138 std::ofstream out (dstFileName, std::ios_base::binary); 139 xe::xml::Writer writer (out); 140 ResultToJUnitHandler handler (writer); 141 xe::TestLogParser parser (&handler); 142 143 XE_CHECK(out.good()); 144 145 out << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"; 146 147 writer << xe::xml::Writer::BeginElement("testsuites") 148 << xe::xml::Writer::BeginElement("testsuite"); 149 150 // Parse and write individual cases 151 parseBatchResult(parser, batchResultFilename); 152 153 writer << xe::xml::Writer::EndElement << xe::xml::Writer::EndElement; 154 } 155 156 int main (int argc, const char* const* argv) 157 { 158 CommandLine cmdLine; 159 try 160 { 161 parseCommandLine(cmdLine, argc, argv); 162 } 163 catch (const std::exception&) 164 { 165 printHelp(argv[0]); 166 return -1; 167 } 168 169 try 170 { 171 batchResultToJUnitReport(cmdLine.batchResultFile.c_str(), cmdLine.outputFile.c_str()); 172 } 173 catch (const std::exception& e) 174 { 175 printf("%s\n", e.what()); 176 return -1; 177 } 178 179 return 0; 180 } 181