Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 #define _CRT_SECURE_NO_WARNINGS | 5 #define _CRT_SECURE_NO_WARNINGS |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <limits> | 10 #include <limits> |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 125 base::PlatformThread::Sleep(kInterval); | 125 base::PlatformThread::Sleep(kInterval); |
| 126 waited += kInterval; | 126 waited += kInterval; |
| 127 } while (status == base::TERMINATION_STATUS_STILL_RUNNING && | 127 } while (status == base::TERMINATION_STATUS_STILL_RUNNING && |
| 128 waited < TestTimeouts::action_max_timeout()); | 128 waited < TestTimeouts::action_max_timeout()); |
| 129 | 129 |
| 130 return status; | 130 return status; |
| 131 } | 131 } |
| 132 | 132 |
| 133 } // namespace | 133 } // namespace |
| 134 | 134 |
| 135 const int kSuccess = 0; | |
| 136 | |
| 135 class ProcessUtilTest : public base::MultiProcessTest { | 137 class ProcessUtilTest : public base::MultiProcessTest { |
| 136 public: | 138 public: |
| 137 #if defined(OS_POSIX) | 139 #if defined(OS_POSIX) |
| 138 // Spawn a child process that counts how many file descriptors are open. | 140 // Spawn a child process that counts how many file descriptors are open. |
| 139 int CountOpenFDsInChild(); | 141 int CountOpenFDsInChild(); |
| 140 #endif | 142 #endif |
| 141 // Converts the filename to a platform specific filepath. | 143 // Converts the filename to a platform specific filepath. |
| 142 // On Android files can not be created in arbitrary directories. | 144 // On Android files can not be created in arbitrary directories. |
| 143 static std::string GetSignalFilePath(const char* filename); | 145 static std::string GetSignalFilePath(const char* filename); |
| 144 }; | 146 }; |
| 145 | 147 |
| 146 std::string ProcessUtilTest::GetSignalFilePath(const char* filename) { | 148 std::string ProcessUtilTest::GetSignalFilePath(const char* filename) { |
| 147 #if !defined(OS_ANDROID) | 149 #if !defined(OS_ANDROID) |
| 148 return filename; | 150 return filename; |
| 149 #else | 151 #else |
| 150 FilePath tmp_dir; | 152 FilePath tmp_dir; |
| 151 PathService::Get(base::DIR_CACHE, &tmp_dir); | 153 PathService::Get(base::DIR_CACHE, &tmp_dir); |
| 152 tmp_dir = tmp_dir.Append(filename); | 154 tmp_dir = tmp_dir.Append(filename); |
| 153 return tmp_dir.value(); | 155 return tmp_dir.value(); |
| 154 #endif | 156 #endif |
| 155 } | 157 } |
| 156 | 158 |
| 157 MULTIPROCESS_TEST_MAIN(SimpleChildProcess) { | 159 MULTIPROCESS_TEST_MAIN(SimpleChildProcess) { |
| 158 return 0; | 160 return kSuccess; |
| 159 } | 161 } |
| 160 | 162 |
| 161 // TODO(viettrungluu): This should be in a "MultiProcessTestTest". | 163 // TODO(viettrungluu): This should be in a "MultiProcessTestTest". |
| 162 TEST_F(ProcessUtilTest, SpawnChild) { | 164 TEST_F(ProcessUtilTest, SpawnChild) { |
| 163 base::Process process = SpawnChild("SimpleChildProcess"); | 165 base::Process process = SpawnChild("SimpleChildProcess"); |
| 164 ASSERT_TRUE(process.IsValid()); | 166 ASSERT_TRUE(process.IsValid()); |
| 165 int exit_code; | 167 int exit_code; |
| 166 EXPECT_TRUE(process.WaitForExitWithTimeout( | 168 EXPECT_TRUE(process.WaitForExitWithTimeout( |
| 167 TestTimeouts::action_max_timeout(), &exit_code)); | 169 TestTimeouts::action_max_timeout(), &exit_code)); |
| 168 } | 170 } |
| 169 | 171 |
| 170 MULTIPROCESS_TEST_MAIN(SlowChildProcess) { | 172 MULTIPROCESS_TEST_MAIN(SlowChildProcess) { |
| 171 WaitToDie(ProcessUtilTest::GetSignalFilePath(kSignalFileSlow).c_str()); | 173 WaitToDie(ProcessUtilTest::GetSignalFilePath(kSignalFileSlow).c_str()); |
| 172 return 0; | 174 return kSuccess; |
| 173 } | 175 } |
| 174 | 176 |
| 175 TEST_F(ProcessUtilTest, KillSlowChild) { | 177 TEST_F(ProcessUtilTest, KillSlowChild) { |
| 176 const std::string signal_file = | 178 const std::string signal_file = |
| 177 ProcessUtilTest::GetSignalFilePath(kSignalFileSlow); | 179 ProcessUtilTest::GetSignalFilePath(kSignalFileSlow); |
| 178 remove(signal_file.c_str()); | 180 remove(signal_file.c_str()); |
| 179 base::Process process = SpawnChild("SlowChildProcess"); | 181 base::Process process = SpawnChild("SlowChildProcess"); |
| 180 ASSERT_TRUE(process.IsValid()); | 182 ASSERT_TRUE(process.IsValid()); |
| 181 SignalChildren(signal_file.c_str()); | 183 SignalChildren(signal_file.c_str()); |
| 182 int exit_code; | 184 int exit_code; |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 196 int exit_code = 42; | 198 int exit_code = 42; |
| 197 EXPECT_EQ(base::TERMINATION_STATUS_STILL_RUNNING, | 199 EXPECT_EQ(base::TERMINATION_STATUS_STILL_RUNNING, |
| 198 base::GetTerminationStatus(process.Handle(), &exit_code)); | 200 base::GetTerminationStatus(process.Handle(), &exit_code)); |
| 199 EXPECT_EQ(kExpectedStillRunningExitCode, exit_code); | 201 EXPECT_EQ(kExpectedStillRunningExitCode, exit_code); |
| 200 | 202 |
| 201 SignalChildren(signal_file.c_str()); | 203 SignalChildren(signal_file.c_str()); |
| 202 exit_code = 42; | 204 exit_code = 42; |
| 203 base::TerminationStatus status = | 205 base::TerminationStatus status = |
| 204 WaitForChildTermination(process.Handle(), &exit_code); | 206 WaitForChildTermination(process.Handle(), &exit_code); |
| 205 EXPECT_EQ(base::TERMINATION_STATUS_NORMAL_TERMINATION, status); | 207 EXPECT_EQ(base::TERMINATION_STATUS_NORMAL_TERMINATION, status); |
| 206 EXPECT_EQ(0, exit_code); | 208 EXPECT_EQ(kSuccess, exit_code); |
| 207 remove(signal_file.c_str()); | 209 remove(signal_file.c_str()); |
| 208 } | 210 } |
| 209 | 211 |
| 212 MULTIPROCESS_TEST_MAIN(CheckCwdProcess) { | |
| 213 base::FilePath expected; | |
| 214 CHECK(base::GetTempDir(&expected)); | |
| 215 expected = MakeAbsoluteFilePath(expected); | |
| 216 CHECK(!expected.empty()); | |
| 217 | |
| 218 base::FilePath actual; | |
| 219 CHECK(base::GetCurrentDirectory(&actual)); | |
| 220 actual = MakeAbsoluteFilePath(actual); | |
| 221 CHECK(!actual.empty()); | |
| 222 | |
| 223 CHECK(expected == actual) << "Expected: " << expected.value() | |
|
Lei Zhang
2016/04/05 23:35:22
Does CHECK_EQ() properly print out FilePaths? If y
Sergey Ulanov
2016/04/06 00:39:50
No, it doesn't work.
| |
| 224 << " Actual: " << actual.value(); | |
| 225 return kSuccess; | |
| 226 } | |
| 227 | |
| 228 TEST_F(ProcessUtilTest, CurrentDirectory) { | |
| 229 // TODO(rickyz): Add support for passing arguments to multiprocess children, | |
| 230 // then create a special directory for this test. | |
| 231 base::FilePath tmp_dir; | |
| 232 ASSERT_TRUE(base::GetTempDir(&tmp_dir)); | |
| 233 | |
| 234 base::LaunchOptions options; | |
| 235 options.current_directory = tmp_dir; | |
| 236 | |
| 237 base::Process process(SpawnChildWithOptions("CheckCwdProcess", options)); | |
| 238 ASSERT_TRUE(process.IsValid()); | |
| 239 | |
| 240 int exit_code = 42; | |
| 241 EXPECT_TRUE(process.WaitForExit(&exit_code)); | |
| 242 EXPECT_EQ(kSuccess, exit_code); | |
| 243 } | |
| 244 | |
| 210 #if defined(OS_WIN) | 245 #if defined(OS_WIN) |
| 211 // TODO(cpu): figure out how to test this in other platforms. | 246 // TODO(cpu): figure out how to test this in other platforms. |
| 212 TEST_F(ProcessUtilTest, GetProcId) { | 247 TEST_F(ProcessUtilTest, GetProcId) { |
| 213 base::ProcessId id1 = base::GetProcId(GetCurrentProcess()); | 248 base::ProcessId id1 = base::GetProcId(GetCurrentProcess()); |
| 214 EXPECT_NE(0ul, id1); | 249 EXPECT_NE(0ul, id1); |
| 215 base::Process process = SpawnChild("SimpleChildProcess"); | 250 base::Process process = SpawnChild("SimpleChildProcess"); |
| 216 ASSERT_TRUE(process.IsValid()); | 251 ASSERT_TRUE(process.IsValid()); |
| 217 base::ProcessId id2 = process.Pid(); | 252 base::ProcessId id2 = process.Pid(); |
| 218 EXPECT_NE(0ul, id2); | 253 EXPECT_NE(0ul, id2); |
| 219 EXPECT_NE(id1, id2); | 254 EXPECT_NE(id1, id2); |
| 220 } | 255 } |
| 221 #endif | 256 #endif // defined(OS_WIN) |
| 222 | 257 |
| 223 #if !defined(OS_MACOSX) | 258 #if !defined(OS_MACOSX) |
| 224 // This test is disabled on Mac, since it's flaky due to ReportCrash | 259 // This test is disabled on Mac, since it's flaky due to ReportCrash |
| 225 // taking a variable amount of time to parse and load the debug and | 260 // taking a variable amount of time to parse and load the debug and |
| 226 // symbol data for this unit test's executable before firing the | 261 // symbol data for this unit test's executable before firing the |
| 227 // signal handler. | 262 // signal handler. |
| 228 // | 263 // |
| 229 // TODO(gspencer): turn this test process into a very small program | 264 // TODO(gspencer): turn this test process into a very small program |
| 230 // with no symbols (instead of using the multiprocess testing | 265 // with no symbols (instead of using the multiprocess testing |
| 231 // framework) to reduce the ReportCrash overhead. | 266 // framework) to reduce the ReportCrash overhead. |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 309 return 1; | 344 return 1; |
| 310 } | 345 } |
| 311 | 346 |
| 312 #if defined(OS_POSIX) | 347 #if defined(OS_POSIX) |
| 313 MULTIPROCESS_TEST_MAIN(TerminatedChildProcess) { | 348 MULTIPROCESS_TEST_MAIN(TerminatedChildProcess) { |
| 314 WaitToDie(ProcessUtilTest::GetSignalFilePath(kSignalFileTerm).c_str()); | 349 WaitToDie(ProcessUtilTest::GetSignalFilePath(kSignalFileTerm).c_str()); |
| 315 // Send a SIGTERM to this process. | 350 // Send a SIGTERM to this process. |
| 316 ::kill(getpid(), SIGTERM); | 351 ::kill(getpid(), SIGTERM); |
| 317 return 1; | 352 return 1; |
| 318 } | 353 } |
| 319 #endif | 354 #endif // defined(OS_POSIX) |
| 320 | 355 |
| 321 TEST_F(ProcessUtilTest, GetTerminationStatusSigKill) { | 356 TEST_F(ProcessUtilTest, GetTerminationStatusSigKill) { |
| 322 const std::string signal_file = | 357 const std::string signal_file = |
| 323 ProcessUtilTest::GetSignalFilePath(kSignalFileKill); | 358 ProcessUtilTest::GetSignalFilePath(kSignalFileKill); |
| 324 remove(signal_file.c_str()); | 359 remove(signal_file.c_str()); |
| 325 base::Process process = SpawnChild("KilledChildProcess"); | 360 base::Process process = SpawnChild("KilledChildProcess"); |
| 326 ASSERT_TRUE(process.IsValid()); | 361 ASSERT_TRUE(process.IsValid()); |
| 327 | 362 |
| 328 int exit_code = 42; | 363 int exit_code = 42; |
| 329 EXPECT_EQ(base::TERMINATION_STATUS_STILL_RUNNING, | 364 EXPECT_EQ(base::TERMINATION_STATUS_STILL_RUNNING, |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 369 base::TerminationStatus status = | 404 base::TerminationStatus status = |
| 370 WaitForChildTermination(process.Handle(), &exit_code); | 405 WaitForChildTermination(process.Handle(), &exit_code); |
| 371 EXPECT_EQ(base::TERMINATION_STATUS_PROCESS_WAS_KILLED, status); | 406 EXPECT_EQ(base::TERMINATION_STATUS_PROCESS_WAS_KILLED, status); |
| 372 | 407 |
| 373 int signaled = WIFSIGNALED(exit_code); | 408 int signaled = WIFSIGNALED(exit_code); |
| 374 EXPECT_NE(0, signaled); | 409 EXPECT_NE(0, signaled); |
| 375 int signal = WTERMSIG(exit_code); | 410 int signal = WTERMSIG(exit_code); |
| 376 EXPECT_EQ(SIGTERM, signal); | 411 EXPECT_EQ(SIGTERM, signal); |
| 377 remove(signal_file.c_str()); | 412 remove(signal_file.c_str()); |
| 378 } | 413 } |
| 379 #endif | 414 #endif // defined(OS_POSIX) |
| 380 | 415 |
| 381 #if defined(OS_WIN) | 416 #if defined(OS_WIN) |
| 382 // TODO(estade): if possible, port this test. | 417 // TODO(estade): if possible, port this test. |
| 383 TEST_F(ProcessUtilTest, GetAppOutput) { | 418 TEST_F(ProcessUtilTest, GetAppOutput) { |
| 384 // Let's create a decently long message. | 419 // Let's create a decently long message. |
| 385 std::string message; | 420 std::string message; |
| 386 for (int i = 0; i < 1025; i++) { // 1025 so it does not end on a kilo-byte | 421 for (int i = 0; i < 1025; i++) { // 1025 so it does not end on a kilo-byte |
| 387 // boundary. | 422 // boundary. |
| 388 message += "Hello!"; | 423 message += "Hello!"; |
| 389 } | 424 } |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 552 if (ret == -1) | 587 if (ret == -1) |
| 553 return false; | 588 return false; |
| 554 | 589 |
| 555 // Remove the guard. It should not be possible to fail in removing the guard | 590 // Remove the guard. It should not be possible to fail in removing the guard |
| 556 // just added. | 591 // just added. |
| 557 ret = change_fdguard_np(fd, &kGuard, GUARD_DUP, NULL, 0, &original_fdflags); | 592 ret = change_fdguard_np(fd, &kGuard, GUARD_DUP, NULL, 0, &original_fdflags); |
| 558 DPCHECK(ret == 0); | 593 DPCHECK(ret == 0); |
| 559 | 594 |
| 560 return true; | 595 return true; |
| 561 } | 596 } |
| 562 #endif // OS_MACOSX | 597 #endif // defined(OS_MACOSX) |
| 563 | 598 |
| 564 } // namespace | 599 } // namespace |
| 565 | 600 |
| 566 MULTIPROCESS_TEST_MAIN(ProcessUtilsLeakFDChildProcess) { | 601 MULTIPROCESS_TEST_MAIN(ProcessUtilsLeakFDChildProcess) { |
| 567 // This child process counts the number of open FDs, it then writes that | 602 // This child process counts the number of open FDs, it then writes that |
| 568 // number out to a pipe connected to the parent. | 603 // number out to a pipe connected to the parent. |
| 569 int num_open_files = 0; | 604 int num_open_files = 0; |
| 570 int write_pipe = kChildPipe; | 605 int write_pipe = kChildPipe; |
| 571 int max_files = GetMaxFilesOpenInProcess(); | 606 int max_files = GetMaxFilesOpenInProcess(); |
| 572 for (int i = STDERR_FILENO + 1; i < max_files; i++) { | 607 for (int i = STDERR_FILENO + 1; i < max_files; i++) { |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 629 return num_open_files; | 664 return num_open_files; |
| 630 } | 665 } |
| 631 | 666 |
| 632 #if defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER) | 667 #if defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER) |
| 633 // ProcessUtilTest.FDRemapping is flaky when ran under xvfb-run on Precise. | 668 // ProcessUtilTest.FDRemapping is flaky when ran under xvfb-run on Precise. |
| 634 // The problem is 100% reproducible with both ASan and TSan. | 669 // The problem is 100% reproducible with both ASan and TSan. |
| 635 // See http://crbug.com/136720. | 670 // See http://crbug.com/136720. |
| 636 #define MAYBE_FDRemapping DISABLED_FDRemapping | 671 #define MAYBE_FDRemapping DISABLED_FDRemapping |
| 637 #else | 672 #else |
| 638 #define MAYBE_FDRemapping FDRemapping | 673 #define MAYBE_FDRemapping FDRemapping |
| 639 #endif | 674 #endif // defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER) |
| 640 TEST_F(ProcessUtilTest, MAYBE_FDRemapping) { | 675 TEST_F(ProcessUtilTest, MAYBE_FDRemapping) { |
| 641 int fds_before = CountOpenFDsInChild(); | 676 int fds_before = CountOpenFDsInChild(); |
| 642 | 677 |
| 643 // open some dummy fds to make sure they don't propagate over to the | 678 // open some dummy fds to make sure they don't propagate over to the |
| 644 // child process. | 679 // child process. |
| 645 int dev_null = open("/dev/null", O_RDONLY); | 680 int dev_null = open("/dev/null", O_RDONLY); |
| 646 int sockets[2]; | 681 int sockets[2]; |
| 647 socketpair(AF_UNIX, SOCK_STREAM, 0, sockets); | 682 socketpair(AF_UNIX, SOCK_STREAM, 0, sockets); |
| 648 | 683 |
| 649 int fds_after = CountOpenFDsInChild(); | 684 int fds_after = CountOpenFDsInChild(); |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 673 fds_to_remap.push_back(std::make_pair(fds[1], 1)); | 708 fds_to_remap.push_back(std::make_pair(fds[1], 1)); |
| 674 base::LaunchOptions options; | 709 base::LaunchOptions options; |
| 675 options.wait = true; | 710 options.wait = true; |
| 676 options.environ = env_changes; | 711 options.environ = env_changes; |
| 677 options.clear_environ = clear_environ; | 712 options.clear_environ = clear_environ; |
| 678 options.fds_to_remap = &fds_to_remap; | 713 options.fds_to_remap = &fds_to_remap; |
| 679 #if defined(OS_LINUX) | 714 #if defined(OS_LINUX) |
| 680 options.clone_flags = clone_flags; | 715 options.clone_flags = clone_flags; |
| 681 #else | 716 #else |
| 682 CHECK_EQ(0, clone_flags); | 717 CHECK_EQ(0, clone_flags); |
| 683 #endif // OS_LINUX | 718 #endif // defined(OS_LINUX) |
| 684 EXPECT_TRUE(base::LaunchProcess(args, options).IsValid()); | 719 EXPECT_TRUE(base::LaunchProcess(args, options).IsValid()); |
| 685 PCHECK(IGNORE_EINTR(close(fds[1])) == 0); | 720 PCHECK(IGNORE_EINTR(close(fds[1])) == 0); |
| 686 | 721 |
| 687 char buf[512]; | 722 char buf[512]; |
| 688 const ssize_t n = HANDLE_EINTR(read(fds[0], buf, sizeof(buf))); | 723 const ssize_t n = HANDLE_EINTR(read(fds[0], buf, sizeof(buf))); |
| 689 | 724 |
| 690 PCHECK(IGNORE_EINTR(close(fds[0])) == 0); | 725 PCHECK(IGNORE_EINTR(close(fds[0])) == 0); |
| 691 | 726 |
| 692 return std::string(buf, n); | 727 return std::string(buf, n); |
| 693 } | 728 } |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 759 | 794 |
| 760 EXPECT_EQ( | 795 EXPECT_EQ( |
| 761 "BASE_TEST=wibble\n", | 796 "BASE_TEST=wibble\n", |
| 762 TestLaunchProcess( | 797 TestLaunchProcess( |
| 763 print_env, env_changes, true /* clear_environ */, no_clone_flags)); | 798 print_env, env_changes, true /* clear_environ */, no_clone_flags)); |
| 764 env_changes.clear(); | 799 env_changes.clear(); |
| 765 EXPECT_EQ( | 800 EXPECT_EQ( |
| 766 "", | 801 "", |
| 767 TestLaunchProcess( | 802 TestLaunchProcess( |
| 768 print_env, env_changes, true /* clear_environ */, no_clone_flags)); | 803 print_env, env_changes, true /* clear_environ */, no_clone_flags)); |
| 769 #endif | 804 #endif // defined(OS_LINUX) |
| 770 } | 805 } |
| 771 | 806 |
| 772 TEST_F(ProcessUtilTest, GetAppOutput) { | 807 TEST_F(ProcessUtilTest, GetAppOutput) { |
| 773 std::string output; | 808 std::string output; |
| 774 | 809 |
| 775 #if defined(OS_ANDROID) | 810 #if defined(OS_ANDROID) |
| 776 std::vector<std::string> argv; | 811 std::vector<std::string> argv; |
| 777 argv.push_back("sh"); // Instead of /bin/sh, force path search to find it. | 812 argv.push_back("sh"); // Instead of /bin/sh, force path search to find it. |
| 778 argv.push_back("-c"); | 813 argv.push_back("-c"); |
| 779 | 814 |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 867 std::vector<std::string> argv; | 902 std::vector<std::string> argv; |
| 868 std::string output; | 903 std::string output; |
| 869 | 904 |
| 870 argv.push_back(std::string(kShellPath)); // argv[0] | 905 argv.push_back(std::string(kShellPath)); // argv[0] |
| 871 argv.push_back("-c"); | 906 argv.push_back("-c"); |
| 872 #if defined(OS_ANDROID) | 907 #if defined(OS_ANDROID) |
| 873 argv.push_back("while echo 12345678901234567890; do :; done"); | 908 argv.push_back("while echo 12345678901234567890; do :; done"); |
| 874 EXPECT_TRUE(base::GetAppOutputRestricted(base::CommandLine(argv), &output, | 909 EXPECT_TRUE(base::GetAppOutputRestricted(base::CommandLine(argv), &output, |
| 875 10)); | 910 10)); |
| 876 EXPECT_STREQ("1234567890", output.c_str()); | 911 EXPECT_STREQ("1234567890", output.c_str()); |
| 877 #else | 912 #else // defined(OS_ANDROID) |
| 878 argv.push_back("yes"); | 913 argv.push_back("yes"); |
| 879 EXPECT_TRUE(base::GetAppOutputRestricted(base::CommandLine(argv), &output, | 914 EXPECT_TRUE(base::GetAppOutputRestricted(base::CommandLine(argv), &output, |
| 880 10)); | 915 10)); |
| 881 EXPECT_STREQ("y\ny\ny\ny\ny\n", output.c_str()); | 916 EXPECT_STREQ("y\ny\ny\ny\ny\n", output.c_str()); |
| 882 #endif | 917 #endif // !defined(OS_ANDROID) |
| 883 } | 918 } |
| 884 #endif | 919 #endif // !defined(OS_MACOSX) && !defined(OS_OPENBSD) |
| 885 | 920 |
| 886 #if defined(ADDRESS_SANITIZER) && defined(OS_MACOSX) && \ | 921 #if defined(ADDRESS_SANITIZER) && defined(OS_MACOSX) && \ |
| 887 defined(ARCH_CPU_64_BITS) | 922 defined(ARCH_CPU_64_BITS) |
| 888 // Times out under AddressSanitizer on 64-bit OS X, see | 923 // Times out under AddressSanitizer on 64-bit OS X, see |
| 889 // http://crbug.com/298197. | 924 // http://crbug.com/298197. |
| 890 #define MAYBE_GetAppOutputRestrictedNoZombies \ | 925 #define MAYBE_GetAppOutputRestrictedNoZombies \ |
| 891 DISABLED_GetAppOutputRestrictedNoZombies | 926 DISABLED_GetAppOutputRestrictedNoZombies |
| 892 #else | 927 #else |
| 893 #define MAYBE_GetAppOutputRestrictedNoZombies GetAppOutputRestrictedNoZombies | 928 #define MAYBE_GetAppOutputRestrictedNoZombies GetAppOutputRestrictedNoZombies |
| 894 #endif | 929 #endif |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 921 // Test getting output from a successful application. | 956 // Test getting output from a successful application. |
| 922 std::vector<std::string> argv; | 957 std::vector<std::string> argv; |
| 923 std::string output; | 958 std::string output; |
| 924 int exit_code; | 959 int exit_code; |
| 925 argv.push_back(std::string(kShellPath)); // argv[0] | 960 argv.push_back(std::string(kShellPath)); // argv[0] |
| 926 argv.push_back("-c"); // argv[1] | 961 argv.push_back("-c"); // argv[1] |
| 927 argv.push_back("echo foo"); // argv[2]; | 962 argv.push_back("echo foo"); // argv[2]; |
| 928 EXPECT_TRUE(base::GetAppOutputWithExitCode(base::CommandLine(argv), &output, | 963 EXPECT_TRUE(base::GetAppOutputWithExitCode(base::CommandLine(argv), &output, |
| 929 &exit_code)); | 964 &exit_code)); |
| 930 EXPECT_STREQ("foo\n", output.c_str()); | 965 EXPECT_STREQ("foo\n", output.c_str()); |
| 931 EXPECT_EQ(exit_code, 0); | 966 EXPECT_EQ(exit_code, kSuccess); |
| 932 | 967 |
| 933 // Test getting output from an application which fails with a specific exit | 968 // Test getting output from an application which fails with a specific exit |
| 934 // code. | 969 // code. |
| 935 output.clear(); | 970 output.clear(); |
| 936 argv[2] = "echo foo; exit 2"; | 971 argv[2] = "echo foo; exit 2"; |
| 937 EXPECT_TRUE(base::GetAppOutputWithExitCode(base::CommandLine(argv), &output, | 972 EXPECT_TRUE(base::GetAppOutputWithExitCode(base::CommandLine(argv), &output, |
| 938 &exit_code)); | 973 &exit_code)); |
| 939 EXPECT_STREQ("foo\n", output.c_str()); | 974 EXPECT_STREQ("foo\n", output.c_str()); |
| 940 EXPECT_EQ(exit_code, 2); | 975 EXPECT_EQ(exit_code, 2); |
| 941 } | 976 } |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 963 &exit_code); | 998 &exit_code); |
| 964 | 999 |
| 965 // Check that process was really killed. | 1000 // Check that process was really killed. |
| 966 EXPECT_TRUE(IsProcessDead(child_process.Handle())); | 1001 EXPECT_TRUE(IsProcessDead(child_process.Handle())); |
| 967 } | 1002 } |
| 968 | 1003 |
| 969 MULTIPROCESS_TEST_MAIN(process_util_test_never_die) { | 1004 MULTIPROCESS_TEST_MAIN(process_util_test_never_die) { |
| 970 while (1) { | 1005 while (1) { |
| 971 sleep(500); | 1006 sleep(500); |
| 972 } | 1007 } |
| 973 return 0; | 1008 return kSuccess; |
| 974 } | 1009 } |
| 975 | 1010 |
| 976 TEST_F(ProcessUtilTest, ImmediateTermination) { | 1011 TEST_F(ProcessUtilTest, ImmediateTermination) { |
| 977 base::Process child_process = SpawnChild("process_util_test_die_immediately"); | 1012 base::Process child_process = SpawnChild("process_util_test_die_immediately"); |
| 978 ASSERT_TRUE(child_process.IsValid()); | 1013 ASSERT_TRUE(child_process.IsValid()); |
| 979 // Give it time to die. | 1014 // Give it time to die. |
| 980 sleep(2); | 1015 sleep(2); |
| 981 base::EnsureProcessTerminated(child_process.Duplicate()); | 1016 base::EnsureProcessTerminated(child_process.Duplicate()); |
| 982 | 1017 |
| 983 // Check that process was really killed. | 1018 // Check that process was really killed. |
| 984 EXPECT_TRUE(IsProcessDead(child_process.Handle())); | 1019 EXPECT_TRUE(IsProcessDead(child_process.Handle())); |
| 985 } | 1020 } |
| 986 | 1021 |
| 987 MULTIPROCESS_TEST_MAIN(process_util_test_die_immediately) { | 1022 MULTIPROCESS_TEST_MAIN(process_util_test_die_immediately) { |
| 988 return 0; | 1023 return kSuccess; |
| 989 } | 1024 } |
| 990 | 1025 |
| 991 #if !defined(OS_ANDROID) | 1026 #if !defined(OS_ANDROID) |
| 992 const char kPipeValue = '\xcc'; | 1027 const char kPipeValue = '\xcc'; |
| 993 | 1028 |
| 994 class ReadFromPipeDelegate : public base::LaunchOptions::PreExecDelegate { | 1029 class ReadFromPipeDelegate : public base::LaunchOptions::PreExecDelegate { |
| 995 public: | 1030 public: |
| 996 explicit ReadFromPipeDelegate(int fd) : fd_(fd) {} | 1031 explicit ReadFromPipeDelegate(int fd) : fd_(fd) {} |
| 997 ~ReadFromPipeDelegate() override {} | 1032 ~ReadFromPipeDelegate() override {} |
| 998 void RunAsyncSafe() override { | 1033 void RunAsyncSafe() override { |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 1028 | 1063 |
| 1029 int exit_code = 42; | 1064 int exit_code = 42; |
| 1030 EXPECT_TRUE(process.WaitForExit(&exit_code)); | 1065 EXPECT_TRUE(process.WaitForExit(&exit_code)); |
| 1031 EXPECT_EQ(0, exit_code); | 1066 EXPECT_EQ(0, exit_code); |
| 1032 } | 1067 } |
| 1033 #endif // !defined(OS_ANDROID) | 1068 #endif // !defined(OS_ANDROID) |
| 1034 | 1069 |
| 1035 #endif // defined(OS_POSIX) | 1070 #endif // defined(OS_POSIX) |
| 1036 | 1071 |
| 1037 #if defined(OS_LINUX) | 1072 #if defined(OS_LINUX) |
| 1038 const int kSuccess = 0; | |
| 1039 | |
| 1040 MULTIPROCESS_TEST_MAIN(CheckPidProcess) { | 1073 MULTIPROCESS_TEST_MAIN(CheckPidProcess) { |
| 1041 const pid_t kInitPid = 1; | 1074 const pid_t kInitPid = 1; |
| 1042 const pid_t pid = syscall(__NR_getpid); | 1075 const pid_t pid = syscall(__NR_getpid); |
| 1043 CHECK(pid == kInitPid); | 1076 CHECK(pid == kInitPid); |
| 1044 CHECK(getpid() == pid); | 1077 CHECK(getpid() == pid); |
| 1045 return kSuccess; | 1078 return kSuccess; |
| 1046 } | 1079 } |
| 1047 | 1080 |
| 1048 #if defined(CLONE_NEWUSER) && defined(CLONE_NEWPID) | 1081 #if defined(CLONE_NEWUSER) && defined(CLONE_NEWPID) |
| 1049 TEST_F(ProcessUtilTest, CloneFlags) { | 1082 TEST_F(ProcessUtilTest, CloneFlags) { |
| 1050 if (RunningOnValgrind() || | 1083 if (RunningOnValgrind() || |
| 1051 !base::PathExists(FilePath("/proc/self/ns/user")) || | 1084 !base::PathExists(FilePath("/proc/self/ns/user")) || |
| 1052 !base::PathExists(FilePath("/proc/self/ns/pid"))) { | 1085 !base::PathExists(FilePath("/proc/self/ns/pid"))) { |
| 1053 // User or PID namespaces are not supported. | 1086 // User or PID namespaces are not supported. |
| 1054 return; | 1087 return; |
| 1055 } | 1088 } |
| 1056 | 1089 |
| 1057 base::LaunchOptions options; | 1090 base::LaunchOptions options; |
| 1058 options.clone_flags = CLONE_NEWUSER | CLONE_NEWPID; | 1091 options.clone_flags = CLONE_NEWUSER | CLONE_NEWPID; |
| 1059 | 1092 |
| 1060 base::Process process(SpawnChildWithOptions("CheckPidProcess", options)); | 1093 base::Process process(SpawnChildWithOptions("CheckPidProcess", options)); |
| 1061 ASSERT_TRUE(process.IsValid()); | 1094 ASSERT_TRUE(process.IsValid()); |
| 1062 | 1095 |
| 1063 int exit_code = 42; | 1096 int exit_code = 42; |
| 1064 EXPECT_TRUE(process.WaitForExit(&exit_code)); | 1097 EXPECT_TRUE(process.WaitForExit(&exit_code)); |
| 1065 EXPECT_EQ(kSuccess, exit_code); | 1098 EXPECT_EQ(kSuccess, exit_code); |
| 1066 } | 1099 } |
| 1067 #endif | 1100 #endif // defined(CLONE_NEWUSER) && defined(CLONE_NEWPID) |
| 1068 | 1101 |
| 1069 TEST(ForkWithFlagsTest, UpdatesPidCache) { | 1102 TEST(ForkWithFlagsTest, UpdatesPidCache) { |
| 1070 // The libc clone function, which allows ForkWithFlags to keep the pid cache | 1103 // The libc clone function, which allows ForkWithFlags to keep the pid cache |
| 1071 // up to date, does not work on Valgrind. | 1104 // up to date, does not work on Valgrind. |
| 1072 if (RunningOnValgrind()) { | 1105 if (RunningOnValgrind()) { |
| 1073 return; | 1106 return; |
| 1074 } | 1107 } |
| 1075 | 1108 |
| 1076 // Warm up the libc pid cache, if there is one. | 1109 // Warm up the libc pid cache, if there is one. |
| 1077 ASSERT_EQ(syscall(__NR_getpid), getpid()); | 1110 ASSERT_EQ(syscall(__NR_getpid), getpid()); |
| 1078 | 1111 |
| 1079 pid_t ctid = 0; | 1112 pid_t ctid = 0; |
| 1080 const pid_t pid = | 1113 const pid_t pid = |
| 1081 base::ForkWithFlags(SIGCHLD | CLONE_CHILD_SETTID, nullptr, &ctid); | 1114 base::ForkWithFlags(SIGCHLD | CLONE_CHILD_SETTID, nullptr, &ctid); |
| 1082 if (pid == 0) { | 1115 if (pid == 0) { |
| 1083 // In child. Check both the raw getpid syscall and the libc getpid wrapper | 1116 // In child. Check both the raw getpid syscall and the libc getpid wrapper |
| 1084 // (which may rely on a pid cache). | 1117 // (which may rely on a pid cache). |
| 1085 RAW_CHECK(syscall(__NR_getpid) == ctid); | 1118 RAW_CHECK(syscall(__NR_getpid) == ctid); |
| 1086 RAW_CHECK(getpid() == ctid); | 1119 RAW_CHECK(getpid() == ctid); |
| 1087 _exit(kSuccess); | 1120 _exit(kSuccess); |
| 1088 } | 1121 } |
| 1089 | 1122 |
| 1090 ASSERT_NE(-1, pid); | 1123 ASSERT_NE(-1, pid); |
| 1091 int status = 42; | 1124 int status = 42; |
| 1092 ASSERT_EQ(pid, HANDLE_EINTR(waitpid(pid, &status, 0))); | 1125 ASSERT_EQ(pid, HANDLE_EINTR(waitpid(pid, &status, 0))); |
| 1093 ASSERT_TRUE(WIFEXITED(status)); | 1126 ASSERT_TRUE(WIFEXITED(status)); |
| 1094 EXPECT_EQ(kSuccess, WEXITSTATUS(status)); | 1127 EXPECT_EQ(kSuccess, WEXITSTATUS(status)); |
| 1095 } | 1128 } |
| 1096 | 1129 |
| 1097 MULTIPROCESS_TEST_MAIN(CheckCwdProcess) { | |
| 1098 base::FilePath expected; | |
| 1099 CHECK(base::GetTempDir(&expected)); | |
| 1100 base::FilePath actual; | |
| 1101 CHECK(base::GetCurrentDirectory(&actual)); | |
| 1102 CHECK(actual == expected); | |
| 1103 return kSuccess; | |
| 1104 } | |
| 1105 | |
| 1106 TEST_F(ProcessUtilTest, CurrentDirectory) { | |
| 1107 // TODO(rickyz): Add support for passing arguments to multiprocess children, | |
| 1108 // then create a special directory for this test. | |
| 1109 base::FilePath tmp_dir; | |
| 1110 ASSERT_TRUE(base::GetTempDir(&tmp_dir)); | |
| 1111 | |
| 1112 base::LaunchOptions options; | |
| 1113 options.current_directory = tmp_dir; | |
| 1114 | |
| 1115 base::Process process(SpawnChildWithOptions("CheckCwdProcess", options)); | |
| 1116 ASSERT_TRUE(process.IsValid()); | |
| 1117 | |
| 1118 int exit_code = 42; | |
| 1119 EXPECT_TRUE(process.WaitForExit(&exit_code)); | |
| 1120 EXPECT_EQ(kSuccess, exit_code); | |
| 1121 } | |
| 1122 | |
| 1123 TEST_F(ProcessUtilTest, InvalidCurrentDirectory) { | 1130 TEST_F(ProcessUtilTest, InvalidCurrentDirectory) { |
| 1124 base::LaunchOptions options; | 1131 base::LaunchOptions options; |
| 1125 options.current_directory = base::FilePath("/dev/null"); | 1132 options.current_directory = base::FilePath("/dev/null"); |
| 1126 | 1133 |
| 1127 base::Process process(SpawnChildWithOptions("SimpleChildProcess", options)); | 1134 base::Process process(SpawnChildWithOptions("SimpleChildProcess", options)); |
| 1128 ASSERT_TRUE(process.IsValid()); | 1135 ASSERT_TRUE(process.IsValid()); |
| 1129 | 1136 |
| 1130 int exit_code = kSuccess; | 1137 int exit_code = kSuccess; |
| 1131 EXPECT_TRUE(process.WaitForExit(&exit_code)); | 1138 EXPECT_TRUE(process.WaitForExit(&exit_code)); |
| 1132 EXPECT_NE(kSuccess, exit_code); | 1139 EXPECT_NE(kSuccess, exit_code); |
| 1133 } | 1140 } |
| 1134 #endif | 1141 #endif // defined(OS_LINUX) |
| OLD | NEW |