| 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 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 93 const base::FilePath& output_file) { | 93 const base::FilePath& output_file) { |
| 94 CommandLine new_cmd_line(*CommandLine::ForCurrentProcess()); | 94 CommandLine new_cmd_line(*CommandLine::ForCurrentProcess()); |
| 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 bool GetSwitchValueAsInt(const std::string& switch_name, int* result) { |
| 104 public: | 104 if (!CommandLine::ForCurrentProcess()->HasSwitch(switch_name)) |
| 105 explicit UnitTestLauncherDelegate(size_t batch_limit, bool use_job_objects) | 105 return true; |
| 106 : batch_limit_(batch_limit), | 106 |
| 107 use_job_objects_(use_job_objects) { | 107 std::string switch_value = |
| 108 CommandLine::ForCurrentProcess()->GetSwitchValueASCII(switch_name); |
| 109 if (!StringToInt(switch_value, result) || *result < 1) { |
| 110 LOG(ERROR) << "Invalid value for " << switch_name << ": " << switch_value; |
| 111 return false; |
| 108 } | 112 } |
| 109 | 113 |
| 110 ~UnitTestLauncherDelegate() override { | 114 return true; |
| 111 DCHECK(thread_checker_.CalledOnValidThread()); | 115 } |
| 116 |
| 117 int LaunchUnitTestsInternal(const RunTestSuiteCallback& run_test_suite, |
| 118 int default_jobs, |
| 119 bool use_job_objects, |
| 120 const Closure& gtest_init) { |
| 121 #if defined(OS_ANDROID) |
| 122 // We can't easily fork on Android, just run the test suite directly. |
| 123 return run_test_suite.Run(); |
| 124 #else |
| 125 bool force_single_process = false; |
| 126 if (CommandLine::ForCurrentProcess()->HasSwitch( |
| 127 switches::kTestLauncherDebugLauncher)) { |
| 128 fprintf(stdout, "Forcing test launcher debugging mode.\n"); |
| 129 fflush(stdout); |
| 130 } else { |
| 131 if (base::debug::BeingDebugged()) { |
| 132 fprintf(stdout, |
| 133 "Debugger detected, switching to single process mode.\n" |
| 134 "Pass --test-launcher-debug-launcher to debug the launcher " |
| 135 "itself.\n"); |
| 136 fflush(stdout); |
| 137 force_single_process = true; |
| 138 } |
| 112 } | 139 } |
| 113 | 140 |
| 114 private: | 141 if (CommandLine::ForCurrentProcess()->HasSwitch(kGTestHelpFlag) || |
| 115 struct GTestCallbackState { | 142 CommandLine::ForCurrentProcess()->HasSwitch(kGTestListTestsFlag) || |
| 116 TestLauncher* test_launcher; | 143 CommandLine::ForCurrentProcess()->HasSwitch(kSingleProcessTestsFlag) || |
| 117 std::vector<std::string> test_names; | 144 force_single_process) { |
| 118 FilePath output_file; | 145 return run_test_suite.Run(); |
| 119 }; | 146 } |
| 147 #endif |
| 120 | 148 |
| 121 bool ShouldRunTest(const std::string& test_case_name, | 149 if (CommandLine::ForCurrentProcess()->HasSwitch(kHelpFlag)) { |
| 122 const std::string& test_name) override { | 150 PrintUsage(); |
| 151 return 0; |
| 152 } |
| 153 |
| 154 base::TimeTicks start_time(base::TimeTicks::Now()); |
| 155 |
| 156 gtest_init.Run(); |
| 157 TestTimeouts::Initialize(); |
| 158 |
| 159 int batch_limit = kDefaultTestBatchLimit; |
| 160 if (!GetSwitchValueAsInt(switches::kTestLauncherBatchLimit, &batch_limit)) |
| 161 return 1; |
| 162 |
| 163 fprintf(stdout, |
| 164 "IMPORTANT DEBUGGING NOTE: batches of tests are run inside their\n" |
| 165 "own process. For debugging a test inside a debugger, use the\n" |
| 166 "--gtest_filter=<your_test_name> flag along with\n" |
| 167 "--single-process-tests.\n"); |
| 168 fflush(stdout); |
| 169 |
| 170 MessageLoopForIO message_loop; |
| 171 |
| 172 UnitTestLauncherDelegate delegate(batch_limit, use_job_objects); |
| 173 base::TestLauncher launcher(&delegate, default_jobs); |
| 174 bool success = launcher.Run(); |
| 175 |
| 176 fprintf(stdout, "Tests took %" PRId64 " seconds.\n", |
| 177 (base::TimeTicks::Now() - start_time).InSeconds()); |
| 178 fflush(stdout); |
| 179 |
| 180 return (success ? 0 : 1); |
| 181 } |
| 182 |
| 183 void InitGoogleTestChar(int* argc, char** argv) { |
| 184 testing::InitGoogleTest(argc, argv); |
| 185 } |
| 186 |
| 187 #if defined(OS_WIN) |
| 188 void InitGoogleTestWChar(int* argc, wchar_t** argv) { |
| 189 testing::InitGoogleTest(argc, argv); |
| 190 } |
| 191 #endif // defined(OS_WIN) |
| 192 |
| 193 } // namespace |
| 194 |
| 195 int LaunchUnitTests(int argc, |
| 196 char** argv, |
| 197 const RunTestSuiteCallback& run_test_suite) { |
| 198 CommandLine::Init(argc, argv); |
| 199 return LaunchUnitTestsInternal(run_test_suite, SysInfo::NumberOfProcessors(), |
| 200 true, Bind(&InitGoogleTestChar, &argc, argv)); |
| 201 } |
| 202 |
| 203 int LaunchUnitTestsSerially(int argc, |
| 204 char** argv, |
| 205 const RunTestSuiteCallback& run_test_suite) { |
| 206 CommandLine::Init(argc, argv); |
| 207 return LaunchUnitTestsInternal(run_test_suite, 1, true, |
| 208 Bind(&InitGoogleTestChar, &argc, argv)); |
| 209 } |
| 210 |
| 211 #if defined(OS_WIN) |
| 212 int LaunchUnitTests(int argc, |
| 213 wchar_t** argv, |
| 214 bool use_job_objects, |
| 215 const RunTestSuiteCallback& run_test_suite) { |
| 216 // Windows CommandLine::Init ignores argv anyway. |
| 217 CommandLine::Init(argc, NULL); |
| 218 return LaunchUnitTestsInternal(run_test_suite, SysInfo::NumberOfProcessors(), |
| 219 use_job_objects, |
| 220 Bind(&InitGoogleTestWChar, &argc, argv)); |
| 221 } |
| 222 #endif // defined(OS_WIN) |
| 223 |
| 224 UnitTestLauncherDelegate::UnitTestLauncherDelegate(size_t batch_limit, |
| 225 bool use_job_objects) |
| 226 : batch_limit_(batch_limit), use_job_objects_(use_job_objects) { |
| 227 } |
| 228 |
| 229 UnitTestLauncherDelegate::~UnitTestLauncherDelegate() { |
| 230 DCHECK(thread_checker_.CalledOnValidThread()); |
| 231 } |
| 232 |
| 233 UnitTestLauncherDelegate::GTestCallbackState::GTestCallbackState() { |
| 234 } |
| 235 |
| 236 UnitTestLauncherDelegate::GTestCallbackState::~GTestCallbackState() { |
| 237 } |
| 238 |
| 239 bool UnitTestLauncherDelegate::GetTests(std::vector<SplitTestName>* output) { |
| 240 DCHECK(thread_checker_.CalledOnValidThread()); |
| 241 *output = GetCompiledInTests(); |
| 242 return true; |
| 243 } |
| 244 |
| 245 bool UnitTestLauncherDelegate::ShouldRunTest(const std::string& test_case_name, |
| 246 const std::string& test_name) { |
| 123 DCHECK(thread_checker_.CalledOnValidThread()); | 247 DCHECK(thread_checker_.CalledOnValidThread()); |
| 124 | 248 |
| 125 // There is no additional logic to disable specific tests. | 249 // There is no additional logic to disable specific tests. |
| 126 return true; | 250 return true; |
| 127 } | 251 } |
| 128 | 252 |
| 129 size_t RunTests(TestLauncher* test_launcher, | 253 size_t UnitTestLauncherDelegate::RunTests( |
| 130 const std::vector<std::string>& test_names) override { | 254 TestLauncher* test_launcher, |
| 255 const std::vector<std::string>& test_names) { |
| 131 DCHECK(thread_checker_.CalledOnValidThread()); | 256 DCHECK(thread_checker_.CalledOnValidThread()); |
| 132 | 257 |
| 133 std::vector<std::string> batch; | 258 std::vector<std::string> batch; |
| 134 for (size_t i = 0; i < test_names.size(); i++) { | 259 for (size_t i = 0; i < test_names.size(); i++) { |
| 135 batch.push_back(test_names[i]); | 260 batch.push_back(test_names[i]); |
| 136 | 261 |
| 137 if (batch.size() >= batch_limit_) { | 262 if (batch.size() >= batch_limit_) { |
| 138 RunBatch(test_launcher, batch); | 263 RunBatch(test_launcher, batch); |
| 139 batch.clear(); | 264 batch.clear(); |
| 140 } | 265 } |
| 141 } | 266 } |
| 142 | 267 |
| 143 RunBatch(test_launcher, batch); | 268 RunBatch(test_launcher, batch); |
| 144 | 269 |
| 145 return test_names.size(); | 270 return test_names.size(); |
| 146 } | 271 } |
| 147 | 272 |
| 148 size_t RetryTests(TestLauncher* test_launcher, | 273 size_t UnitTestLauncherDelegate::RetryTests( |
| 149 const std::vector<std::string>& test_names) override { | 274 TestLauncher* test_launcher, |
| 275 const std::vector<std::string>& test_names) { |
| 150 MessageLoop::current()->PostTask( | 276 MessageLoop::current()->PostTask( |
| 151 FROM_HERE, | 277 FROM_HERE, |
| 152 Bind(&UnitTestLauncherDelegate::RunSerially, | 278 Bind(&UnitTestLauncherDelegate::RunSerially, |
| 153 Unretained(this), | 279 Unretained(this), |
| 154 test_launcher, | 280 test_launcher, |
| 155 test_names)); | 281 test_names)); |
| 156 return test_names.size(); | 282 return test_names.size(); |
| 157 } | 283 } |
| 158 | 284 |
| 159 void RunSerially(TestLauncher* test_launcher, | 285 void UnitTestLauncherDelegate::RunSerially( |
| 160 const std::vector<std::string>& test_names) { | 286 TestLauncher* test_launcher, |
| 287 const std::vector<std::string>& test_names) { |
| 161 if (test_names.empty()) | 288 if (test_names.empty()) |
| 162 return; | 289 return; |
| 163 | 290 |
| 164 std::vector<std::string> new_test_names(test_names); | 291 std::vector<std::string> new_test_names(test_names); |
| 165 std::string test_name(new_test_names.back()); | 292 std::string test_name(new_test_names.back()); |
| 166 new_test_names.pop_back(); | 293 new_test_names.pop_back(); |
| 167 | 294 |
| 168 // Create a dedicated temporary directory to store the xml result data | 295 // Create a dedicated temporary directory to store the xml result data |
| 169 // per run to ensure clean state and make it possible to launch multiple | 296 // per run to ensure clean state and make it possible to launch multiple |
| 170 // processes in parallel. | 297 // processes in parallel. |
| (...skipping 15 matching lines...) Expand all Loading... |
| 186 cmd_line, | 313 cmd_line, |
| 187 std::string(), | 314 std::string(), |
| 188 TestTimeouts::test_launcher_timeout(), | 315 TestTimeouts::test_launcher_timeout(), |
| 189 use_job_objects_ ? TestLauncher::USE_JOB_OBJECTS : 0, | 316 use_job_objects_ ? TestLauncher::USE_JOB_OBJECTS : 0, |
| 190 Bind(&UnitTestLauncherDelegate::SerialGTestCallback, | 317 Bind(&UnitTestLauncherDelegate::SerialGTestCallback, |
| 191 Unretained(this), | 318 Unretained(this), |
| 192 callback_state, | 319 callback_state, |
| 193 new_test_names)); | 320 new_test_names)); |
| 194 } | 321 } |
| 195 | 322 |
| 196 void RunBatch(TestLauncher* test_launcher, | 323 void UnitTestLauncherDelegate::RunBatch( |
| 197 const std::vector<std::string>& test_names) { | 324 TestLauncher* test_launcher, |
| 325 const std::vector<std::string>& test_names) { |
| 198 DCHECK(thread_checker_.CalledOnValidThread()); | 326 DCHECK(thread_checker_.CalledOnValidThread()); |
| 199 | 327 |
| 200 if (test_names.empty()) | 328 if (test_names.empty()) |
| 201 return; | 329 return; |
| 202 | 330 |
| 203 // Create a dedicated temporary directory to store the xml result data | 331 // Create a dedicated temporary directory to store the xml result data |
| 204 // per run to ensure clean state and make it possible to launch multiple | 332 // per run to ensure clean state and make it possible to launch multiple |
| 205 // processes in parallel. | 333 // processes in parallel. |
| 206 base::FilePath output_file; | 334 base::FilePath output_file; |
| 207 CHECK(CreateNewTempDirectory(FilePath::StringType(), &output_file)); | 335 CHECK(CreateNewTempDirectory(FilePath::StringType(), &output_file)); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 227 test_launcher->LaunchChildGTestProcess( | 355 test_launcher->LaunchChildGTestProcess( |
| 228 cmd_line, | 356 cmd_line, |
| 229 std::string(), | 357 std::string(), |
| 230 timeout, | 358 timeout, |
| 231 use_job_objects_ ? TestLauncher::USE_JOB_OBJECTS : 0, | 359 use_job_objects_ ? TestLauncher::USE_JOB_OBJECTS : 0, |
| 232 Bind(&UnitTestLauncherDelegate::GTestCallback, | 360 Bind(&UnitTestLauncherDelegate::GTestCallback, |
| 233 Unretained(this), | 361 Unretained(this), |
| 234 callback_state)); | 362 callback_state)); |
| 235 } | 363 } |
| 236 | 364 |
| 237 void GTestCallback(const GTestCallbackState& callback_state, | 365 void UnitTestLauncherDelegate::GTestCallback( |
| 238 int exit_code, | 366 const GTestCallbackState& callback_state, |
| 239 const TimeDelta& elapsed_time, | 367 int exit_code, |
| 240 bool was_timeout, | 368 const TimeDelta& elapsed_time, |
| 241 const std::string& output) { | 369 bool was_timeout, |
| 370 const std::string& output) { |
| 242 DCHECK(thread_checker_.CalledOnValidThread()); | 371 DCHECK(thread_checker_.CalledOnValidThread()); |
| 243 std::vector<std::string> tests_to_relaunch; | 372 std::vector<std::string> tests_to_relaunch; |
| 244 ProcessTestResults(callback_state.test_launcher, | 373 ProcessTestResults(callback_state.test_launcher, |
| 245 callback_state.test_names, | 374 callback_state.test_names, |
| 246 callback_state.output_file, | 375 callback_state.output_file, |
| 247 output, | 376 output, |
| 248 exit_code, | 377 exit_code, |
| 249 was_timeout, | 378 was_timeout, |
| 250 &tests_to_relaunch); | 379 &tests_to_relaunch); |
| 251 | 380 |
| 252 // Relaunch requested tests in parallel, but only use single | 381 // Relaunch requested tests in parallel, but only use single |
| 253 // test per batch for more precise results (crashes, test passes | 382 // test per batch for more precise results (crashes, test passes |
| 254 // but non-zero exit codes etc). | 383 // but non-zero exit codes etc). |
| 255 for (size_t i = 0; i < tests_to_relaunch.size(); i++) { | 384 for (size_t i = 0; i < tests_to_relaunch.size(); i++) { |
| 256 std::vector<std::string> batch; | 385 std::vector<std::string> batch; |
| 257 batch.push_back(tests_to_relaunch[i]); | 386 batch.push_back(tests_to_relaunch[i]); |
| 258 RunBatch(callback_state.test_launcher, batch); | 387 RunBatch(callback_state.test_launcher, batch); |
| 259 } | 388 } |
| 260 | 389 |
| 261 // The temporary file's directory is also temporary. | 390 // The temporary file's directory is also temporary. |
| 262 DeleteFile(callback_state.output_file.DirName(), true); | 391 DeleteFile(callback_state.output_file.DirName(), true); |
| 263 } | 392 } |
| 264 | 393 |
| 265 void SerialGTestCallback(const GTestCallbackState& callback_state, | 394 void UnitTestLauncherDelegate::SerialGTestCallback( |
| 266 const std::vector<std::string>& test_names, | 395 const GTestCallbackState& callback_state, |
| 267 int exit_code, | 396 const std::vector<std::string>& test_names, |
| 268 const TimeDelta& elapsed_time, | 397 int exit_code, |
| 269 bool was_timeout, | 398 const TimeDelta& elapsed_time, |
| 270 const std::string& output) { | 399 bool was_timeout, |
| 400 const std::string& output) { |
| 271 DCHECK(thread_checker_.CalledOnValidThread()); | 401 DCHECK(thread_checker_.CalledOnValidThread()); |
| 272 std::vector<std::string> tests_to_relaunch; | 402 std::vector<std::string> tests_to_relaunch; |
| 273 bool called_any_callbacks = | 403 bool called_any_callbacks = |
| 274 ProcessTestResults(callback_state.test_launcher, | 404 ProcessTestResults(callback_state.test_launcher, |
| 275 callback_state.test_names, | 405 callback_state.test_names, |
| 276 callback_state.output_file, | 406 callback_state.output_file, |
| 277 output, | 407 output, |
| 278 exit_code, | 408 exit_code, |
| 279 was_timeout, | 409 was_timeout, |
| 280 &tests_to_relaunch); | 410 &tests_to_relaunch); |
| 281 | 411 |
| 282 // There is only one test, there cannot be other tests to relaunch | 412 // There is only one test, there cannot be other tests to relaunch |
| 283 // due to a crash. | 413 // due to a crash. |
| 284 DCHECK(tests_to_relaunch.empty()); | 414 DCHECK(tests_to_relaunch.empty()); |
| 285 | 415 |
| 286 // There is only one test, we should have called back with its result. | 416 // There is only one test, we should have called back with its result. |
| 287 DCHECK(called_any_callbacks); | 417 DCHECK(called_any_callbacks); |
| 288 | 418 |
| 289 // The temporary file's directory is also temporary. | 419 // The temporary file's directory is also temporary. |
| 290 DeleteFile(callback_state.output_file.DirName(), true); | 420 DeleteFile(callback_state.output_file.DirName(), true); |
| 291 | 421 |
| 292 MessageLoop::current()->PostTask( | 422 MessageLoop::current()->PostTask( |
| 293 FROM_HERE, | 423 FROM_HERE, |
| 294 Bind(&UnitTestLauncherDelegate::RunSerially, | 424 Bind(&UnitTestLauncherDelegate::RunSerially, |
| 295 Unretained(this), | 425 Unretained(this), |
| 296 callback_state.test_launcher, | 426 callback_state.test_launcher, |
| 297 test_names)); | 427 test_names)); |
| 298 } | 428 } |
| 299 | 429 |
| 300 static bool ProcessTestResults( | 430 // static |
| 431 bool UnitTestLauncherDelegate::ProcessTestResults( |
| 301 TestLauncher* test_launcher, | 432 TestLauncher* test_launcher, |
| 302 const std::vector<std::string>& test_names, | 433 const std::vector<std::string>& test_names, |
| 303 const base::FilePath& output_file, | 434 const base::FilePath& output_file, |
| 304 const std::string& output, | 435 const std::string& output, |
| 305 int exit_code, | 436 int exit_code, |
| 306 bool was_timeout, | 437 bool was_timeout, |
| 307 std::vector<std::string>* tests_to_relaunch) { | 438 std::vector<std::string>* tests_to_relaunch) { |
| 308 std::vector<TestResult> test_results; | 439 std::vector<TestResult> test_results; |
| 309 bool crashed = false; | 440 bool crashed = false; |
| 310 bool have_test_results = | 441 bool have_test_results = |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 427 test_result.full_name = test_names[i]; | 558 test_result.full_name = test_names[i]; |
| 428 test_result.status = TestResult::TEST_UNKNOWN; | 559 test_result.status = TestResult::TEST_UNKNOWN; |
| 429 test_launcher->OnTestFinished(test_result); | 560 test_launcher->OnTestFinished(test_result); |
| 430 called_any_callback = true; | 561 called_any_callback = true; |
| 431 } | 562 } |
| 432 } | 563 } |
| 433 | 564 |
| 434 return called_any_callback; | 565 return called_any_callback; |
| 435 } | 566 } |
| 436 | 567 |
| 437 ThreadChecker thread_checker_; | |
| 438 | |
| 439 // Maximum number of tests to run in a single batch. | |
| 440 size_t batch_limit_; | |
| 441 | |
| 442 // Determines whether we use job objects on Windows. | |
| 443 bool use_job_objects_; | |
| 444 }; | |
| 445 | |
| 446 bool GetSwitchValueAsInt(const std::string& switch_name, int* result) { | |
| 447 if (!CommandLine::ForCurrentProcess()->HasSwitch(switch_name)) | |
| 448 return true; | |
| 449 | |
| 450 std::string switch_value = | |
| 451 CommandLine::ForCurrentProcess()->GetSwitchValueASCII(switch_name); | |
| 452 if (!StringToInt(switch_value, result) || *result < 1) { | |
| 453 LOG(ERROR) << "Invalid value for " << switch_name << ": " << switch_value; | |
| 454 return false; | |
| 455 } | |
| 456 | |
| 457 return true; | |
| 458 } | |
| 459 | |
| 460 int LaunchUnitTestsInternal(const RunTestSuiteCallback& run_test_suite, | |
| 461 int default_jobs, | |
| 462 bool use_job_objects, | |
| 463 const Closure& gtest_init) { | |
| 464 #if defined(OS_ANDROID) | |
| 465 // We can't easily fork on Android, just run the test suite directly. | |
| 466 return run_test_suite.Run(); | |
| 467 #else | |
| 468 bool force_single_process = false; | |
| 469 if (CommandLine::ForCurrentProcess()->HasSwitch( | |
| 470 switches::kTestLauncherDebugLauncher)) { | |
| 471 fprintf(stdout, "Forcing test launcher debugging mode.\n"); | |
| 472 fflush(stdout); | |
| 473 } else { | |
| 474 if (base::debug::BeingDebugged()) { | |
| 475 fprintf(stdout, | |
| 476 "Debugger detected, switching to single process mode.\n" | |
| 477 "Pass --test-launcher-debug-launcher to debug the launcher " | |
| 478 "itself.\n"); | |
| 479 fflush(stdout); | |
| 480 force_single_process = true; | |
| 481 } | |
| 482 } | |
| 483 | |
| 484 if (CommandLine::ForCurrentProcess()->HasSwitch(kGTestHelpFlag) || | |
| 485 CommandLine::ForCurrentProcess()->HasSwitch(kGTestListTestsFlag) || | |
| 486 CommandLine::ForCurrentProcess()->HasSwitch(kSingleProcessTestsFlag) || | |
| 487 force_single_process) { | |
| 488 return run_test_suite.Run(); | |
| 489 } | |
| 490 #endif | |
| 491 | |
| 492 if (CommandLine::ForCurrentProcess()->HasSwitch(kHelpFlag)) { | |
| 493 PrintUsage(); | |
| 494 return 0; | |
| 495 } | |
| 496 | |
| 497 base::TimeTicks start_time(base::TimeTicks::Now()); | |
| 498 | |
| 499 gtest_init.Run(); | |
| 500 TestTimeouts::Initialize(); | |
| 501 | |
| 502 int batch_limit = kDefaultTestBatchLimit; | |
| 503 if (!GetSwitchValueAsInt(switches::kTestLauncherBatchLimit, &batch_limit)) | |
| 504 return 1; | |
| 505 | |
| 506 fprintf(stdout, | |
| 507 "IMPORTANT DEBUGGING NOTE: batches of tests are run inside their\n" | |
| 508 "own process. For debugging a test inside a debugger, use the\n" | |
| 509 "--gtest_filter=<your_test_name> flag along with\n" | |
| 510 "--single-process-tests.\n"); | |
| 511 fflush(stdout); | |
| 512 | |
| 513 MessageLoopForIO message_loop; | |
| 514 | |
| 515 UnitTestLauncherDelegate delegate(batch_limit, use_job_objects); | |
| 516 base::TestLauncher launcher(&delegate, default_jobs); | |
| 517 bool success = launcher.Run(); | |
| 518 | |
| 519 fprintf(stdout, | |
| 520 "Tests took %" PRId64 " seconds.\n", | |
| 521 (base::TimeTicks::Now() - start_time).InSeconds()); | |
| 522 fflush(stdout); | |
| 523 | |
| 524 return (success ? 0 : 1); | |
| 525 } | |
| 526 | |
| 527 void InitGoogleTestChar(int* argc, char** argv) { | |
| 528 testing::InitGoogleTest(argc, argv); | |
| 529 } | |
| 530 | |
| 531 #if defined(OS_WIN) | |
| 532 void InitGoogleTestWChar(int* argc, wchar_t** argv) { | |
| 533 testing::InitGoogleTest(argc, argv); | |
| 534 } | |
| 535 #endif // defined(OS_WIN) | |
| 536 | |
| 537 } // namespace | |
| 538 | |
| 539 int LaunchUnitTests(int argc, | |
| 540 char** argv, | |
| 541 const RunTestSuiteCallback& run_test_suite) { | |
| 542 CommandLine::Init(argc, argv); | |
| 543 return LaunchUnitTestsInternal( | |
| 544 run_test_suite, | |
| 545 SysInfo::NumberOfProcessors(), | |
| 546 true, | |
| 547 Bind(&InitGoogleTestChar, &argc, argv)); | |
| 548 } | |
| 549 | |
| 550 int LaunchUnitTestsSerially(int argc, | |
| 551 char** argv, | |
| 552 const RunTestSuiteCallback& run_test_suite) { | |
| 553 CommandLine::Init(argc, argv); | |
| 554 return LaunchUnitTestsInternal( | |
| 555 run_test_suite, | |
| 556 1, | |
| 557 true, | |
| 558 Bind(&InitGoogleTestChar, &argc, argv)); | |
| 559 } | |
| 560 | |
| 561 #if defined(OS_WIN) | |
| 562 int LaunchUnitTests(int argc, | |
| 563 wchar_t** argv, | |
| 564 bool use_job_objects, | |
| 565 const RunTestSuiteCallback& run_test_suite) { | |
| 566 // Windows CommandLine::Init ignores argv anyway. | |
| 567 CommandLine::Init(argc, NULL); | |
| 568 return LaunchUnitTestsInternal( | |
| 569 run_test_suite, | |
| 570 SysInfo::NumberOfProcessors(), | |
| 571 use_job_objects, | |
| 572 Bind(&InitGoogleTestWChar, &argc, argv)); | |
| 573 } | |
| 574 #endif // defined(OS_WIN) | |
| 575 | |
| 576 } // namespace base | 568 } // namespace base |
| OLD | NEW |