Extension syncing: Introduce a NeedsSync pref
[chromium-blink-merge.git] / base / test / gtest_xml_util.cc
blobe24d5223108ab4f176b2a95cac142ab3dfacf17d
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/test/gtest_xml_util.h"
7 #include "base/files/file_util.h"
8 #include "base/logging.h"
9 #include "base/strings/stringprintf.h"
10 #include "base/test/gtest_util.h"
11 #include "base/test/launcher/test_launcher.h"
12 #include "third_party/libxml/chromium/libxml_utils.h"
14 namespace base {
16 namespace {
18 // This is used for the xml parser to report errors. This assumes the context
19 // is a pointer to a std::string where the error message should be appended.
20 static void XmlErrorFunc(void *context, const char *message, ...) {
21 va_list args;
22 va_start(args, message);
23 std::string* error = static_cast<std::string*>(context);
24 StringAppendV(error, message, args);
25 va_end(args);
28 } // namespace
30 bool ProcessGTestOutput(const base::FilePath& output_file,
31 std::vector<TestResult>* results,
32 bool* crashed) {
33 DCHECK(results);
35 std::string xml_contents;
36 if (!ReadFileToString(output_file, &xml_contents))
37 return false;
39 // Silence XML errors - otherwise they go to stderr.
40 std::string xml_errors;
41 ScopedXmlErrorFunc error_func(&xml_errors, &XmlErrorFunc);
43 XmlReader xml_reader;
44 if (!xml_reader.Load(xml_contents))
45 return false;
47 enum {
48 STATE_INIT,
49 STATE_TESTSUITE,
50 STATE_TESTCASE,
51 STATE_FAILURE,
52 STATE_END,
53 } state = STATE_INIT;
55 while (xml_reader.Read()) {
56 xml_reader.SkipToElement();
57 std::string node_name(xml_reader.NodeName());
59 switch (state) {
60 case STATE_INIT:
61 if (node_name == "testsuites" && !xml_reader.IsClosingElement())
62 state = STATE_TESTSUITE;
63 else
64 return false;
65 break;
66 case STATE_TESTSUITE:
67 if (node_name == "testsuites" && xml_reader.IsClosingElement())
68 state = STATE_END;
69 else if (node_name == "testsuite" && !xml_reader.IsClosingElement())
70 state = STATE_TESTCASE;
71 else
72 return false;
73 break;
74 case STATE_TESTCASE:
75 if (node_name == "testsuite" && xml_reader.IsClosingElement()) {
76 state = STATE_TESTSUITE;
77 } else if (node_name == "x-teststart" &&
78 !xml_reader.IsClosingElement()) {
79 // This is our custom extension that helps recognize which test was
80 // running when the test binary crashed.
81 TestResult result;
83 std::string test_case_name;
84 if (!xml_reader.NodeAttribute("classname", &test_case_name))
85 return false;
86 std::string test_name;
87 if (!xml_reader.NodeAttribute("name", &test_name))
88 return false;
89 result.full_name = FormatFullTestName(test_case_name, test_name);
91 result.elapsed_time = TimeDelta();
93 // Assume the test crashed - we can correct that later.
94 result.status = TestResult::TEST_CRASH;
96 results->push_back(result);
97 } else if (node_name == "testcase" && !xml_reader.IsClosingElement()) {
98 std::string test_status;
99 if (!xml_reader.NodeAttribute("status", &test_status))
100 return false;
102 if (test_status != "run" && test_status != "notrun")
103 return false;
104 if (test_status != "run")
105 break;
107 TestResult result;
109 std::string test_case_name;
110 if (!xml_reader.NodeAttribute("classname", &test_case_name))
111 return false;
112 std::string test_name;
113 if (!xml_reader.NodeAttribute("name", &test_name))
114 return false;
115 result.full_name = test_case_name + "." + test_name;
117 std::string test_time_str;
118 if (!xml_reader.NodeAttribute("time", &test_time_str))
119 return false;
120 result.elapsed_time = TimeDelta::FromMicroseconds(
121 static_cast<int64>(strtod(test_time_str.c_str(), NULL) *
122 Time::kMicrosecondsPerSecond));
124 result.status = TestResult::TEST_SUCCESS;
126 if (!results->empty() &&
127 results->at(results->size() - 1).full_name == result.full_name &&
128 results->at(results->size() - 1).status ==
129 TestResult::TEST_CRASH) {
130 // Erase the fail-safe "crashed" result - now we know the test did
131 // not crash.
132 results->pop_back();
135 results->push_back(result);
136 } else if (node_name == "failure" && !xml_reader.IsClosingElement()) {
137 std::string failure_message;
138 if (!xml_reader.NodeAttribute("message", &failure_message))
139 return false;
141 DCHECK(!results->empty());
142 results->at(results->size() - 1).status = TestResult::TEST_FAILURE;
144 state = STATE_FAILURE;
145 } else if (node_name == "testcase" && xml_reader.IsClosingElement()) {
146 // Deliberately empty.
147 } else {
148 return false;
150 break;
151 case STATE_FAILURE:
152 if (node_name == "failure" && xml_reader.IsClosingElement())
153 state = STATE_TESTCASE;
154 else
155 return false;
156 break;
157 case STATE_END:
158 // If we are here and there are still XML elements, the file has wrong
159 // format.
160 return false;
164 *crashed = (state != STATE_END);
165 return true;
168 } // namespace base