Upstream oodles of Chrome for Android code into Chromium.
[chromium-blink-merge.git] / chrome / browser / process_info_snapshot_mac_unittest.cc
blobe95cf0c91b28107f4f455861e59d33ef2cf44b79
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/process_info_snapshot.h"
7 #include <sys/types.h> // For |uid_t| (and |pid_t|).
8 #include <unistd.h> // For |getpid()|, |getuid()|, etc.
10 #include <vector>
12 #include "base/command_line.h"
13 #include "base/files/file_path.h"
14 #include "base/logging.h"
15 #include "base/mac/mac_util.h"
16 #include "base/posix/eintr_wrapper.h"
17 #include "base/process/launch.h"
18 #include "base/process/process.h"
19 #include "base/process/process_metrics.h"
20 #include "testing/gtest/include/gtest/gtest.h"
22 typedef testing::Test ProcessInfoSnapshotMacTest;
24 TEST_F(ProcessInfoSnapshotMacTest, FindPidOneTest) {
25 // Sample process with PID 1, which should exist and presumably belong to
26 // root.
27 std::vector<base::ProcessId> pid_list;
28 pid_list.push_back(1);
29 ProcessInfoSnapshot snapshot;
30 ASSERT_TRUE(snapshot.Sample(pid_list));
32 ProcessInfoSnapshot::ProcInfoEntry proc_info;
33 ASSERT_TRUE(snapshot.GetProcInfo(1, &proc_info));
34 EXPECT_EQ(1, static_cast<int64>(proc_info.pid));
35 EXPECT_EQ(0, static_cast<int64>(proc_info.ppid));
36 EXPECT_EQ(0, static_cast<int64>(proc_info.uid));
37 EXPECT_EQ(0, static_cast<int64>(proc_info.euid));
38 EXPECT_GE(proc_info.rss, 0u);
39 EXPECT_GT(proc_info.vsize, 0u);
41 // Try out the |Get...OfPID()|, but don't examine the results, since they
42 // depend on how we map |ProcInfoEntry| to |...KBytes|.
43 base::CommittedKBytes usage;
44 EXPECT_TRUE(snapshot.GetCommittedKBytesOfPID(1, &usage));
45 base::WorkingSetKBytes ws_usage;
46 EXPECT_TRUE(snapshot.GetWorkingSetKBytesOfPID(1, &ws_usage));
48 // Make sure it hasn't picked up some other PID (say, 2).
49 EXPECT_FALSE(snapshot.GetProcInfo(2, &proc_info));
51 // Make sure PID 2 still isn't there (in case I mess up my use of std::map).
52 EXPECT_FALSE(snapshot.GetProcInfo(2, &proc_info));
54 // Test |Reset()|.
55 snapshot.Reset();
56 EXPECT_FALSE(snapshot.GetProcInfo(1, &proc_info));
59 TEST_F(ProcessInfoSnapshotMacTest, FindPidSelfTest) {
60 // Sample this process and its parent.
61 base::ProcessId pid = static_cast<base::ProcessId>(getpid());
62 base::ProcessId ppid = static_cast<base::ProcessId>(getppid());
63 uid_t uid = getuid();
64 uid_t euid = geteuid();
65 EXPECT_NE(static_cast<int64>(ppid), 0);
67 std::vector<base::ProcessId> pid_list;
68 pid_list.push_back(pid);
69 pid_list.push_back(ppid);
70 ProcessInfoSnapshot snapshot;
71 ASSERT_TRUE(snapshot.Sample(pid_list));
73 // Find our process.
74 ProcessInfoSnapshot::ProcInfoEntry proc_info;
75 ASSERT_TRUE(snapshot.GetProcInfo(pid, &proc_info));
76 EXPECT_EQ(pid, proc_info.pid);
77 EXPECT_EQ(ppid, proc_info.ppid);
78 EXPECT_EQ(uid, proc_info.uid);
79 EXPECT_EQ(euid, proc_info.euid);
80 // Sanity check: we're running, so we should occupy at least 100 kilobytes.
81 EXPECT_GE(proc_info.rss, 100u);
82 // Sanity check: our |vsize| is presumably at least a megabyte.
83 EXPECT_GE(proc_info.vsize, 1024u);
85 // Collection of some memory statistics is broken in OSX 10.9+.
86 // http://crbug.com/383553
87 if (!base::mac::IsOSMavericksOrLater()) {
88 // Shared memory should also > 1 MB.
89 EXPECT_GE(proc_info.rshrd, 1024u);
90 // Same with private memory.
91 EXPECT_GE(proc_info.rprvt, 1024u);
94 // Find our parent.
95 ASSERT_TRUE(snapshot.GetProcInfo(ppid, &proc_info));
96 EXPECT_EQ(ppid, proc_info.pid);
97 EXPECT_NE(static_cast<int64>(proc_info.ppid), 0);
98 EXPECT_EQ(uid, proc_info.uid); // This (and the following) should be true
99 EXPECT_EQ(euid, proc_info.euid); // under reasonable circumstances.
100 // Can't say anything definite about its |rss|.
101 EXPECT_GT(proc_info.vsize, 0u); // Its |vsize| should be nonzero though.
104 // To verify that ProcessInfoSnapshot is getting the actual uid and effective
105 // uid, this test runs top. top should have a uid of the caller and effective
106 // uid of 0 (root).
107 TEST_F(ProcessInfoSnapshotMacTest, EffectiveVsRealUserIDTest) {
108 // Create a pipe to be able to read top's output.
109 int fds[2];
110 PCHECK(pipe(fds) == 0);
111 base::FileHandleMappingVector fds_to_remap;
112 fds_to_remap.push_back(std::make_pair(fds[1], 1));
114 // Hook up top's stderr to the test process' stderr.
115 fds_to_remap.push_back(std::make_pair(fileno(stderr), 2));
117 std::vector<std::string> argv;
118 argv.push_back("/usr/bin/top");
119 argv.push_back("-l");
120 argv.push_back("0");
122 base::LaunchOptions options;
123 options.fds_to_remap = &fds_to_remap;
124 base::Process process = base::LaunchProcess(argv, options);
125 ASSERT_TRUE(process.IsValid());
126 PCHECK(IGNORE_EINTR(close(fds[1])) == 0);
128 // Wait until there's some output form top. This is an easy way to tell that
129 // the exec() call is done and top is actually running.
130 char buf[1];
131 PCHECK(HANDLE_EINTR(read(fds[0], buf, 1)) == 1);
133 std::vector<base::ProcessId> pid_list;
134 pid_list.push_back(process.Pid());
135 ProcessInfoSnapshot snapshot;
136 ASSERT_TRUE(snapshot.Sample(pid_list));
138 ProcessInfoSnapshot::ProcInfoEntry proc_info;
139 ASSERT_TRUE(snapshot.GetProcInfo(process.Pid(), &proc_info));
140 // Effective user ID should be 0 (root).
141 EXPECT_EQ(proc_info.euid, 0u);
142 // Real user ID should match the calling process's user id.
143 EXPECT_EQ(proc_info.uid, geteuid());
145 ASSERT_TRUE(process.Terminate(0, true));
146 PCHECK(IGNORE_EINTR(close(fds[0])) == 0);