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_child = SpawnChild("SimpleChildProcess"); |
46 ASSERT_TRUE(process.IsValid()); | 46 ASSERT_TRUE(spawn_child.process.IsValid()); |
47 ASSERT_FALSE(process.is_current()); | 47 ASSERT_FALSE(spawn_child.process.is_current()); |
48 process.Close(); | 48 spawn_child.process.Close(); |
49 ASSERT_FALSE(process.IsValid()); | 49 ASSERT_FALSE(spawn_child.process.IsValid()); |
50 } | 50 } |
51 | 51 |
52 TEST_F(ProcessTest, CreateCurrent) { | 52 TEST_F(ProcessTest, CreateCurrent) { |
53 Process process = Process::Current(); | 53 Process process = Process::Current(); |
54 ASSERT_TRUE(process.IsValid()); | 54 ASSERT_TRUE(process.IsValid()); |
55 ASSERT_TRUE(process.is_current()); | 55 ASSERT_TRUE(process.is_current()); |
56 process.Close(); | 56 process.Close(); |
57 ASSERT_FALSE(process.IsValid()); | 57 ASSERT_FALSE(process.IsValid()); |
58 } | 58 } |
59 | 59 |
60 TEST_F(ProcessTest, Move) { | 60 TEST_F(ProcessTest, Move) { |
61 Process process1(SpawnChild("SimpleChildProcess")); | 61 SpawnChildResult spawn_result = SpawnChild("SimpleChildProcess"); |
| 62 Process& process1 = spawn_result.process; |
62 EXPECT_TRUE(process1.IsValid()); | 63 EXPECT_TRUE(process1.IsValid()); |
63 | 64 |
64 Process process2; | 65 Process process2; |
65 EXPECT_FALSE(process2.IsValid()); | 66 EXPECT_FALSE(process2.IsValid()); |
66 | 67 |
67 process2 = std::move(process1); | 68 process2 = std::move(process1); |
68 EXPECT_TRUE(process2.IsValid()); | 69 EXPECT_TRUE(process2.IsValid()); |
69 EXPECT_FALSE(process1.IsValid()); | 70 EXPECT_FALSE(process1.IsValid()); |
70 EXPECT_FALSE(process2.is_current()); | 71 EXPECT_FALSE(process2.is_current()); |
71 | 72 |
72 Process process3 = Process::Current(); | 73 Process process3 = Process::Current(); |
73 process2 = std::move(process3); | 74 process2 = std::move(process3); |
74 EXPECT_TRUE(process2.is_current()); | 75 EXPECT_TRUE(process2.is_current()); |
75 EXPECT_TRUE(process2.IsValid()); | 76 EXPECT_TRUE(process2.IsValid()); |
76 EXPECT_FALSE(process3.IsValid()); | 77 EXPECT_FALSE(process3.IsValid()); |
77 } | 78 } |
78 | 79 |
79 TEST_F(ProcessTest, Duplicate) { | 80 TEST_F(ProcessTest, Duplicate) { |
80 Process process1(SpawnChild("SimpleChildProcess")); | 81 SpawnChildResult spawn_result = SpawnChild("SimpleChildProcess"); |
| 82 Process& process1 = spawn_result.process; |
81 ASSERT_TRUE(process1.IsValid()); | 83 ASSERT_TRUE(process1.IsValid()); |
82 | 84 |
83 Process process2 = process1.Duplicate(); | 85 Process process2 = process1.Duplicate(); |
84 ASSERT_TRUE(process1.IsValid()); | 86 ASSERT_TRUE(process1.IsValid()); |
85 ASSERT_TRUE(process2.IsValid()); | 87 ASSERT_TRUE(process2.IsValid()); |
86 EXPECT_EQ(process1.Pid(), process2.Pid()); | 88 EXPECT_EQ(process1.Pid(), process2.Pid()); |
87 EXPECT_FALSE(process1.is_current()); | 89 EXPECT_FALSE(process1.is_current()); |
88 EXPECT_FALSE(process2.is_current()); | 90 EXPECT_FALSE(process2.is_current()); |
89 | 91 |
90 process1.Close(); | 92 process1.Close(); |
91 ASSERT_TRUE(process2.IsValid()); | 93 ASSERT_TRUE(process2.IsValid()); |
92 } | 94 } |
93 | 95 |
94 TEST_F(ProcessTest, DuplicateCurrent) { | 96 TEST_F(ProcessTest, DuplicateCurrent) { |
95 Process process1 = Process::Current(); | 97 Process process1 = Process::Current(); |
96 ASSERT_TRUE(process1.IsValid()); | 98 ASSERT_TRUE(process1.IsValid()); |
97 | 99 |
98 Process process2 = process1.Duplicate(); | 100 Process process2 = process1.Duplicate(); |
99 ASSERT_TRUE(process1.IsValid()); | 101 ASSERT_TRUE(process1.IsValid()); |
100 ASSERT_TRUE(process2.IsValid()); | 102 ASSERT_TRUE(process2.IsValid()); |
101 EXPECT_EQ(process1.Pid(), process2.Pid()); | 103 EXPECT_EQ(process1.Pid(), process2.Pid()); |
102 EXPECT_TRUE(process1.is_current()); | 104 EXPECT_TRUE(process1.is_current()); |
103 EXPECT_TRUE(process2.is_current()); | 105 EXPECT_TRUE(process2.is_current()); |
104 | 106 |
105 process1.Close(); | 107 process1.Close(); |
106 ASSERT_TRUE(process2.IsValid()); | 108 ASSERT_TRUE(process2.IsValid()); |
107 } | 109 } |
108 | 110 |
109 TEST_F(ProcessTest, DeprecatedGetProcessFromHandle) { | 111 TEST_F(ProcessTest, DeprecatedGetProcessFromHandle) { |
110 Process process1(SpawnChild("SimpleChildProcess")); | 112 SpawnChildResult spawn_result = SpawnChild("SimpleChildProcess"); |
| 113 Process& process1 = spawn_result.process; |
111 ASSERT_TRUE(process1.IsValid()); | 114 ASSERT_TRUE(process1.IsValid()); |
112 | 115 |
113 Process process2 = Process::DeprecatedGetProcessFromHandle(process1.Handle()); | 116 Process process2 = Process::DeprecatedGetProcessFromHandle(process1.Handle()); |
114 ASSERT_TRUE(process1.IsValid()); | 117 ASSERT_TRUE(process1.IsValid()); |
115 ASSERT_TRUE(process2.IsValid()); | 118 ASSERT_TRUE(process2.IsValid()); |
116 EXPECT_EQ(process1.Pid(), process2.Pid()); | 119 EXPECT_EQ(process1.Pid(), process2.Pid()); |
117 EXPECT_FALSE(process1.is_current()); | 120 EXPECT_FALSE(process1.is_current()); |
118 EXPECT_FALSE(process2.is_current()); | 121 EXPECT_FALSE(process2.is_current()); |
119 | 122 |
120 process1.Close(); | 123 process1.Close(); |
121 ASSERT_TRUE(process2.IsValid()); | 124 ASSERT_TRUE(process2.IsValid()); |
122 } | 125 } |
123 | 126 |
124 MULTIPROCESS_TEST_MAIN(SleepyChildProcess) { | 127 MULTIPROCESS_TEST_MAIN(SleepyChildProcess) { |
125 PlatformThread::Sleep(TestTimeouts::action_max_timeout()); | 128 PlatformThread::Sleep(TestTimeouts::action_max_timeout()); |
126 return 0; | 129 return 0; |
127 } | 130 } |
128 | 131 |
129 TEST_F(ProcessTest, Terminate) { | 132 TEST_F(ProcessTest, Terminate) { |
130 Process process(SpawnChild("SleepyChildProcess")); | 133 SpawnChildResult spawn_result = SpawnChild("SleepyChildProcess"); |
| 134 Process& process = spawn_result.process; |
131 ASSERT_TRUE(process.IsValid()); | 135 ASSERT_TRUE(process.IsValid()); |
132 | 136 |
133 const int kDummyExitCode = 42; | 137 const int kDummyExitCode = 42; |
134 int exit_code = kDummyExitCode; | 138 int exit_code = kDummyExitCode; |
135 EXPECT_EQ(TERMINATION_STATUS_STILL_RUNNING, | 139 EXPECT_EQ(TERMINATION_STATUS_STILL_RUNNING, |
136 GetTerminationStatus(process.Handle(), &exit_code)); | 140 GetTerminationStatus(process.Handle(), &exit_code)); |
137 EXPECT_EQ(kExpectedStillRunningExitCode, exit_code); | 141 EXPECT_EQ(kExpectedStillRunningExitCode, exit_code); |
138 | 142 |
139 exit_code = kDummyExitCode; | 143 exit_code = kDummyExitCode; |
140 int kExpectedExitCode = 250; | 144 int kExpectedExitCode = 250; |
(...skipping 25 matching lines...) Expand all Loading... |
166 | 170 |
167 MULTIPROCESS_TEST_MAIN(TerminateCurrentProcessImmediatelyWithCode0) { | 171 MULTIPROCESS_TEST_MAIN(TerminateCurrentProcessImmediatelyWithCode0) { |
168 base::ThreadLocalPointer<ThreadLocalObject> object; | 172 base::ThreadLocalPointer<ThreadLocalObject> object; |
169 base::AtExitManager::RegisterCallback(&AtExitHandler, NULL); | 173 base::AtExitManager::RegisterCallback(&AtExitHandler, NULL); |
170 Process::TerminateCurrentProcessImmediately(0); | 174 Process::TerminateCurrentProcessImmediately(0); |
171 NOTREACHED(); | 175 NOTREACHED(); |
172 return 42; | 176 return 42; |
173 } | 177 } |
174 | 178 |
175 TEST_F(ProcessTest, TerminateCurrentProcessImmediatelyWithZeroExitCode) { | 179 TEST_F(ProcessTest, TerminateCurrentProcessImmediatelyWithZeroExitCode) { |
176 Process process(SpawnChild("TerminateCurrentProcessImmediatelyWithCode0")); | 180 SpawnChildResult spawn_child = |
177 ASSERT_TRUE(process.IsValid()); | 181 SpawnChild("TerminateCurrentProcessImmediatelyWithCode0"); |
| 182 ASSERT_TRUE(spawn_child.process.IsValid()); |
178 int exit_code = 42; | 183 int exit_code = 42; |
179 ASSERT_TRUE(process.WaitForExitWithTimeout(TestTimeouts::action_max_timeout(), | 184 ASSERT_TRUE(spawn_child.process.WaitForExitWithTimeout( |
180 &exit_code)); | 185 TestTimeouts::action_max_timeout(), &exit_code)); |
181 EXPECT_EQ(0, exit_code); | 186 EXPECT_EQ(0, exit_code); |
182 } | 187 } |
183 | 188 |
184 MULTIPROCESS_TEST_MAIN(TerminateCurrentProcessImmediatelyWithCode250) { | 189 MULTIPROCESS_TEST_MAIN(TerminateCurrentProcessImmediatelyWithCode250) { |
185 Process::TerminateCurrentProcessImmediately(250); | 190 Process::TerminateCurrentProcessImmediately(250); |
186 NOTREACHED(); | 191 NOTREACHED(); |
187 return 42; | 192 return 42; |
188 } | 193 } |
189 | 194 |
190 TEST_F(ProcessTest, TerminateCurrentProcessImmediatelyWithNonZeroExitCode) { | 195 TEST_F(ProcessTest, TerminateCurrentProcessImmediatelyWithNonZeroExitCode) { |
191 Process process(SpawnChild("TerminateCurrentProcessImmediatelyWithCode250")); | 196 SpawnChildResult spawn_child = |
192 ASSERT_TRUE(process.IsValid()); | 197 SpawnChild("TerminateCurrentProcessImmediatelyWithCode250"); |
| 198 ASSERT_TRUE(spawn_child.process.IsValid()); |
193 int exit_code = 42; | 199 int exit_code = 42; |
194 ASSERT_TRUE(process.WaitForExitWithTimeout(TestTimeouts::action_max_timeout(), | 200 ASSERT_TRUE(spawn_child.process.WaitForExitWithTimeout( |
195 &exit_code)); | 201 TestTimeouts::action_max_timeout(), &exit_code)); |
196 EXPECT_EQ(250, exit_code); | 202 EXPECT_EQ(250, exit_code); |
197 } | 203 } |
198 | 204 |
199 MULTIPROCESS_TEST_MAIN(FastSleepyChildProcess) { | 205 MULTIPROCESS_TEST_MAIN(FastSleepyChildProcess) { |
200 PlatformThread::Sleep(TestTimeouts::tiny_timeout() * 10); | 206 PlatformThread::Sleep(TestTimeouts::tiny_timeout() * 10); |
201 return 0; | 207 return 0; |
202 } | 208 } |
203 | 209 |
204 TEST_F(ProcessTest, WaitForExit) { | 210 TEST_F(ProcessTest, WaitForExit) { |
205 Process process(SpawnChild("FastSleepyChildProcess")); | 211 SpawnChildResult spawn_child = SpawnChild("FastSleepyChildProcess"); |
206 ASSERT_TRUE(process.IsValid()); | 212 ASSERT_TRUE(spawn_child.process.IsValid()); |
207 | 213 |
208 const int kDummyExitCode = 42; | 214 const int kDummyExitCode = 42; |
209 int exit_code = kDummyExitCode; | 215 int exit_code = kDummyExitCode; |
210 EXPECT_TRUE(process.WaitForExit(&exit_code)); | 216 EXPECT_TRUE(spawn_child.process.WaitForExit(&exit_code)); |
211 EXPECT_EQ(0, exit_code); | 217 EXPECT_EQ(0, exit_code); |
212 } | 218 } |
213 | 219 |
214 TEST_F(ProcessTest, WaitForExitWithTimeout) { | 220 TEST_F(ProcessTest, WaitForExitWithTimeout) { |
215 Process process(SpawnChild("SleepyChildProcess")); | 221 SpawnChildResult spawn_child = SpawnChild("SleepyChildProcess"); |
216 ASSERT_TRUE(process.IsValid()); | 222 ASSERT_TRUE(spawn_child.process.IsValid()); |
217 | 223 |
218 const int kDummyExitCode = 42; | 224 const int kDummyExitCode = 42; |
219 int exit_code = kDummyExitCode; | 225 int exit_code = kDummyExitCode; |
220 TimeDelta timeout = TestTimeouts::tiny_timeout(); | 226 TimeDelta timeout = TestTimeouts::tiny_timeout(); |
221 EXPECT_FALSE(process.WaitForExitWithTimeout(timeout, &exit_code)); | 227 EXPECT_FALSE(spawn_child.process.WaitForExitWithTimeout(timeout, &exit_code)); |
222 EXPECT_EQ(kDummyExitCode, exit_code); | 228 EXPECT_EQ(kDummyExitCode, exit_code); |
223 | 229 |
224 process.Terminate(kDummyExitCode, false); | 230 spawn_child.process.Terminate(kDummyExitCode, false); |
225 } | 231 } |
226 | 232 |
227 // Ensure that the priority of a process is restored correctly after | 233 // Ensure that the priority of a process is restored correctly after |
228 // backgrounding and restoring. | 234 // backgrounding and restoring. |
229 // Note: a platform may not be willing or able to lower the priority of | 235 // 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. | 236 // a process. The calls to SetProcessBackground should be noops then. |
231 TEST_F(ProcessTest, SetProcessBackgrounded) { | 237 TEST_F(ProcessTest, SetProcessBackgrounded) { |
232 if (!Process::CanBackgroundProcesses()) | 238 if (!Process::CanBackgroundProcesses()) |
233 return; | 239 return; |
234 Process process(SpawnChild("SimpleChildProcess")); | 240 SpawnChildResult spawn_child = SpawnChild("SimpleChildProcess"); |
235 int old_priority = process.GetPriority(); | 241 int old_priority = spawn_child.process.GetPriority(); |
236 #if defined(OS_WIN) | 242 #if defined(OS_WIN) |
237 EXPECT_TRUE(process.SetProcessBackgrounded(true)); | 243 EXPECT_TRUE(spawn_child.process.SetProcessBackgrounded(true)); |
238 EXPECT_TRUE(process.IsProcessBackgrounded()); | 244 EXPECT_TRUE(spawn_child.process.IsProcessBackgrounded()); |
239 EXPECT_TRUE(process.SetProcessBackgrounded(false)); | 245 EXPECT_TRUE(spawn_child.process.SetProcessBackgrounded(false)); |
240 EXPECT_FALSE(process.IsProcessBackgrounded()); | 246 EXPECT_FALSE(spawn_child.process.IsProcessBackgrounded()); |
241 #elif defined(OS_MACOSX) | 247 #elif defined(OS_MACOSX) |
242 // On the Mac, backgrounding a process requires a port to that process. | 248 // 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 | 249 // 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 | 250 // part of base. Additionally, there is an indefinite amount of time between |
245 // spawning a process and receiving its port. Because this test just checks | 251 // spawning a process and receiving its port. Because this test just checks |
246 // the ability to background/foreground a process, we can use the current | 252 // the ability to background/foreground a process, we can use the current |
247 // process's port instead. | 253 // process's port instead. |
248 FakePortProvider provider; | 254 FakePortProvider provider; |
249 EXPECT_TRUE(process.SetProcessBackgrounded(&provider, true)); | 255 EXPECT_TRUE(spawn_child.process.SetProcessBackgrounded(&provider, true)); |
250 EXPECT_TRUE(process.IsProcessBackgrounded(&provider)); | 256 EXPECT_TRUE(spawn_child.process.IsProcessBackgrounded(&provider)); |
251 EXPECT_TRUE(process.SetProcessBackgrounded(&provider, false)); | 257 EXPECT_TRUE(spawn_child.process.SetProcessBackgrounded(&provider, false)); |
252 EXPECT_FALSE(process.IsProcessBackgrounded(&provider)); | 258 EXPECT_FALSE(spawn_child.process.IsProcessBackgrounded(&provider)); |
253 | 259 |
254 #else | 260 #else |
255 process.SetProcessBackgrounded(true); | 261 spawn_child.process.SetProcessBackgrounded(true); |
256 process.SetProcessBackgrounded(false); | 262 spawn_child.process.SetProcessBackgrounded(false); |
257 #endif | 263 #endif |
258 int new_priority = process.GetPriority(); | 264 int new_priority = spawn_child.process.GetPriority(); |
259 EXPECT_EQ(old_priority, new_priority); | 265 EXPECT_EQ(old_priority, new_priority); |
260 } | 266 } |
261 | 267 |
262 // Same as SetProcessBackgrounded but to this very process. It uses | 268 // Same as SetProcessBackgrounded but to this very process. It uses |
263 // a different code path at least for Windows. | 269 // a different code path at least for Windows. |
264 TEST_F(ProcessTest, SetProcessBackgroundedSelf) { | 270 TEST_F(ProcessTest, SetProcessBackgroundedSelf) { |
265 if (!Process::CanBackgroundProcesses()) | 271 if (!Process::CanBackgroundProcesses()) |
266 return; | 272 return; |
267 Process process = Process::Current(); | 273 Process process = Process::Current(); |
268 int old_priority = process.GetPriority(); | 274 int old_priority = process.GetPriority(); |
(...skipping 26 matching lines...) Expand all Loading... |
295 "2:freezer:/chrome_renderers/to_be_frozen\n" | 301 "2:freezer:/chrome_renderers/to_be_frozen\n" |
296 "1:cpu:/chrome_renderers/background\n"; | 302 "1:cpu:/chrome_renderers/background\n"; |
297 | 303 |
298 EXPECT_FALSE(IsProcessBackgroundedCGroup(kNotBackgrounded)); | 304 EXPECT_FALSE(IsProcessBackgroundedCGroup(kNotBackgrounded)); |
299 EXPECT_TRUE(IsProcessBackgroundedCGroup(kBackgrounded)); | 305 EXPECT_TRUE(IsProcessBackgroundedCGroup(kBackgrounded)); |
300 } | 306 } |
301 | 307 |
302 #endif // defined(OS_CHROMEOS) | 308 #endif // defined(OS_CHROMEOS) |
303 | 309 |
304 } // namespace base | 310 } // namespace base |
OLD | NEW |