| 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 |