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: 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 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