| 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 #include <memory> | 7 #include <memory> |
| 8 | 8 |
| 9 #include "base/at_exit.h" | 9 #include "base/at_exit.h" |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 385 const TestLauncher::GTestProcessCompletedCallback& completed_callback, | 385 const TestLauncher::GTestProcessCompletedCallback& completed_callback, |
| 386 const TestLauncher::GTestProcessLaunchedCallback& launched_callback) { | 386 const TestLauncher::GTestProcessLaunchedCallback& launched_callback) { |
| 387 TimeTicks start_time = TimeTicks::Now(); | 387 TimeTicks start_time = TimeTicks::Now(); |
| 388 | 388 |
| 389 // Redirect child process output to a file. | 389 // Redirect child process output to a file. |
| 390 FilePath output_file; | 390 FilePath output_file; |
| 391 CHECK(CreateTemporaryFile(&output_file)); | 391 CHECK(CreateTemporaryFile(&output_file)); |
| 392 | 392 |
| 393 LaunchOptions options; | 393 LaunchOptions options; |
| 394 #if defined(OS_WIN) | 394 #if defined(OS_WIN) |
| 395 options.inherit_mode = test_launch_options.inherit_mode; |
| 396 options.handles_to_inherit = test_launch_options.handles_to_inherit; |
| 397 |
| 395 win::ScopedHandle handle; | 398 win::ScopedHandle handle; |
| 396 | 399 |
| 397 if (redirect_stdio) { | 400 if (redirect_stdio) { |
| 398 handle.Set(CreateFile(output_file.value().c_str(), GENERIC_WRITE, | 401 handle.Set(CreateFile(output_file.value().c_str(), GENERIC_WRITE, |
| 399 FILE_SHARE_READ | FILE_SHARE_DELETE, nullptr, | 402 FILE_SHARE_READ | FILE_SHARE_DELETE, nullptr, |
| 400 OPEN_EXISTING, FILE_ATTRIBUTE_TEMPORARY, NULL)); | 403 OPEN_EXISTING, FILE_ATTRIBUTE_TEMPORARY, NULL)); |
| 401 CHECK(handle.IsValid()); | 404 CHECK(handle.IsValid()); |
| 402 options.inherit_handles = true; | |
| 403 options.stdin_handle = INVALID_HANDLE_VALUE; | 405 options.stdin_handle = INVALID_HANDLE_VALUE; |
| 404 options.stdout_handle = handle.Get(); | 406 options.stdout_handle = handle.Get(); |
| 405 options.stderr_handle = handle.Get(); | 407 options.stderr_handle = handle.Get(); |
| 406 } | 408 // See LaunchOptions.stdout_handle comments for why this compares against |
| 407 | 409 // FILE_TYPE_CHAR. |
| 408 if (test_launch_options.inherit_handles) { | 410 if (options.inherit_mode == base::LaunchOptions::Inherit::kSpecific && |
| 409 if (!options.inherit_handles) { | 411 GetFileType(handle.Get()) != FILE_TYPE_CHAR) |
| 410 options.inherit_handles = true; | 412 options.handles_to_inherit.push_back(handle.Get()); |
| 411 options.stdin_handle = nullptr; | |
| 412 options.stdout_handle = nullptr; | |
| 413 options.stderr_handle = nullptr; | |
| 414 } | |
| 415 DCHECK(!options.handles_to_inherit); | |
| 416 options.handles_to_inherit = test_launch_options.handles_to_inherit; | |
| 417 } | 413 } |
| 418 | 414 |
| 419 #elif defined(OS_POSIX) | 415 #elif defined(OS_POSIX) |
| 420 options.new_process_group = true; | 416 options.new_process_group = true; |
| 421 #if defined(OS_LINUX) | 417 #if defined(OS_LINUX) |
| 422 options.kill_on_parent_death = true; | 418 options.kill_on_parent_death = true; |
| 423 #endif // defined(OS_LINUX) | 419 #endif // defined(OS_LINUX) |
| 424 | 420 |
| 425 FileHandleMappingVector fds_mapping; | |
| 426 ScopedFD output_file_fd; | 421 ScopedFD output_file_fd; |
| 427 | 422 |
| 423 options.fds_to_remap = test_launch_options.fds_to_remap; |
| 428 if (redirect_stdio) { | 424 if (redirect_stdio) { |
| 429 output_file_fd.reset(open(output_file.value().c_str(), O_RDWR)); | 425 output_file_fd.reset(open(output_file.value().c_str(), O_RDWR)); |
| 430 CHECK(output_file_fd.is_valid()); | 426 CHECK(output_file_fd.is_valid()); |
| 431 | 427 |
| 432 fds_mapping.push_back(std::make_pair(output_file_fd.get(), STDOUT_FILENO)); | 428 options.fds_to_remap.push_back( |
| 433 fds_mapping.push_back(std::make_pair(output_file_fd.get(), STDERR_FILENO)); | 429 std::make_pair(output_file_fd.get(), STDOUT_FILENO)); |
| 434 options.fds_to_remap = &fds_mapping; | 430 options.fds_to_remap.push_back( |
| 435 } | 431 std::make_pair(output_file_fd.get(), STDERR_FILENO)); |
| 436 if (test_launch_options.fds_to_remap) { | |
| 437 fds_mapping.insert(fds_mapping.end(), | |
| 438 test_launch_options.fds_to_remap->begin(), | |
| 439 test_launch_options.fds_to_remap->end()); | |
| 440 options.fds_to_remap = &fds_mapping; | |
| 441 } | 432 } |
| 442 #endif | 433 #endif |
| 443 | 434 |
| 444 bool was_timeout = false; | 435 bool was_timeout = false; |
| 445 int exit_code = LaunchChildTestProcessWithOptions( | 436 int exit_code = LaunchChildTestProcessWithOptions( |
| 446 command_line, options, test_launch_options.flags, timeout, | 437 command_line, options, test_launch_options.flags, timeout, |
| 447 launched_callback, &was_timeout); | 438 launched_callback, &was_timeout); |
| 448 | 439 |
| 449 if (redirect_stdio) { | 440 if (redirect_stdio) { |
| 450 #if defined(OS_WIN) | 441 #if defined(OS_WIN) |
| (...skipping 26 matching lines...) Expand all Loading... |
| 477 const char kGTestFilterFlag[] = "gtest_filter"; | 468 const char kGTestFilterFlag[] = "gtest_filter"; |
| 478 const char kGTestFlagfileFlag[] = "gtest_flagfile"; | 469 const char kGTestFlagfileFlag[] = "gtest_flagfile"; |
| 479 const char kGTestHelpFlag[] = "gtest_help"; | 470 const char kGTestHelpFlag[] = "gtest_help"; |
| 480 const char kGTestListTestsFlag[] = "gtest_list_tests"; | 471 const char kGTestListTestsFlag[] = "gtest_list_tests"; |
| 481 const char kGTestRepeatFlag[] = "gtest_repeat"; | 472 const char kGTestRepeatFlag[] = "gtest_repeat"; |
| 482 const char kGTestRunDisabledTestsFlag[] = "gtest_also_run_disabled_tests"; | 473 const char kGTestRunDisabledTestsFlag[] = "gtest_also_run_disabled_tests"; |
| 483 const char kGTestOutputFlag[] = "gtest_output"; | 474 const char kGTestOutputFlag[] = "gtest_output"; |
| 484 | 475 |
| 485 TestLauncherDelegate::~TestLauncherDelegate() {} | 476 TestLauncherDelegate::~TestLauncherDelegate() {} |
| 486 | 477 |
| 478 TestLauncher::LaunchOptions::LaunchOptions() = default; |
| 479 TestLauncher::LaunchOptions::LaunchOptions(const LaunchOptions& other) = |
| 480 default; |
| 481 TestLauncher::LaunchOptions::~LaunchOptions() = default; |
| 482 |
| 487 TestLauncher::TestLauncher(TestLauncherDelegate* launcher_delegate, | 483 TestLauncher::TestLauncher(TestLauncherDelegate* launcher_delegate, |
| 488 size_t parallel_jobs) | 484 size_t parallel_jobs) |
| 489 : launcher_delegate_(launcher_delegate), | 485 : launcher_delegate_(launcher_delegate), |
| 490 total_shards_(1), | 486 total_shards_(1), |
| 491 shard_index_(0), | 487 shard_index_(0), |
| 492 cycles_(1), | 488 cycles_(1), |
| 493 test_found_count_(0), | 489 test_found_count_(0), |
| 494 test_started_count_(0), | 490 test_started_count_(0), |
| 495 test_finished_count_(0), | 491 test_finished_count_(0), |
| 496 test_success_count_(0), | 492 test_success_count_(0), |
| (...skipping 738 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1235 } | 1231 } |
| 1236 | 1232 |
| 1237 std::string snippet(full_output.substr(run_pos)); | 1233 std::string snippet(full_output.substr(run_pos)); |
| 1238 if (end_pos != std::string::npos) | 1234 if (end_pos != std::string::npos) |
| 1239 snippet = full_output.substr(run_pos, end_pos - run_pos); | 1235 snippet = full_output.substr(run_pos, end_pos - run_pos); |
| 1240 | 1236 |
| 1241 return snippet; | 1237 return snippet; |
| 1242 } | 1238 } |
| 1243 | 1239 |
| 1244 } // namespace base | 1240 } // namespace base |
| OLD | NEW |