| 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 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 153 return tmp_dir.value(); | 153 return tmp_dir.value(); |
| 154 #endif | 154 #endif |
| 155 } | 155 } |
| 156 | 156 |
| 157 MULTIPROCESS_TEST_MAIN(SimpleChildProcess) { | 157 MULTIPROCESS_TEST_MAIN(SimpleChildProcess) { |
| 158 return kSuccess; | 158 return kSuccess; |
| 159 } | 159 } |
| 160 | 160 |
| 161 // TODO(viettrungluu): This should be in a "MultiProcessTestTest". | 161 // TODO(viettrungluu): This should be in a "MultiProcessTestTest". |
| 162 TEST_F(ProcessUtilTest, SpawnChild) { | 162 TEST_F(ProcessUtilTest, SpawnChild) { |
| 163 base::Process process = SpawnChild("SimpleChildProcess"); | 163 base::SpawnChildResult spawn_child = SpawnChild("SimpleChildProcess"); |
| 164 ASSERT_TRUE(process.IsValid()); | 164 ASSERT_TRUE(spawn_child.process.IsValid()); |
| 165 int exit_code; | 165 int exit_code; |
| 166 EXPECT_TRUE(process.WaitForExitWithTimeout( | 166 EXPECT_TRUE(spawn_child.process.WaitForExitWithTimeout( |
| 167 TestTimeouts::action_max_timeout(), &exit_code)); | 167 TestTimeouts::action_max_timeout(), &exit_code)); |
| 168 } | 168 } |
| 169 | 169 |
| 170 MULTIPROCESS_TEST_MAIN(SlowChildProcess) { | 170 MULTIPROCESS_TEST_MAIN(SlowChildProcess) { |
| 171 WaitToDie(ProcessUtilTest::GetSignalFilePath(kSignalFileSlow).c_str()); | 171 WaitToDie(ProcessUtilTest::GetSignalFilePath(kSignalFileSlow).c_str()); |
| 172 return kSuccess; | 172 return kSuccess; |
| 173 } | 173 } |
| 174 | 174 |
| 175 TEST_F(ProcessUtilTest, KillSlowChild) { | 175 TEST_F(ProcessUtilTest, KillSlowChild) { |
| 176 const std::string signal_file = | 176 const std::string signal_file = |
| 177 ProcessUtilTest::GetSignalFilePath(kSignalFileSlow); | 177 ProcessUtilTest::GetSignalFilePath(kSignalFileSlow); |
| 178 remove(signal_file.c_str()); | 178 remove(signal_file.c_str()); |
| 179 base::Process process = SpawnChild("SlowChildProcess"); | 179 base::SpawnChildResult spawn_child = SpawnChild("SlowChildProcess"); |
| 180 ASSERT_TRUE(process.IsValid()); | 180 ASSERT_TRUE(spawn_child.process.IsValid()); |
| 181 SignalChildren(signal_file.c_str()); | 181 SignalChildren(signal_file.c_str()); |
| 182 int exit_code; | 182 int exit_code; |
| 183 EXPECT_TRUE(process.WaitForExitWithTimeout( | 183 EXPECT_TRUE(spawn_child.process.WaitForExitWithTimeout( |
| 184 TestTimeouts::action_max_timeout(), &exit_code)); | 184 TestTimeouts::action_max_timeout(), &exit_code)); |
| 185 remove(signal_file.c_str()); | 185 remove(signal_file.c_str()); |
| 186 } | 186 } |
| 187 | 187 |
| 188 // Times out on Linux and Win, flakes on other platforms, http://crbug.com/95058 | 188 // Times out on Linux and Win, flakes on other platforms, http://crbug.com/95058 |
| 189 TEST_F(ProcessUtilTest, DISABLED_GetTerminationStatusExit) { | 189 TEST_F(ProcessUtilTest, DISABLED_GetTerminationStatusExit) { |
| 190 const std::string signal_file = | 190 const std::string signal_file = |
| 191 ProcessUtilTest::GetSignalFilePath(kSignalFileSlow); | 191 ProcessUtilTest::GetSignalFilePath(kSignalFileSlow); |
| 192 remove(signal_file.c_str()); | 192 remove(signal_file.c_str()); |
| 193 base::Process process = SpawnChild("SlowChildProcess"); | 193 base::SpawnChildResult spawn_child = SpawnChild("SlowChildProcess"); |
| 194 ASSERT_TRUE(process.IsValid()); | 194 ASSERT_TRUE(spawn_child.process.IsValid()); |
| 195 | 195 |
| 196 int exit_code = 42; | 196 int exit_code = 42; |
| 197 EXPECT_EQ(base::TERMINATION_STATUS_STILL_RUNNING, | 197 EXPECT_EQ( |
| 198 base::GetTerminationStatus(process.Handle(), &exit_code)); | 198 base::TERMINATION_STATUS_STILL_RUNNING, |
| 199 base::GetTerminationStatus(spawn_child.process.Handle(), &exit_code)); |
| 199 EXPECT_EQ(kExpectedStillRunningExitCode, exit_code); | 200 EXPECT_EQ(kExpectedStillRunningExitCode, exit_code); |
| 200 | 201 |
| 201 SignalChildren(signal_file.c_str()); | 202 SignalChildren(signal_file.c_str()); |
| 202 exit_code = 42; | 203 exit_code = 42; |
| 203 base::TerminationStatus status = | 204 base::TerminationStatus status = |
| 204 WaitForChildTermination(process.Handle(), &exit_code); | 205 WaitForChildTermination(spawn_child.process.Handle(), &exit_code); |
| 205 EXPECT_EQ(base::TERMINATION_STATUS_NORMAL_TERMINATION, status); | 206 EXPECT_EQ(base::TERMINATION_STATUS_NORMAL_TERMINATION, status); |
| 206 EXPECT_EQ(kSuccess, exit_code); | 207 EXPECT_EQ(kSuccess, exit_code); |
| 207 remove(signal_file.c_str()); | 208 remove(signal_file.c_str()); |
| 208 } | 209 } |
| 209 | 210 |
| 210 // On Android SpawnProcess() doesn't use LaunchProcess() and doesn't support | 211 // On Android SpawnProcess() doesn't use LaunchProcess() and doesn't support |
| 211 // LaunchOptions::current_directory. | 212 // LaunchOptions::current_directory. |
| 212 #if !defined(OS_ANDROID) | 213 #if !defined(OS_ANDROID) |
| 213 MULTIPROCESS_TEST_MAIN(CheckCwdProcess) { | 214 MULTIPROCESS_TEST_MAIN(CheckCwdProcess) { |
| 214 base::FilePath expected; | 215 base::FilePath expected; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 228 | 229 |
| 229 TEST_F(ProcessUtilTest, CurrentDirectory) { | 230 TEST_F(ProcessUtilTest, CurrentDirectory) { |
| 230 // TODO(rickyz): Add support for passing arguments to multiprocess children, | 231 // TODO(rickyz): Add support for passing arguments to multiprocess children, |
| 231 // then create a special directory for this test. | 232 // then create a special directory for this test. |
| 232 base::FilePath tmp_dir; | 233 base::FilePath tmp_dir; |
| 233 ASSERT_TRUE(base::GetTempDir(&tmp_dir)); | 234 ASSERT_TRUE(base::GetTempDir(&tmp_dir)); |
| 234 | 235 |
| 235 base::LaunchOptions options; | 236 base::LaunchOptions options; |
| 236 options.current_directory = tmp_dir; | 237 options.current_directory = tmp_dir; |
| 237 | 238 |
| 238 base::Process process(SpawnChildWithOptions("CheckCwdProcess", options)); | 239 base::SpawnChildResult spawn_child = |
| 239 ASSERT_TRUE(process.IsValid()); | 240 SpawnChildWithOptions("CheckCwdProcess", options); |
| 241 ASSERT_TRUE(spawn_child.process.IsValid()); |
| 240 | 242 |
| 241 int exit_code = 42; | 243 int exit_code = 42; |
| 242 EXPECT_TRUE(process.WaitForExit(&exit_code)); | 244 EXPECT_TRUE(spawn_child.process.WaitForExit(&exit_code)); |
| 243 EXPECT_EQ(kSuccess, exit_code); | 245 EXPECT_EQ(kSuccess, exit_code); |
| 244 } | 246 } |
| 245 #endif // !defined(OS_ANDROID) | 247 #endif // !defined(OS_ANDROID) |
| 246 | 248 |
| 247 #if defined(OS_WIN) | 249 #if defined(OS_WIN) |
| 248 // TODO(cpu): figure out how to test this in other platforms. | 250 // TODO(cpu): figure out how to test this in other platforms. |
| 249 TEST_F(ProcessUtilTest, GetProcId) { | 251 TEST_F(ProcessUtilTest, GetProcId) { |
| 250 base::ProcessId id1 = base::GetProcId(GetCurrentProcess()); | 252 base::ProcessId id1 = base::GetProcId(GetCurrentProcess()); |
| 251 EXPECT_NE(0ul, id1); | 253 EXPECT_NE(0ul, id1); |
| 252 base::Process process = SpawnChild("SimpleChildProcess"); | 254 base::SpawnChildResult spawn_child = SpawnChild("SimpleChildProcess"); |
| 253 ASSERT_TRUE(process.IsValid()); | 255 ASSERT_TRUE(spawn_child.process.IsValid()); |
| 254 base::ProcessId id2 = process.Pid(); | 256 base::ProcessId id2 = spawn_child.process.Pid(); |
| 255 EXPECT_NE(0ul, id2); | 257 EXPECT_NE(0ul, id2); |
| 256 EXPECT_NE(id1, id2); | 258 EXPECT_NE(id1, id2); |
| 257 } | 259 } |
| 258 #endif // defined(OS_WIN) | 260 #endif // defined(OS_WIN) |
| 259 | 261 |
| 260 #if !defined(OS_MACOSX) && !defined(OS_ANDROID) | 262 #if !defined(OS_MACOSX) && !defined(OS_ANDROID) |
| 261 // 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 |
| 262 // 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 |
| 263 // symbol data for this unit test's executable before firing the | 265 // symbol data for this unit test's executable before firing the |
| 264 // signal handler. | 266 // signal handler. |
| (...skipping 23 matching lines...) Expand all Loading... |
| 288 // AddressSanitizer. | 290 // AddressSanitizer. |
| 289 #if defined(ADDRESS_SANITIZER) || defined(SYZYASAN) | 291 #if defined(ADDRESS_SANITIZER) || defined(SYZYASAN) |
| 290 #define MAYBE_GetTerminationStatusCrash DISABLED_GetTerminationStatusCrash | 292 #define MAYBE_GetTerminationStatusCrash DISABLED_GetTerminationStatusCrash |
| 291 #else | 293 #else |
| 292 #define MAYBE_GetTerminationStatusCrash GetTerminationStatusCrash | 294 #define MAYBE_GetTerminationStatusCrash GetTerminationStatusCrash |
| 293 #endif | 295 #endif |
| 294 TEST_F(ProcessUtilTest, MAYBE_GetTerminationStatusCrash) { | 296 TEST_F(ProcessUtilTest, MAYBE_GetTerminationStatusCrash) { |
| 295 const std::string signal_file = | 297 const std::string signal_file = |
| 296 ProcessUtilTest::GetSignalFilePath(kSignalFileCrash); | 298 ProcessUtilTest::GetSignalFilePath(kSignalFileCrash); |
| 297 remove(signal_file.c_str()); | 299 remove(signal_file.c_str()); |
| 298 base::Process process = SpawnChild("CrashingChildProcess"); | 300 base::SpawnChildResult spawn_child = SpawnChild("CrashingChildProcess"); |
| 299 ASSERT_TRUE(process.IsValid()); | 301 ASSERT_TRUE(spawn_child.process.IsValid()); |
| 300 | 302 |
| 301 int exit_code = 42; | 303 int exit_code = 42; |
| 302 EXPECT_EQ(base::TERMINATION_STATUS_STILL_RUNNING, | 304 EXPECT_EQ( |
| 303 base::GetTerminationStatus(process.Handle(), &exit_code)); | 305 base::TERMINATION_STATUS_STILL_RUNNING, |
| 306 base::GetTerminationStatus(spawn_child.process.Handle(), &exit_code)); |
| 304 EXPECT_EQ(kExpectedStillRunningExitCode, exit_code); | 307 EXPECT_EQ(kExpectedStillRunningExitCode, exit_code); |
| 305 | 308 |
| 306 SignalChildren(signal_file.c_str()); | 309 SignalChildren(signal_file.c_str()); |
| 307 exit_code = 42; | 310 exit_code = 42; |
| 308 base::TerminationStatus status = | 311 base::TerminationStatus status = |
| 309 WaitForChildTermination(process.Handle(), &exit_code); | 312 WaitForChildTermination(spawn_child.process.Handle(), &exit_code); |
| 310 EXPECT_EQ(base::TERMINATION_STATUS_PROCESS_CRASHED, status); | 313 EXPECT_EQ(base::TERMINATION_STATUS_PROCESS_CRASHED, status); |
| 311 | 314 |
| 312 #if defined(OS_WIN) | 315 #if defined(OS_WIN) |
| 313 EXPECT_EQ(static_cast<int>(0xc0000005), exit_code); | 316 EXPECT_EQ(static_cast<int>(0xc0000005), exit_code); |
| 314 #elif defined(OS_POSIX) | 317 #elif defined(OS_POSIX) |
| 315 int signaled = WIFSIGNALED(exit_code); | 318 int signaled = WIFSIGNALED(exit_code); |
| 316 EXPECT_NE(0, signaled); | 319 EXPECT_NE(0, signaled); |
| 317 int signal = WTERMSIG(exit_code); | 320 int signal = WTERMSIG(exit_code); |
| 318 EXPECT_EQ(SIGSEGV, signal); | 321 EXPECT_EQ(SIGSEGV, signal); |
| 319 #endif | 322 #endif |
| (...skipping 23 matching lines...) Expand all Loading... |
| 343 // Send a SIGTERM to this process. | 346 // Send a SIGTERM to this process. |
| 344 ::kill(getpid(), SIGTERM); | 347 ::kill(getpid(), SIGTERM); |
| 345 return 1; | 348 return 1; |
| 346 } | 349 } |
| 347 #endif // defined(OS_POSIX) | 350 #endif // defined(OS_POSIX) |
| 348 | 351 |
| 349 TEST_F(ProcessUtilTest, GetTerminationStatusSigKill) { | 352 TEST_F(ProcessUtilTest, GetTerminationStatusSigKill) { |
| 350 const std::string signal_file = | 353 const std::string signal_file = |
| 351 ProcessUtilTest::GetSignalFilePath(kSignalFileKill); | 354 ProcessUtilTest::GetSignalFilePath(kSignalFileKill); |
| 352 remove(signal_file.c_str()); | 355 remove(signal_file.c_str()); |
| 353 base::Process process = SpawnChild("KilledChildProcess"); | 356 base::SpawnChildResult spawn_child = SpawnChild("KilledChildProcess"); |
| 354 ASSERT_TRUE(process.IsValid()); | 357 ASSERT_TRUE(spawn_child.process.IsValid()); |
| 355 | 358 |
| 356 int exit_code = 42; | 359 int exit_code = 42; |
| 357 EXPECT_EQ(base::TERMINATION_STATUS_STILL_RUNNING, | 360 EXPECT_EQ( |
| 358 base::GetTerminationStatus(process.Handle(), &exit_code)); | 361 base::TERMINATION_STATUS_STILL_RUNNING, |
| 362 base::GetTerminationStatus(spawn_child.process.Handle(), &exit_code)); |
| 359 EXPECT_EQ(kExpectedStillRunningExitCode, exit_code); | 363 EXPECT_EQ(kExpectedStillRunningExitCode, exit_code); |
| 360 | 364 |
| 361 SignalChildren(signal_file.c_str()); | 365 SignalChildren(signal_file.c_str()); |
| 362 exit_code = 42; | 366 exit_code = 42; |
| 363 base::TerminationStatus status = | 367 base::TerminationStatus status = |
| 364 WaitForChildTermination(process.Handle(), &exit_code); | 368 WaitForChildTermination(spawn_child.process.Handle(), &exit_code); |
| 365 #if defined(OS_CHROMEOS) | 369 #if defined(OS_CHROMEOS) |
| 366 EXPECT_EQ(base::TERMINATION_STATUS_PROCESS_WAS_KILLED_BY_OOM, status); | 370 EXPECT_EQ(base::TERMINATION_STATUS_PROCESS_WAS_KILLED_BY_OOM, status); |
| 367 #else | 371 #else |
| 368 EXPECT_EQ(base::TERMINATION_STATUS_PROCESS_WAS_KILLED, status); | 372 EXPECT_EQ(base::TERMINATION_STATUS_PROCESS_WAS_KILLED, status); |
| 369 #endif | 373 #endif |
| 370 | 374 |
| 371 #if defined(OS_WIN) | 375 #if defined(OS_WIN) |
| 372 EXPECT_EQ(kExpectedKilledExitCode, exit_code); | 376 EXPECT_EQ(kExpectedKilledExitCode, exit_code); |
| 373 #elif defined(OS_POSIX) | 377 #elif defined(OS_POSIX) |
| 374 int signaled = WIFSIGNALED(exit_code); | 378 int signaled = WIFSIGNALED(exit_code); |
| 375 EXPECT_NE(0, signaled); | 379 EXPECT_NE(0, signaled); |
| 376 int signal = WTERMSIG(exit_code); | 380 int signal = WTERMSIG(exit_code); |
| 377 EXPECT_EQ(SIGKILL, signal); | 381 EXPECT_EQ(SIGKILL, signal); |
| 378 #endif | 382 #endif |
| 379 remove(signal_file.c_str()); | 383 remove(signal_file.c_str()); |
| 380 } | 384 } |
| 381 | 385 |
| 382 #if defined(OS_POSIX) | 386 #if defined(OS_POSIX) |
| 383 TEST_F(ProcessUtilTest, GetTerminationStatusSigTerm) { | 387 TEST_F(ProcessUtilTest, GetTerminationStatusSigTerm) { |
| 384 const std::string signal_file = | 388 const std::string signal_file = |
| 385 ProcessUtilTest::GetSignalFilePath(kSignalFileTerm); | 389 ProcessUtilTest::GetSignalFilePath(kSignalFileTerm); |
| 386 remove(signal_file.c_str()); | 390 remove(signal_file.c_str()); |
| 387 base::Process process = SpawnChild("TerminatedChildProcess"); | 391 base::SpawnChildResult spawn_child = SpawnChild("TerminatedChildProcess"); |
| 388 ASSERT_TRUE(process.IsValid()); | 392 ASSERT_TRUE(spawn_child.process.IsValid()); |
| 389 | 393 |
| 390 int exit_code = 42; | 394 int exit_code = 42; |
| 391 EXPECT_EQ(base::TERMINATION_STATUS_STILL_RUNNING, | 395 EXPECT_EQ( |
| 392 base::GetTerminationStatus(process.Handle(), &exit_code)); | 396 base::TERMINATION_STATUS_STILL_RUNNING, |
| 397 base::GetTerminationStatus(spawn_child.process.Handle(), &exit_code)); |
| 393 EXPECT_EQ(kExpectedStillRunningExitCode, exit_code); | 398 EXPECT_EQ(kExpectedStillRunningExitCode, exit_code); |
| 394 | 399 |
| 395 SignalChildren(signal_file.c_str()); | 400 SignalChildren(signal_file.c_str()); |
| 396 exit_code = 42; | 401 exit_code = 42; |
| 397 base::TerminationStatus status = | 402 base::TerminationStatus status = |
| 398 WaitForChildTermination(process.Handle(), &exit_code); | 403 WaitForChildTermination(spawn_child.process.Handle(), &exit_code); |
| 399 EXPECT_EQ(base::TERMINATION_STATUS_PROCESS_WAS_KILLED, status); | 404 EXPECT_EQ(base::TERMINATION_STATUS_PROCESS_WAS_KILLED, status); |
| 400 | 405 |
| 401 int signaled = WIFSIGNALED(exit_code); | 406 int signaled = WIFSIGNALED(exit_code); |
| 402 EXPECT_NE(0, signaled); | 407 EXPECT_NE(0, signaled); |
| 403 int signal = WTERMSIG(exit_code); | 408 int signal = WTERMSIG(exit_code); |
| 404 EXPECT_EQ(SIGTERM, signal); | 409 EXPECT_EQ(SIGTERM, signal); |
| 405 remove(signal_file.c_str()); | 410 remove(signal_file.c_str()); |
| 406 } | 411 } |
| 407 #endif // defined(OS_POSIX) | 412 #endif // defined(OS_POSIX) |
| 408 | 413 |
| (...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 620 | 625 |
| 621 int ProcessUtilTest::CountOpenFDsInChild() { | 626 int ProcessUtilTest::CountOpenFDsInChild() { |
| 622 int fds[2]; | 627 int fds[2]; |
| 623 if (pipe(fds) < 0) | 628 if (pipe(fds) < 0) |
| 624 NOTREACHED(); | 629 NOTREACHED(); |
| 625 | 630 |
| 626 base::FileHandleMappingVector fd_mapping_vec; | 631 base::FileHandleMappingVector fd_mapping_vec; |
| 627 fd_mapping_vec.push_back(std::pair<int, int>(fds[1], kChildPipe)); | 632 fd_mapping_vec.push_back(std::pair<int, int>(fds[1], kChildPipe)); |
| 628 base::LaunchOptions options; | 633 base::LaunchOptions options; |
| 629 options.fds_to_remap = &fd_mapping_vec; | 634 options.fds_to_remap = &fd_mapping_vec; |
| 630 base::Process process = | 635 base::SpawnChildResult spawn_child = |
| 631 SpawnChildWithOptions("ProcessUtilsLeakFDChildProcess", options); | 636 SpawnChildWithOptions("ProcessUtilsLeakFDChildProcess", options); |
| 632 CHECK(process.IsValid()); | 637 CHECK(spawn_child.process.IsValid()); |
| 633 int ret = IGNORE_EINTR(close(fds[1])); | 638 int ret = IGNORE_EINTR(close(fds[1])); |
| 634 DPCHECK(ret == 0); | 639 DPCHECK(ret == 0); |
| 635 | 640 |
| 636 // Read number of open files in client process from pipe; | 641 // Read number of open files in client process from pipe; |
| 637 int num_open_files = -1; | 642 int num_open_files = -1; |
| 638 ssize_t bytes_read = | 643 ssize_t bytes_read = |
| 639 HANDLE_EINTR(read(fds[0], &num_open_files, sizeof(num_open_files))); | 644 HANDLE_EINTR(read(fds[0], &num_open_files, sizeof(num_open_files))); |
| 640 CHECK_EQ(bytes_read, static_cast<ssize_t>(sizeof(num_open_files))); | 645 CHECK_EQ(bytes_read, static_cast<ssize_t>(sizeof(num_open_files))); |
| 641 | 646 |
| 642 #if defined(THREAD_SANITIZER) | 647 #if defined(THREAD_SANITIZER) |
| 643 // Compiler-based ThreadSanitizer makes this test slow. | 648 // Compiler-based ThreadSanitizer makes this test slow. |
| 644 base::TimeDelta timeout = base::TimeDelta::FromSeconds(3); | 649 base::TimeDelta timeout = base::TimeDelta::FromSeconds(3); |
| 645 #else | 650 #else |
| 646 base::TimeDelta timeout = base::TimeDelta::FromSeconds(1); | 651 base::TimeDelta timeout = base::TimeDelta::FromSeconds(1); |
| 647 #endif | 652 #endif |
| 648 int exit_code; | 653 int exit_code; |
| 649 CHECK(process.WaitForExitWithTimeout(timeout, &exit_code)); | 654 CHECK(spawn_child.process.WaitForExitWithTimeout(timeout, &exit_code)); |
| 650 ret = IGNORE_EINTR(close(fds[0])); | 655 ret = IGNORE_EINTR(close(fds[0])); |
| 651 DPCHECK(ret == 0); | 656 DPCHECK(ret == 0); |
| 652 | 657 |
| 653 return num_open_files; | 658 return num_open_files; |
| 654 } | 659 } |
| 655 | 660 |
| 656 #if defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER) | 661 #if defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER) |
| 657 // ProcessUtilTest.FDRemapping is flaky when ran under xvfb-run on Precise. | 662 // ProcessUtilTest.FDRemapping is flaky when ran under xvfb-run on Precise. |
| 658 // The problem is 100% reproducible with both ASan and TSan. | 663 // The problem is 100% reproducible with both ASan and TSan. |
| 659 // See http://crbug.com/136720. | 664 // See http://crbug.com/136720. |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 862 // TODO(port): port those unit tests. | 867 // TODO(port): port those unit tests. |
| 863 bool IsProcessDead(base::ProcessHandle child) { | 868 bool IsProcessDead(base::ProcessHandle child) { |
| 864 // waitpid() will actually reap the process which is exactly NOT what we | 869 // waitpid() will actually reap the process which is exactly NOT what we |
| 865 // want to test for. The good thing is that if it can't find the process | 870 // want to test for. The good thing is that if it can't find the process |
| 866 // we'll get a nice value for errno which we can test for. | 871 // we'll get a nice value for errno which we can test for. |
| 867 const pid_t result = HANDLE_EINTR(waitpid(child, NULL, WNOHANG)); | 872 const pid_t result = HANDLE_EINTR(waitpid(child, NULL, WNOHANG)); |
| 868 return result == -1 && errno == ECHILD; | 873 return result == -1 && errno == ECHILD; |
| 869 } | 874 } |
| 870 | 875 |
| 871 TEST_F(ProcessUtilTest, DelayedTermination) { | 876 TEST_F(ProcessUtilTest, DelayedTermination) { |
| 872 base::Process child_process = SpawnChild("process_util_test_never_die"); | 877 base::SpawnChildResult spawn_child = |
| 873 ASSERT_TRUE(child_process.IsValid()); | 878 SpawnChild("process_util_test_never_die"); |
| 874 base::EnsureProcessTerminated(child_process.Duplicate()); | 879 ASSERT_TRUE(spawn_child.process.IsValid()); |
| 880 base::EnsureProcessTerminated(spawn_child.process.Duplicate()); |
| 875 int exit_code; | 881 int exit_code; |
| 876 child_process.WaitForExitWithTimeout(base::TimeDelta::FromSeconds(5), | 882 spawn_child.process.WaitForExitWithTimeout(base::TimeDelta::FromSeconds(5), |
| 877 &exit_code); | 883 &exit_code); |
| 878 | 884 |
| 879 // Check that process was really killed. | 885 // Check that process was really killed. |
| 880 EXPECT_TRUE(IsProcessDead(child_process.Handle())); | 886 EXPECT_TRUE(IsProcessDead(spawn_child.process.Handle())); |
| 881 } | 887 } |
| 882 | 888 |
| 883 MULTIPROCESS_TEST_MAIN(process_util_test_never_die) { | 889 MULTIPROCESS_TEST_MAIN(process_util_test_never_die) { |
| 884 while (1) { | 890 while (1) { |
| 885 sleep(500); | 891 sleep(500); |
| 886 } | 892 } |
| 887 return kSuccess; | 893 return kSuccess; |
| 888 } | 894 } |
| 889 | 895 |
| 890 TEST_F(ProcessUtilTest, ImmediateTermination) { | 896 TEST_F(ProcessUtilTest, ImmediateTermination) { |
| 891 base::Process child_process = SpawnChild("process_util_test_die_immediately"); | 897 base::SpawnChildResult spawn_child = |
| 892 ASSERT_TRUE(child_process.IsValid()); | 898 SpawnChild("process_util_test_die_immediately"); |
| 899 ASSERT_TRUE(spawn_child.process.IsValid()); |
| 893 // Give it time to die. | 900 // Give it time to die. |
| 894 sleep(2); | 901 sleep(2); |
| 895 base::EnsureProcessTerminated(child_process.Duplicate()); | 902 base::EnsureProcessTerminated(spawn_child.process.Duplicate()); |
| 896 | 903 |
| 897 // Check that process was really killed. | 904 // Check that process was really killed. |
| 898 EXPECT_TRUE(IsProcessDead(child_process.Handle())); | 905 EXPECT_TRUE(IsProcessDead(spawn_child.process.Handle())); |
| 899 } | 906 } |
| 900 | 907 |
| 901 MULTIPROCESS_TEST_MAIN(process_util_test_die_immediately) { | 908 MULTIPROCESS_TEST_MAIN(process_util_test_die_immediately) { |
| 902 return kSuccess; | 909 return kSuccess; |
| 903 } | 910 } |
| 904 | 911 |
| 905 #if !defined(OS_ANDROID) | 912 #if !defined(OS_ANDROID) |
| 906 const char kPipeValue = '\xcc'; | 913 const char kPipeValue = '\xcc'; |
| 907 | 914 |
| 908 class ReadFromPipeDelegate : public base::LaunchOptions::PreExecDelegate { | 915 class ReadFromPipeDelegate : public base::LaunchOptions::PreExecDelegate { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 927 | 934 |
| 928 base::ScopedFD read_fd(pipe_fds[0]); | 935 base::ScopedFD read_fd(pipe_fds[0]); |
| 929 base::ScopedFD write_fd(pipe_fds[1]); | 936 base::ScopedFD write_fd(pipe_fds[1]); |
| 930 base::FileHandleMappingVector fds_to_remap; | 937 base::FileHandleMappingVector fds_to_remap; |
| 931 fds_to_remap.push_back(std::make_pair(read_fd.get(), read_fd.get())); | 938 fds_to_remap.push_back(std::make_pair(read_fd.get(), read_fd.get())); |
| 932 | 939 |
| 933 ReadFromPipeDelegate read_from_pipe_delegate(read_fd.get()); | 940 ReadFromPipeDelegate read_from_pipe_delegate(read_fd.get()); |
| 934 base::LaunchOptions options; | 941 base::LaunchOptions options; |
| 935 options.fds_to_remap = &fds_to_remap; | 942 options.fds_to_remap = &fds_to_remap; |
| 936 options.pre_exec_delegate = &read_from_pipe_delegate; | 943 options.pre_exec_delegate = &read_from_pipe_delegate; |
| 937 base::Process process(SpawnChildWithOptions("SimpleChildProcess", options)); | 944 base::SpawnChildResult spawn_child = |
| 938 ASSERT_TRUE(process.IsValid()); | 945 SpawnChildWithOptions("SimpleChildProcess", options); |
| 946 ASSERT_TRUE(spawn_child.process.IsValid()); |
| 939 | 947 |
| 940 read_fd.reset(); | 948 read_fd.reset(); |
| 941 ASSERT_EQ(1, HANDLE_EINTR(write(write_fd.get(), &kPipeValue, 1))); | 949 ASSERT_EQ(1, HANDLE_EINTR(write(write_fd.get(), &kPipeValue, 1))); |
| 942 | 950 |
| 943 int exit_code = 42; | 951 int exit_code = 42; |
| 944 EXPECT_TRUE(process.WaitForExit(&exit_code)); | 952 EXPECT_TRUE(spawn_child.process.WaitForExit(&exit_code)); |
| 945 EXPECT_EQ(0, exit_code); | 953 EXPECT_EQ(0, exit_code); |
| 946 } | 954 } |
| 947 #endif // !defined(OS_ANDROID) | 955 #endif // !defined(OS_ANDROID) |
| 948 | 956 |
| 949 #endif // defined(OS_POSIX) | 957 #endif // defined(OS_POSIX) |
| 950 | 958 |
| 951 #if defined(OS_LINUX) | 959 #if defined(OS_LINUX) |
| 952 MULTIPROCESS_TEST_MAIN(CheckPidProcess) { | 960 MULTIPROCESS_TEST_MAIN(CheckPidProcess) { |
| 953 const pid_t kInitPid = 1; | 961 const pid_t kInitPid = 1; |
| 954 const pid_t pid = syscall(__NR_getpid); | 962 const pid_t pid = syscall(__NR_getpid); |
| 955 CHECK(pid == kInitPid); | 963 CHECK(pid == kInitPid); |
| 956 CHECK(getpid() == pid); | 964 CHECK(getpid() == pid); |
| 957 return kSuccess; | 965 return kSuccess; |
| 958 } | 966 } |
| 959 | 967 |
| 960 #if defined(CLONE_NEWUSER) && defined(CLONE_NEWPID) | 968 #if defined(CLONE_NEWUSER) && defined(CLONE_NEWPID) |
| 961 TEST_F(ProcessUtilTest, CloneFlags) { | 969 TEST_F(ProcessUtilTest, CloneFlags) { |
| 962 if (RunningOnValgrind() || | 970 if (RunningOnValgrind() || |
| 963 !base::PathExists(FilePath("/proc/self/ns/user")) || | 971 !base::PathExists(FilePath("/proc/self/ns/user")) || |
| 964 !base::PathExists(FilePath("/proc/self/ns/pid"))) { | 972 !base::PathExists(FilePath("/proc/self/ns/pid"))) { |
| 965 // User or PID namespaces are not supported. | 973 // User or PID namespaces are not supported. |
| 966 return; | 974 return; |
| 967 } | 975 } |
| 968 | 976 |
| 969 base::LaunchOptions options; | 977 base::LaunchOptions options; |
| 970 options.clone_flags = CLONE_NEWUSER | CLONE_NEWPID; | 978 options.clone_flags = CLONE_NEWUSER | CLONE_NEWPID; |
| 971 | 979 |
| 972 base::Process process(SpawnChildWithOptions("CheckPidProcess", options)); | 980 base::SpawnChildResult spawn_child = |
| 973 ASSERT_TRUE(process.IsValid()); | 981 SpawnChildWithOptions("CheckPidProcess", options); |
| 982 ASSERT_TRUE(spawn_child.process.IsValid()); |
| 974 | 983 |
| 975 int exit_code = 42; | 984 int exit_code = 42; |
| 976 EXPECT_TRUE(process.WaitForExit(&exit_code)); | 985 EXPECT_TRUE(spawn_child.process.WaitForExit(&exit_code)); |
| 977 EXPECT_EQ(kSuccess, exit_code); | 986 EXPECT_EQ(kSuccess, exit_code); |
| 978 } | 987 } |
| 979 #endif // defined(CLONE_NEWUSER) && defined(CLONE_NEWPID) | 988 #endif // defined(CLONE_NEWUSER) && defined(CLONE_NEWPID) |
| 980 | 989 |
| 981 TEST(ForkWithFlagsTest, UpdatesPidCache) { | 990 TEST(ForkWithFlagsTest, UpdatesPidCache) { |
| 982 // The libc clone function, which allows ForkWithFlags to keep the pid cache | 991 // The libc clone function, which allows ForkWithFlags to keep the pid cache |
| 983 // up to date, does not work on Valgrind. | 992 // up to date, does not work on Valgrind. |
| 984 if (RunningOnValgrind()) { | 993 if (RunningOnValgrind()) { |
| 985 return; | 994 return; |
| 986 } | 995 } |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1003 int status = 42; | 1012 int status = 42; |
| 1004 ASSERT_EQ(pid, HANDLE_EINTR(waitpid(pid, &status, 0))); | 1013 ASSERT_EQ(pid, HANDLE_EINTR(waitpid(pid, &status, 0))); |
| 1005 ASSERT_TRUE(WIFEXITED(status)); | 1014 ASSERT_TRUE(WIFEXITED(status)); |
| 1006 EXPECT_EQ(kSuccess, WEXITSTATUS(status)); | 1015 EXPECT_EQ(kSuccess, WEXITSTATUS(status)); |
| 1007 } | 1016 } |
| 1008 | 1017 |
| 1009 TEST_F(ProcessUtilTest, InvalidCurrentDirectory) { | 1018 TEST_F(ProcessUtilTest, InvalidCurrentDirectory) { |
| 1010 base::LaunchOptions options; | 1019 base::LaunchOptions options; |
| 1011 options.current_directory = base::FilePath("/dev/null"); | 1020 options.current_directory = base::FilePath("/dev/null"); |
| 1012 | 1021 |
| 1013 base::Process process(SpawnChildWithOptions("SimpleChildProcess", options)); | 1022 base::SpawnChildResult spawn_child = |
| 1014 ASSERT_TRUE(process.IsValid()); | 1023 SpawnChildWithOptions("SimpleChildProcess", options); |
| 1024 ASSERT_TRUE(spawn_child.process.IsValid()); |
| 1015 | 1025 |
| 1016 int exit_code = kSuccess; | 1026 int exit_code = kSuccess; |
| 1017 EXPECT_TRUE(process.WaitForExit(&exit_code)); | 1027 EXPECT_TRUE(spawn_child.process.WaitForExit(&exit_code)); |
| 1018 EXPECT_NE(kSuccess, exit_code); | 1028 EXPECT_NE(kSuccess, exit_code); |
| 1019 } | 1029 } |
| 1020 #endif // defined(OS_LINUX) | 1030 #endif // defined(OS_LINUX) |
| OLD | NEW |