Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(233)

Side by Side Diff: base/test/unit_test_launcher.cc

Issue 23757033: GTTF: Support running browser tests in parallel (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/test/unit_test_launcher.h" 5 #include "base/test/unit_test_launcher.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/callback_helpers.h" 8 #include "base/callback_helpers.h"
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/compiler_specific.h" 10 #include "base/compiler_specific.h"
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
92 struct TestLaunchInfo { 92 struct TestLaunchInfo {
93 std::string GetFullName() const { 93 std::string GetFullName() const {
94 return test_case_name + "." + test_name; 94 return test_case_name + "." + test_name;
95 } 95 }
96 96
97 std::string test_case_name; 97 std::string test_case_name;
98 std::string test_name; 98 std::string test_name;
99 TestResultCallback callback; 99 TestResultCallback callback;
100 }; 100 };
101 101
102 virtual std::string GetTestNameForFiltering(
103 const testing::TestCase* test_case,
104 const testing::TestInfo* test_info) OVERRIDE {
105 DCHECK(thread_checker_.CalledOnValidThread());
106
107 return std::string(test_case->name()) + "." + test_info->name();
108 }
109
102 virtual bool ShouldRunTest(const testing::TestCase* test_case, 110 virtual bool ShouldRunTest(const testing::TestCase* test_case,
103 const testing::TestInfo* test_info) OVERRIDE { 111 const testing::TestInfo* test_info) OVERRIDE {
104 DCHECK(thread_checker_.CalledOnValidThread()); 112 DCHECK(thread_checker_.CalledOnValidThread());
105 113
106 // There is no additional logic to disable specific tests. 114 // There is no additional logic to disable specific tests.
107 return true; 115 return true;
108 } 116 }
109 117
110 virtual void RunTest(const testing::TestCase* test_case, 118 virtual void RunTest(const testing::TestCase* test_case,
111 const testing::TestInfo* test_info, 119 const testing::TestInfo* test_info,
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 Bind(&UnitTestLauncherDelegate::GTestCallback, 168 Bind(&UnitTestLauncherDelegate::GTestCallback,
161 base::Unretained(this), 169 base::Unretained(this),
162 tests_, 170 tests_,
163 output_file)); 171 output_file));
164 tests_.clear(); 172 tests_.clear();
165 } 173 }
166 174
167 void GTestCallback(const std::vector<TestLaunchInfo>& tests, 175 void GTestCallback(const std::vector<TestLaunchInfo>& tests,
168 const FilePath& output_file, 176 const FilePath& output_file,
169 int exit_code, 177 int exit_code,
178 const TimeDelta& elapsed_time,
170 bool was_timeout, 179 bool was_timeout,
171 const std::string& output) { 180 const std::string& output) {
172 DCHECK(thread_checker_.CalledOnValidThread()); 181 DCHECK(thread_checker_.CalledOnValidThread());
173 std::vector<TestLaunchInfo> tests_to_relaunch_after_interruption; 182 std::vector<TestLaunchInfo> tests_to_relaunch_after_interruption;
174 bool called_any_callbacks = 183 bool called_any_callbacks =
175 ProcessTestResults(tests, 184 ProcessTestResults(tests,
176 output_file, 185 output_file,
177 output, 186 output,
178 exit_code, 187 exit_code,
179 was_timeout, 188 was_timeout,
180 &tests_to_relaunch_after_interruption); 189 &tests_to_relaunch_after_interruption);
181 190
182 for (size_t i = 0; i < tests_to_relaunch_after_interruption.size(); i++) 191 for (size_t i = 0; i < tests_to_relaunch_after_interruption.size(); i++)
183 tests_.push_back(tests_to_relaunch_after_interruption[i]); 192 tests_.push_back(tests_to_relaunch_after_interruption[i]);
184 RunRemainingTests(); 193 RunRemainingTests();
185 194
186 if (called_any_callbacks) 195 if (called_any_callbacks)
187 parallel_launcher_.ResetOutputWatchdog(); 196 parallel_launcher_.ResetOutputWatchdog();
188 197
189 // The temporary file's directory is also temporary. 198 // The temporary file's directory is also temporary.
190 DeleteFile(output_file.DirName(), true); 199 DeleteFile(output_file.DirName(), true);
191 } 200 }
192 201
193 static void MaybePrintTestOutputSnippet(const TestResult& result,
194 const std::string& full_output) {
195 if (result.status == TestResult::TEST_SUCCESS)
196 return;
197
198 size_t run_pos = full_output.find(std::string("[ RUN ] ") +
199 result.GetFullName());
200 if (run_pos == std::string::npos)
201 return;
202
203 size_t end_pos = full_output.find(std::string("[ FAILED ] ") +
204 result.GetFullName(),
205 run_pos);
206 if (end_pos != std::string::npos) {
207 size_t newline_pos = full_output.find("\n", end_pos);
208 if (newline_pos != std::string::npos)
209 end_pos = newline_pos + 1;
210 }
211
212 std::string snippet(full_output.substr(run_pos));
213 if (end_pos != std::string::npos)
214 snippet = full_output.substr(run_pos, end_pos - run_pos);
215
216 // TODO(phajdan.jr): Indent each line of the snippet so it's more
217 // noticeable.
218 fprintf(stdout, "%s", snippet.c_str());
219 fflush(stdout);
220 }
221
222 static bool ProcessTestResults( 202 static bool ProcessTestResults(
223 const std::vector<TestLaunchInfo>& tests, 203 const std::vector<TestLaunchInfo>& tests,
224 const base::FilePath& output_file, 204 const base::FilePath& output_file,
225 const std::string& output, 205 const std::string& output,
226 int exit_code, 206 int exit_code,
227 bool was_timeout, 207 bool was_timeout,
228 std::vector<TestLaunchInfo>* tests_to_relaunch_after_interruption) { 208 std::vector<TestLaunchInfo>* tests_to_relaunch_after_interruption) {
229 std::vector<TestResult> test_results; 209 std::vector<TestResult> test_results;
230 bool crashed = false; 210 bool crashed = false;
231 bool have_test_results = 211 bool have_test_results =
(...skipping 16 matching lines...) Expand all
248 if (test_result.status == TestResult::TEST_CRASH) { 228 if (test_result.status == TestResult::TEST_CRASH) {
249 had_interrupted_test = true; 229 had_interrupted_test = true;
250 230
251 if (was_timeout) { 231 if (was_timeout) {
252 // Fix up the test status: we forcibly kill the child process 232 // Fix up the test status: we forcibly kill the child process
253 // after the timeout, so from XML results it looks just like 233 // after the timeout, so from XML results it looks just like
254 // a crash. 234 // a crash.
255 test_result.status = TestResult::TEST_TIMEOUT; 235 test_result.status = TestResult::TEST_TIMEOUT;
256 } 236 }
257 } 237 }
258 MaybePrintTestOutputSnippet(test_result, output); 238 PrintTestOutputSnippetOnFailure(test_result, output);
259 tests[i].callback.Run(test_result); 239 tests[i].callback.Run(test_result);
260 called_any_callback = true; 240 called_any_callback = true;
261 } else if (had_interrupted_test) { 241 } else if (had_interrupted_test) {
262 tests_to_relaunch_after_interruption->push_back(tests[i]); 242 tests_to_relaunch_after_interruption->push_back(tests[i]);
263 } else { 243 } else {
264 // TODO(phajdan.jr): Explicitly pass the info that the test didn't 244 // TODO(phajdan.jr): Explicitly pass the info that the test didn't
265 // run for a mysterious reason. 245 // run for a mysterious reason.
266 LOG(ERROR) << "no test result for " << tests[i].GetFullName(); 246 LOG(ERROR) << "no test result for " << tests[i].GetFullName();
267 TestResult test_result; 247 TestResult test_result;
268 test_result.test_case_name = tests[i].test_case_name; 248 test_result.test_case_name = tests[i].test_case_name;
269 test_result.test_name = tests[i].test_name; 249 test_result.test_name = tests[i].test_name;
270 test_result.status = TestResult::TEST_UNKNOWN; 250 test_result.status = TestResult::TEST_UNKNOWN;
271 MaybePrintTestOutputSnippet(test_result, output); 251 PrintTestOutputSnippetOnFailure(test_result, output);
272 tests[i].callback.Run(test_result); 252 tests[i].callback.Run(test_result);
273 called_any_callback = true; 253 called_any_callback = true;
274 } 254 }
275 } 255 }
276 256
277 // TODO(phajdan.jr): Handle the case where processing XML output 257 // TODO(phajdan.jr): Handle the case where processing XML output
278 // indicates a crash but none of the test results is marked as crashing. 258 // indicates a crash but none of the test results is marked as crashing.
279 259
280 // TODO(phajdan.jr): Handle the case where the exit code is non-zero 260 // TODO(phajdan.jr): Handle the case where the exit code is non-zero
281 // but results file indicates that all tests passed (e.g. crash during 261 // but results file indicates that all tests passed (e.g. crash during
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
374 354
375 fprintf(stdout, 355 fprintf(stdout,
376 "Tests took %" PRId64 " seconds.\n", 356 "Tests took %" PRId64 " seconds.\n",
377 (base::TimeTicks::Now() - start_time).InSeconds()); 357 (base::TimeTicks::Now() - start_time).InSeconds());
378 fflush(stdout); 358 fflush(stdout);
379 359
380 return exit_code; 360 return exit_code;
381 } 361 }
382 362
383 } // namespace base 363 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698