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" |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
95 | 95 |
96 new_cmd_line.AppendSwitchPath(switches::kTestLauncherOutput, output_file); | 96 new_cmd_line.AppendSwitchPath(switches::kTestLauncherOutput, output_file); |
97 new_cmd_line.AppendSwitchASCII(kGTestFilterFlag, JoinString(test_names, ":")); | 97 new_cmd_line.AppendSwitchASCII(kGTestFilterFlag, JoinString(test_names, ":")); |
98 new_cmd_line.AppendSwitch(kSingleProcessTestsFlag); | 98 new_cmd_line.AppendSwitch(kSingleProcessTestsFlag); |
99 | 99 |
100 return new_cmd_line; | 100 return new_cmd_line; |
101 } | 101 } |
102 | 102 |
103 class UnitTestLauncherDelegate : public TestLauncherDelegate { | 103 class UnitTestLauncherDelegate : public TestLauncherDelegate { |
104 public: | 104 public: |
105 explicit UnitTestLauncherDelegate(size_t batch_limit) | 105 explicit UnitTestLauncherDelegate(size_t batch_limit, bool use_job_objects) |
106 : batch_limit_(batch_limit) { | 106 : batch_limit_(batch_limit), |
| 107 use_job_objects_(use_job_objects) { |
107 } | 108 } |
108 | 109 |
109 virtual ~UnitTestLauncherDelegate() { | 110 virtual ~UnitTestLauncherDelegate() { |
110 DCHECK(thread_checker_.CalledOnValidThread()); | 111 DCHECK(thread_checker_.CalledOnValidThread()); |
111 } | 112 } |
112 | 113 |
113 private: | 114 private: |
114 struct GTestCallbackState { | 115 struct GTestCallbackState { |
115 TestLauncher* test_launcher; | 116 TestLauncher* test_launcher; |
116 std::vector<std::string> test_names; | 117 std::vector<std::string> test_names; |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
179 | 180 |
180 GTestCallbackState callback_state; | 181 GTestCallbackState callback_state; |
181 callback_state.test_launcher = test_launcher; | 182 callback_state.test_launcher = test_launcher; |
182 callback_state.test_names = current_test_names; | 183 callback_state.test_names = current_test_names; |
183 callback_state.output_file = output_file; | 184 callback_state.output_file = output_file; |
184 | 185 |
185 test_launcher->LaunchChildGTestProcess( | 186 test_launcher->LaunchChildGTestProcess( |
186 cmd_line, | 187 cmd_line, |
187 std::string(), | 188 std::string(), |
188 TestTimeouts::test_launcher_timeout(), | 189 TestTimeouts::test_launcher_timeout(), |
| 190 use_job_objects_, |
189 Bind(&UnitTestLauncherDelegate::SerialGTestCallback, | 191 Bind(&UnitTestLauncherDelegate::SerialGTestCallback, |
190 Unretained(this), | 192 Unretained(this), |
191 callback_state, | 193 callback_state, |
192 new_test_names)); | 194 new_test_names)); |
193 } | 195 } |
194 | 196 |
195 void RunBatch(TestLauncher* test_launcher, | 197 void RunBatch(TestLauncher* test_launcher, |
196 const std::vector<std::string>& test_names) { | 198 const std::vector<std::string>& test_names) { |
197 DCHECK(thread_checker_.CalledOnValidThread()); | 199 DCHECK(thread_checker_.CalledOnValidThread()); |
198 | 200 |
(...skipping 21 matching lines...) Expand all Loading... |
220 | 222 |
221 GTestCallbackState callback_state; | 223 GTestCallbackState callback_state; |
222 callback_state.test_launcher = test_launcher; | 224 callback_state.test_launcher = test_launcher; |
223 callback_state.test_names = test_names; | 225 callback_state.test_names = test_names; |
224 callback_state.output_file = output_file; | 226 callback_state.output_file = output_file; |
225 | 227 |
226 test_launcher->LaunchChildGTestProcess( | 228 test_launcher->LaunchChildGTestProcess( |
227 cmd_line, | 229 cmd_line, |
228 std::string(), | 230 std::string(), |
229 timeout, | 231 timeout, |
| 232 use_job_objects_, |
230 Bind(&UnitTestLauncherDelegate::GTestCallback, | 233 Bind(&UnitTestLauncherDelegate::GTestCallback, |
231 Unretained(this), | 234 Unretained(this), |
232 callback_state)); | 235 callback_state)); |
233 } | 236 } |
234 | 237 |
235 void GTestCallback(const GTestCallbackState& callback_state, | 238 void GTestCallback(const GTestCallbackState& callback_state, |
236 int exit_code, | 239 int exit_code, |
237 const TimeDelta& elapsed_time, | 240 const TimeDelta& elapsed_time, |
238 bool was_timeout, | 241 bool was_timeout, |
239 const std::string& output) { | 242 const std::string& output) { |
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
429 } | 432 } |
430 } | 433 } |
431 | 434 |
432 return called_any_callback; | 435 return called_any_callback; |
433 } | 436 } |
434 | 437 |
435 ThreadChecker thread_checker_; | 438 ThreadChecker thread_checker_; |
436 | 439 |
437 // Maximum number of tests to run in a single batch. | 440 // Maximum number of tests to run in a single batch. |
438 size_t batch_limit_; | 441 size_t batch_limit_; |
| 442 |
| 443 // Determines whether we use job objects on Windows. |
| 444 bool use_job_objects_; |
439 }; | 445 }; |
440 | 446 |
441 bool GetSwitchValueAsInt(const std::string& switch_name, int* result) { | 447 bool GetSwitchValueAsInt(const std::string& switch_name, int* result) { |
442 if (!CommandLine::ForCurrentProcess()->HasSwitch(switch_name)) | 448 if (!CommandLine::ForCurrentProcess()->HasSwitch(switch_name)) |
443 return true; | 449 return true; |
444 | 450 |
445 std::string switch_value = | 451 std::string switch_value = |
446 CommandLine::ForCurrentProcess()->GetSwitchValueASCII(switch_name); | 452 CommandLine::ForCurrentProcess()->GetSwitchValueASCII(switch_name); |
447 if (!StringToInt(switch_value, result) || *result < 1) { | 453 if (!StringToInt(switch_value, result) || *result < 1) { |
448 LOG(ERROR) << "Invalid value for " << switch_name << ": " << switch_value; | 454 LOG(ERROR) << "Invalid value for " << switch_name << ": " << switch_value; |
449 return false; | 455 return false; |
450 } | 456 } |
451 | 457 |
452 return true; | 458 return true; |
453 } | 459 } |
454 | 460 |
455 int LaunchUnitTestsInternal(int argc, | 461 int LaunchUnitTestsInternal(const RunTestSuiteCallback& run_test_suite, |
456 char** argv, | 462 int default_jobs, |
457 const RunTestSuiteCallback& run_test_suite, | 463 bool use_job_objects, |
458 int default_jobs) { | 464 const Closure& gtest_init) { |
459 CommandLine::Init(argc, argv); | |
460 | |
461 #if defined(OS_ANDROID) | 465 #if defined(OS_ANDROID) |
462 // We can't easily fork on Android, just run the test suite directly. | 466 // We can't easily fork on Android, just run the test suite directly. |
463 return run_test_suite.Run(); | 467 return run_test_suite.Run(); |
464 #else | 468 #else |
465 bool force_single_process = false; | 469 bool force_single_process = false; |
466 if (CommandLine::ForCurrentProcess()->HasSwitch( | 470 if (CommandLine::ForCurrentProcess()->HasSwitch( |
467 switches::kTestLauncherDebugLauncher)) { | 471 switches::kTestLauncherDebugLauncher)) { |
468 fprintf(stdout, "Forcing test launcher debugging mode.\n"); | 472 fprintf(stdout, "Forcing test launcher debugging mode.\n"); |
469 fflush(stdout); | 473 fflush(stdout); |
470 } else { | 474 } else { |
(...skipping 24 matching lines...) Expand all Loading... |
495 } | 499 } |
496 #endif | 500 #endif |
497 | 501 |
498 if (CommandLine::ForCurrentProcess()->HasSwitch(kHelpFlag)) { | 502 if (CommandLine::ForCurrentProcess()->HasSwitch(kHelpFlag)) { |
499 PrintUsage(); | 503 PrintUsage(); |
500 return 0; | 504 return 0; |
501 } | 505 } |
502 | 506 |
503 base::TimeTicks start_time(base::TimeTicks::Now()); | 507 base::TimeTicks start_time(base::TimeTicks::Now()); |
504 | 508 |
505 testing::InitGoogleTest(&argc, argv); | 509 gtest_init.Run(); |
506 TestTimeouts::Initialize(); | 510 TestTimeouts::Initialize(); |
507 | 511 |
508 int batch_limit = kDefaultTestBatchLimit; | 512 int batch_limit = kDefaultTestBatchLimit; |
509 if (!GetSwitchValueAsInt(switches::kTestLauncherBatchLimit, &batch_limit)) | 513 if (!GetSwitchValueAsInt(switches::kTestLauncherBatchLimit, &batch_limit)) |
510 return 1; | 514 return 1; |
511 | 515 |
512 fprintf(stdout, | 516 fprintf(stdout, |
513 "IMPORTANT DEBUGGING NOTE: batches of tests are run inside their\n" | 517 "IMPORTANT DEBUGGING NOTE: batches of tests are run inside their\n" |
514 "own process. For debugging a test inside a debugger, use the\n" | 518 "own process. For debugging a test inside a debugger, use the\n" |
515 "--gtest_filter=<your_test_name> flag along with\n" | 519 "--gtest_filter=<your_test_name> flag along with\n" |
516 "--single-process-tests.\n"); | 520 "--single-process-tests.\n"); |
517 fflush(stdout); | 521 fflush(stdout); |
518 | 522 |
519 MessageLoopForIO message_loop; | 523 MessageLoopForIO message_loop; |
520 | 524 |
521 UnitTestLauncherDelegate delegate(batch_limit); | 525 UnitTestLauncherDelegate delegate(batch_limit, use_job_objects); |
522 base::TestLauncher launcher(&delegate, default_jobs); | 526 base::TestLauncher launcher(&delegate, default_jobs); |
523 bool success = launcher.Run(argc, argv); | 527 bool success = launcher.Run(); |
524 | 528 |
525 fprintf(stdout, | 529 fprintf(stdout, |
526 "Tests took %" PRId64 " seconds.\n", | 530 "Tests took %" PRId64 " seconds.\n", |
527 (base::TimeTicks::Now() - start_time).InSeconds()); | 531 (base::TimeTicks::Now() - start_time).InSeconds()); |
528 fflush(stdout); | 532 fflush(stdout); |
529 | 533 |
530 return (success ? 0 : 1); | 534 return (success ? 0 : 1); |
531 } | 535 } |
532 | 536 |
| 537 void InitGoogleTestChar(int* argc, char** argv) { |
| 538 testing::InitGoogleTest(argc, argv); |
| 539 } |
| 540 |
| 541 #if defined(OS_WIN) |
| 542 void InitGoogleTestWChar(int* argc, wchar_t** argv) { |
| 543 testing::InitGoogleTest(argc, argv); |
| 544 } |
| 545 #endif // defined(OS_WIN) |
| 546 |
533 } // namespace | 547 } // namespace |
534 | 548 |
535 int LaunchUnitTests(int argc, | 549 int LaunchUnitTests(int argc, |
536 char** argv, | 550 char** argv, |
537 const RunTestSuiteCallback& run_test_suite) { | 551 const RunTestSuiteCallback& run_test_suite) { |
| 552 CommandLine::Init(argc, argv); |
538 return LaunchUnitTestsInternal( | 553 return LaunchUnitTestsInternal( |
539 argc, argv, run_test_suite, SysInfo::NumberOfProcessors()); | 554 run_test_suite, |
| 555 SysInfo::NumberOfProcessors(), |
| 556 true, |
| 557 Bind(&InitGoogleTestChar, &argc, argv)); |
540 } | 558 } |
541 | 559 |
542 int LaunchUnitTestsSerially(int argc, | 560 int LaunchUnitTestsSerially(int argc, |
543 char** argv, | 561 char** argv, |
544 const RunTestSuiteCallback& run_test_suite) { | 562 const RunTestSuiteCallback& run_test_suite) { |
545 return LaunchUnitTestsInternal(argc, argv, run_test_suite, 1); | 563 CommandLine::Init(argc, argv); |
| 564 return LaunchUnitTestsInternal( |
| 565 run_test_suite, |
| 566 1, |
| 567 true, |
| 568 Bind(&InitGoogleTestChar, &argc, argv)); |
546 } | 569 } |
547 | 570 |
| 571 #if defined(OS_WIN) |
| 572 int LaunchUnitTests(int argc, |
| 573 wchar_t** argv, |
| 574 bool use_job_objects, |
| 575 const RunTestSuiteCallback& run_test_suite) { |
| 576 // Windows CommandLine::Init ignores argv anyway. |
| 577 CommandLine::Init(argc, NULL); |
| 578 return LaunchUnitTestsInternal( |
| 579 run_test_suite, |
| 580 SysInfo::NumberOfProcessors(), |
| 581 use_job_objects, |
| 582 Bind(&InitGoogleTestWChar, &argc, argv)); |
| 583 } |
| 584 #endif // defined(OS_WIN) |
| 585 |
548 } // namespace base | 586 } // namespace base |
OLD | NEW |