1*6777b538SAndroid Build Coastguard Worker // Copyright 2014 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker
5*6777b538SAndroid Build Coastguard Worker #include "base/process/process.h"
6*6777b538SAndroid Build Coastguard Worker
7*6777b538SAndroid Build Coastguard Worker #include <memory>
8*6777b538SAndroid Build Coastguard Worker #include <string>
9*6777b538SAndroid Build Coastguard Worker #include <string_view>
10*6777b538SAndroid Build Coastguard Worker #include <utility>
11*6777b538SAndroid Build Coastguard Worker
12*6777b538SAndroid Build Coastguard Worker #include "base/at_exit.h"
13*6777b538SAndroid Build Coastguard Worker #include "base/debug/invalid_access_win.h"
14*6777b538SAndroid Build Coastguard Worker #include "base/process/kill.h"
15*6777b538SAndroid Build Coastguard Worker #include "base/test/multiprocess_test.h"
16*6777b538SAndroid Build Coastguard Worker #include "base/test/test_timeouts.h"
17*6777b538SAndroid Build Coastguard Worker #include "base/threading/platform_thread.h"
18*6777b538SAndroid Build Coastguard Worker #include "base/threading/platform_thread_internal_posix.h"
19*6777b538SAndroid Build Coastguard Worker #include "base/threading/thread_local.h"
20*6777b538SAndroid Build Coastguard Worker #include "build/build_config.h"
21*6777b538SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
22*6777b538SAndroid Build Coastguard Worker #include "testing/multiprocess_func_list.h"
23*6777b538SAndroid Build Coastguard Worker
24*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_CHROMEOS)
25*6777b538SAndroid Build Coastguard Worker #include <sys/resource.h>
26*6777b538SAndroid Build Coastguard Worker #include <unistd.h>
27*6777b538SAndroid Build Coastguard Worker
28*6777b538SAndroid Build Coastguard Worker #include <vector>
29*6777b538SAndroid Build Coastguard Worker
30*6777b538SAndroid Build Coastguard Worker #include "base/files/file_path.h"
31*6777b538SAndroid Build Coastguard Worker #include "base/files/file_util.h"
32*6777b538SAndroid Build Coastguard Worker #include "base/process/internal_linux.h"
33*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_number_conversions.h"
34*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_split.h"
35*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_util.h"
36*6777b538SAndroid Build Coastguard Worker #include "base/strings/stringprintf.h"
37*6777b538SAndroid Build Coastguard Worker #include "base/test/scoped_feature_list.h"
38*6777b538SAndroid Build Coastguard Worker #include "base/test/task_environment.h"
39*6777b538SAndroid Build Coastguard Worker #include "base/time/time.h"
40*6777b538SAndroid Build Coastguard Worker #endif // BUILDFLAG(IS_CHROMEOS)
41*6777b538SAndroid Build Coastguard Worker
42*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
43*6777b538SAndroid Build Coastguard Worker #include <windows.h>
44*6777b538SAndroid Build Coastguard Worker
45*6777b538SAndroid Build Coastguard Worker #include "base/win/base_win_buildflags.h"
46*6777b538SAndroid Build Coastguard Worker #endif
47*6777b538SAndroid Build Coastguard Worker
48*6777b538SAndroid Build Coastguard Worker namespace {
49*6777b538SAndroid Build Coastguard Worker
50*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
51*6777b538SAndroid Build Coastguard Worker constexpr int kExpectedStillRunningExitCode = 0x102;
52*6777b538SAndroid Build Coastguard Worker #else
53*6777b538SAndroid Build Coastguard Worker constexpr int kExpectedStillRunningExitCode = 0;
54*6777b538SAndroid Build Coastguard Worker #endif
55*6777b538SAndroid Build Coastguard Worker
56*6777b538SAndroid Build Coastguard Worker constexpr int kDummyExitCode = 42;
57*6777b538SAndroid Build Coastguard Worker
58*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_APPLE)
59*6777b538SAndroid Build Coastguard Worker // Fake port provider that returns the calling process's
60*6777b538SAndroid Build Coastguard Worker // task port, ignoring its argument.
61*6777b538SAndroid Build Coastguard Worker class FakePortProvider : public base::PortProvider {
TaskForHandle(base::ProcessHandle process_handle) const62*6777b538SAndroid Build Coastguard Worker mach_port_t TaskForHandle(base::ProcessHandle process_handle) const override {
63*6777b538SAndroid Build Coastguard Worker return mach_task_self();
64*6777b538SAndroid Build Coastguard Worker }
65*6777b538SAndroid Build Coastguard Worker };
66*6777b538SAndroid Build Coastguard Worker #endif
67*6777b538SAndroid Build Coastguard Worker
68*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_CHROMEOS)
69*6777b538SAndroid Build Coastguard Worker const char kForeground[] = "/chrome_renderers/foreground";
70*6777b538SAndroid Build Coastguard Worker const char kCgroupRoot[] = "/sys/fs/cgroup/cpu";
71*6777b538SAndroid Build Coastguard Worker const char kFullRendererCgroupRoot[] = "/sys/fs/cgroup/cpu/chrome_renderers";
72*6777b538SAndroid Build Coastguard Worker const char kProcPath[] = "/proc/%d/cgroup";
73*6777b538SAndroid Build Coastguard Worker
GetProcessCpuCgroup(const base::Process & process)74*6777b538SAndroid Build Coastguard Worker std::string GetProcessCpuCgroup(const base::Process& process) {
75*6777b538SAndroid Build Coastguard Worker std::string proc;
76*6777b538SAndroid Build Coastguard Worker if (!base::ReadFileToString(
77*6777b538SAndroid Build Coastguard Worker base::FilePath(base::StringPrintf(kProcPath, process.Pid())),
78*6777b538SAndroid Build Coastguard Worker &proc)) {
79*6777b538SAndroid Build Coastguard Worker return std::string();
80*6777b538SAndroid Build Coastguard Worker }
81*6777b538SAndroid Build Coastguard Worker
82*6777b538SAndroid Build Coastguard Worker std::vector<std::string_view> lines = SplitStringPiece(
83*6777b538SAndroid Build Coastguard Worker proc, "\n", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
84*6777b538SAndroid Build Coastguard Worker for (const auto& line : lines) {
85*6777b538SAndroid Build Coastguard Worker std::vector<std::string_view> fields = SplitStringPiece(
86*6777b538SAndroid Build Coastguard Worker line, ":", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
87*6777b538SAndroid Build Coastguard Worker if (fields.size() != 3U) {
88*6777b538SAndroid Build Coastguard Worker continue;
89*6777b538SAndroid Build Coastguard Worker }
90*6777b538SAndroid Build Coastguard Worker
91*6777b538SAndroid Build Coastguard Worker if (fields[1] == "cpu") {
92*6777b538SAndroid Build Coastguard Worker return static_cast<std::string>(fields[2]);
93*6777b538SAndroid Build Coastguard Worker }
94*6777b538SAndroid Build Coastguard Worker }
95*6777b538SAndroid Build Coastguard Worker
96*6777b538SAndroid Build Coastguard Worker return std::string();
97*6777b538SAndroid Build Coastguard Worker }
98*6777b538SAndroid Build Coastguard Worker
AddProcessToCpuCgroup(const base::Process & process,const std::string & cgroup)99*6777b538SAndroid Build Coastguard Worker bool AddProcessToCpuCgroup(const base::Process& process,
100*6777b538SAndroid Build Coastguard Worker const std::string& cgroup) {
101*6777b538SAndroid Build Coastguard Worker base::FilePath path(cgroup);
102*6777b538SAndroid Build Coastguard Worker path = path.Append("cgroup.procs");
103*6777b538SAndroid Build Coastguard Worker return base::WriteFile(path, base::NumberToString(process.Pid()));
104*6777b538SAndroid Build Coastguard Worker }
105*6777b538SAndroid Build Coastguard Worker #endif // BUILDFLAG(IS_CHROMEOS)
106*6777b538SAndroid Build Coastguard Worker
107*6777b538SAndroid Build Coastguard Worker } // namespace
108*6777b538SAndroid Build Coastguard Worker
109*6777b538SAndroid Build Coastguard Worker namespace base {
110*6777b538SAndroid Build Coastguard Worker
111*6777b538SAndroid Build Coastguard Worker class ProcessTest : public MultiProcessTest {
112*6777b538SAndroid Build Coastguard Worker };
113*6777b538SAndroid Build Coastguard Worker
TEST_F(ProcessTest,Create)114*6777b538SAndroid Build Coastguard Worker TEST_F(ProcessTest, Create) {
115*6777b538SAndroid Build Coastguard Worker Process process(SpawnChild("SimpleChildProcess"));
116*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(process.IsValid());
117*6777b538SAndroid Build Coastguard Worker ASSERT_FALSE(process.is_current());
118*6777b538SAndroid Build Coastguard Worker EXPECT_NE(process.Pid(), kNullProcessId);
119*6777b538SAndroid Build Coastguard Worker process.Close();
120*6777b538SAndroid Build Coastguard Worker ASSERT_FALSE(process.IsValid());
121*6777b538SAndroid Build Coastguard Worker }
122*6777b538SAndroid Build Coastguard Worker
TEST_F(ProcessTest,CreateCurrent)123*6777b538SAndroid Build Coastguard Worker TEST_F(ProcessTest, CreateCurrent) {
124*6777b538SAndroid Build Coastguard Worker Process process = Process::Current();
125*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(process.IsValid());
126*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(process.is_current());
127*6777b538SAndroid Build Coastguard Worker EXPECT_NE(process.Pid(), kNullProcessId);
128*6777b538SAndroid Build Coastguard Worker process.Close();
129*6777b538SAndroid Build Coastguard Worker ASSERT_FALSE(process.IsValid());
130*6777b538SAndroid Build Coastguard Worker }
131*6777b538SAndroid Build Coastguard Worker
TEST_F(ProcessTest,Move)132*6777b538SAndroid Build Coastguard Worker TEST_F(ProcessTest, Move) {
133*6777b538SAndroid Build Coastguard Worker Process process1(SpawnChild("SimpleChildProcess"));
134*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(process1.IsValid());
135*6777b538SAndroid Build Coastguard Worker
136*6777b538SAndroid Build Coastguard Worker Process process2;
137*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(process2.IsValid());
138*6777b538SAndroid Build Coastguard Worker
139*6777b538SAndroid Build Coastguard Worker process2 = std::move(process1);
140*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(process2.IsValid());
141*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(process1.IsValid());
142*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(process2.is_current());
143*6777b538SAndroid Build Coastguard Worker
144*6777b538SAndroid Build Coastguard Worker Process process3 = Process::Current();
145*6777b538SAndroid Build Coastguard Worker process2 = std::move(process3);
146*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(process2.is_current());
147*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(process2.IsValid());
148*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(process3.IsValid());
149*6777b538SAndroid Build Coastguard Worker }
150*6777b538SAndroid Build Coastguard Worker
TEST_F(ProcessTest,Duplicate)151*6777b538SAndroid Build Coastguard Worker TEST_F(ProcessTest, Duplicate) {
152*6777b538SAndroid Build Coastguard Worker Process process1(SpawnChild("SimpleChildProcess"));
153*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(process1.IsValid());
154*6777b538SAndroid Build Coastguard Worker
155*6777b538SAndroid Build Coastguard Worker Process process2 = process1.Duplicate();
156*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(process1.IsValid());
157*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(process2.IsValid());
158*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(process1.Pid(), process2.Pid());
159*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(process1.is_current());
160*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(process2.is_current());
161*6777b538SAndroid Build Coastguard Worker
162*6777b538SAndroid Build Coastguard Worker process1.Close();
163*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(process2.IsValid());
164*6777b538SAndroid Build Coastguard Worker }
165*6777b538SAndroid Build Coastguard Worker
TEST_F(ProcessTest,DuplicateCurrent)166*6777b538SAndroid Build Coastguard Worker TEST_F(ProcessTest, DuplicateCurrent) {
167*6777b538SAndroid Build Coastguard Worker Process process1 = Process::Current();
168*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(process1.IsValid());
169*6777b538SAndroid Build Coastguard Worker
170*6777b538SAndroid Build Coastguard Worker Process process2 = process1.Duplicate();
171*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(process1.IsValid());
172*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(process2.IsValid());
173*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(process1.Pid(), process2.Pid());
174*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(process1.is_current());
175*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(process2.is_current());
176*6777b538SAndroid Build Coastguard Worker
177*6777b538SAndroid Build Coastguard Worker process1.Close();
178*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(process2.IsValid());
179*6777b538SAndroid Build Coastguard Worker }
180*6777b538SAndroid Build Coastguard Worker
MULTIPROCESS_TEST_MAIN(SleepyChildProcess)181*6777b538SAndroid Build Coastguard Worker MULTIPROCESS_TEST_MAIN(SleepyChildProcess) {
182*6777b538SAndroid Build Coastguard Worker PlatformThread::Sleep(TestTimeouts::action_max_timeout());
183*6777b538SAndroid Build Coastguard Worker return 0;
184*6777b538SAndroid Build Coastguard Worker }
185*6777b538SAndroid Build Coastguard Worker
186*6777b538SAndroid Build Coastguard Worker // TODO(https://crbug.com/726484): Enable these tests on Fuchsia when
187*6777b538SAndroid Build Coastguard Worker // CreationTime() is implemented.
TEST_F(ProcessTest,CreationTimeCurrentProcess)188*6777b538SAndroid Build Coastguard Worker TEST_F(ProcessTest, CreationTimeCurrentProcess) {
189*6777b538SAndroid Build Coastguard Worker // The current process creation time should be less than or equal to the
190*6777b538SAndroid Build Coastguard Worker // current time.
191*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(Process::Current().CreationTime().is_null());
192*6777b538SAndroid Build Coastguard Worker EXPECT_LE(Process::Current().CreationTime(), Time::Now());
193*6777b538SAndroid Build Coastguard Worker }
194*6777b538SAndroid Build Coastguard Worker
195*6777b538SAndroid Build Coastguard Worker #if !BUILDFLAG(IS_ANDROID) // Cannot read other processes' creation time on
196*6777b538SAndroid Build Coastguard Worker // Android.
TEST_F(ProcessTest,CreationTimeOtherProcess)197*6777b538SAndroid Build Coastguard Worker TEST_F(ProcessTest, CreationTimeOtherProcess) {
198*6777b538SAndroid Build Coastguard Worker // The creation time of a process should be between a time recorded before it
199*6777b538SAndroid Build Coastguard Worker // was spawned and a time recorded after it was spawned. However, since the
200*6777b538SAndroid Build Coastguard Worker // base::Time and process creation clocks don't match, tolerate some error.
201*6777b538SAndroid Build Coastguard Worker constexpr base::TimeDelta kTolerance =
202*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
203*6777b538SAndroid Build Coastguard Worker // On Linux, process creation time is relative to boot time which has a
204*6777b538SAndroid Build Coastguard Worker // 1-second resolution. Tolerate 1 second for the imprecise boot time and
205*6777b538SAndroid Build Coastguard Worker // 100 ms for the imprecise clock.
206*6777b538SAndroid Build Coastguard Worker Milliseconds(1100);
207*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_WIN)
208*6777b538SAndroid Build Coastguard Worker // On Windows, process creation time is based on the system clock while
209*6777b538SAndroid Build Coastguard Worker // Time::Now() is a combination of system clock and
210*6777b538SAndroid Build Coastguard Worker // QueryPerformanceCounter(). Tolerate 100 ms for the clock mismatch.
211*6777b538SAndroid Build Coastguard Worker Milliseconds(100);
212*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_FUCHSIA)
213*6777b538SAndroid Build Coastguard Worker // On Mac and Fuchsia, process creation time should be very precise.
214*6777b538SAndroid Build Coastguard Worker Milliseconds(0);
215*6777b538SAndroid Build Coastguard Worker #else
216*6777b538SAndroid Build Coastguard Worker #error Unsupported platform
217*6777b538SAndroid Build Coastguard Worker #endif
218*6777b538SAndroid Build Coastguard Worker const Time before_creation = Time::Now();
219*6777b538SAndroid Build Coastguard Worker Process process(SpawnChild("SleepyChildProcess"));
220*6777b538SAndroid Build Coastguard Worker const Time after_creation = Time::Now();
221*6777b538SAndroid Build Coastguard Worker const Time creation = process.CreationTime();
222*6777b538SAndroid Build Coastguard Worker EXPECT_LE(before_creation - kTolerance, creation);
223*6777b538SAndroid Build Coastguard Worker EXPECT_LE(creation, after_creation + kTolerance);
224*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(process.Terminate(kDummyExitCode, true));
225*6777b538SAndroid Build Coastguard Worker }
226*6777b538SAndroid Build Coastguard Worker #endif // !BUILDFLAG(IS_ANDROID)
227*6777b538SAndroid Build Coastguard Worker
TEST_F(ProcessTest,Terminate)228*6777b538SAndroid Build Coastguard Worker TEST_F(ProcessTest, Terminate) {
229*6777b538SAndroid Build Coastguard Worker Process process(SpawnChild("SleepyChildProcess"));
230*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(process.IsValid());
231*6777b538SAndroid Build Coastguard Worker
232*6777b538SAndroid Build Coastguard Worker int exit_code = kDummyExitCode;
233*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(TERMINATION_STATUS_STILL_RUNNING,
234*6777b538SAndroid Build Coastguard Worker GetTerminationStatus(process.Handle(), &exit_code));
235*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kExpectedStillRunningExitCode, exit_code);
236*6777b538SAndroid Build Coastguard Worker
237*6777b538SAndroid Build Coastguard Worker exit_code = kDummyExitCode;
238*6777b538SAndroid Build Coastguard Worker int kExpectedExitCode = 250;
239*6777b538SAndroid Build Coastguard Worker process.Terminate(kExpectedExitCode, false);
240*6777b538SAndroid Build Coastguard Worker process.WaitForExitWithTimeout(TestTimeouts::action_max_timeout(),
241*6777b538SAndroid Build Coastguard Worker &exit_code);
242*6777b538SAndroid Build Coastguard Worker
243*6777b538SAndroid Build Coastguard Worker EXPECT_NE(TERMINATION_STATUS_STILL_RUNNING,
244*6777b538SAndroid Build Coastguard Worker GetTerminationStatus(process.Handle(), &exit_code));
245*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
246*6777b538SAndroid Build Coastguard Worker // Only Windows propagates the |exit_code| set in Terminate().
247*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kExpectedExitCode, exit_code);
248*6777b538SAndroid Build Coastguard Worker #endif
249*6777b538SAndroid Build Coastguard Worker }
250*6777b538SAndroid Build Coastguard Worker
AtExitHandler(void *)251*6777b538SAndroid Build Coastguard Worker void AtExitHandler(void*) {
252*6777b538SAndroid Build Coastguard Worker // At-exit handler should not be called at
253*6777b538SAndroid Build Coastguard Worker // Process::TerminateCurrentProcessImmediately.
254*6777b538SAndroid Build Coastguard Worker DCHECK(false);
255*6777b538SAndroid Build Coastguard Worker }
256*6777b538SAndroid Build Coastguard Worker
257*6777b538SAndroid Build Coastguard Worker class ThreadLocalObject {
258*6777b538SAndroid Build Coastguard Worker public:
~ThreadLocalObject()259*6777b538SAndroid Build Coastguard Worker ~ThreadLocalObject() {
260*6777b538SAndroid Build Coastguard Worker // Thread-local storage should not be destructed at
261*6777b538SAndroid Build Coastguard Worker // Process::TerminateCurrentProcessImmediately.
262*6777b538SAndroid Build Coastguard Worker DCHECK(false);
263*6777b538SAndroid Build Coastguard Worker }
264*6777b538SAndroid Build Coastguard Worker };
265*6777b538SAndroid Build Coastguard Worker
MULTIPROCESS_TEST_MAIN(TerminateCurrentProcessImmediatelyWithCode0)266*6777b538SAndroid Build Coastguard Worker MULTIPROCESS_TEST_MAIN(TerminateCurrentProcessImmediatelyWithCode0) {
267*6777b538SAndroid Build Coastguard Worker base::ThreadLocalOwnedPointer<ThreadLocalObject> object;
268*6777b538SAndroid Build Coastguard Worker object.Set(std::make_unique<ThreadLocalObject>());
269*6777b538SAndroid Build Coastguard Worker base::AtExitManager::RegisterCallback(&AtExitHandler, nullptr);
270*6777b538SAndroid Build Coastguard Worker Process::TerminateCurrentProcessImmediately(0);
271*6777b538SAndroid Build Coastguard Worker }
272*6777b538SAndroid Build Coastguard Worker
TEST_F(ProcessTest,TerminateCurrentProcessImmediatelyWithZeroExitCode)273*6777b538SAndroid Build Coastguard Worker TEST_F(ProcessTest, TerminateCurrentProcessImmediatelyWithZeroExitCode) {
274*6777b538SAndroid Build Coastguard Worker Process process(SpawnChild("TerminateCurrentProcessImmediatelyWithCode0"));
275*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(process.IsValid());
276*6777b538SAndroid Build Coastguard Worker int exit_code = 42;
277*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(process.WaitForExitWithTimeout(TestTimeouts::action_max_timeout(),
278*6777b538SAndroid Build Coastguard Worker &exit_code));
279*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, exit_code);
280*6777b538SAndroid Build Coastguard Worker }
281*6777b538SAndroid Build Coastguard Worker
MULTIPROCESS_TEST_MAIN(TerminateCurrentProcessImmediatelyWithCode250)282*6777b538SAndroid Build Coastguard Worker MULTIPROCESS_TEST_MAIN(TerminateCurrentProcessImmediatelyWithCode250) {
283*6777b538SAndroid Build Coastguard Worker Process::TerminateCurrentProcessImmediately(250);
284*6777b538SAndroid Build Coastguard Worker }
285*6777b538SAndroid Build Coastguard Worker
TEST_F(ProcessTest,TerminateCurrentProcessImmediatelyWithNonZeroExitCode)286*6777b538SAndroid Build Coastguard Worker TEST_F(ProcessTest, TerminateCurrentProcessImmediatelyWithNonZeroExitCode) {
287*6777b538SAndroid Build Coastguard Worker Process process(SpawnChild("TerminateCurrentProcessImmediatelyWithCode250"));
288*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(process.IsValid());
289*6777b538SAndroid Build Coastguard Worker int exit_code = 42;
290*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(process.WaitForExitWithTimeout(TestTimeouts::action_max_timeout(),
291*6777b538SAndroid Build Coastguard Worker &exit_code));
292*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(250, exit_code);
293*6777b538SAndroid Build Coastguard Worker }
294*6777b538SAndroid Build Coastguard Worker
MULTIPROCESS_TEST_MAIN(FastSleepyChildProcess)295*6777b538SAndroid Build Coastguard Worker MULTIPROCESS_TEST_MAIN(FastSleepyChildProcess) {
296*6777b538SAndroid Build Coastguard Worker PlatformThread::Sleep(TestTimeouts::tiny_timeout() * 10);
297*6777b538SAndroid Build Coastguard Worker return 0;
298*6777b538SAndroid Build Coastguard Worker }
299*6777b538SAndroid Build Coastguard Worker
TEST_F(ProcessTest,WaitForExit)300*6777b538SAndroid Build Coastguard Worker TEST_F(ProcessTest, WaitForExit) {
301*6777b538SAndroid Build Coastguard Worker Process process(SpawnChild("FastSleepyChildProcess"));
302*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(process.IsValid());
303*6777b538SAndroid Build Coastguard Worker
304*6777b538SAndroid Build Coastguard Worker int exit_code = kDummyExitCode;
305*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(process.WaitForExit(&exit_code));
306*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, exit_code);
307*6777b538SAndroid Build Coastguard Worker }
308*6777b538SAndroid Build Coastguard Worker
TEST_F(ProcessTest,WaitForExitWithTimeout)309*6777b538SAndroid Build Coastguard Worker TEST_F(ProcessTest, WaitForExitWithTimeout) {
310*6777b538SAndroid Build Coastguard Worker Process process(SpawnChild("SleepyChildProcess"));
311*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(process.IsValid());
312*6777b538SAndroid Build Coastguard Worker
313*6777b538SAndroid Build Coastguard Worker int exit_code = kDummyExitCode;
314*6777b538SAndroid Build Coastguard Worker TimeDelta timeout = TestTimeouts::tiny_timeout();
315*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(process.WaitForExitWithTimeout(timeout, &exit_code));
316*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kDummyExitCode, exit_code);
317*6777b538SAndroid Build Coastguard Worker
318*6777b538SAndroid Build Coastguard Worker process.Terminate(kDummyExitCode, false);
319*6777b538SAndroid Build Coastguard Worker }
320*6777b538SAndroid Build Coastguard Worker
321*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
TEST_F(ProcessTest,WaitForExitOrEventWithProcessExit)322*6777b538SAndroid Build Coastguard Worker TEST_F(ProcessTest, WaitForExitOrEventWithProcessExit) {
323*6777b538SAndroid Build Coastguard Worker Process process(SpawnChild("FastSleepyChildProcess"));
324*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(process.IsValid());
325*6777b538SAndroid Build Coastguard Worker
326*6777b538SAndroid Build Coastguard Worker base::win::ScopedHandle stop_watching_handle(
327*6777b538SAndroid Build Coastguard Worker CreateEvent(nullptr, TRUE, FALSE, nullptr));
328*6777b538SAndroid Build Coastguard Worker
329*6777b538SAndroid Build Coastguard Worker int exit_code = kDummyExitCode;
330*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(process.WaitForExitOrEvent(stop_watching_handle, &exit_code),
331*6777b538SAndroid Build Coastguard Worker base::Process::WaitExitStatus::PROCESS_EXITED);
332*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, exit_code);
333*6777b538SAndroid Build Coastguard Worker }
334*6777b538SAndroid Build Coastguard Worker
TEST_F(ProcessTest,WaitForExitOrEventWithEventSet)335*6777b538SAndroid Build Coastguard Worker TEST_F(ProcessTest, WaitForExitOrEventWithEventSet) {
336*6777b538SAndroid Build Coastguard Worker Process process(SpawnChild("SleepyChildProcess"));
337*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(process.IsValid());
338*6777b538SAndroid Build Coastguard Worker
339*6777b538SAndroid Build Coastguard Worker base::win::ScopedHandle stop_watching_handle(
340*6777b538SAndroid Build Coastguard Worker CreateEvent(nullptr, TRUE, TRUE, nullptr));
341*6777b538SAndroid Build Coastguard Worker
342*6777b538SAndroid Build Coastguard Worker int exit_code = kDummyExitCode;
343*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(process.WaitForExitOrEvent(stop_watching_handle, &exit_code),
344*6777b538SAndroid Build Coastguard Worker base::Process::WaitExitStatus::STOP_EVENT_SIGNALED);
345*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kDummyExitCode, exit_code);
346*6777b538SAndroid Build Coastguard Worker
347*6777b538SAndroid Build Coastguard Worker process.Terminate(kDummyExitCode, false);
348*6777b538SAndroid Build Coastguard Worker }
349*6777b538SAndroid Build Coastguard Worker #endif // BUILDFLAG(IS_WIN)
350*6777b538SAndroid Build Coastguard Worker
351*6777b538SAndroid Build Coastguard Worker // Ensure that the priority of a process is restored correctly after
352*6777b538SAndroid Build Coastguard Worker // backgrounding and restoring.
353*6777b538SAndroid Build Coastguard Worker // Note: a platform may not be willing or able to lower the priority of
354*6777b538SAndroid Build Coastguard Worker // a process. The calls to SetProcessPriority should be noops then.
TEST_F(ProcessTest,SetProcessPriority)355*6777b538SAndroid Build Coastguard Worker TEST_F(ProcessTest, SetProcessPriority) {
356*6777b538SAndroid Build Coastguard Worker if (!Process::CanSetPriority()) {
357*6777b538SAndroid Build Coastguard Worker return;
358*6777b538SAndroid Build Coastguard Worker }
359*6777b538SAndroid Build Coastguard Worker Process process(SpawnChild("SimpleChildProcess"));
360*6777b538SAndroid Build Coastguard Worker int old_os_priority = process.GetOSPriority();
361*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_APPLE)
362*6777b538SAndroid Build Coastguard Worker // On the Mac, backgrounding a process requires a port to that process.
363*6777b538SAndroid Build Coastguard Worker // In the browser it's available through the MachBroker class, which is not
364*6777b538SAndroid Build Coastguard Worker // part of base. Additionally, there is an indefinite amount of time between
365*6777b538SAndroid Build Coastguard Worker // spawning a process and receiving its port. Because this test just checks
366*6777b538SAndroid Build Coastguard Worker // the ability to background/foreground a process, we can use the current
367*6777b538SAndroid Build Coastguard Worker // process's port instead.
368*6777b538SAndroid Build Coastguard Worker FakePortProvider provider;
369*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(process.SetPriority(&provider, Process::Priority::kBestEffort));
370*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(process.GetPriority(&provider), Process::Priority::kBestEffort);
371*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(process.SetPriority(&provider, Process::Priority::kUserBlocking));
372*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(process.GetPriority(&provider), Process::Priority::kUserBlocking);
373*6777b538SAndroid Build Coastguard Worker
374*6777b538SAndroid Build Coastguard Worker #else
375*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(process.SetPriority(base::Process::Priority::kBestEffort));
376*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(process.GetPriority(), Process::Priority::kBestEffort);
377*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(process.SetPriority(base::Process::Priority::kUserBlocking));
378*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(process.GetPriority(), Process::Priority::kUserBlocking);
379*6777b538SAndroid Build Coastguard Worker #endif
380*6777b538SAndroid Build Coastguard Worker int new_os_priority = process.GetOSPriority();
381*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(old_os_priority, new_os_priority);
382*6777b538SAndroid Build Coastguard Worker }
383*6777b538SAndroid Build Coastguard Worker
384*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_CHROMEOS)
IsThreadRT(PlatformThreadId thread_id)385*6777b538SAndroid Build Coastguard Worker bool IsThreadRT(PlatformThreadId thread_id) {
386*6777b538SAndroid Build Coastguard Worker // Check if the thread is running in real-time mode
387*6777b538SAndroid Build Coastguard Worker int sched = sched_getscheduler(
388*6777b538SAndroid Build Coastguard Worker PlatformThread::CurrentId() == thread_id ? 0 : thread_id);
389*6777b538SAndroid Build Coastguard Worker if (sched == -1) {
390*6777b538SAndroid Build Coastguard Worker // The thread may disappear for any reason so ignore ESRCH.
391*6777b538SAndroid Build Coastguard Worker DPLOG_IF(ERROR, errno != ESRCH)
392*6777b538SAndroid Build Coastguard Worker << "Failed to call sched_getscheduler on thread_id=" << thread_id;
393*6777b538SAndroid Build Coastguard Worker return false;
394*6777b538SAndroid Build Coastguard Worker }
395*6777b538SAndroid Build Coastguard Worker return sched == SCHED_RR || sched == SCHED_FIFO;
396*6777b538SAndroid Build Coastguard Worker }
397*6777b538SAndroid Build Coastguard Worker
398*6777b538SAndroid Build Coastguard Worker // Verify that all the threads in a process are RT or not.
AssertThreadsRT(int process_id,bool is_rt)399*6777b538SAndroid Build Coastguard Worker void AssertThreadsRT(int process_id, bool is_rt) {
400*6777b538SAndroid Build Coastguard Worker internal::ForEachProcessTask(
401*6777b538SAndroid Build Coastguard Worker process_id, [is_rt](PlatformThreadId tid, const FilePath& /* path */) {
402*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(IsThreadRT(tid), is_rt);
403*6777b538SAndroid Build Coastguard Worker });
404*6777b538SAndroid Build Coastguard Worker }
405*6777b538SAndroid Build Coastguard Worker
AssertThreadsType(int process_id,ThreadType type)406*6777b538SAndroid Build Coastguard Worker void AssertThreadsType(int process_id, ThreadType type) {
407*6777b538SAndroid Build Coastguard Worker internal::ForEachProcessTask(process_id, [process_id, type](
408*6777b538SAndroid Build Coastguard Worker PlatformThreadId tid,
409*6777b538SAndroid Build Coastguard Worker const FilePath& path) {
410*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(PlatformThread::GetThreadTypeFromThreadId(process_id, tid), type);
411*6777b538SAndroid Build Coastguard Worker });
412*6777b538SAndroid Build Coastguard Worker }
413*6777b538SAndroid Build Coastguard Worker
AssertThreadsBgState(int process_id,bool is_bg)414*6777b538SAndroid Build Coastguard Worker void AssertThreadsBgState(int process_id, bool is_bg) {
415*6777b538SAndroid Build Coastguard Worker internal::ForEachProcessTask(
416*6777b538SAndroid Build Coastguard Worker process_id, [is_bg](PlatformThreadId tid, const FilePath& path) {
417*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(PlatformThreadLinux::IsThreadBackgroundedForTest(tid), is_bg);
418*6777b538SAndroid Build Coastguard Worker });
419*6777b538SAndroid Build Coastguard Worker }
420*6777b538SAndroid Build Coastguard Worker
421*6777b538SAndroid Build Coastguard Worker namespace {
422*6777b538SAndroid Build Coastguard Worker
423*6777b538SAndroid Build Coastguard Worker class FunctionTestThread : public PlatformThread::Delegate {
424*6777b538SAndroid Build Coastguard Worker public:
425*6777b538SAndroid Build Coastguard Worker FunctionTestThread() = default;
426*6777b538SAndroid Build Coastguard Worker
427*6777b538SAndroid Build Coastguard Worker FunctionTestThread(const FunctionTestThread&) = delete;
428*6777b538SAndroid Build Coastguard Worker FunctionTestThread& operator=(const FunctionTestThread&) = delete;
429*6777b538SAndroid Build Coastguard Worker
ThreadMain()430*6777b538SAndroid Build Coastguard Worker void ThreadMain() override {
431*6777b538SAndroid Build Coastguard Worker PlatformThread::SetCurrentThreadType(ThreadType::kCompositing);
432*6777b538SAndroid Build Coastguard Worker while (true) {
433*6777b538SAndroid Build Coastguard Worker PlatformThread::Sleep(Milliseconds(100));
434*6777b538SAndroid Build Coastguard Worker }
435*6777b538SAndroid Build Coastguard Worker }
436*6777b538SAndroid Build Coastguard Worker };
437*6777b538SAndroid Build Coastguard Worker
438*6777b538SAndroid Build Coastguard Worker class RTAudioFunctionTestThread : public PlatformThread::Delegate {
439*6777b538SAndroid Build Coastguard Worker public:
440*6777b538SAndroid Build Coastguard Worker RTAudioFunctionTestThread() = default;
441*6777b538SAndroid Build Coastguard Worker
442*6777b538SAndroid Build Coastguard Worker RTAudioFunctionTestThread(const RTAudioFunctionTestThread&) = delete;
443*6777b538SAndroid Build Coastguard Worker RTAudioFunctionTestThread& operator=(const RTAudioFunctionTestThread&) =
444*6777b538SAndroid Build Coastguard Worker delete;
445*6777b538SAndroid Build Coastguard Worker
ThreadMain()446*6777b538SAndroid Build Coastguard Worker void ThreadMain() override {
447*6777b538SAndroid Build Coastguard Worker PlatformThread::SetCurrentThreadType(ThreadType::kRealtimeAudio);
448*6777b538SAndroid Build Coastguard Worker while (true) {
449*6777b538SAndroid Build Coastguard Worker PlatformThread::Sleep(Milliseconds(100));
450*6777b538SAndroid Build Coastguard Worker }
451*6777b538SAndroid Build Coastguard Worker }
452*6777b538SAndroid Build Coastguard Worker };
453*6777b538SAndroid Build Coastguard Worker
454*6777b538SAndroid Build Coastguard Worker class RTDisplayFunctionTestThread : public PlatformThread::Delegate {
455*6777b538SAndroid Build Coastguard Worker public:
456*6777b538SAndroid Build Coastguard Worker RTDisplayFunctionTestThread() = default;
457*6777b538SAndroid Build Coastguard Worker
458*6777b538SAndroid Build Coastguard Worker RTDisplayFunctionTestThread(const RTDisplayFunctionTestThread&) = delete;
459*6777b538SAndroid Build Coastguard Worker RTDisplayFunctionTestThread& operator=(const RTDisplayFunctionTestThread&) =
460*6777b538SAndroid Build Coastguard Worker delete;
461*6777b538SAndroid Build Coastguard Worker
ThreadMain()462*6777b538SAndroid Build Coastguard Worker void ThreadMain() override {
463*6777b538SAndroid Build Coastguard Worker PlatformThread::SetCurrentThreadType(ThreadType::kCompositing);
464*6777b538SAndroid Build Coastguard Worker while (true) {
465*6777b538SAndroid Build Coastguard Worker PlatformThread::Sleep(Milliseconds(100));
466*6777b538SAndroid Build Coastguard Worker }
467*6777b538SAndroid Build Coastguard Worker }
468*6777b538SAndroid Build Coastguard Worker };
469*6777b538SAndroid Build Coastguard Worker
470*6777b538SAndroid Build Coastguard Worker int create_threads_after_bg;
471*6777b538SAndroid Build Coastguard Worker bool bg_threads_created;
472*6777b538SAndroid Build Coastguard Worker bool prebg_threads_created;
473*6777b538SAndroid Build Coastguard Worker bool audio_rt_threads_created;
474*6777b538SAndroid Build Coastguard Worker bool display_rt_threads_created;
475*6777b538SAndroid Build Coastguard Worker
sig_create_threads_after_bg(int signum)476*6777b538SAndroid Build Coastguard Worker void sig_create_threads_after_bg(int signum) {
477*6777b538SAndroid Build Coastguard Worker if (signum == SIGUSR1) {
478*6777b538SAndroid Build Coastguard Worker create_threads_after_bg = true;
479*6777b538SAndroid Build Coastguard Worker }
480*6777b538SAndroid Build Coastguard Worker }
481*6777b538SAndroid Build Coastguard Worker
sig_prebg_threads_created_handler(int signum)482*6777b538SAndroid Build Coastguard Worker void sig_prebg_threads_created_handler(int signum) {
483*6777b538SAndroid Build Coastguard Worker if (signum == SIGUSR1) {
484*6777b538SAndroid Build Coastguard Worker prebg_threads_created = true;
485*6777b538SAndroid Build Coastguard Worker }
486*6777b538SAndroid Build Coastguard Worker }
487*6777b538SAndroid Build Coastguard Worker
sig_bg_threads_created_handler(int signum)488*6777b538SAndroid Build Coastguard Worker void sig_bg_threads_created_handler(int signum) {
489*6777b538SAndroid Build Coastguard Worker if (signum == SIGUSR2) {
490*6777b538SAndroid Build Coastguard Worker bg_threads_created = true;
491*6777b538SAndroid Build Coastguard Worker }
492*6777b538SAndroid Build Coastguard Worker }
493*6777b538SAndroid Build Coastguard Worker
sig_audio_rt_threads_created_handler(int signum)494*6777b538SAndroid Build Coastguard Worker void sig_audio_rt_threads_created_handler(int signum) {
495*6777b538SAndroid Build Coastguard Worker if (signum == SIGUSR1) {
496*6777b538SAndroid Build Coastguard Worker audio_rt_threads_created = true;
497*6777b538SAndroid Build Coastguard Worker }
498*6777b538SAndroid Build Coastguard Worker }
499*6777b538SAndroid Build Coastguard Worker
sig_display_rt_threads_created_handler(int signum)500*6777b538SAndroid Build Coastguard Worker void sig_display_rt_threads_created_handler(int signum) {
501*6777b538SAndroid Build Coastguard Worker if (signum == SIGUSR1) {
502*6777b538SAndroid Build Coastguard Worker display_rt_threads_created = true;
503*6777b538SAndroid Build Coastguard Worker }
504*6777b538SAndroid Build Coastguard Worker }
505*6777b538SAndroid Build Coastguard Worker
506*6777b538SAndroid Build Coastguard Worker } // namespace
507*6777b538SAndroid Build Coastguard Worker
MULTIPROCESS_TEST_MAIN(ProcessThreadBackgroundingMain)508*6777b538SAndroid Build Coastguard Worker MULTIPROCESS_TEST_MAIN(ProcessThreadBackgroundingMain) {
509*6777b538SAndroid Build Coastguard Worker PlatformThreadHandle handle1, handle2, handle3;
510*6777b538SAndroid Build Coastguard Worker FunctionTestThread thread1, thread2, thread3;
511*6777b538SAndroid Build Coastguard Worker base::test::ScopedFeatureList scoped_feature_list(kSetThreadBgForBgProcess);
512*6777b538SAndroid Build Coastguard Worker PlatformThreadChromeOS::InitializeFeatures();
513*6777b538SAndroid Build Coastguard Worker PlatformThread::SetCurrentThreadType(ThreadType::kCompositing);
514*6777b538SAndroid Build Coastguard Worker
515*6777b538SAndroid Build Coastguard Worker // Register signal handler to be notified to create threads after backgrounding.
516*6777b538SAndroid Build Coastguard Worker signal(SIGUSR1, sig_create_threads_after_bg);
517*6777b538SAndroid Build Coastguard Worker
518*6777b538SAndroid Build Coastguard Worker if (!PlatformThread::Create(0, &thread1, &handle1)) {
519*6777b538SAndroid Build Coastguard Worker ADD_FAILURE() << "ProcessThreadBackgroundingMain: Failed to create thread1";
520*6777b538SAndroid Build Coastguard Worker return 1;
521*6777b538SAndroid Build Coastguard Worker }
522*6777b538SAndroid Build Coastguard Worker
523*6777b538SAndroid Build Coastguard Worker if (!PlatformThread::Create(0, &thread2, &handle2)) {
524*6777b538SAndroid Build Coastguard Worker ADD_FAILURE() << "ProcessThreadBackgroundingMain: Failed to create thread2";
525*6777b538SAndroid Build Coastguard Worker return 1;
526*6777b538SAndroid Build Coastguard Worker }
527*6777b538SAndroid Build Coastguard Worker
528*6777b538SAndroid Build Coastguard Worker // Signal that the pre-backgrounding threads were created.
529*6777b538SAndroid Build Coastguard Worker kill(getppid(), SIGUSR1);
530*6777b538SAndroid Build Coastguard Worker
531*6777b538SAndroid Build Coastguard Worker // Wait for the signal to background.
532*6777b538SAndroid Build Coastguard Worker while (create_threads_after_bg == 0) {
533*6777b538SAndroid Build Coastguard Worker PlatformThread::Sleep(Milliseconds(100));
534*6777b538SAndroid Build Coastguard Worker }
535*6777b538SAndroid Build Coastguard Worker
536*6777b538SAndroid Build Coastguard Worker // Test creation of thread while process is backgrounded.
537*6777b538SAndroid Build Coastguard Worker if (!PlatformThread::Create(0, &thread3, &handle3)) {
538*6777b538SAndroid Build Coastguard Worker ADD_FAILURE() << "ProcessThreadBackgroundingMain: Failed to create thread3";
539*6777b538SAndroid Build Coastguard Worker return 1;
540*6777b538SAndroid Build Coastguard Worker }
541*6777b538SAndroid Build Coastguard Worker
542*6777b538SAndroid Build Coastguard Worker // Signal that the thread after backgrounding was created.
543*6777b538SAndroid Build Coastguard Worker kill(getppid(), SIGUSR2);
544*6777b538SAndroid Build Coastguard Worker
545*6777b538SAndroid Build Coastguard Worker while (true) {
546*6777b538SAndroid Build Coastguard Worker PlatformThread::Sleep(Milliseconds(100));
547*6777b538SAndroid Build Coastguard Worker }
548*6777b538SAndroid Build Coastguard Worker }
549*6777b538SAndroid Build Coastguard Worker
550*6777b538SAndroid Build Coastguard Worker // ProcessThreadBackgrounding: A test to create a process and verify
551*6777b538SAndroid Build Coastguard Worker // that the threads in the process are backgrounded correctly.
TEST_F(ProcessTest,ProcessThreadBackgrounding)552*6777b538SAndroid Build Coastguard Worker TEST_F(ProcessTest, ProcessThreadBackgrounding) {
553*6777b538SAndroid Build Coastguard Worker if (!PlatformThread::CanChangeThreadType(ThreadType::kDefault,
554*6777b538SAndroid Build Coastguard Worker ThreadType::kCompositing)) {
555*6777b538SAndroid Build Coastguard Worker return;
556*6777b538SAndroid Build Coastguard Worker }
557*6777b538SAndroid Build Coastguard Worker
558*6777b538SAndroid Build Coastguard Worker base::test::ScopedFeatureList scoped_feature_list(kSetThreadBgForBgProcess);
559*6777b538SAndroid Build Coastguard Worker PlatformThreadChromeOS::InitializeFeatures();
560*6777b538SAndroid Build Coastguard Worker
561*6777b538SAndroid Build Coastguard Worker // Register signal handlers to be notified of events in child process.
562*6777b538SAndroid Build Coastguard Worker signal(SIGUSR1, sig_prebg_threads_created_handler);
563*6777b538SAndroid Build Coastguard Worker signal(SIGUSR2, sig_bg_threads_created_handler);
564*6777b538SAndroid Build Coastguard Worker
565*6777b538SAndroid Build Coastguard Worker Process process(SpawnChild("ProcessThreadBackgroundingMain"));
566*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(process.IsValid());
567*6777b538SAndroid Build Coastguard Worker
568*6777b538SAndroid Build Coastguard Worker // Wait for the signal that the initial pre-backgrounding
569*6777b538SAndroid Build Coastguard Worker // threads were created.
570*6777b538SAndroid Build Coastguard Worker while (!prebg_threads_created) {
571*6777b538SAndroid Build Coastguard Worker PlatformThread::Sleep(Milliseconds(100));
572*6777b538SAndroid Build Coastguard Worker }
573*6777b538SAndroid Build Coastguard Worker
574*6777b538SAndroid Build Coastguard Worker // Verify that the threads are initially in the foreground.
575*6777b538SAndroid Build Coastguard Worker AssertThreadsType(process.Pid(), ThreadType::kCompositing);
576*6777b538SAndroid Build Coastguard Worker AssertThreadsBgState(process.Pid(), false);
577*6777b538SAndroid Build Coastguard Worker
578*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(process.SetPriority(Process::Priority::kBestEffort));
579*6777b538SAndroid Build Coastguard Worker
580*6777b538SAndroid Build Coastguard Worker // Send a signal to create a thread while the process is backgrounded.
581*6777b538SAndroid Build Coastguard Worker kill(process.Pid(), SIGUSR1);
582*6777b538SAndroid Build Coastguard Worker
583*6777b538SAndroid Build Coastguard Worker // Wait for the signal that backgrounding completed
584*6777b538SAndroid Build Coastguard Worker while (!bg_threads_created) {
585*6777b538SAndroid Build Coastguard Worker PlatformThread::Sleep(Milliseconds(100));
586*6777b538SAndroid Build Coastguard Worker }
587*6777b538SAndroid Build Coastguard Worker
588*6777b538SAndroid Build Coastguard Worker // Verify that the threads are backgrounded.
589*6777b538SAndroid Build Coastguard Worker AssertThreadsType(process.Pid(), ThreadType::kCompositing);
590*6777b538SAndroid Build Coastguard Worker AssertThreadsBgState(process.Pid(), true);
591*6777b538SAndroid Build Coastguard Worker
592*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(process.SetPriority(Process::Priority::kUserBlocking));
593*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(process.GetPriority() == base::Process::Priority::kUserBlocking);
594*6777b538SAndroid Build Coastguard Worker
595*6777b538SAndroid Build Coastguard Worker // Verify that the threads are foregrounded.
596*6777b538SAndroid Build Coastguard Worker AssertThreadsType(process.Pid(), ThreadType::kCompositing);
597*6777b538SAndroid Build Coastguard Worker AssertThreadsBgState(process.Pid(), false);
598*6777b538SAndroid Build Coastguard Worker }
599*6777b538SAndroid Build Coastguard Worker
MULTIPROCESS_TEST_MAIN(ProcessRTAudioBgMain)600*6777b538SAndroid Build Coastguard Worker MULTIPROCESS_TEST_MAIN(ProcessRTAudioBgMain) {
601*6777b538SAndroid Build Coastguard Worker PlatformThreadHandle handle1;
602*6777b538SAndroid Build Coastguard Worker RTAudioFunctionTestThread thread1;
603*6777b538SAndroid Build Coastguard Worker base::test::ScopedFeatureList scoped_feature_list(kSetThreadBgForBgProcess);
604*6777b538SAndroid Build Coastguard Worker PlatformThreadChromeOS::InitializeFeatures();
605*6777b538SAndroid Build Coastguard Worker PlatformThread::SetCurrentThreadType(ThreadType::kRealtimeAudio);
606*6777b538SAndroid Build Coastguard Worker
607*6777b538SAndroid Build Coastguard Worker if (!PlatformThread::Create(0, &thread1, &handle1)) {
608*6777b538SAndroid Build Coastguard Worker ADD_FAILURE() << "ProcessRTAudioBgMain: Failed to create thread1";
609*6777b538SAndroid Build Coastguard Worker return 1;
610*6777b538SAndroid Build Coastguard Worker }
611*6777b538SAndroid Build Coastguard Worker
612*6777b538SAndroid Build Coastguard Worker // Signal that the RT thread was created.
613*6777b538SAndroid Build Coastguard Worker kill(getppid(), SIGUSR1);
614*6777b538SAndroid Build Coastguard Worker
615*6777b538SAndroid Build Coastguard Worker while (true) {
616*6777b538SAndroid Build Coastguard Worker PlatformThread::Sleep(Milliseconds(100));
617*6777b538SAndroid Build Coastguard Worker }
618*6777b538SAndroid Build Coastguard Worker }
619*6777b538SAndroid Build Coastguard Worker
620*6777b538SAndroid Build Coastguard Worker // Test the property of kRealTimeAudio threads in a backgrounded process.
TEST_F(ProcessTest,ProcessRTAudioBg)621*6777b538SAndroid Build Coastguard Worker TEST_F(ProcessTest, ProcessRTAudioBg) {
622*6777b538SAndroid Build Coastguard Worker if (!PlatformThread::CanChangeThreadType(ThreadType::kDefault,
623*6777b538SAndroid Build Coastguard Worker ThreadType::kCompositing)) {
624*6777b538SAndroid Build Coastguard Worker return;
625*6777b538SAndroid Build Coastguard Worker }
626*6777b538SAndroid Build Coastguard Worker
627*6777b538SAndroid Build Coastguard Worker base::test::ScopedFeatureList scoped_feature_list(kSetThreadBgForBgProcess);
628*6777b538SAndroid Build Coastguard Worker PlatformThreadChromeOS::InitializeFeatures();
629*6777b538SAndroid Build Coastguard Worker
630*6777b538SAndroid Build Coastguard Worker // Register signal handler to check if RT thread was created by child process.
631*6777b538SAndroid Build Coastguard Worker signal(SIGUSR1, sig_audio_rt_threads_created_handler);
632*6777b538SAndroid Build Coastguard Worker
633*6777b538SAndroid Build Coastguard Worker Process process(SpawnChild("ProcessRTAudioBgMain"));
634*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(process.IsValid());
635*6777b538SAndroid Build Coastguard Worker
636*6777b538SAndroid Build Coastguard Worker // Wait for signal that threads were spawned
637*6777b538SAndroid Build Coastguard Worker while (!audio_rt_threads_created) {
638*6777b538SAndroid Build Coastguard Worker PlatformThread::Sleep(Milliseconds(100));
639*6777b538SAndroid Build Coastguard Worker }
640*6777b538SAndroid Build Coastguard Worker
641*6777b538SAndroid Build Coastguard Worker AssertThreadsRT(process.Pid(), true);
642*6777b538SAndroid Build Coastguard Worker AssertThreadsType(process.Pid(), ThreadType::kRealtimeAudio);
643*6777b538SAndroid Build Coastguard Worker AssertThreadsBgState(process.Pid(), false);
644*6777b538SAndroid Build Coastguard Worker
645*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(process.SetPriority(Process::Priority::kBestEffort));
646*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(process.GetPriority() == base::Process::Priority::kBestEffort);
647*6777b538SAndroid Build Coastguard Worker
648*6777b538SAndroid Build Coastguard Worker // Verify that nothing changed when process is kBestEffort
649*6777b538SAndroid Build Coastguard Worker AssertThreadsRT(process.Pid(), true);
650*6777b538SAndroid Build Coastguard Worker AssertThreadsType(process.Pid(), ThreadType::kRealtimeAudio);
651*6777b538SAndroid Build Coastguard Worker AssertThreadsBgState(process.Pid(), false);
652*6777b538SAndroid Build Coastguard Worker
653*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(process.SetPriority(Process::Priority::kUserBlocking));
654*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(process.GetPriority() == base::Process::Priority::kUserBlocking);
655*6777b538SAndroid Build Coastguard Worker
656*6777b538SAndroid Build Coastguard Worker // Verify that nothing changed when process is kUserBlocking
657*6777b538SAndroid Build Coastguard Worker AssertThreadsRT(process.Pid(), true);
658*6777b538SAndroid Build Coastguard Worker AssertThreadsType(process.Pid(), ThreadType::kRealtimeAudio);
659*6777b538SAndroid Build Coastguard Worker AssertThreadsBgState(process.Pid(), false);
660*6777b538SAndroid Build Coastguard Worker }
661*6777b538SAndroid Build Coastguard Worker
MULTIPROCESS_TEST_MAIN(ProcessRTDisplayBgMain)662*6777b538SAndroid Build Coastguard Worker MULTIPROCESS_TEST_MAIN(ProcessRTDisplayBgMain) {
663*6777b538SAndroid Build Coastguard Worker PlatformThreadHandle handle1;
664*6777b538SAndroid Build Coastguard Worker RTDisplayFunctionTestThread thread1;
665*6777b538SAndroid Build Coastguard Worker base::test::ScopedFeatureList scoped_feature_list;
666*6777b538SAndroid Build Coastguard Worker scoped_feature_list.InitWithFeatures(
667*6777b538SAndroid Build Coastguard Worker {kSetThreadBgForBgProcess, kSetRtForDisplayThreads}, {});
668*6777b538SAndroid Build Coastguard Worker PlatformThreadChromeOS::InitializeFeatures();
669*6777b538SAndroid Build Coastguard Worker
670*6777b538SAndroid Build Coastguard Worker PlatformThread::SetCurrentThreadType(ThreadType::kCompositing);
671*6777b538SAndroid Build Coastguard Worker
672*6777b538SAndroid Build Coastguard Worker if (!PlatformThread::Create(0, &thread1, &handle1)) {
673*6777b538SAndroid Build Coastguard Worker ADD_FAILURE() << "ProcessRTDisplayBgMain: Failed to create thread1";
674*6777b538SAndroid Build Coastguard Worker return 1;
675*6777b538SAndroid Build Coastguard Worker }
676*6777b538SAndroid Build Coastguard Worker
677*6777b538SAndroid Build Coastguard Worker // Signal that the RT thread was created.
678*6777b538SAndroid Build Coastguard Worker kill(getppid(), SIGUSR1);
679*6777b538SAndroid Build Coastguard Worker
680*6777b538SAndroid Build Coastguard Worker while (true) {
681*6777b538SAndroid Build Coastguard Worker PlatformThread::Sleep(Milliseconds(100));
682*6777b538SAndroid Build Coastguard Worker }
683*6777b538SAndroid Build Coastguard Worker }
684*6777b538SAndroid Build Coastguard Worker
685*6777b538SAndroid Build Coastguard Worker // Test the property of kCompositing threads in a backgrounded process.
TEST_F(ProcessTest,ProcessRTDisplayBg)686*6777b538SAndroid Build Coastguard Worker TEST_F(ProcessTest, ProcessRTDisplayBg) {
687*6777b538SAndroid Build Coastguard Worker if (!PlatformThread::CanChangeThreadType(ThreadType::kDefault,
688*6777b538SAndroid Build Coastguard Worker ThreadType::kCompositing)) {
689*6777b538SAndroid Build Coastguard Worker return;
690*6777b538SAndroid Build Coastguard Worker }
691*6777b538SAndroid Build Coastguard Worker
692*6777b538SAndroid Build Coastguard Worker base::test::ScopedFeatureList scoped_feature_list;
693*6777b538SAndroid Build Coastguard Worker scoped_feature_list.InitWithFeatures(
694*6777b538SAndroid Build Coastguard Worker {kSetThreadBgForBgProcess, kSetRtForDisplayThreads}, {});
695*6777b538SAndroid Build Coastguard Worker PlatformThreadChromeOS::InitializeFeatures();
696*6777b538SAndroid Build Coastguard Worker
697*6777b538SAndroid Build Coastguard Worker // Register signal handler to check if RT thread was created by child process.
698*6777b538SAndroid Build Coastguard Worker signal(SIGUSR1, sig_display_rt_threads_created_handler);
699*6777b538SAndroid Build Coastguard Worker
700*6777b538SAndroid Build Coastguard Worker Process process(SpawnChild("ProcessRTDisplayBgMain"));
701*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(process.IsValid());
702*6777b538SAndroid Build Coastguard Worker
703*6777b538SAndroid Build Coastguard Worker // Wait for signal that threads were spawned
704*6777b538SAndroid Build Coastguard Worker while (!display_rt_threads_created) {
705*6777b538SAndroid Build Coastguard Worker PlatformThread::Sleep(Milliseconds(100));
706*6777b538SAndroid Build Coastguard Worker }
707*6777b538SAndroid Build Coastguard Worker
708*6777b538SAndroid Build Coastguard Worker AssertThreadsRT(process.Pid(), true);
709*6777b538SAndroid Build Coastguard Worker AssertThreadsType(process.Pid(), ThreadType::kCompositing);
710*6777b538SAndroid Build Coastguard Worker AssertThreadsBgState(process.Pid(), false);
711*6777b538SAndroid Build Coastguard Worker
712*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(process.SetPriority(Process::Priority::kBestEffort));
713*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(process.GetPriority() == base::Process::Priority::kBestEffort);
714*6777b538SAndroid Build Coastguard Worker
715*6777b538SAndroid Build Coastguard Worker // Verify that the threads transitioned away from RT when process is
716*6777b538SAndroid Build Coastguard Worker // kBestEffort
717*6777b538SAndroid Build Coastguard Worker AssertThreadsRT(process.Pid(), false);
718*6777b538SAndroid Build Coastguard Worker AssertThreadsType(process.Pid(), ThreadType::kCompositing);
719*6777b538SAndroid Build Coastguard Worker AssertThreadsBgState(process.Pid(), true);
720*6777b538SAndroid Build Coastguard Worker
721*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(process.SetPriority(Process::Priority::kUserBlocking));
722*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(process.GetPriority() == base::Process::Priority::kUserBlocking);
723*6777b538SAndroid Build Coastguard Worker
724*6777b538SAndroid Build Coastguard Worker // Verify that it is back to RT when process is kUserBlocking
725*6777b538SAndroid Build Coastguard Worker AssertThreadsRT(process.Pid(), true);
726*6777b538SAndroid Build Coastguard Worker AssertThreadsType(process.Pid(), ThreadType::kCompositing);
727*6777b538SAndroid Build Coastguard Worker AssertThreadsBgState(process.Pid(), false);
728*6777b538SAndroid Build Coastguard Worker }
729*6777b538SAndroid Build Coastguard Worker
730*6777b538SAndroid Build Coastguard Worker #endif // BUILDFLAG(IS_CHROMEOS)
731*6777b538SAndroid Build Coastguard Worker
732*6777b538SAndroid Build Coastguard Worker // Consumers can use WaitForExitWithTimeout(base::TimeDelta(), nullptr) to check
733*6777b538SAndroid Build Coastguard Worker // whether the process is still running. This may not be safe because of the
734*6777b538SAndroid Build Coastguard Worker // potential reusing of the process id. So we won't export Process::IsRunning()
735*6777b538SAndroid Build Coastguard Worker // on all platforms. But for the controllable scenario in the test cases, the
736*6777b538SAndroid Build Coastguard Worker // behavior should be guaranteed.
TEST_F(ProcessTest,CurrentProcessIsRunning)737*6777b538SAndroid Build Coastguard Worker TEST_F(ProcessTest, CurrentProcessIsRunning) {
738*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(Process::Current().WaitForExitWithTimeout(
739*6777b538SAndroid Build Coastguard Worker base::TimeDelta(), nullptr));
740*6777b538SAndroid Build Coastguard Worker }
741*6777b538SAndroid Build Coastguard Worker
742*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_APPLE)
743*6777b538SAndroid Build Coastguard Worker // On Mac OSX, we can detect whether a non-child process is running.
TEST_F(ProcessTest,PredefinedProcessIsRunning)744*6777b538SAndroid Build Coastguard Worker TEST_F(ProcessTest, PredefinedProcessIsRunning) {
745*6777b538SAndroid Build Coastguard Worker // Process 1 is the /sbin/launchd, it should be always running.
746*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(Process::Open(1).WaitForExitWithTimeout(
747*6777b538SAndroid Build Coastguard Worker base::TimeDelta(), nullptr));
748*6777b538SAndroid Build Coastguard Worker }
749*6777b538SAndroid Build Coastguard Worker #endif
750*6777b538SAndroid Build Coastguard Worker
751*6777b538SAndroid Build Coastguard Worker // Test is disabled on Windows AMR64 because
752*6777b538SAndroid Build Coastguard Worker // TerminateWithHeapCorruption() isn't expected to work there.
753*6777b538SAndroid Build Coastguard Worker // See: https://crbug.com/1054423
754*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
755*6777b538SAndroid Build Coastguard Worker #if defined(ARCH_CPU_ARM64)
756*6777b538SAndroid Build Coastguard Worker #define MAYBE_HeapCorruption DISABLED_HeapCorruption
757*6777b538SAndroid Build Coastguard Worker #else
758*6777b538SAndroid Build Coastguard Worker #define MAYBE_HeapCorruption HeapCorruption
759*6777b538SAndroid Build Coastguard Worker #endif
TEST_F(ProcessTest,MAYBE_HeapCorruption)760*6777b538SAndroid Build Coastguard Worker TEST_F(ProcessTest, MAYBE_HeapCorruption) {
761*6777b538SAndroid Build Coastguard Worker EXPECT_EXIT(base::debug::win::TerminateWithHeapCorruption(),
762*6777b538SAndroid Build Coastguard Worker ::testing::ExitedWithCode(STATUS_HEAP_CORRUPTION), "");
763*6777b538SAndroid Build Coastguard Worker }
764*6777b538SAndroid Build Coastguard Worker
765*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(WIN_ENABLE_CFG_GUARDS)
766*6777b538SAndroid Build Coastguard Worker #define MAYBE_ControlFlowViolation ControlFlowViolation
767*6777b538SAndroid Build Coastguard Worker #else
768*6777b538SAndroid Build Coastguard Worker #define MAYBE_ControlFlowViolation DISABLED_ControlFlowViolation
769*6777b538SAndroid Build Coastguard Worker #endif
TEST_F(ProcessTest,MAYBE_ControlFlowViolation)770*6777b538SAndroid Build Coastguard Worker TEST_F(ProcessTest, MAYBE_ControlFlowViolation) {
771*6777b538SAndroid Build Coastguard Worker // CFG causes ntdll!RtlFailFast2 to be called resulting in uncatchable
772*6777b538SAndroid Build Coastguard Worker // 0xC0000409 (STATUS_STACK_BUFFER_OVERRUN) exception.
773*6777b538SAndroid Build Coastguard Worker EXPECT_EXIT(base::debug::win::TerminateWithControlFlowViolation(),
774*6777b538SAndroid Build Coastguard Worker ::testing::ExitedWithCode(STATUS_STACK_BUFFER_OVERRUN), "");
775*6777b538SAndroid Build Coastguard Worker }
776*6777b538SAndroid Build Coastguard Worker
777*6777b538SAndroid Build Coastguard Worker #endif // BUILDFLAG(IS_WIN)
778*6777b538SAndroid Build Coastguard Worker
TEST_F(ProcessTest,ChildProcessIsRunning)779*6777b538SAndroid Build Coastguard Worker TEST_F(ProcessTest, ChildProcessIsRunning) {
780*6777b538SAndroid Build Coastguard Worker Process process(SpawnChild("SleepyChildProcess"));
781*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(process.WaitForExitWithTimeout(
782*6777b538SAndroid Build Coastguard Worker base::TimeDelta(), nullptr));
783*6777b538SAndroid Build Coastguard Worker process.Terminate(0, true);
784*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(process.WaitForExitWithTimeout(
785*6777b538SAndroid Build Coastguard Worker base::TimeDelta(), nullptr));
786*6777b538SAndroid Build Coastguard Worker }
787*6777b538SAndroid Build Coastguard Worker
788*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_CHROMEOS)
789*6777b538SAndroid Build Coastguard Worker
790*6777b538SAndroid Build Coastguard Worker // Tests that the function GetProcessPriorityCGroup() can parse the contents
791*6777b538SAndroid Build Coastguard Worker // of the /proc/<pid>/cgroup file successfully.
TEST_F(ProcessTest,TestGetProcessPriorityCGroup)792*6777b538SAndroid Build Coastguard Worker TEST_F(ProcessTest, TestGetProcessPriorityCGroup) {
793*6777b538SAndroid Build Coastguard Worker const char kNotBackgroundedCGroup[] = "5:cpuacct,cpu,cpuset:/daemons\n";
794*6777b538SAndroid Build Coastguard Worker const char kBackgroundedCGroup[] =
795*6777b538SAndroid Build Coastguard Worker "2:freezer:/chrome_renderers/to_be_frozen\n"
796*6777b538SAndroid Build Coastguard Worker "1:cpu:/chrome_renderers/background\n";
797*6777b538SAndroid Build Coastguard Worker
798*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(GetProcessPriorityCGroup(kNotBackgroundedCGroup),
799*6777b538SAndroid Build Coastguard Worker Process::Priority::kUserBlocking);
800*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(GetProcessPriorityCGroup(kBackgroundedCGroup),
801*6777b538SAndroid Build Coastguard Worker Process::Priority::kBestEffort);
802*6777b538SAndroid Build Coastguard Worker }
803*6777b538SAndroid Build Coastguard Worker
TEST_F(ProcessTest,InitializePriorityEmptyProcess)804*6777b538SAndroid Build Coastguard Worker TEST_F(ProcessTest, InitializePriorityEmptyProcess) {
805*6777b538SAndroid Build Coastguard Worker // TODO(b/172213843): base::Process is used by base::TestSuite::Initialize
806*6777b538SAndroid Build Coastguard Worker // before we can use ScopedFeatureList here. Update the test to allow the
807*6777b538SAndroid Build Coastguard Worker // use of ScopedFeatureList before base::TestSuite::Initialize runs.
808*6777b538SAndroid Build Coastguard Worker if (!Process::OneGroupPerRendererEnabledForTesting())
809*6777b538SAndroid Build Coastguard Worker return;
810*6777b538SAndroid Build Coastguard Worker
811*6777b538SAndroid Build Coastguard Worker Process process;
812*6777b538SAndroid Build Coastguard Worker process.InitializePriority();
813*6777b538SAndroid Build Coastguard Worker const std::string unique_token = process.unique_token();
814*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(unique_token.empty());
815*6777b538SAndroid Build Coastguard Worker }
816*6777b538SAndroid Build Coastguard Worker
TEST_F(ProcessTest,SetProcessBackgroundedOneCgroupPerRender)817*6777b538SAndroid Build Coastguard Worker TEST_F(ProcessTest, SetProcessBackgroundedOneCgroupPerRender) {
818*6777b538SAndroid Build Coastguard Worker if (!Process::OneGroupPerRendererEnabledForTesting())
819*6777b538SAndroid Build Coastguard Worker return;
820*6777b538SAndroid Build Coastguard Worker
821*6777b538SAndroid Build Coastguard Worker base::test::TaskEnvironment task_env;
822*6777b538SAndroid Build Coastguard Worker
823*6777b538SAndroid Build Coastguard Worker Process process(SpawnChild("SimpleChildProcess"));
824*6777b538SAndroid Build Coastguard Worker process.InitializePriority();
825*6777b538SAndroid Build Coastguard Worker const std::string unique_token = process.unique_token();
826*6777b538SAndroid Build Coastguard Worker ASSERT_FALSE(unique_token.empty());
827*6777b538SAndroid Build Coastguard Worker
828*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(process.SetPriority(Process::Priority::kUserBlocking));
829*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(process.GetPriority(), Process::Priority::kUserBlocking);
830*6777b538SAndroid Build Coastguard Worker std::string cgroup = GetProcessCpuCgroup(process);
831*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(cgroup.empty());
832*6777b538SAndroid Build Coastguard Worker EXPECT_NE(cgroup.find(unique_token), std::string::npos);
833*6777b538SAndroid Build Coastguard Worker
834*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(process.SetPriority(Process::Priority::kBestEffort));
835*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(process.GetPriority(), Process::Priority::kBestEffort);
836*6777b538SAndroid Build Coastguard Worker
837*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(process.Terminate(0, false));
838*6777b538SAndroid Build Coastguard Worker // Terminate should post a task, wait for it to run
839*6777b538SAndroid Build Coastguard Worker task_env.RunUntilIdle();
840*6777b538SAndroid Build Coastguard Worker
841*6777b538SAndroid Build Coastguard Worker cgroup = std::string(kCgroupRoot) + cgroup;
842*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(base::DirectoryExists(FilePath(cgroup)));
843*6777b538SAndroid Build Coastguard Worker }
844*6777b538SAndroid Build Coastguard Worker
TEST_F(ProcessTest,CleanUpBusyProcess)845*6777b538SAndroid Build Coastguard Worker TEST_F(ProcessTest, CleanUpBusyProcess) {
846*6777b538SAndroid Build Coastguard Worker if (!Process::OneGroupPerRendererEnabledForTesting())
847*6777b538SAndroid Build Coastguard Worker return;
848*6777b538SAndroid Build Coastguard Worker
849*6777b538SAndroid Build Coastguard Worker base::test::TaskEnvironment task_env;
850*6777b538SAndroid Build Coastguard Worker
851*6777b538SAndroid Build Coastguard Worker Process process(SpawnChild("SimpleChildProcess"));
852*6777b538SAndroid Build Coastguard Worker process.InitializePriority();
853*6777b538SAndroid Build Coastguard Worker const std::string unique_token = process.unique_token();
854*6777b538SAndroid Build Coastguard Worker ASSERT_FALSE(unique_token.empty());
855*6777b538SAndroid Build Coastguard Worker
856*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(process.SetPriority(Process::Priority::kUserBlocking));
857*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(process.GetPriority(), Process::Priority::kUserBlocking);
858*6777b538SAndroid Build Coastguard Worker std::string cgroup = GetProcessCpuCgroup(process);
859*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(cgroup.empty());
860*6777b538SAndroid Build Coastguard Worker EXPECT_NE(cgroup.find(unique_token), std::string::npos);
861*6777b538SAndroid Build Coastguard Worker
862*6777b538SAndroid Build Coastguard Worker // Add another process to the cgroup to ensure it stays busy.
863*6777b538SAndroid Build Coastguard Worker cgroup = std::string(kCgroupRoot) + cgroup;
864*6777b538SAndroid Build Coastguard Worker Process process2(SpawnChild("SimpleChildProcess"));
865*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(AddProcessToCpuCgroup(process2, cgroup));
866*6777b538SAndroid Build Coastguard Worker
867*6777b538SAndroid Build Coastguard Worker // Terminate the first process that should tirgger a cleanup of the cgroup
868*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(process.Terminate(0, false));
869*6777b538SAndroid Build Coastguard Worker // Wait until the background task runs once. This should fail and requeue
870*6777b538SAndroid Build Coastguard Worker // another task to retry.
871*6777b538SAndroid Build Coastguard Worker task_env.RunUntilIdle();
872*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(base::DirectoryExists(FilePath(cgroup)));
873*6777b538SAndroid Build Coastguard Worker
874*6777b538SAndroid Build Coastguard Worker // Move the second process to free the cgroup
875*6777b538SAndroid Build Coastguard Worker std::string foreground_path =
876*6777b538SAndroid Build Coastguard Worker std::string(kCgroupRoot) + std::string(kForeground);
877*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(AddProcessToCpuCgroup(process2, foreground_path));
878*6777b538SAndroid Build Coastguard Worker
879*6777b538SAndroid Build Coastguard Worker // Wait for the retry.
880*6777b538SAndroid Build Coastguard Worker PlatformThread::Sleep(base::Milliseconds(1100));
881*6777b538SAndroid Build Coastguard Worker task_env.RunUntilIdle();
882*6777b538SAndroid Build Coastguard Worker // The cgroup should be deleted now.
883*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(base::DirectoryExists(FilePath(cgroup)));
884*6777b538SAndroid Build Coastguard Worker
885*6777b538SAndroid Build Coastguard Worker process2.Terminate(0, false);
886*6777b538SAndroid Build Coastguard Worker }
887*6777b538SAndroid Build Coastguard Worker
TEST_F(ProcessTest,SetProcessBackgroundedEmptyToken)888*6777b538SAndroid Build Coastguard Worker TEST_F(ProcessTest, SetProcessBackgroundedEmptyToken) {
889*6777b538SAndroid Build Coastguard Worker if (!Process::OneGroupPerRendererEnabledForTesting())
890*6777b538SAndroid Build Coastguard Worker return;
891*6777b538SAndroid Build Coastguard Worker
892*6777b538SAndroid Build Coastguard Worker Process process(SpawnChild("SimpleChildProcess"));
893*6777b538SAndroid Build Coastguard Worker const std::string unique_token = process.unique_token();
894*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(unique_token.empty());
895*6777b538SAndroid Build Coastguard Worker
896*6777b538SAndroid Build Coastguard Worker // Moving to the foreground should use the default foreground path.
897*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(process.SetPriority(Process::Priority::kUserBlocking));
898*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(process.GetPriority(), Process::Priority::kUserBlocking);
899*6777b538SAndroid Build Coastguard Worker std::string cgroup = GetProcessCpuCgroup(process);
900*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(cgroup.empty());
901*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(cgroup, kForeground);
902*6777b538SAndroid Build Coastguard Worker }
903*6777b538SAndroid Build Coastguard Worker
TEST_F(ProcessTest,CleansUpStaleGroups)904*6777b538SAndroid Build Coastguard Worker TEST_F(ProcessTest, CleansUpStaleGroups) {
905*6777b538SAndroid Build Coastguard Worker if (!Process::OneGroupPerRendererEnabledForTesting())
906*6777b538SAndroid Build Coastguard Worker return;
907*6777b538SAndroid Build Coastguard Worker
908*6777b538SAndroid Build Coastguard Worker base::test::TaskEnvironment task_env;
909*6777b538SAndroid Build Coastguard Worker
910*6777b538SAndroid Build Coastguard Worker // Create a process that will not be cleaned up
911*6777b538SAndroid Build Coastguard Worker Process process(SpawnChild("SimpleChildProcess"));
912*6777b538SAndroid Build Coastguard Worker process.InitializePriority();
913*6777b538SAndroid Build Coastguard Worker const std::string unique_token = process.unique_token();
914*6777b538SAndroid Build Coastguard Worker ASSERT_FALSE(unique_token.empty());
915*6777b538SAndroid Build Coastguard Worker
916*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(process.SetPriority(Process::Priority::kBestEffort));
917*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(process.GetPriority(), Process::Priority::kBestEffort);
918*6777b538SAndroid Build Coastguard Worker
919*6777b538SAndroid Build Coastguard Worker // Create a stale cgroup
920*6777b538SAndroid Build Coastguard Worker std::string root = kFullRendererCgroupRoot;
921*6777b538SAndroid Build Coastguard Worker std::string cgroup = root + "/" + unique_token;
922*6777b538SAndroid Build Coastguard Worker std::vector<std::string> tokens = base::SplitString(
923*6777b538SAndroid Build Coastguard Worker cgroup, "-", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
924*6777b538SAndroid Build Coastguard Worker tokens[1] = "fake";
925*6777b538SAndroid Build Coastguard Worker std::string fake_cgroup = base::JoinString(tokens, "-");
926*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(base::CreateDirectory(FilePath(fake_cgroup)));
927*6777b538SAndroid Build Coastguard Worker
928*6777b538SAndroid Build Coastguard Worker // Clean up stale groups
929*6777b538SAndroid Build Coastguard Worker Process::CleanUpStaleProcessStates();
930*6777b538SAndroid Build Coastguard Worker
931*6777b538SAndroid Build Coastguard Worker // validate the fake group is deleted
932*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(base::DirectoryExists(FilePath(fake_cgroup)));
933*6777b538SAndroid Build Coastguard Worker
934*6777b538SAndroid Build Coastguard Worker // validate the active process cgroup is not deleted
935*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(base::DirectoryExists(FilePath(cgroup)));
936*6777b538SAndroid Build Coastguard Worker
937*6777b538SAndroid Build Coastguard Worker // validate foreground and background are not deleted
938*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(base::DirectoryExists(FilePath(root + "/foreground")));
939*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(base::DirectoryExists(FilePath(root + "/background")));
940*6777b538SAndroid Build Coastguard Worker
941*6777b538SAndroid Build Coastguard Worker // clean up the process
942*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(process.Terminate(0, false));
943*6777b538SAndroid Build Coastguard Worker // Terminate should post a task, wait for it to run
944*6777b538SAndroid Build Coastguard Worker task_env.RunUntilIdle();
945*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(base::DirectoryExists(FilePath(cgroup)));
946*6777b538SAndroid Build Coastguard Worker }
947*6777b538SAndroid Build Coastguard Worker
TEST_F(ProcessTest,OneCgroupDoesNotCleanUpGroupsWithWrongPrefix)948*6777b538SAndroid Build Coastguard Worker TEST_F(ProcessTest, OneCgroupDoesNotCleanUpGroupsWithWrongPrefix) {
949*6777b538SAndroid Build Coastguard Worker if (!Process::OneGroupPerRendererEnabledForTesting())
950*6777b538SAndroid Build Coastguard Worker return;
951*6777b538SAndroid Build Coastguard Worker
952*6777b538SAndroid Build Coastguard Worker base::test::TaskEnvironment task_env;
953*6777b538SAndroid Build Coastguard Worker
954*6777b538SAndroid Build Coastguard Worker // Create a process that will not be cleaned up
955*6777b538SAndroid Build Coastguard Worker Process process(SpawnChild("SimpleChildProcess"));
956*6777b538SAndroid Build Coastguard Worker process.InitializePriority();
957*6777b538SAndroid Build Coastguard Worker const std::string unique_token = process.unique_token();
958*6777b538SAndroid Build Coastguard Worker ASSERT_FALSE(unique_token.empty());
959*6777b538SAndroid Build Coastguard Worker
960*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(process.SetPriority(Process::Priority::kUserBlocking));
961*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(process.GetPriority(), Process::Priority::kUserBlocking);
962*6777b538SAndroid Build Coastguard Worker std::string cgroup = GetProcessCpuCgroup(process);
963*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(cgroup.empty());
964*6777b538SAndroid Build Coastguard Worker EXPECT_NE(cgroup.find(unique_token), std::string::npos);
965*6777b538SAndroid Build Coastguard Worker
966*6777b538SAndroid Build Coastguard Worker // Create a stale cgroup
967*6777b538SAndroid Build Coastguard Worker FilePath cgroup_path = FilePath(std::string(kCgroupRoot) + cgroup);
968*6777b538SAndroid Build Coastguard Worker FilePath fake_cgroup = FilePath(kFullRendererCgroupRoot).AppendASCII("fake");
969*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(base::CreateDirectory(fake_cgroup));
970*6777b538SAndroid Build Coastguard Worker
971*6777b538SAndroid Build Coastguard Worker // Clean up stale groups
972*6777b538SAndroid Build Coastguard Worker Process::CleanUpStaleProcessStates();
973*6777b538SAndroid Build Coastguard Worker
974*6777b538SAndroid Build Coastguard Worker // validate the fake group is deleted
975*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(base::DirectoryExists(fake_cgroup));
976*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(base::DirectoryExists(cgroup_path));
977*6777b538SAndroid Build Coastguard Worker
978*6777b538SAndroid Build Coastguard Worker // clean up the process
979*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(process.SetPriority(Process::Priority::kBestEffort));
980*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(process.GetPriority(), Process::Priority::kBestEffort);
981*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(process.Terminate(0, false));
982*6777b538SAndroid Build Coastguard Worker task_env.RunUntilIdle();
983*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(base::DirectoryExists(cgroup_path));
984*6777b538SAndroid Build Coastguard Worker base::DeleteFile(fake_cgroup);
985*6777b538SAndroid Build Coastguard Worker }
986*6777b538SAndroid Build Coastguard Worker #endif // BUILDFLAG(IS_CHROMEOS)
987*6777b538SAndroid Build Coastguard Worker
988*6777b538SAndroid Build Coastguard Worker } // namespace base
989