OLD | NEW |
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/launcher/unit_test_launcher.h" | 5 #include "base/test/launcher/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" |
11 #include "base/file_util.h" | 11 #include "base/file_util.h" |
12 #include "base/files/scoped_temp_dir.h" | 12 #include "base/files/scoped_temp_dir.h" |
13 #include "base/format_macros.h" | 13 #include "base/format_macros.h" |
14 #include "base/message_loop/message_loop.h" | 14 #include "base/message_loop/message_loop.h" |
15 #include "base/stl_util.h" | 15 #include "base/stl_util.h" |
16 #include "base/strings/string_number_conversions.h" | 16 #include "base/strings/string_number_conversions.h" |
17 #include "base/strings/string_util.h" | 17 #include "base/strings/string_util.h" |
18 #include "base/sys_info.h" | 18 #include "base/sys_info.h" |
19 #include "base/test/gtest_xml_util.h" | 19 #include "base/test/gtest_xml_util.h" |
20 #include "base/test/launcher/parallel_test_launcher.h" | |
21 #include "base/test/launcher/test_launcher.h" | 20 #include "base/test/launcher/test_launcher.h" |
22 #include "base/test/test_switches.h" | 21 #include "base/test/test_switches.h" |
23 #include "base/test/test_timeouts.h" | 22 #include "base/test/test_timeouts.h" |
24 #include "base/threading/thread_checker.h" | 23 #include "base/threading/thread_checker.h" |
25 #include "testing/gtest/include/gtest/gtest.h" | 24 #include "testing/gtest/include/gtest/gtest.h" |
26 | 25 |
27 namespace base { | 26 namespace base { |
28 | 27 |
29 namespace { | 28 namespace { |
30 | 29 |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
72 new_cmd_line.AppendSwitchPath(switches::kTestLauncherOutput, output_file); | 71 new_cmd_line.AppendSwitchPath(switches::kTestLauncherOutput, output_file); |
73 new_cmd_line.AppendSwitchASCII(kGTestFilterFlag, JoinString(test_names, ":")); | 72 new_cmd_line.AppendSwitchASCII(kGTestFilterFlag, JoinString(test_names, ":")); |
74 new_cmd_line.AppendSwitch(kSingleProcessTestsFlag); | 73 new_cmd_line.AppendSwitch(kSingleProcessTestsFlag); |
75 new_cmd_line.AppendSwitch(kBraveNewTestLauncherFlag); | 74 new_cmd_line.AppendSwitch(kBraveNewTestLauncherFlag); |
76 | 75 |
77 return new_cmd_line; | 76 return new_cmd_line; |
78 } | 77 } |
79 | 78 |
80 class UnitTestLauncherDelegate : public TestLauncherDelegate { | 79 class UnitTestLauncherDelegate : public TestLauncherDelegate { |
81 public: | 80 public: |
82 UnitTestLauncherDelegate(size_t jobs, size_t batch_limit) | 81 explicit UnitTestLauncherDelegate(size_t batch_limit) |
83 : parallel_launcher_(jobs), | 82 : batch_limit_(batch_limit) { |
84 batch_limit_(batch_limit) { | |
85 } | 83 } |
86 | 84 |
87 virtual ~UnitTestLauncherDelegate() { | 85 virtual ~UnitTestLauncherDelegate() { |
88 DCHECK(thread_checker_.CalledOnValidThread()); | 86 DCHECK(thread_checker_.CalledOnValidThread()); |
89 } | 87 } |
90 | 88 |
91 private: | 89 private: |
92 struct GTestCallbackState { | 90 struct GTestCallbackState { |
93 TestLauncher* test_launcher; | 91 TestLauncher* test_launcher; |
94 std::vector<std::string> test_names; | 92 std::vector<std::string> test_names; |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
166 std::vector<std::string> current_test_names; | 164 std::vector<std::string> current_test_names; |
167 current_test_names.push_back(test_name); | 165 current_test_names.push_back(test_name); |
168 CommandLine cmd_line( | 166 CommandLine cmd_line( |
169 GetCommandLineForChildGTestProcess(current_test_names, output_file)); | 167 GetCommandLineForChildGTestProcess(current_test_names, output_file)); |
170 | 168 |
171 GTestCallbackState callback_state; | 169 GTestCallbackState callback_state; |
172 callback_state.test_launcher = test_launcher; | 170 callback_state.test_launcher = test_launcher; |
173 callback_state.test_names = current_test_names; | 171 callback_state.test_names = current_test_names; |
174 callback_state.output_file = output_file; | 172 callback_state.output_file = output_file; |
175 | 173 |
176 parallel_launcher_.LaunchChildGTestProcess( | 174 test_launcher->LaunchChildGTestProcess( |
177 cmd_line, | 175 cmd_line, |
178 std::string(), | 176 std::string(), |
179 TestTimeouts::test_launcher_timeout(), | 177 TestTimeouts::test_launcher_timeout(), |
180 Bind(&UnitTestLauncherDelegate::SerialGTestCallback, | 178 Bind(&UnitTestLauncherDelegate::SerialGTestCallback, |
181 Unretained(this), | 179 Unretained(this), |
182 callback_state, | 180 callback_state, |
183 new_test_names)); | 181 new_test_names)); |
184 } | 182 } |
185 | 183 |
186 void RunBatch(TestLauncher* test_launcher, | 184 void RunBatch(TestLauncher* test_launcher, |
(...skipping 21 matching lines...) Expand all Loading... |
208 // Note: do NOT parse child's stdout to do that, it's known to be | 206 // Note: do NOT parse child's stdout to do that, it's known to be |
209 // unreliable (e.g. buffering issues can mix up the output). | 207 // unreliable (e.g. buffering issues can mix up the output). |
210 base::TimeDelta timeout = | 208 base::TimeDelta timeout = |
211 test_names.size() * TestTimeouts::test_launcher_timeout(); | 209 test_names.size() * TestTimeouts::test_launcher_timeout(); |
212 | 210 |
213 GTestCallbackState callback_state; | 211 GTestCallbackState callback_state; |
214 callback_state.test_launcher = test_launcher; | 212 callback_state.test_launcher = test_launcher; |
215 callback_state.test_names = test_names; | 213 callback_state.test_names = test_names; |
216 callback_state.output_file = output_file; | 214 callback_state.output_file = output_file; |
217 | 215 |
218 parallel_launcher_.LaunchChildGTestProcess( | 216 test_launcher->LaunchChildGTestProcess( |
219 cmd_line, | 217 cmd_line, |
220 std::string(), | 218 std::string(), |
221 timeout, | 219 timeout, |
222 Bind(&UnitTestLauncherDelegate::GTestCallback, | 220 Bind(&UnitTestLauncherDelegate::GTestCallback, |
223 Unretained(this), | 221 Unretained(this), |
224 callback_state)); | 222 callback_state)); |
225 } | 223 } |
226 | 224 |
227 void GTestCallback(const GTestCallbackState& callback_state, | 225 void GTestCallback(const GTestCallbackState& callback_state, |
228 int exit_code, | 226 int exit_code, |
229 const TimeDelta& elapsed_time, | 227 const TimeDelta& elapsed_time, |
230 bool was_timeout, | 228 bool was_timeout, |
231 const std::string& output) { | 229 const std::string& output) { |
232 DCHECK(thread_checker_.CalledOnValidThread()); | 230 DCHECK(thread_checker_.CalledOnValidThread()); |
233 std::vector<std::string> tests_to_relaunch_after_interruption; | 231 std::vector<std::string> tests_to_relaunch_after_interruption; |
234 bool called_any_callbacks = | 232 ProcessTestResults(callback_state.test_launcher, |
235 ProcessTestResults(callback_state.test_launcher, | 233 callback_state.test_names, |
236 callback_state.test_names, | 234 callback_state.output_file, |
237 callback_state.output_file, | 235 output, |
238 output, | 236 exit_code, |
239 exit_code, | 237 was_timeout, |
240 was_timeout, | 238 &tests_to_relaunch_after_interruption); |
241 &tests_to_relaunch_after_interruption); | |
242 | 239 |
243 RunBatch(callback_state.test_launcher, | 240 RunBatch(callback_state.test_launcher, |
244 tests_to_relaunch_after_interruption); | 241 tests_to_relaunch_after_interruption); |
245 | 242 |
246 if (called_any_callbacks) | |
247 parallel_launcher_.ResetOutputWatchdog(); | |
248 | |
249 // The temporary file's directory is also temporary. | 243 // The temporary file's directory is also temporary. |
250 DeleteFile(callback_state.output_file.DirName(), true); | 244 DeleteFile(callback_state.output_file.DirName(), true); |
251 } | 245 } |
252 | 246 |
253 void SerialGTestCallback(const GTestCallbackState& callback_state, | 247 void SerialGTestCallback(const GTestCallbackState& callback_state, |
254 const std::vector<std::string>& test_names, | 248 const std::vector<std::string>& test_names, |
255 int exit_code, | 249 int exit_code, |
256 const TimeDelta& elapsed_time, | 250 const TimeDelta& elapsed_time, |
257 bool was_timeout, | 251 bool was_timeout, |
258 const std::string& output) { | 252 const std::string& output) { |
259 DCHECK(thread_checker_.CalledOnValidThread()); | 253 DCHECK(thread_checker_.CalledOnValidThread()); |
260 std::vector<std::string> tests_to_relaunch_after_interruption; | 254 std::vector<std::string> tests_to_relaunch_after_interruption; |
261 bool called_any_callbacks = | 255 bool called_any_callbacks = |
262 ProcessTestResults(callback_state.test_launcher, | 256 ProcessTestResults(callback_state.test_launcher, |
263 callback_state.test_names, | 257 callback_state.test_names, |
264 callback_state.output_file, | 258 callback_state.output_file, |
265 output, | 259 output, |
266 exit_code, | 260 exit_code, |
267 was_timeout, | 261 was_timeout, |
268 &tests_to_relaunch_after_interruption); | 262 &tests_to_relaunch_after_interruption); |
269 | 263 |
270 // There is only one test, there cannot be other tests to relaunch | 264 // There is only one test, there cannot be other tests to relaunch |
271 // due to a crash. | 265 // due to a crash. |
272 DCHECK(tests_to_relaunch_after_interruption.empty()); | 266 DCHECK(tests_to_relaunch_after_interruption.empty()); |
273 | 267 |
274 if (called_any_callbacks) { | 268 // There is only one test, we should have called back with its result. |
275 parallel_launcher_.ResetOutputWatchdog(); | 269 DCHECK(called_any_callbacks); |
276 } else { | |
277 // There is only one test, we should have called back with its result. | |
278 NOTREACHED(); | |
279 } | |
280 | 270 |
281 // The temporary file's directory is also temporary. | 271 // The temporary file's directory is also temporary. |
282 DeleteFile(callback_state.output_file.DirName(), true); | 272 DeleteFile(callback_state.output_file.DirName(), true); |
283 | 273 |
284 MessageLoop::current()->PostTask( | 274 MessageLoop::current()->PostTask( |
285 FROM_HERE, | 275 FROM_HERE, |
286 Bind(&UnitTestLauncherDelegate::RunSerially, | 276 Bind(&UnitTestLauncherDelegate::RunSerially, |
287 Unretained(this), | 277 Unretained(this), |
288 callback_state.test_launcher, | 278 callback_state.test_launcher, |
289 test_names)); | 279 test_names)); |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
382 test_launcher->OnTestFinished(test_result); | 372 test_launcher->OnTestFinished(test_result); |
383 called_any_callback = true; | 373 called_any_callback = true; |
384 } | 374 } |
385 } | 375 } |
386 | 376 |
387 return called_any_callback; | 377 return called_any_callback; |
388 } | 378 } |
389 | 379 |
390 ThreadChecker thread_checker_; | 380 ThreadChecker thread_checker_; |
391 | 381 |
392 ParallelTestLauncher parallel_launcher_; | |
393 | |
394 // Maximum number of tests to run in a single batch. | 382 // Maximum number of tests to run in a single batch. |
395 size_t batch_limit_; | 383 size_t batch_limit_; |
396 }; | 384 }; |
397 | 385 |
398 bool GetSwitchValueAsInt(const std::string& switch_name, int* result) { | 386 bool GetSwitchValueAsInt(const std::string& switch_name, int* result) { |
399 if (!CommandLine::ForCurrentProcess()->HasSwitch(switch_name)) | 387 if (!CommandLine::ForCurrentProcess()->HasSwitch(switch_name)) |
400 return true; | 388 return true; |
401 | 389 |
402 std::string switch_value = | 390 std::string switch_value = |
403 CommandLine::ForCurrentProcess()->GetSwitchValueASCII(switch_name); | 391 CommandLine::ForCurrentProcess()->GetSwitchValueASCII(switch_name); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
442 fprintf(stdout, | 430 fprintf(stdout, |
443 "Starting tests (using %d parallel jobs)...\n" | 431 "Starting tests (using %d parallel jobs)...\n" |
444 "IMPORTANT DEBUGGING NOTE: batches of tests are run inside their\n" | 432 "IMPORTANT DEBUGGING NOTE: batches of tests are run inside their\n" |
445 "own process. For debugging a test inside a debugger, use the\n" | 433 "own process. For debugging a test inside a debugger, use the\n" |
446 "--gtest_filter=<your_test_name> flag along with\n" | 434 "--gtest_filter=<your_test_name> flag along with\n" |
447 "--single-process-tests.\n", jobs); | 435 "--single-process-tests.\n", jobs); |
448 fflush(stdout); | 436 fflush(stdout); |
449 | 437 |
450 MessageLoopForIO message_loop; | 438 MessageLoopForIO message_loop; |
451 | 439 |
452 base::UnitTestLauncherDelegate delegate(jobs, batch_limit); | 440 base::UnitTestLauncherDelegate delegate(batch_limit); |
453 base::TestLauncher launcher(&delegate); | 441 base::TestLauncher launcher(&delegate, jobs); |
454 bool success = launcher.Run(argc, argv); | 442 bool success = launcher.Run(argc, argv); |
455 | 443 |
456 fprintf(stdout, | 444 fprintf(stdout, |
457 "Tests took %" PRId64 " seconds.\n", | 445 "Tests took %" PRId64 " seconds.\n", |
458 (base::TimeTicks::Now() - start_time).InSeconds()); | 446 (base::TimeTicks::Now() - start_time).InSeconds()); |
459 fflush(stdout); | 447 fflush(stdout); |
460 | 448 |
461 return (success ? 0 : 1); | 449 return (success ? 0 : 1); |
462 } | 450 } |
463 | 451 |
464 } // namespace base | 452 } // namespace base |
OLD | NEW |