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