1 /*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "PsParser.h"
18
19 #include "frameworks/base/core/proto/android/os/ps.pb.h"
20
21 #include <android-base/file.h>
22 #include <android-base/test_utils.h>
23 #include <gmock/gmock.h>
24 #include <google/protobuf/message_lite.h>
25 #include <gtest/gtest.h>
26 #include <string.h>
27 #include <fcntl.h>
28
29 using namespace android::base;
30 using namespace android::os;
31 using namespace std;
32 using ::testing::StrEq;
33 using ::testing::Test;
34 using ::testing::internal::CaptureStderr;
35 using ::testing::internal::CaptureStdout;
36 using ::testing::internal::GetCapturedStderr;
37 using ::testing::internal::GetCapturedStdout;
38
39 class PsParserTest : public Test {
40 public:
SetUp()41 virtual void SetUp() override {
42 ASSERT_TRUE(tf.fd != -1);
43 }
44
45 protected:
46 TemporaryFile tf;
47
48 const string kTestPath = GetExecutableDirectory();
49 const string kTestDataPath = kTestPath + "/testdata/";
50 };
51
TEST_F(PsParserTest,Normal)52 TEST_F(PsParserTest, Normal) {
53 const string testFile = kTestDataPath + "ps.txt";
54 PsParser parser;
55 PsProto expected;
56 PsProto got;
57
58 PsProto::Process* record1 = expected.add_processes();
59 record1->set_label("u:r:init:s0");
60 record1->set_user("root");
61 record1->set_pid(1);
62 record1->set_tid(1);
63 record1->set_ppid(0);
64 record1->set_vsz(15816);
65 record1->set_rss(2636);
66 record1->set_wchan("SyS_epoll_wait");
67 record1->set_addr("0");
68 record1->set_s(PsProto_Process_ProcessStateCode_STATE_S);
69 record1->set_pri(19);
70 record1->set_ni(0);
71 record1->set_rtprio("-");
72 record1->set_sch(PsProto_Process_SchedulingPolicy_SCH_NORMAL);
73 record1->set_pcy(PsProto::Process::POLICY_FG);
74 record1->set_time("00:00:01");
75 record1->set_cmd("init");
76
77 PsProto::Process* record2 = expected.add_processes();
78 record2->set_label("u:r:kernel:s0");
79 record2->set_user("root");
80 record2->set_pid(2);
81 record2->set_tid(2);
82 record2->set_ppid(0);
83 record2->set_vsz(0);
84 record2->set_rss(0);
85 record2->set_wchan("kthreadd");
86 record2->set_addr("0");
87 record2->set_s(PsProto_Process_ProcessStateCode_STATE_S);
88 record2->set_pri(19);
89 record2->set_ni(0);
90 record2->set_rtprio("-");
91 record2->set_sch(PsProto_Process_SchedulingPolicy_SCH_NORMAL);
92 record2->set_pcy(PsProto::Process::POLICY_FG);
93 record2->set_time("00:00:00");
94 record2->set_cmd("kthreadd");
95
96 PsProto::Process* record3 = expected.add_processes();
97 record3->set_label("u:r:surfaceflinger:s0");
98 record3->set_user("system");
99 record3->set_pid(499);
100 record3->set_tid(534);
101 record3->set_ppid(1);
102 record3->set_vsz(73940);
103 record3->set_rss(22024);
104 record3->set_wchan("futex_wait_queue_me");
105 record3->set_addr("0");
106 record3->set_s(PsProto_Process_ProcessStateCode_STATE_S);
107 record3->set_pri(42);
108 record3->set_ni(-9);
109 record3->set_rtprio("2");
110 record3->set_sch(PsProto_Process_SchedulingPolicy_SCH_FIFO);
111 record3->set_pcy(PsProto::Process::POLICY_FG);
112 record3->set_time("00:00:00");
113 record3->set_cmd("EventThread");
114
115 PsProto::Process* record4 = expected.add_processes();
116 record4->set_label("u:r:hal_gnss_default:s0");
117 record4->set_user("gps");
118 record4->set_pid(670);
119 record4->set_tid(2004);
120 record4->set_ppid(1);
121 record4->set_vsz(43064);
122 record4->set_rss(7272);
123 record4->set_wchan("poll_schedule_timeout");
124 record4->set_addr("0");
125 record4->set_s(PsProto_Process_ProcessStateCode_STATE_S);
126 record4->set_pri(19);
127 record4->set_ni(0);
128 record4->set_rtprio("-");
129 record4->set_sch(PsProto_Process_SchedulingPolicy_SCH_NORMAL);
130 record4->set_pcy(PsProto::Process::POLICY_FG);
131 record4->set_time("00:00:00");
132 record4->set_cmd("Loc_hal_worker");
133
134 PsProto::Process* record5 = expected.add_processes();
135 record5->set_label("u:r:platform_app:s0:c512,c768");
136 record5->set_user("u0_a48");
137 record5->set_pid(1660);
138 record5->set_tid(1976);
139 record5->set_ppid(806);
140 record5->set_vsz(4468612);
141 record5->set_rss(138328);
142 record5->set_wchan("binder_thread_read");
143 record5->set_addr("0");
144 record5->set_s(PsProto_Process_ProcessStateCode_STATE_S);
145 record5->set_pri(35);
146 record5->set_ni(-16);
147 record5->set_rtprio("-");
148 record5->set_sch(PsProto_Process_SchedulingPolicy_SCH_NORMAL);
149 record5->set_pcy(PsProto::Process::POLICY_TA);
150 record5->set_time("00:00:00");
151 record5->set_cmd("HwBinder:1660_1");
152
153 PsProto::Process* record6 = expected.add_processes();
154 record6->set_label("u:r:perfd:s0");
155 record6->set_user("root");
156 record6->set_pid(1939);
157 record6->set_tid(1946);
158 record6->set_ppid(1);
159 record6->set_vsz(18132);
160 record6->set_rss(2088);
161 record6->set_wchan("__skb_recv_datagram");
162 record6->set_addr("7b9782fd14");
163 record6->set_s(PsProto_Process_ProcessStateCode_STATE_S);
164 record6->set_pri(19);
165 record6->set_ni(0);
166 record6->set_rtprio("-");
167 record6->set_sch(PsProto_Process_SchedulingPolicy_SCH_NORMAL);
168 record6->set_pcy(PsProto::Process::POLICY_UNKNOWN);
169 record6->set_time("00:00:00");
170 record6->set_cmd("perfd");
171
172 PsProto::Process* record7 = expected.add_processes();
173 record7->set_label("u:r:perfd:s0");
174 record7->set_user("root");
175 record7->set_pid(1939);
176 record7->set_tid(1955);
177 record7->set_ppid(1);
178 record7->set_vsz(18132);
179 record7->set_rss(2088);
180 record7->set_wchan("do_sigtimedwait");
181 record7->set_addr("7b9782ff6c");
182 record7->set_s(PsProto_Process_ProcessStateCode_STATE_S);
183 record7->set_pri(19);
184 record7->set_ni(0);
185 record7->set_rtprio("-");
186 record7->set_sch(PsProto_Process_SchedulingPolicy_SCH_NORMAL);
187 record7->set_pcy(PsProto::Process::POLICY_UNKNOWN);
188 record7->set_time("00:00:00");
189 record7->set_cmd("POSIX timer 0");
190
191 PsProto::Process* record8 = expected.add_processes();
192 record8->set_label("u:r:shell:s0");
193 record8->set_user("shell");
194 record8->set_pid(2645);
195 record8->set_tid(2645);
196 record8->set_ppid(802);
197 record8->set_vsz(11664);
198 record8->set_rss(2972);
199 record8->set_wchan("0");
200 record8->set_addr("7f67a2f8b4");
201 record8->set_s(PsProto_Process_ProcessStateCode_STATE_R);
202 record8->set_pri(19);
203 record8->set_ni(0);
204 record8->set_rtprio("-");
205 record8->set_sch(PsProto_Process_SchedulingPolicy_SCH_NORMAL);
206 record8->set_pcy(PsProto::Process::POLICY_FG);
207 record8->set_time("00:00:00");
208 record8->set_cmd("ps");
209
210 int fd = open(testFile.c_str(), O_RDONLY);
211 ASSERT_TRUE(fd != -1);
212
213 CaptureStdout();
214 ASSERT_EQ(NO_ERROR, parser.Parse(fd, STDOUT_FILENO));
215 got.ParseFromString(GetCapturedStdout());
216 bool matches = true;
217
218 if (got.processes_size() != expected.processes_size()) {
219 fprintf(stderr, "Got %d processes, want %d\n", got.processes_size(), expected.processes_size());
220 matches = false;
221 } else {
222 int n = got.processes_size();
223 for (int i = 0; i < n; i++) {
224 PsProto::Process g = got.processes(i);
225 PsProto::Process e = expected.processes(i);
226
227 if (g.label() != e.label()) {
228 fprintf(stderr, "prcs[%d]: Invalid label. Got %s, want %s\n", i, g.label().c_str(), e.label().c_str());
229 matches = false;
230 }
231 if (g.user() != e.user()) {
232 fprintf(stderr, "prcs[%d]: Invalid user. Got %s, want %s\n", i, g.user().c_str(), e.user().c_str());
233 matches = false;
234 }
235 if (g.pid() != e.pid()) {
236 fprintf(stderr, "prcs[%d]: Invalid pid. Got %d, want %d\n", i, g.pid(), e.pid());
237 matches = false;
238 }
239 if (g.tid() != e.tid()) {
240 fprintf(stderr, "prcs[%d]: Invalid tid. Got %d, want %d\n", i, g.tid(), e.tid());
241 matches = false;
242 }
243 if (g.ppid() != e.ppid()) {
244 fprintf(stderr, "prcs[%d]: Invalid ppid. Got %d, want %d\n", i, g.ppid(), e.ppid());
245 matches = false;
246 }
247 if (g.vsz() != e.vsz()) {
248 fprintf(stderr, "prcs[%d]: Invalid vsz. Got %d, want %d\n", i, g.vsz(), e.vsz());
249 matches = false;
250 }
251 if (g.rss() != e.rss()) {
252 fprintf(stderr, "prcs[%d]: Invalid rss. Got %d, want %d\n", i, g.rss(), e.rss());
253 matches = false;
254 }
255 if (g.wchan() != e.wchan()) {
256 fprintf(stderr, "prcs[%d]: Invalid wchan. Got %s, want %s\n", i, g.wchan().c_str(), e.wchan().c_str());
257 matches = false;
258 }
259 if (g.addr() != e.addr()) {
260 fprintf(stderr, "prcs[%d]: Invalid addr. Got %s, want %s\n", i, g.addr().c_str(), e.addr().c_str());
261 matches = false;
262 }
263 if (g.s() != e.s()) {
264 fprintf(stderr, "prcs[%d]: Invalid s. Got %u, want %u\n", i, g.s(), e.s());
265 matches = false;
266 }
267 if (g.pri() != e.pri()) {
268 fprintf(stderr, "prcs[%d]: Invalid pri. Got %d, want %d\n", i, g.pri(), e.pri());
269 matches = false;
270 }
271 if (g.ni() != e.ni()) {
272 fprintf(stderr, "prcs[%d]: Invalid ni. Got %d, want %d\n", i, g.ni(), e.ni());
273 matches = false;
274 }
275 if (g.rtprio() != e.rtprio()) {
276 fprintf(stderr, "prcs[%d]: Invalid rtprio. Got %s, want %s\n", i, g.rtprio().c_str(), e.rtprio().c_str());
277 matches = false;
278 }
279 if (g.sch() != e.sch()) {
280 fprintf(stderr, "prcs[%d]: Invalid sch. Got %u, want %u\n", i, g.sch(), e.sch());
281 matches = false;
282 }
283 if (g.pcy() != e.pcy()) {
284 fprintf(stderr, "prcs[%d]: Invalid pcy. Got %u, want %u\n", i, g.pcy(), e.pcy());
285 matches = false;
286 }
287 if (g.time() != e.time()) {
288 fprintf(stderr, "prcs[%d]: Invalid time. Got %s, want %s\n", i, g.time().c_str(), e.time().c_str());
289 matches = false;
290 }
291 if (g.cmd() != e.cmd()) {
292 fprintf(stderr, "prcs[%d]: Invalid cmd. Got %s, want %s\n", i, g.cmd().c_str(), e.cmd().c_str());
293 matches = false;
294 }
295 }
296 }
297
298 EXPECT_TRUE(matches);
299 close(fd);
300 }
301