OLD | NEW |
---|---|
(Empty) | |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #include "base/process/process.h" | |
6 | |
7 #include "base/process/kill.h" | |
8 #include "base/test/multiprocess_test.h" | |
9 #include "base/test/test_timeouts.h" | |
10 #include "base/threading/platform_thread.h" | |
11 #include "testing/gtest/include/gtest/gtest.h" | |
12 #include "testing/multiprocess_func_list.h" | |
13 | |
14 | |
15 namespace { | |
16 | |
17 #if defined(OS_WIN) | |
18 const int kExpectedStillRunningExitCode = 0x102; | |
19 #else | |
20 const int kExpectedStillRunningExitCode = 0; | |
21 #endif | |
22 | |
23 } // namespace | |
24 | |
25 class ProcessTest : public base::MultiProcessTest { | |
26 }; | |
27 | |
28 TEST_F(ProcessTest, Create) { | |
29 base::Process process(SpawnChild("SimpleChildProcess")); | |
Lei Zhang
2014/10/16 02:50:08
nit: put the entire test in namespace base.
rvargas (doing something else)
2014/10/16 19:06:10
:( I like to treat tests as consumers of the code
| |
30 ASSERT_TRUE(process.IsValid()); | |
31 ASSERT_FALSE(process.is_current()); | |
32 process.Close(); | |
33 ASSERT_FALSE(process.IsValid()); | |
34 } | |
35 | |
36 TEST_F(ProcessTest, CreateCurrent) { | |
37 base::Process process = base::Process::Current(); | |
38 ASSERT_TRUE(process.IsValid()); | |
39 ASSERT_TRUE(process.is_current()); | |
40 process.Close(); | |
41 ASSERT_FALSE(process.IsValid()); | |
42 } | |
43 | |
44 TEST_F(ProcessTest, Move) { | |
45 base::Process process1(SpawnChild("SimpleChildProcess")); | |
46 EXPECT_TRUE(process1.IsValid()); | |
47 | |
48 base::Process process2; | |
49 EXPECT_FALSE(process2.IsValid()); | |
50 | |
51 process2 = process1.Pass(); | |
52 EXPECT_TRUE(process2.IsValid()); | |
53 EXPECT_FALSE(process1.IsValid()); | |
54 EXPECT_FALSE(process2.is_current()); | |
55 | |
56 base::Process process3 = base::Process::Current(); | |
57 process2 = process3.Pass(); | |
58 EXPECT_TRUE(process2.is_current()); | |
59 EXPECT_TRUE(process2.IsValid()); | |
60 EXPECT_FALSE(process3.IsValid()); | |
61 } | |
62 | |
63 TEST_F(ProcessTest, Duplicate) { | |
64 base::Process process1(SpawnChild("SimpleChildProcess")); | |
65 ASSERT_TRUE(process1.IsValid()); | |
66 | |
67 base::Process process2 = process1.Duplicate(); | |
68 ASSERT_TRUE(process1.IsValid()); | |
69 ASSERT_TRUE(process2.IsValid()); | |
70 EXPECT_EQ(process1.pid(), process2.pid()); | |
71 EXPECT_FALSE(process1.is_current()); | |
72 EXPECT_FALSE(process2.is_current()); | |
73 | |
74 process1.Close(); | |
75 ASSERT_TRUE(process2.IsValid()); | |
76 } | |
77 | |
78 TEST_F(ProcessTest, DuplicateCurrent) { | |
79 base::Process process1 = base::Process::Current(); | |
80 ASSERT_TRUE(process1.IsValid()); | |
81 | |
82 base::Process process2 = process1.Duplicate(); | |
83 ASSERT_TRUE(process1.IsValid()); | |
84 ASSERT_TRUE(process2.IsValid()); | |
85 EXPECT_EQ(process1.pid(), process2.pid()); | |
86 EXPECT_TRUE(process1.is_current()); | |
87 EXPECT_TRUE(process2.is_current()); | |
88 | |
89 process1.Close(); | |
90 ASSERT_TRUE(process2.IsValid()); | |
91 } | |
92 | |
93 MULTIPROCESS_TEST_MAIN(SleepyChildProcess) { | |
94 base::PlatformThread::Sleep(TestTimeouts::action_max_timeout()); | |
95 return 0; | |
96 } | |
97 | |
98 TEST_F(ProcessTest, Terminate) { | |
99 base::Process process(SpawnChild("SleepyChildProcess")); | |
100 ASSERT_TRUE(process.IsValid()); | |
101 | |
102 const int kDummyExitCode = 42; | |
103 int exit_code = kDummyExitCode; | |
104 EXPECT_EQ(base::TERMINATION_STATUS_STILL_RUNNING, | |
105 base::GetTerminationStatus(process.Handle(), &exit_code)); | |
106 EXPECT_EQ(kExpectedStillRunningExitCode, exit_code); | |
107 | |
108 exit_code = kDummyExitCode; | |
109 int kExpectedExitCode = 250; | |
110 process.Terminate(kExpectedExitCode); | |
111 base::WaitForSingleProcess(process.Handle(), | |
112 TestTimeouts::action_max_timeout()); | |
113 | |
114 EXPECT_NE(base::TERMINATION_STATUS_STILL_RUNNING, | |
115 base::GetTerminationStatus(process.Handle(), &exit_code)); | |
116 #if !defined(OS_POSIX) | |
117 // The POSIX implementation actually ignores the exit_code. | |
118 EXPECT_EQ(kExpectedExitCode, exit_code); | |
119 #endif | |
120 } | |
121 | |
122 // Ensure that the priority of a process is restored correctly after | |
123 // backgrounding and restoring. | |
124 // Note: a platform may not be willing or able to lower the priority of | |
125 // a process. The calls to SetProcessBackground should be noops then. | |
126 TEST_F(ProcessTest, SetProcessBackgrounded) { | |
127 base::Process process(SpawnChild("SimpleChildProcess")); | |
128 int old_priority = process.GetPriority(); | |
129 #if defined(OS_WIN) | |
130 EXPECT_TRUE(process.SetProcessBackgrounded(true)); | |
131 EXPECT_TRUE(process.IsProcessBackgrounded()); | |
132 EXPECT_TRUE(process.SetProcessBackgrounded(false)); | |
133 EXPECT_FALSE(process.IsProcessBackgrounded()); | |
134 #else | |
135 process.SetProcessBackgrounded(true); | |
136 process.SetProcessBackgrounded(false); | |
137 #endif | |
138 int new_priority = process.GetPriority(); | |
139 EXPECT_EQ(old_priority, new_priority); | |
140 } | |
141 | |
142 // Same as SetProcessBackgrounded but to this very process. It uses | |
143 // a different code path at least for Windows. | |
144 TEST_F(ProcessTest, SetProcessBackgroundedSelf) { | |
145 base::Process process = base::Process::Current(); | |
146 int old_priority = process.GetPriority(); | |
147 #if defined(OS_WIN) | |
148 EXPECT_TRUE(process.SetProcessBackgrounded(true)); | |
149 EXPECT_TRUE(process.IsProcessBackgrounded()); | |
150 EXPECT_TRUE(process.SetProcessBackgrounded(false)); | |
151 EXPECT_FALSE(process.IsProcessBackgrounded()); | |
152 #else | |
153 process.SetProcessBackgrounded(true); | |
154 process.SetProcessBackgrounded(false); | |
155 #endif | |
156 int new_priority = process.GetPriority(); | |
157 EXPECT_EQ(old_priority, new_priority); | |
158 } | |
OLD | NEW |