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/test_launcher.h" | 5 #include "base/test/launcher/test_launcher.h" |
6 | 6 |
7 #if defined(OS_POSIX) | 7 #if defined(OS_POSIX) |
8 #include <fcntl.h> | 8 #include <fcntl.h> |
9 #endif | 9 #endif |
10 | 10 |
11 #include "base/at_exit.h" | 11 #include "base/at_exit.h" |
12 #include "base/bind.h" | 12 #include "base/bind.h" |
13 #include "base/command_line.h" | 13 #include "base/command_line.h" |
14 #include "base/environment.h" | 14 #include "base/environment.h" |
15 #include "base/files/file_path.h" | 15 #include "base/files/file_path.h" |
16 #include "base/files/file_util.h" | 16 #include "base/files/file_util.h" |
17 #include "base/files/scoped_file.h" | 17 #include "base/files/scoped_file.h" |
18 #include "base/format_macros.h" | 18 #include "base/format_macros.h" |
19 #include "base/hash.h" | 19 #include "base/hash.h" |
20 #include "base/lazy_instance.h" | 20 #include "base/lazy_instance.h" |
21 #include "base/location.h" | |
21 #include "base/logging.h" | 22 #include "base/logging.h" |
22 #include "base/memory/scoped_ptr.h" | 23 #include "base/memory/scoped_ptr.h" |
23 #include "base/message_loop/message_loop.h" | 24 #include "base/message_loop/message_loop.h" |
24 #include "base/process/kill.h" | 25 #include "base/process/kill.h" |
25 #include "base/process/launch.h" | 26 #include "base/process/launch.h" |
27 #include "base/single_thread_task_runner.h" | |
26 #include "base/strings/string_number_conversions.h" | 28 #include "base/strings/string_number_conversions.h" |
27 #include "base/strings/string_split.h" | 29 #include "base/strings/string_split.h" |
28 #include "base/strings/string_util.h" | 30 #include "base/strings/string_util.h" |
29 #include "base/strings/stringize_macros.h" | 31 #include "base/strings/stringize_macros.h" |
30 #include "base/strings/stringprintf.h" | 32 #include "base/strings/stringprintf.h" |
31 #include "base/strings/utf_string_conversions.h" | 33 #include "base/strings/utf_string_conversions.h" |
32 #include "base/test/gtest_util.h" | 34 #include "base/test/gtest_util.h" |
33 #include "base/test/launcher/test_results_tracker.h" | 35 #include "base/test/launcher/test_results_tracker.h" |
34 #include "base/test/sequenced_worker_pool_owner.h" | 36 #include "base/test/sequenced_worker_pool_owner.h" |
35 #include "base/test/test_switches.h" | 37 #include "base/test/test_switches.h" |
36 #include "base/test/test_timeouts.h" | 38 #include "base/test/test_timeouts.h" |
39 #include "base/thread_task_runner_handle.h" | |
37 #include "base/threading/thread_checker.h" | 40 #include "base/threading/thread_checker.h" |
38 #include "base/time/time.h" | 41 #include "base/time/time.h" |
39 #include "testing/gtest/include/gtest/gtest.h" | 42 #include "testing/gtest/include/gtest/gtest.h" |
40 | 43 |
41 #if defined(OS_MACOSX) | 44 #if defined(OS_MACOSX) |
42 #include "base/mac/scoped_nsautorelease_pool.h" | 45 #include "base/mac/scoped_nsautorelease_pool.h" |
43 #endif | 46 #endif |
44 | 47 |
45 #if defined(OS_WIN) | 48 #if defined(OS_WIN) |
46 #include "base/win/windows_version.h" | 49 #include "base/win/windows_version.h" |
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
342 bool was_timeout, | 345 bool was_timeout, |
343 const std::string& output) { | 346 const std::string& output) { |
344 callback.Run(exit_code, elapsed_time, was_timeout, output); | 347 callback.Run(exit_code, elapsed_time, was_timeout, output); |
345 } | 348 } |
346 | 349 |
347 void DoLaunchChildTestProcess( | 350 void DoLaunchChildTestProcess( |
348 const CommandLine& command_line, | 351 const CommandLine& command_line, |
349 TimeDelta timeout, | 352 TimeDelta timeout, |
350 int flags, | 353 int flags, |
351 bool redirect_stdio, | 354 bool redirect_stdio, |
352 scoped_refptr<MessageLoopProxy> message_loop_proxy, | 355 scoped_refptr<SingleThreadTaskRunner> task_runner, |
danakj
2015/04/21 20:16:30
nit: can you change this to a STTR*? It doesn't wa
Sami
2015/04/23 17:48:25
Sure, done.
| |
353 const TestLauncher::LaunchChildGTestProcessCallback& callback) { | 356 const TestLauncher::LaunchChildGTestProcessCallback& callback) { |
354 TimeTicks start_time = TimeTicks::Now(); | 357 TimeTicks start_time = TimeTicks::Now(); |
355 | 358 |
356 // Redirect child process output to a file. | 359 // Redirect child process output to a file. |
357 FilePath output_file; | 360 FilePath output_file; |
358 CHECK(CreateTemporaryFile(&output_file)); | 361 CHECK(CreateTemporaryFile(&output_file)); |
359 | 362 |
360 LaunchOptions options; | 363 LaunchOptions options; |
361 #if defined(OS_WIN) | 364 #if defined(OS_WIN) |
362 win::ScopedHandle handle; | 365 win::ScopedHandle handle; |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
416 std::string output_file_contents; | 419 std::string output_file_contents; |
417 CHECK(ReadFileToString(output_file, &output_file_contents)); | 420 CHECK(ReadFileToString(output_file, &output_file_contents)); |
418 | 421 |
419 if (!DeleteFile(output_file, false)) { | 422 if (!DeleteFile(output_file, false)) { |
420 // This needs to be non-fatal at least for Windows. | 423 // This needs to be non-fatal at least for Windows. |
421 LOG(WARNING) << "Failed to delete " << output_file.AsUTF8Unsafe(); | 424 LOG(WARNING) << "Failed to delete " << output_file.AsUTF8Unsafe(); |
422 } | 425 } |
423 | 426 |
424 // Run target callback on the thread it was originating from, not on | 427 // Run target callback on the thread it was originating from, not on |
425 // a worker pool thread. | 428 // a worker pool thread. |
426 message_loop_proxy->PostTask( | 429 task_runner->PostTask(FROM_HERE, Bind(&RunCallback, callback, exit_code, |
427 FROM_HERE, | 430 TimeTicks::Now() - start_time, |
428 Bind(&RunCallback, | 431 was_timeout, output_file_contents)); |
429 callback, | |
430 exit_code, | |
431 TimeTicks::Now() - start_time, | |
432 was_timeout, | |
433 output_file_contents)); | |
434 } | 432 } |
435 | 433 |
436 } // namespace | 434 } // namespace |
437 | 435 |
438 const char kGTestFilterFlag[] = "gtest_filter"; | 436 const char kGTestFilterFlag[] = "gtest_filter"; |
439 const char kGTestHelpFlag[] = "gtest_help"; | 437 const char kGTestHelpFlag[] = "gtest_help"; |
440 const char kGTestListTestsFlag[] = "gtest_list_tests"; | 438 const char kGTestListTestsFlag[] = "gtest_list_tests"; |
441 const char kGTestRepeatFlag[] = "gtest_repeat"; | 439 const char kGTestRepeatFlag[] = "gtest_repeat"; |
442 const char kGTestRunDisabledTestsFlag[] = "gtest_also_run_disabled_tests"; | 440 const char kGTestRunDisabledTestsFlag[] = "gtest_also_run_disabled_tests"; |
443 const char kGTestOutputFlag[] = "gtest_output"; | 441 const char kGTestOutputFlag[] = "gtest_output"; |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
497 g_shutdown_pipe[0], | 495 g_shutdown_pipe[0], |
498 true, | 496 true, |
499 MessageLoopForIO::WATCH_READ, | 497 MessageLoopForIO::WATCH_READ, |
500 &controller, | 498 &controller, |
501 &watcher)); | 499 &watcher)); |
502 #endif // defined(OS_POSIX) | 500 #endif // defined(OS_POSIX) |
503 | 501 |
504 // Start the watchdog timer. | 502 // Start the watchdog timer. |
505 watchdog_timer_.Reset(); | 503 watchdog_timer_.Reset(); |
506 | 504 |
507 MessageLoop::current()->PostTask( | 505 ThreadTaskRunnerHandle::Get()->PostTask( |
508 FROM_HERE, | 506 FROM_HERE, Bind(&TestLauncher::RunTestIteration, Unretained(this))); |
509 Bind(&TestLauncher::RunTestIteration, Unretained(this))); | |
510 | 507 |
511 MessageLoop::current()->Run(); | 508 MessageLoop::current()->Run(); |
512 | 509 |
513 if (requested_cycles != 1) | 510 if (requested_cycles != 1) |
514 results_tracker_.PrintSummaryOfAllIterations(); | 511 results_tracker_.PrintSummaryOfAllIterations(); |
515 | 512 |
516 MaybeSaveSummaryAsJSON(); | 513 MaybeSaveSummaryAsJSON(); |
517 | 514 |
518 return run_result_; | 515 return run_result_; |
519 } | 516 } |
520 | 517 |
521 void TestLauncher::LaunchChildGTestProcess( | 518 void TestLauncher::LaunchChildGTestProcess( |
522 const CommandLine& command_line, | 519 const CommandLine& command_line, |
523 const std::string& wrapper, | 520 const std::string& wrapper, |
524 TimeDelta timeout, | 521 TimeDelta timeout, |
525 int flags, | 522 int flags, |
526 const LaunchChildGTestProcessCallback& callback) { | 523 const LaunchChildGTestProcessCallback& callback) { |
527 DCHECK(thread_checker_.CalledOnValidThread()); | 524 DCHECK(thread_checker_.CalledOnValidThread()); |
528 | 525 |
529 // Record the exact command line used to launch the child. | 526 // Record the exact command line used to launch the child. |
530 CommandLine new_command_line( | 527 CommandLine new_command_line( |
531 PrepareCommandLineForGTest(command_line, wrapper)); | 528 PrepareCommandLineForGTest(command_line, wrapper)); |
532 | 529 |
533 // When running in parallel mode we need to redirect stdio to avoid mixed-up | 530 // When running in parallel mode we need to redirect stdio to avoid mixed-up |
534 // output. We also always redirect on the bots to get the test output into | 531 // output. We also always redirect on the bots to get the test output into |
535 // JSON summary. | 532 // JSON summary. |
536 bool redirect_stdio = (parallel_jobs_ > 1) || BotModeEnabled(); | 533 bool redirect_stdio = (parallel_jobs_ > 1) || BotModeEnabled(); |
537 | 534 |
538 worker_pool_owner_->pool()->PostWorkerTask( | 535 worker_pool_owner_->pool()->PostWorkerTask( |
539 FROM_HERE, | 536 FROM_HERE, Bind(&DoLaunchChildTestProcess, new_command_line, timeout, |
540 Bind(&DoLaunchChildTestProcess, | 537 flags, redirect_stdio, ThreadTaskRunnerHandle::Get(), |
541 new_command_line, | 538 Bind(&TestLauncher::OnLaunchTestProcessFinished, |
542 timeout, | 539 Unretained(this), callback))); |
543 flags, | |
544 redirect_stdio, | |
545 MessageLoopProxy::current(), | |
546 Bind(&TestLauncher::OnLaunchTestProcessFinished, | |
547 Unretained(this), | |
548 callback))); | |
549 } | 540 } |
550 | 541 |
551 void TestLauncher::OnTestFinished(const TestResult& result) { | 542 void TestLauncher::OnTestFinished(const TestResult& result) { |
552 ++test_finished_count_; | 543 ++test_finished_count_; |
553 | 544 |
554 bool print_snippet = false; | 545 bool print_snippet = false; |
555 std::string print_test_stdio("auto"); | 546 std::string print_test_stdio("auto"); |
556 if (CommandLine::ForCurrentProcess()->HasSwitch( | 547 if (CommandLine::ForCurrentProcess()->HasSwitch( |
557 switches::kTestLauncherPrintTestStdio)) { | 548 switches::kTestLauncherPrintTestStdio)) { |
558 print_test_stdio = CommandLine::ForCurrentProcess()->GetSwitchValueASCII( | 549 print_test_stdio = CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
(...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
950 test_names.push_back(test_name); | 941 test_names.push_back(test_name); |
951 } | 942 } |
952 | 943 |
953 test_started_count_ = launcher_delegate_->RunTests(this, test_names); | 944 test_started_count_ = launcher_delegate_->RunTests(this, test_names); |
954 | 945 |
955 if (test_started_count_ == 0) { | 946 if (test_started_count_ == 0) { |
956 fprintf(stdout, "0 tests run\n"); | 947 fprintf(stdout, "0 tests run\n"); |
957 fflush(stdout); | 948 fflush(stdout); |
958 | 949 |
959 // No tests have actually been started, so kick off the next iteration. | 950 // No tests have actually been started, so kick off the next iteration. |
960 MessageLoop::current()->PostTask( | 951 ThreadTaskRunnerHandle::Get()->PostTask( |
961 FROM_HERE, | 952 FROM_HERE, Bind(&TestLauncher::RunTestIteration, Unretained(this))); |
962 Bind(&TestLauncher::RunTestIteration, Unretained(this))); | |
963 } | 953 } |
964 } | 954 } |
965 | 955 |
966 void TestLauncher::RunTestIteration() { | 956 void TestLauncher::RunTestIteration() { |
967 if (cycles_ == 0) { | 957 if (cycles_ == 0) { |
968 MessageLoop::current()->Quit(); | 958 MessageLoop::current()->Quit(); |
969 return; | 959 return; |
970 } | 960 } |
971 | 961 |
972 // Special value "-1" means "repeat indefinitely". | 962 // Special value "-1" means "repeat indefinitely". |
973 cycles_ = (cycles_ == -1) ? cycles_ : cycles_ - 1; | 963 cycles_ = (cycles_ == -1) ? cycles_ : cycles_ - 1; |
974 | 964 |
975 test_started_count_ = 0; | 965 test_started_count_ = 0; |
976 test_finished_count_ = 0; | 966 test_finished_count_ = 0; |
977 test_success_count_ = 0; | 967 test_success_count_ = 0; |
978 test_broken_count_ = 0; | 968 test_broken_count_ = 0; |
979 retry_count_ = 0; | 969 retry_count_ = 0; |
980 tests_to_retry_.clear(); | 970 tests_to_retry_.clear(); |
981 results_tracker_.OnTestIterationStarting(); | 971 results_tracker_.OnTestIterationStarting(); |
982 | 972 |
983 MessageLoop::current()->PostTask( | 973 ThreadTaskRunnerHandle::Get()->PostTask( |
984 FROM_HERE, Bind(&TestLauncher::RunTests, Unretained(this))); | 974 FROM_HERE, Bind(&TestLauncher::RunTests, Unretained(this))); |
985 } | 975 } |
986 | 976 |
987 void TestLauncher::MaybeSaveSummaryAsJSON() { | 977 void TestLauncher::MaybeSaveSummaryAsJSON() { |
988 const CommandLine* command_line = CommandLine::ForCurrentProcess(); | 978 const CommandLine* command_line = CommandLine::ForCurrentProcess(); |
989 if (command_line->HasSwitch(switches::kTestLauncherSummaryOutput)) { | 979 if (command_line->HasSwitch(switches::kTestLauncherSummaryOutput)) { |
990 FilePath summary_path(command_line->GetSwitchValuePath( | 980 FilePath summary_path(command_line->GetSwitchValuePath( |
991 switches::kTestLauncherSummaryOutput)); | 981 switches::kTestLauncherSummaryOutput)); |
992 if (!results_tracker_.SaveSummaryAsJSON(summary_path)) { | 982 if (!results_tracker_.SaveSummaryAsJSON(summary_path)) { |
993 LOG(ERROR) << "Failed to save test launcher output summary."; | 983 LOG(ERROR) << "Failed to save test launcher output summary."; |
(...skipping 26 matching lines...) Expand all Loading... | |
1020 fflush(stdout); | 1010 fflush(stdout); |
1021 } else { | 1011 } else { |
1022 // Signal failure, but continue to run all requested test iterations. | 1012 // Signal failure, but continue to run all requested test iterations. |
1023 // With the summary of all iterations at the end this is a good default. | 1013 // With the summary of all iterations at the end this is a good default. |
1024 run_result_ = false; | 1014 run_result_ = false; |
1025 } | 1015 } |
1026 | 1016 |
1027 results_tracker_.PrintSummaryOfCurrentIteration(); | 1017 results_tracker_.PrintSummaryOfCurrentIteration(); |
1028 | 1018 |
1029 // Kick off the next iteration. | 1019 // Kick off the next iteration. |
1030 MessageLoop::current()->PostTask( | 1020 ThreadTaskRunnerHandle::Get()->PostTask( |
1031 FROM_HERE, | 1021 FROM_HERE, Bind(&TestLauncher::RunTestIteration, Unretained(this))); |
1032 Bind(&TestLauncher::RunTestIteration, Unretained(this))); | |
1033 } | 1022 } |
1034 | 1023 |
1035 void TestLauncher::OnOutputTimeout() { | 1024 void TestLauncher::OnOutputTimeout() { |
1036 DCHECK(thread_checker_.CalledOnValidThread()); | 1025 DCHECK(thread_checker_.CalledOnValidThread()); |
1037 | 1026 |
1038 AutoLock lock(g_live_processes_lock.Get()); | 1027 AutoLock lock(g_live_processes_lock.Get()); |
1039 | 1028 |
1040 fprintf(stdout, "Still waiting for the following processes to finish:\n"); | 1029 fprintf(stdout, "Still waiting for the following processes to finish:\n"); |
1041 | 1030 |
1042 for (std::map<ProcessHandle, CommandLine>::iterator i = | 1031 for (std::map<ProcessHandle, CommandLine>::iterator i = |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1081 } | 1070 } |
1082 | 1071 |
1083 std::string snippet(full_output.substr(run_pos)); | 1072 std::string snippet(full_output.substr(run_pos)); |
1084 if (end_pos != std::string::npos) | 1073 if (end_pos != std::string::npos) |
1085 snippet = full_output.substr(run_pos, end_pos - run_pos); | 1074 snippet = full_output.substr(run_pos, end_pos - run_pos); |
1086 | 1075 |
1087 return snippet; | 1076 return snippet; |
1088 } | 1077 } |
1089 | 1078 |
1090 } // namespace base | 1079 } // namespace base |
OLD | NEW |