- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / process_info_snapshot_mac_unittest.cc
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.
4
5 #include "chrome/browser/process_info_snapshot.h"
6
7 #include <sys/types.h>  // For |uid_t| (and |pid_t|).
8 #include <unistd.h>  // For |getpid()|, |getuid()|, etc.
9
10 #include <vector>
11
12 #include "base/command_line.h"
13 #include "base/files/file_path.h"
14 #include "base/logging.h"
15 #include "base/posix/eintr_wrapper.h"
16 #include "base/process/kill.h"
17 #include "base/process/launch.h"
18 #include "base/process/process_handle.h"
19 #include "base/process/process_metrics.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21
22 typedef testing::Test ProcessInfoSnapshotMacTest;
23
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));
31
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);
40
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));
47
48   // Make sure it hasn't picked up some other PID (say, 2).
49   EXPECT_FALSE(snapshot.GetProcInfo(2, &proc_info));
50
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));
53
54   // Test |Reset()|.
55   snapshot.Reset();
56   EXPECT_FALSE(snapshot.GetProcInfo(1, &proc_info));
57 }
58
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);
66
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));
72
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   EXPECT_GE(proc_info.rss, 100u);     // Sanity check: we're running, so we
81                                       // should occupy at least 100 kilobytes.
82   EXPECT_GE(proc_info.vsize, 1024u);  // Sanity check: our |vsize| is presumably
83                                       // at least a megabyte.
84   EXPECT_GE(proc_info.rshrd, 1024u);  // Shared memory should also > 1 MB.
85   EXPECT_GE(proc_info.rprvt, 1024u);  // Same with private memory.
86
87   // Find our parent.
88   ASSERT_TRUE(snapshot.GetProcInfo(ppid, &proc_info));
89   EXPECT_EQ(ppid, proc_info.pid);
90   EXPECT_NE(static_cast<int64>(proc_info.ppid), 0);
91   EXPECT_EQ(uid, proc_info.uid);    // This (and the following) should be true
92   EXPECT_EQ(euid, proc_info.euid);  // under reasonable circumstances.
93   // Can't say anything definite about its |rss|.
94   EXPECT_GT(proc_info.vsize, 0u);   // Its |vsize| should be nonzero though.
95 }
96
97 // To verify that ProcessInfoSnapshot is getting the actual uid and effective
98 // uid, this test runs top. top should have a uid of the caller and effective
99 // uid of 0 (root).
100 TEST_F(ProcessInfoSnapshotMacTest, EffectiveVsRealUserIDTest) {
101   // Create a pipe to be able to read top's output.
102   int fds[2];
103   PCHECK(pipe(fds) == 0);
104   base::FileHandleMappingVector fds_to_remap;
105   fds_to_remap.push_back(std::make_pair(fds[1], 1));
106
107   // Hook up top's stderr to the test process' stderr.
108   fds_to_remap.push_back(std::make_pair(fileno(stderr), 2));
109
110   std::vector<std::string> argv;
111   argv.push_back("/usr/bin/top");
112   argv.push_back("-l");
113   argv.push_back("0");
114
115   base::ProcessHandle process_handle;
116   base::LaunchOptions options;
117   options.fds_to_remap = &fds_to_remap;
118   ASSERT_TRUE(base::LaunchProcess(argv, options, &process_handle));
119   PCHECK(HANDLE_EINTR(close(fds[1])) == 0);
120
121   // Wait until there's some output form top. This is an easy way to tell that
122   // the exec() call is done and top is actually running.
123   char buf[1];
124   PCHECK(HANDLE_EINTR(read(fds[0], buf, 1)) == 1);
125
126   std::vector<base::ProcessId> pid_list;
127   pid_list.push_back(process_handle);
128   ProcessInfoSnapshot snapshot;
129   ASSERT_TRUE(snapshot.Sample(pid_list));
130
131   ProcessInfoSnapshot::ProcInfoEntry proc_info;
132   ASSERT_TRUE(snapshot.GetProcInfo(process_handle, &proc_info));
133   // Effective user ID should be 0 (root).
134   EXPECT_EQ(proc_info.euid, 0u);
135   // Real user ID should match the calling process's user id.
136   EXPECT_EQ(proc_info.uid, geteuid());
137
138   ASSERT_TRUE(base::KillProcess(process_handle, 0, true));
139   PCHECK(HANDLE_EINTR(close(fds[0])) == 0);
140 }