13551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 23551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 33551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// found in the LICENSE file. 43551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 53551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/test/gtest_xml_util.h" 63551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 76e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "base/files/file_util.h" 83551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/logging.h" 9424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "base/strings/stringprintf.h" 104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/test/launcher/test_launcher.h" 113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "third_party/libxml/chromium/libxml_utils.h" 123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)namespace base { 143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 15424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)namespace { 16424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 17424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// This is used for the xml parser to report errors. This assumes the context 18424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// is a pointer to a std::string where the error message should be appended. 19424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)static void XmlErrorFunc(void *context, const char *message, ...) { 20424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) va_list args; 21424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) va_start(args, message); 22424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) std::string* error = static_cast<std::string*>(context); 23424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) base::StringAppendV(error, message, args); 24424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) va_end(args); 25424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 26424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 27424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} // namespace 28424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 29424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)XmlUnitTestResultPrinter::XmlUnitTestResultPrinter() : output_file_(NULL) { 30424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 31424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 32424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)XmlUnitTestResultPrinter::~XmlUnitTestResultPrinter() { 33424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (output_file_) { 34424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) fprintf(output_file_, "</testsuites>\n"); 35424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) fflush(output_file_); 36a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::CloseFile(output_file_); 37424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 38424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 39424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 40424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)bool XmlUnitTestResultPrinter::Initialize(const FilePath& output_file_path) { 41424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK(!output_file_); 42a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) output_file_ = OpenFile(output_file_path, "w"); 43424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (!output_file_) 44424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return false; 45424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 46424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) fprintf(output_file_, 47424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<testsuites>\n"); 48424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) fflush(output_file_); 49424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 50424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return true; 51424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 52424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 53424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void XmlUnitTestResultPrinter::OnTestCaseStart( 54424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const testing::TestCase& test_case) { 55424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) fprintf(output_file_, " <testsuite>\n"); 56424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) fflush(output_file_); 57424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 58424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 59424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void XmlUnitTestResultPrinter::OnTestStart(const testing::TestInfo& test_info) { 60424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // This is our custom extension - it helps to recognize which test was running 61424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // when the test binary crashed. Note that we cannot even open the <testcase> 62424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // tag here - it requires e.g. run time of the test to be known. 63424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) fprintf(output_file_, 64424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) " <x-teststart name=\"%s\" classname=\"%s\" />\n", 65424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) test_info.name(), 66424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) test_info.test_case_name()); 67424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) fflush(output_file_); 68424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 69424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 70424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void XmlUnitTestResultPrinter::OnTestEnd(const testing::TestInfo& test_info) { 71424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) fprintf(output_file_, 72424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) " <testcase name=\"%s\" status=\"run\" time=\"%.3f\"" 73424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) " classname=\"%s\">\n", 74424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) test_info.name(), 75424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) static_cast<double>(test_info.result()->elapsed_time()) / 76424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) Time::kMillisecondsPerSecond, 77424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) test_info.test_case_name()); 78424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (test_info.result()->Failed()) 79424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) fprintf(output_file_, " <failure message=\"\" type=\"\"></failure>\n"); 80424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) fprintf(output_file_, " </testcase>\n"); 81424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) fflush(output_file_); 82424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 83424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 84424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void XmlUnitTestResultPrinter::OnTestCaseEnd( 85424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const testing::TestCase& test_case) { 86424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) fprintf(output_file_, " </testsuite>\n"); 87424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) fflush(output_file_); 88424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 89424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool ProcessGTestOutput(const base::FilePath& output_file, 91424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) std::vector<TestResult>* results, 92424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) bool* crashed) { 933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK(results); 943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string xml_contents; 9658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (!ReadFileToString(output_file, &xml_contents)) 973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return false; 983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 99424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Silence XML errors - otherwise they go to stderr. 100424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) std::string xml_errors; 101424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ScopedXmlErrorFunc error_func(&xml_errors, &XmlErrorFunc); 102424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 1033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) XmlReader xml_reader; 1043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!xml_reader.Load(xml_contents)) 1053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return false; 1063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) enum { 1083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) STATE_INIT, 1093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) STATE_TESTSUITE, 1103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) STATE_TESTCASE, 1113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) STATE_FAILURE, 1123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) STATE_END, 1133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } state = STATE_INIT; 1143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) while (xml_reader.Read()) { 1163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) xml_reader.SkipToElement(); 1173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string node_name(xml_reader.NodeName()); 1183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) switch (state) { 1203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case STATE_INIT: 1213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (node_name == "testsuites" && !xml_reader.IsClosingElement()) 1223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) state = STATE_TESTSUITE; 1233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) else 1243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return false; 1253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) break; 1263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case STATE_TESTSUITE: 1273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (node_name == "testsuites" && xml_reader.IsClosingElement()) 1283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) state = STATE_END; 1293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) else if (node_name == "testsuite" && !xml_reader.IsClosingElement()) 1303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) state = STATE_TESTCASE; 1313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) else 1323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return false; 1333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) break; 1343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case STATE_TESTCASE: 1353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (node_name == "testsuite" && xml_reader.IsClosingElement()) { 1363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) state = STATE_TESTSUITE; 137424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } else if (node_name == "x-teststart" && 138424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) !xml_reader.IsClosingElement()) { 139424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // This is our custom extension that helps recognize which test was 140424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // running when the test binary crashed. 141424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) TestResult result; 1421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) std::string test_case_name; 1441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (!xml_reader.NodeAttribute("classname", &test_case_name)) 145424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return false; 1461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) std::string test_name; 1471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (!xml_reader.NodeAttribute("name", &test_name)) 148424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return false; 1495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) result.full_name = TestLauncher::FormatFullTestName(test_case_name, 1505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) test_name); 151424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 152424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) result.elapsed_time = TimeDelta(); 153424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 154424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Assume the test crashed - we can correct that later. 15558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) result.status = TestResult::TEST_CRASH; 156424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 157424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) results->push_back(result); 1583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else if (node_name == "testcase" && !xml_reader.IsClosingElement()) { 1593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string test_status; 1603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!xml_reader.NodeAttribute("status", &test_status)) 1613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return false; 1623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (test_status != "run" && test_status != "notrun") 1643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return false; 1653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (test_status != "run") 1663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) break; 1673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) TestResult result; 1691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) std::string test_case_name; 1711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (!xml_reader.NodeAttribute("classname", &test_case_name)) 1723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return false; 1731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) std::string test_name; 1741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (!xml_reader.NodeAttribute("name", &test_name)) 1753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return false; 1761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) result.full_name = test_case_name + "." + test_name; 1773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string test_time_str; 1793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!xml_reader.NodeAttribute("time", &test_time_str)) 1803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return false; 1813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) result.elapsed_time = 1823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) TimeDelta::FromMicroseconds(strtod(test_time_str.c_str(), NULL) * 1833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) Time::kMicrosecondsPerSecond); 1843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 18558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) result.status = TestResult::TEST_SUCCESS; 186424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 187424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (!results->empty() && 1881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) results->at(results->size() - 1).full_name == result.full_name && 18958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) results->at(results->size() - 1).status == 19058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) TestResult::TEST_CRASH) { 191424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Erase the fail-safe "crashed" result - now we know the test did 192424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // not crash. 193424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) results->pop_back(); 194424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 1953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) results->push_back(result); 1973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else if (node_name == "failure" && !xml_reader.IsClosingElement()) { 1983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string failure_message; 1993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!xml_reader.NodeAttribute("message", &failure_message)) 2003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return false; 2013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK(!results->empty()); 20358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) results->at(results->size() - 1).status = TestResult::TEST_FAILURE; 2043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) state = STATE_FAILURE; 2063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else if (node_name == "testcase" && xml_reader.IsClosingElement()) { 2073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Deliberately empty. 2083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else { 2093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return false; 2103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 2113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) break; 2123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case STATE_FAILURE: 2133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (node_name == "failure" && xml_reader.IsClosingElement()) 2143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) state = STATE_TESTCASE; 2153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) else 2163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return false; 2173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) break; 2183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case STATE_END: 2193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // If we are here and there are still XML elements, the file has wrong 2203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // format. 2213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return false; 2223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 2233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 2243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 225424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) *crashed = (state != STATE_END); 2263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return true; 2273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 2283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 229424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} // namespace base 230