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 |