| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/process/process.h" | 5 #include "base/process/process.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/at_exit.h" | 9 #include "base/at_exit.h" |
| 10 #include "base/process/kill.h" | 10 #include "base/process/kill.h" |
| (...skipping 24 matching lines...) Expand all Loading... |
| 35 #endif | 35 #endif |
| 36 | 36 |
| 37 } // namespace | 37 } // namespace |
| 38 | 38 |
| 39 namespace base { | 39 namespace base { |
| 40 | 40 |
| 41 class ProcessTest : public MultiProcessTest { | 41 class ProcessTest : public MultiProcessTest { |
| 42 }; | 42 }; |
| 43 | 43 |
| 44 TEST_F(ProcessTest, Create) { | 44 TEST_F(ProcessTest, Create) { |
| 45 Process process(SpawnChild("SimpleChildProcess")); | 45 SpawnChildResult spawn_result = SpawnChild("SimpleChildProcess"); |
| 46 Process process(std::move(spawn_result.process)); |
| 46 ASSERT_TRUE(process.IsValid()); | 47 ASSERT_TRUE(process.IsValid()); |
| 47 ASSERT_FALSE(process.is_current()); | 48 ASSERT_FALSE(process.is_current()); |
| 48 process.Close(); | 49 process.Close(); |
| 49 ASSERT_FALSE(process.IsValid()); | 50 ASSERT_FALSE(process.IsValid()); |
| 50 } | 51 } |
| 51 | 52 |
| 52 TEST_F(ProcessTest, CreateCurrent) { | 53 TEST_F(ProcessTest, CreateCurrent) { |
| 53 Process process = Process::Current(); | 54 Process process = Process::Current(); |
| 54 ASSERT_TRUE(process.IsValid()); | 55 ASSERT_TRUE(process.IsValid()); |
| 55 ASSERT_TRUE(process.is_current()); | 56 ASSERT_TRUE(process.is_current()); |
| 56 process.Close(); | 57 process.Close(); |
| 57 ASSERT_FALSE(process.IsValid()); | 58 ASSERT_FALSE(process.IsValid()); |
| 58 } | 59 } |
| 59 | 60 |
| 60 TEST_F(ProcessTest, Move) { | 61 TEST_F(ProcessTest, Move) { |
| 61 Process process1(SpawnChild("SimpleChildProcess")); | 62 SpawnChildResult spawn_result = SpawnChild("SimpleChildProcess"); |
| 63 Process process1(std::move(spawn_result.process)); |
| 62 EXPECT_TRUE(process1.IsValid()); | 64 EXPECT_TRUE(process1.IsValid()); |
| 63 | 65 |
| 64 Process process2; | 66 Process process2; |
| 65 EXPECT_FALSE(process2.IsValid()); | 67 EXPECT_FALSE(process2.IsValid()); |
| 66 | 68 |
| 67 process2 = std::move(process1); | 69 process2 = std::move(process1); |
| 68 EXPECT_TRUE(process2.IsValid()); | 70 EXPECT_TRUE(process2.IsValid()); |
| 69 EXPECT_FALSE(process1.IsValid()); | 71 EXPECT_FALSE(process1.IsValid()); |
| 70 EXPECT_FALSE(process2.is_current()); | 72 EXPECT_FALSE(process2.is_current()); |
| 71 | 73 |
| 72 Process process3 = Process::Current(); | 74 Process process3 = Process::Current(); |
| 73 process2 = std::move(process3); | 75 process2 = std::move(process3); |
| 74 EXPECT_TRUE(process2.is_current()); | 76 EXPECT_TRUE(process2.is_current()); |
| 75 EXPECT_TRUE(process2.IsValid()); | 77 EXPECT_TRUE(process2.IsValid()); |
| 76 EXPECT_FALSE(process3.IsValid()); | 78 EXPECT_FALSE(process3.IsValid()); |
| 77 } | 79 } |
| 78 | 80 |
| 79 TEST_F(ProcessTest, Duplicate) { | 81 TEST_F(ProcessTest, Duplicate) { |
| 80 Process process1(SpawnChild("SimpleChildProcess")); | 82 SpawnChildResult spawn_result = SpawnChild("SimpleChildProcess"); |
| 83 Process process1(std::move(spawn_result.process)); |
| 81 ASSERT_TRUE(process1.IsValid()); | 84 ASSERT_TRUE(process1.IsValid()); |
| 82 | 85 |
| 83 Process process2 = process1.Duplicate(); | 86 Process process2 = process1.Duplicate(); |
| 84 ASSERT_TRUE(process1.IsValid()); | 87 ASSERT_TRUE(process1.IsValid()); |
| 85 ASSERT_TRUE(process2.IsValid()); | 88 ASSERT_TRUE(process2.IsValid()); |
| 86 EXPECT_EQ(process1.Pid(), process2.Pid()); | 89 EXPECT_EQ(process1.Pid(), process2.Pid()); |
| 87 EXPECT_FALSE(process1.is_current()); | 90 EXPECT_FALSE(process1.is_current()); |
| 88 EXPECT_FALSE(process2.is_current()); | 91 EXPECT_FALSE(process2.is_current()); |
| 89 | 92 |
| 90 process1.Close(); | 93 process1.Close(); |
| 91 ASSERT_TRUE(process2.IsValid()); | 94 ASSERT_TRUE(process2.IsValid()); |
| 92 } | 95 } |
| 93 | 96 |
| 94 TEST_F(ProcessTest, DuplicateCurrent) { | 97 TEST_F(ProcessTest, DuplicateCurrent) { |
| 95 Process process1 = Process::Current(); | 98 Process process1 = Process::Current(); |
| 96 ASSERT_TRUE(process1.IsValid()); | 99 ASSERT_TRUE(process1.IsValid()); |
| 97 | 100 |
| 98 Process process2 = process1.Duplicate(); | 101 Process process2 = process1.Duplicate(); |
| 99 ASSERT_TRUE(process1.IsValid()); | 102 ASSERT_TRUE(process1.IsValid()); |
| 100 ASSERT_TRUE(process2.IsValid()); | 103 ASSERT_TRUE(process2.IsValid()); |
| 101 EXPECT_EQ(process1.Pid(), process2.Pid()); | 104 EXPECT_EQ(process1.Pid(), process2.Pid()); |
| 102 EXPECT_TRUE(process1.is_current()); | 105 EXPECT_TRUE(process1.is_current()); |
| 103 EXPECT_TRUE(process2.is_current()); | 106 EXPECT_TRUE(process2.is_current()); |
| 104 | 107 |
| 105 process1.Close(); | 108 process1.Close(); |
| 106 ASSERT_TRUE(process2.IsValid()); | 109 ASSERT_TRUE(process2.IsValid()); |
| 107 } | 110 } |
| 108 | 111 |
| 109 TEST_F(ProcessTest, DeprecatedGetProcessFromHandle) { | 112 TEST_F(ProcessTest, DeprecatedGetProcessFromHandle) { |
| 110 Process process1(SpawnChild("SimpleChildProcess")); | 113 SpawnChildResult spawn_result = SpawnChild("SimpleChildProcess"); |
| 114 Process process1(std::move(spawn_result.process)); |
| 111 ASSERT_TRUE(process1.IsValid()); | 115 ASSERT_TRUE(process1.IsValid()); |
| 112 | 116 |
| 113 Process process2 = Process::DeprecatedGetProcessFromHandle(process1.Handle()); | 117 Process process2 = Process::DeprecatedGetProcessFromHandle(process1.Handle()); |
| 114 ASSERT_TRUE(process1.IsValid()); | 118 ASSERT_TRUE(process1.IsValid()); |
| 115 ASSERT_TRUE(process2.IsValid()); | 119 ASSERT_TRUE(process2.IsValid()); |
| 116 EXPECT_EQ(process1.Pid(), process2.Pid()); | 120 EXPECT_EQ(process1.Pid(), process2.Pid()); |
| 117 EXPECT_FALSE(process1.is_current()); | 121 EXPECT_FALSE(process1.is_current()); |
| 118 EXPECT_FALSE(process2.is_current()); | 122 EXPECT_FALSE(process2.is_current()); |
| 119 | 123 |
| 120 process1.Close(); | 124 process1.Close(); |
| 121 ASSERT_TRUE(process2.IsValid()); | 125 ASSERT_TRUE(process2.IsValid()); |
| 122 } | 126 } |
| 123 | 127 |
| 124 MULTIPROCESS_TEST_MAIN(SleepyChildProcess) { | 128 MULTIPROCESS_TEST_MAIN(SleepyChildProcess) { |
| 125 PlatformThread::Sleep(TestTimeouts::action_max_timeout()); | 129 PlatformThread::Sleep(TestTimeouts::action_max_timeout()); |
| 126 return 0; | 130 return 0; |
| 127 } | 131 } |
| 128 | 132 |
| 129 TEST_F(ProcessTest, Terminate) { | 133 TEST_F(ProcessTest, Terminate) { |
| 130 Process process(SpawnChild("SleepyChildProcess")); | 134 SpawnChildResult spawn_result = SpawnChild("SleepyChildProcess"); |
| 135 Process process(std::move(spawn_result.process)); |
| 131 ASSERT_TRUE(process.IsValid()); | 136 ASSERT_TRUE(process.IsValid()); |
| 132 | 137 |
| 133 const int kDummyExitCode = 42; | 138 const int kDummyExitCode = 42; |
| 134 int exit_code = kDummyExitCode; | 139 int exit_code = kDummyExitCode; |
| 135 EXPECT_EQ(TERMINATION_STATUS_STILL_RUNNING, | 140 EXPECT_EQ(TERMINATION_STATUS_STILL_RUNNING, |
| 136 GetTerminationStatus(process.Handle(), &exit_code)); | 141 GetTerminationStatus(process.Handle(), &exit_code)); |
| 137 EXPECT_EQ(kExpectedStillRunningExitCode, exit_code); | 142 EXPECT_EQ(kExpectedStillRunningExitCode, exit_code); |
| 138 | 143 |
| 139 exit_code = kDummyExitCode; | 144 exit_code = kDummyExitCode; |
| 140 int kExpectedExitCode = 250; | 145 int kExpectedExitCode = 250; |
| (...skipping 25 matching lines...) Expand all Loading... |
| 166 | 171 |
| 167 MULTIPROCESS_TEST_MAIN(TerminateCurrentProcessImmediatelyWithCode0) { | 172 MULTIPROCESS_TEST_MAIN(TerminateCurrentProcessImmediatelyWithCode0) { |
| 168 base::ThreadLocalPointer<ThreadLocalObject> object; | 173 base::ThreadLocalPointer<ThreadLocalObject> object; |
| 169 base::AtExitManager::RegisterCallback(&AtExitHandler, NULL); | 174 base::AtExitManager::RegisterCallback(&AtExitHandler, NULL); |
| 170 Process::TerminateCurrentProcessImmediately(0); | 175 Process::TerminateCurrentProcessImmediately(0); |
| 171 NOTREACHED(); | 176 NOTREACHED(); |
| 172 return 42; | 177 return 42; |
| 173 } | 178 } |
| 174 | 179 |
| 175 TEST_F(ProcessTest, TerminateCurrentProcessImmediatelyWithZeroExitCode) { | 180 TEST_F(ProcessTest, TerminateCurrentProcessImmediatelyWithZeroExitCode) { |
| 176 Process process(SpawnChild("TerminateCurrentProcessImmediatelyWithCode0")); | 181 SpawnChildResult spawn_result = |
| 182 SpawnChild("TerminateCurrentProcessImmediatelyWithCode0"); |
| 183 Process process(std::move(spawn_result.process)); |
| 177 ASSERT_TRUE(process.IsValid()); | 184 ASSERT_TRUE(process.IsValid()); |
| 178 int exit_code = 42; | 185 int exit_code = 42; |
| 179 ASSERT_TRUE(process.WaitForExitWithTimeout(TestTimeouts::action_max_timeout(), | 186 ASSERT_TRUE(process.WaitForExitWithTimeout(TestTimeouts::action_max_timeout(), |
| 180 &exit_code)); | 187 &exit_code)); |
| 181 EXPECT_EQ(0, exit_code); | 188 EXPECT_EQ(0, exit_code); |
| 182 } | 189 } |
| 183 | 190 |
| 184 MULTIPROCESS_TEST_MAIN(TerminateCurrentProcessImmediatelyWithCode250) { | 191 MULTIPROCESS_TEST_MAIN(TerminateCurrentProcessImmediatelyWithCode250) { |
| 185 Process::TerminateCurrentProcessImmediately(250); | 192 Process::TerminateCurrentProcessImmediately(250); |
| 186 NOTREACHED(); | 193 NOTREACHED(); |
| 187 return 42; | 194 return 42; |
| 188 } | 195 } |
| 189 | 196 |
| 190 TEST_F(ProcessTest, TerminateCurrentProcessImmediatelyWithNonZeroExitCode) { | 197 TEST_F(ProcessTest, TerminateCurrentProcessImmediatelyWithNonZeroExitCode) { |
| 191 Process process(SpawnChild("TerminateCurrentProcessImmediatelyWithCode250")); | 198 SpawnChildResult spawn_result = |
| 199 SpawnChild("TerminateCurrentProcessImmediatelyWithCode250"); |
| 200 Process process(std::move(spawn_result.process)); |
| 192 ASSERT_TRUE(process.IsValid()); | 201 ASSERT_TRUE(process.IsValid()); |
| 193 int exit_code = 42; | 202 int exit_code = 42; |
| 194 ASSERT_TRUE(process.WaitForExitWithTimeout(TestTimeouts::action_max_timeout(), | 203 ASSERT_TRUE(process.WaitForExitWithTimeout(TestTimeouts::action_max_timeout(), |
| 195 &exit_code)); | 204 &exit_code)); |
| 196 EXPECT_EQ(250, exit_code); | 205 EXPECT_EQ(250, exit_code); |
| 197 } | 206 } |
| 198 | 207 |
| 199 MULTIPROCESS_TEST_MAIN(FastSleepyChildProcess) { | 208 MULTIPROCESS_TEST_MAIN(FastSleepyChildProcess) { |
| 200 PlatformThread::Sleep(TestTimeouts::tiny_timeout() * 10); | 209 PlatformThread::Sleep(TestTimeouts::tiny_timeout() * 10); |
| 201 return 0; | 210 return 0; |
| 202 } | 211 } |
| 203 | 212 |
| 204 TEST_F(ProcessTest, WaitForExit) { | 213 TEST_F(ProcessTest, WaitForExit) { |
| 205 Process process(SpawnChild("FastSleepyChildProcess")); | 214 SpawnChildResult spawn_result = SpawnChild("FastSleepyChildProcess"); |
| 215 Process process(std::move(spawn_result.process)); |
| 206 ASSERT_TRUE(process.IsValid()); | 216 ASSERT_TRUE(process.IsValid()); |
| 207 | 217 |
| 208 const int kDummyExitCode = 42; | 218 const int kDummyExitCode = 42; |
| 209 int exit_code = kDummyExitCode; | 219 int exit_code = kDummyExitCode; |
| 210 EXPECT_TRUE(process.WaitForExit(&exit_code)); | 220 EXPECT_TRUE(process.WaitForExit(&exit_code)); |
| 211 EXPECT_EQ(0, exit_code); | 221 EXPECT_EQ(0, exit_code); |
| 212 } | 222 } |
| 213 | 223 |
| 214 TEST_F(ProcessTest, WaitForExitWithTimeout) { | 224 TEST_F(ProcessTest, WaitForExitWithTimeout) { |
| 215 Process process(SpawnChild("SleepyChildProcess")); | 225 SpawnChildResult spawn_result = SpawnChild("SleepyChildProcess"); |
| 226 Process process(std::move(spawn_result.process)); |
| 216 ASSERT_TRUE(process.IsValid()); | 227 ASSERT_TRUE(process.IsValid()); |
| 217 | 228 |
| 218 const int kDummyExitCode = 42; | 229 const int kDummyExitCode = 42; |
| 219 int exit_code = kDummyExitCode; | 230 int exit_code = kDummyExitCode; |
| 220 TimeDelta timeout = TestTimeouts::tiny_timeout(); | 231 TimeDelta timeout = TestTimeouts::tiny_timeout(); |
| 221 EXPECT_FALSE(process.WaitForExitWithTimeout(timeout, &exit_code)); | 232 EXPECT_FALSE(process.WaitForExitWithTimeout(timeout, &exit_code)); |
| 222 EXPECT_EQ(kDummyExitCode, exit_code); | 233 EXPECT_EQ(kDummyExitCode, exit_code); |
| 223 | 234 |
| 224 process.Terminate(kDummyExitCode, false); | 235 process.Terminate(kDummyExitCode, false); |
| 225 } | 236 } |
| 226 | 237 |
| 227 // Ensure that the priority of a process is restored correctly after | 238 // Ensure that the priority of a process is restored correctly after |
| 228 // backgrounding and restoring. | 239 // backgrounding and restoring. |
| 229 // Note: a platform may not be willing or able to lower the priority of | 240 // Note: a platform may not be willing or able to lower the priority of |
| 230 // a process. The calls to SetProcessBackground should be noops then. | 241 // a process. The calls to SetProcessBackground should be noops then. |
| 231 TEST_F(ProcessTest, SetProcessBackgrounded) { | 242 TEST_F(ProcessTest, SetProcessBackgrounded) { |
| 232 if (!Process::CanBackgroundProcesses()) | 243 if (!Process::CanBackgroundProcesses()) |
| 233 return; | 244 return; |
| 234 Process process(SpawnChild("SimpleChildProcess")); | 245 SpawnChildResult spawn_result = SpawnChild("SimpleChildProcess"); |
| 246 Process process(std::move(spawn_result.process)); |
| 235 int old_priority = process.GetPriority(); | 247 int old_priority = process.GetPriority(); |
| 236 #if defined(OS_WIN) | 248 #if defined(OS_WIN) |
| 237 EXPECT_TRUE(process.SetProcessBackgrounded(true)); | 249 EXPECT_TRUE(process.SetProcessBackgrounded(true)); |
| 238 EXPECT_TRUE(process.IsProcessBackgrounded()); | 250 EXPECT_TRUE(process.IsProcessBackgrounded()); |
| 239 EXPECT_TRUE(process.SetProcessBackgrounded(false)); | 251 EXPECT_TRUE(process.SetProcessBackgrounded(false)); |
| 240 EXPECT_FALSE(process.IsProcessBackgrounded()); | 252 EXPECT_FALSE(process.IsProcessBackgrounded()); |
| 241 #elif defined(OS_MACOSX) | 253 #elif defined(OS_MACOSX) |
| 242 // On the Mac, backgrounding a process requires a port to that process. | 254 // On the Mac, backgrounding a process requires a port to that process. |
| 243 // In the browser it's available through the MachBroker class, which is not | 255 // In the browser it's available through the MachBroker class, which is not |
| 244 // part of base. Additionally, there is an indefinite amount of time between | 256 // part of base. Additionally, there is an indefinite amount of time between |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 295 "2:freezer:/chrome_renderers/to_be_frozen\n" | 307 "2:freezer:/chrome_renderers/to_be_frozen\n" |
| 296 "1:cpu:/chrome_renderers/background\n"; | 308 "1:cpu:/chrome_renderers/background\n"; |
| 297 | 309 |
| 298 EXPECT_FALSE(IsProcessBackgroundedCGroup(kNotBackgrounded)); | 310 EXPECT_FALSE(IsProcessBackgroundedCGroup(kNotBackgrounded)); |
| 299 EXPECT_TRUE(IsProcessBackgroundedCGroup(kBackgrounded)); | 311 EXPECT_TRUE(IsProcessBackgroundedCGroup(kBackgrounded)); |
| 300 } | 312 } |
| 301 | 313 |
| 302 #endif // defined(OS_CHROMEOS) | 314 #endif // defined(OS_CHROMEOS) |
| 303 | 315 |
| 304 } // namespace base | 316 } // namespace base |
| OLD | NEW |