1 /*
2 * Copyright 2021 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 "MockPackageInfoResolver.h"
18 #include "MockUidCpuStatsCollector.h"
19 #include "MockUidIoStatsCollector.h"
20 #include "MockUidProcStatsCollector.h"
21 #include "PackageInfoTestUtils.h"
22 #include "UidIoStatsCollector.h"
23 #include "UidProcStatsCollector.h"
24 #include "UidProcStatsCollectorTestUtils.h"
25 #include "UidStatsCollector.h"
26
27 #include <android-base/stringprintf.h>
28 #include <gmock/gmock.h>
29 #include <utils/RefBase.h>
30
31 #include <inttypes.h>
32
33 #include <string>
34
35 namespace android {
36 namespace automotive {
37 namespace watchdog {
38
39 using ::android::automotive::watchdog::internal::PackageInfo;
40 using ::android::automotive::watchdog::internal::UidType;
41 using ::android::base::Error;
42 using ::android::base::Result;
43 using ::android::base::StringAppendF;
44 using ::android::base::StringPrintf;
45 using ::testing::AllOf;
46 using ::testing::Eq;
47 using ::testing::ExplainMatchResult;
48 using ::testing::Field;
49 using ::testing::IsEmpty;
50 using ::testing::Matcher;
51 using ::testing::Return;
52 using ::testing::UnorderedElementsAre;
53 using ::testing::UnorderedElementsAreArray;
54
55 namespace {
56
toString(const UidStats & uidStats)57 std::string toString(const UidStats& uidStats) {
58 return StringPrintf("UidStats{packageInfo: %s, cpuTimeMillis: %" PRId64
59 ", ioStats: %s, procStats: %s}",
60 uidStats.packageInfo.toString().c_str(), uidStats.cpuTimeMillis,
61 uidStats.ioStats.toString().c_str(), uidStats.procStats.toString().c_str());
62 }
63
toString(const std::vector<UidStats> & uidStats)64 std::string toString(const std::vector<UidStats>& uidStats) {
65 std::string buffer;
66 StringAppendF(&buffer, "{");
67 for (const auto& stats : uidStats) {
68 StringAppendF(&buffer, "%s\n", toString(stats).c_str());
69 }
70 StringAppendF(&buffer, "}");
71 return buffer;
72 }
73
74 MATCHER_P(UidStatsEq, expected, "") {
75 return ExplainMatchResult(AllOf(Field("packageInfo", &UidStats::packageInfo,
76 PackageInfoEq(expected.packageInfo)),
77 Field("cpuTimeMillis", &UidStats::cpuTimeMillis,
78 Eq(expected.cpuTimeMillis)),
79 Field("ioStats", &UidStats::ioStats, Eq(expected.ioStats)),
80 Field("procStats", &UidStats::procStats,
81 UidProcStatsEq(expected.procStats))),
82 arg, result_listener);
83 }
84
UidStatsMatchers(const std::vector<UidStats> & uidStats)85 std::vector<Matcher<const UidStats&>> UidStatsMatchers(const std::vector<UidStats>& uidStats) {
86 std::vector<Matcher<const UidStats&>> matchers;
87 for (const auto& stats : uidStats) {
88 matchers.push_back(UidStatsEq(stats));
89 }
90 return matchers;
91 }
92
samplePackageInfoByUid()93 std::unordered_map<uid_t, PackageInfo> samplePackageInfoByUid() {
94 return {{1001234, constructPackageInfo("system.daemon", 1001234, UidType::NATIVE)},
95 {1005678, constructPackageInfo("kitchensink.app", 1005678, UidType::APPLICATION)}};
96 }
97
sampleUidIoStatsByUid()98 std::unordered_map<uid_t, UidIoStats> sampleUidIoStatsByUid() {
99 return {{1001234,
100 UidIoStats{/*fgRdBytes=*/3'000, /*bgRdBytes=*/0,
101 /*fgWrBytes=*/500,
102 /*bgWrBytes=*/0, /*fgFsync=*/20,
103 /*bgFsync=*/0}},
104 {1005678,
105 UidIoStats{/*fgRdBytes=*/30, /*bgRdBytes=*/100,
106 /*fgWrBytes=*/50, /*bgWrBytes=*/200,
107 /*fgFsync=*/45, /*bgFsync=*/60}}};
108 }
109
sampleUidProcStatsByUid()110 std::unordered_map<uid_t, UidProcStats> sampleUidProcStatsByUid() {
111 return {{1001234,
112 UidProcStats{.cpuTimeMillis = 10,
113 .totalMajorFaults = 220,
114 .totalTasksCount = 2,
115 .ioBlockedTasksCount = 1,
116 .processStatsByPid = {{1, {"init", 0, 10, 220, 2, 1}}}}},
117 {1005678,
118 UidProcStats{.cpuTimeMillis = 43,
119 .totalMajorFaults = 600,
120 .totalTasksCount = 2,
121 .ioBlockedTasksCount = 2,
122 .processStatsByPid = {
123 {1000, {"system_server", 13'400, 43, 600, 2, 2}}}}}};
124 }
125
sampleUidCpuStatsByUid()126 std::unordered_map<uid_t, int64_t> sampleUidCpuStatsByUid() {
127 return {{1001234, 15}, {1005678, 43}};
128 }
129
sampleUidStats()130 std::vector<UidStats> sampleUidStats() {
131 return {{.packageInfo = constructPackageInfo("system.daemon", 1001234, UidType::NATIVE),
132 .cpuTimeMillis = 15,
133 .ioStats = UidIoStats{/*fgRdBytes=*/3'000, /*bgRdBytes=*/0, /*fgWrBytes=*/500,
134 /*bgWrBytes=*/0, /*fgFsync=*/20, /*bgFsync=*/0},
135 .procStats = UidProcStats{.cpuTimeMillis = 10,
136 .totalMajorFaults = 220,
137 .totalTasksCount = 2,
138 .ioBlockedTasksCount = 1,
139 .processStatsByPid = {{1, {"init", 0, 10, 220, 2, 1}}}}},
140 {.packageInfo = constructPackageInfo("kitchensink.app", 1005678, UidType::APPLICATION),
141 .cpuTimeMillis = 43,
142 .ioStats = UidIoStats{/*fgRdBytes=*/30, /*bgRdBytes=*/100, /*fgWrBytes=*/50,
143 /*bgWrBytes=*/200,
144 /*fgFsync=*/45, /*bgFsync=*/60},
145 .procStats = UidProcStats{.cpuTimeMillis = 43,
146 .totalMajorFaults = 600,
147 .totalTasksCount = 2,
148 .ioBlockedTasksCount = 2,
149 .processStatsByPid = {
150 {1000, {"system_server", 13'400, 43, 600, 2, 2}}}}}};
151 }
152
153 } // namespace
154
155 namespace internal {
156
157 class UidStatsCollectorPeer final : public RefBase {
158 public:
UidStatsCollectorPeer(sp<UidStatsCollector> collector)159 explicit UidStatsCollectorPeer(sp<UidStatsCollector> collector) : mCollector(collector) {}
160
setPackageInfoResolver(const sp<PackageInfoResolverInterface> & packageInfoResolver)161 void setPackageInfoResolver(const sp<PackageInfoResolverInterface>& packageInfoResolver) {
162 mCollector->mPackageInfoResolver = packageInfoResolver;
163 }
164
setUidIoStatsCollector(const sp<UidIoStatsCollectorInterface> & uidIoStatsCollector)165 void setUidIoStatsCollector(const sp<UidIoStatsCollectorInterface>& uidIoStatsCollector) {
166 mCollector->mUidIoStatsCollector = uidIoStatsCollector;
167 }
168
setUidProcStatsCollector(const sp<UidProcStatsCollectorInterface> & uidProcStatsCollector)169 void setUidProcStatsCollector(const sp<UidProcStatsCollectorInterface>& uidProcStatsCollector) {
170 mCollector->mUidProcStatsCollector = uidProcStatsCollector;
171 }
172
setUidCpuStatsCollector(const sp<UidCpuStatsCollectorInterface> & uidCpuStatsCollector)173 void setUidCpuStatsCollector(const sp<UidCpuStatsCollectorInterface>& uidCpuStatsCollector) {
174 mCollector->mUidCpuStatsCollector = uidCpuStatsCollector;
175 }
176
177 private:
178 sp<UidStatsCollector> mCollector;
179 };
180
181 } // namespace internal
182
183 class UidStatsCollectorTest : public ::testing::Test {
184 protected:
SetUp()185 virtual void SetUp() {
186 mUidStatsCollector = sp<UidStatsCollector>::make();
187 mUidStatsCollectorPeer = sp<internal::UidStatsCollectorPeer>::make(mUidStatsCollector);
188 mMockPackageInfoResolver = sp<MockPackageInfoResolver>::make();
189 mMockUidIoStatsCollector = sp<MockUidIoStatsCollector>::make();
190 mMockUidProcStatsCollector = sp<MockUidProcStatsCollector>::make();
191 mMockUidCpuStatsCollector = sp<MockUidCpuStatsCollector>::make();
192 mUidStatsCollectorPeer->setPackageInfoResolver(mMockPackageInfoResolver);
193 mUidStatsCollectorPeer->setUidIoStatsCollector(mMockUidIoStatsCollector);
194 mUidStatsCollectorPeer->setUidProcStatsCollector(mMockUidProcStatsCollector);
195 mUidStatsCollectorPeer->setUidCpuStatsCollector(mMockUidCpuStatsCollector);
196 }
197
TearDown()198 virtual void TearDown() {
199 mUidStatsCollector.clear();
200 mUidStatsCollectorPeer.clear();
201 mMockPackageInfoResolver.clear();
202 mMockUidIoStatsCollector.clear();
203 mMockUidProcStatsCollector.clear();
204 mMockUidCpuStatsCollector.clear();
205 }
206
207 sp<UidStatsCollector> mUidStatsCollector;
208 sp<internal::UidStatsCollectorPeer> mUidStatsCollectorPeer;
209 sp<MockPackageInfoResolver> mMockPackageInfoResolver;
210 sp<MockUidIoStatsCollector> mMockUidIoStatsCollector;
211 sp<MockUidProcStatsCollector> mMockUidProcStatsCollector;
212 sp<MockUidCpuStatsCollector> mMockUidCpuStatsCollector;
213 };
214
TEST_F(UidStatsCollectorTest,TestInit)215 TEST_F(UidStatsCollectorTest, TestInit) {
216 EXPECT_CALL(*mMockUidIoStatsCollector, init()).Times(1);
217 EXPECT_CALL(*mMockUidProcStatsCollector, init()).Times(1);
218
219 mUidStatsCollector->init();
220 }
221
TEST_F(UidStatsCollectorTest,TestCollect)222 TEST_F(UidStatsCollectorTest, TestCollect) {
223 EXPECT_CALL(*mMockUidIoStatsCollector, enabled()).WillOnce(Return(true));
224 EXPECT_CALL(*mMockUidProcStatsCollector, enabled()).WillOnce(Return(true));
225
226 EXPECT_CALL(*mMockUidIoStatsCollector, collect()).WillOnce(Return(Result<void>()));
227 EXPECT_CALL(*mMockUidProcStatsCollector, collect()).WillOnce(Return(Result<void>()));
228
229 EXPECT_CALL(*mMockUidIoStatsCollector, latestStats())
230 .WillOnce(Return(std::unordered_map<uid_t, UidIoStats>()));
231 EXPECT_CALL(*mMockUidProcStatsCollector, latestStats())
232 .WillOnce(Return(std::unordered_map<uid_t, UidProcStats>()));
233
234 EXPECT_CALL(*mMockUidIoStatsCollector, deltaStats())
235 .WillOnce(Return(std::unordered_map<uid_t, UidIoStats>()));
236 EXPECT_CALL(*mMockUidProcStatsCollector, deltaStats())
237 .WillOnce(Return(std::unordered_map<uid_t, UidProcStats>()));
238
239 ASSERT_RESULT_OK(mUidStatsCollector->collect());
240 }
241
TEST_F(UidStatsCollectorTest,TestFailsCollectOnUidIoStatsCollectorError)242 TEST_F(UidStatsCollectorTest, TestFailsCollectOnUidIoStatsCollectorError) {
243 Result<void> errorResult = Error() << "Failed to collect per-UID I/O stats";
244 EXPECT_CALL(*mMockUidIoStatsCollector, collect()).WillOnce(Return(errorResult));
245
246 ASSERT_FALSE(mUidStatsCollector->collect().ok())
247 << "Must fail to collect when per-UID I/O stats collector fails";
248 }
249
TEST_F(UidStatsCollectorTest,TestFailsCollectOnUidProcStatsCollectorError)250 TEST_F(UidStatsCollectorTest, TestFailsCollectOnUidProcStatsCollectorError) {
251 Result<void> errorResult = Error() << "Failed to collect per-UID proc stats";
252 EXPECT_CALL(*mMockUidProcStatsCollector, collect()).WillOnce(Return(errorResult));
253
254 ASSERT_FALSE(mUidStatsCollector->collect().ok())
255 << "Must fail to collect when per-UID proc stats collector fails";
256 }
257
TEST_F(UidStatsCollectorTest,TestCollectLatestStats)258 TEST_F(UidStatsCollectorTest, TestCollectLatestStats) {
259 const std::unordered_map<uid_t, PackageInfo> packageInfoByUid = samplePackageInfoByUid();
260 const std::unordered_map<uid_t, UidIoStats> uidIoStatsByUid = sampleUidIoStatsByUid();
261 const std::unordered_map<uid_t, UidProcStats> uidProcStatsByUid = sampleUidProcStatsByUid();
262 const std::unordered_map<uid_t, int64_t> uidCpuStatsByUid = sampleUidCpuStatsByUid();
263
264 EXPECT_CALL(*mMockPackageInfoResolver,
265 getPackageInfosForUids(UnorderedElementsAre(1001234, 1005678)))
266 .WillOnce(Return(packageInfoByUid));
267 EXPECT_CALL(*mMockUidIoStatsCollector, latestStats()).WillOnce(Return(uidIoStatsByUid));
268 EXPECT_CALL(*mMockUidProcStatsCollector, latestStats()).WillOnce(Return(uidProcStatsByUid));
269 EXPECT_CALL(*mMockUidCpuStatsCollector, latestStats()).WillOnce(Return(uidCpuStatsByUid));
270
271 ASSERT_RESULT_OK(mUidStatsCollector->collect());
272
273 const std::vector<UidStats> expected = sampleUidStats();
274
275 auto actual = mUidStatsCollector->latestStats();
276
277 EXPECT_THAT(actual, UnorderedElementsAreArray(UidStatsMatchers(expected)))
278 << "Latest UID stats doesn't match.\nExpected: " << toString(expected)
279 << "\nActual: " << toString(actual);
280
281 actual = mUidStatsCollector->deltaStats();
282
283 EXPECT_THAT(actual, IsEmpty()) << "Delta UID stats isn't empty.\nActual: " << toString(actual);
284 }
285
TEST_F(UidStatsCollectorTest,TestCollectDeltaStats)286 TEST_F(UidStatsCollectorTest, TestCollectDeltaStats) {
287 const std::unordered_map<uid_t, PackageInfo> packageInfoByUid = samplePackageInfoByUid();
288 const std::unordered_map<uid_t, UidIoStats> uidIoStatsByUid = sampleUidIoStatsByUid();
289 const std::unordered_map<uid_t, UidProcStats> uidProcStatsByUid = sampleUidProcStatsByUid();
290 const std::unordered_map<uid_t, int64_t> uidCpuStatsByUid = sampleUidCpuStatsByUid();
291
292 EXPECT_CALL(*mMockPackageInfoResolver,
293 getPackageInfosForUids(UnorderedElementsAre(1001234, 1005678)))
294 .WillOnce(Return(packageInfoByUid));
295 EXPECT_CALL(*mMockUidIoStatsCollector, deltaStats()).WillOnce(Return(uidIoStatsByUid));
296 EXPECT_CALL(*mMockUidProcStatsCollector, deltaStats()).WillOnce(Return(uidProcStatsByUid));
297 EXPECT_CALL(*mMockUidCpuStatsCollector, deltaStats()).WillOnce(Return(uidCpuStatsByUid));
298
299 ASSERT_RESULT_OK(mUidStatsCollector->collect());
300
301 const std::vector<UidStats> expected = sampleUidStats();
302
303 auto actual = mUidStatsCollector->deltaStats();
304
305 EXPECT_THAT(actual, UnorderedElementsAreArray(UidStatsMatchers(expected)))
306 << "Delta UID stats doesn't match.\nExpected: " << toString(expected)
307 << "\nActual: " << toString(actual);
308
309 actual = mUidStatsCollector->latestStats();
310
311 EXPECT_THAT(actual, IsEmpty()) << "Latest UID stats isn't empty.\nActual: " << toString(actual);
312 }
313
TEST_F(UidStatsCollectorTest,TestCollectDeltaStatsWithMissingUidIoStats)314 TEST_F(UidStatsCollectorTest, TestCollectDeltaStatsWithMissingUidIoStats) {
315 const std::unordered_map<uid_t, PackageInfo> packageInfoByUid = samplePackageInfoByUid();
316 std::unordered_map<uid_t, UidIoStats> uidIoStatsByUid = sampleUidIoStatsByUid();
317 uidIoStatsByUid.erase(1001234);
318 const std::unordered_map<uid_t, UidProcStats> uidProcStatsByUid = sampleUidProcStatsByUid();
319 const std::unordered_map<uid_t, int64_t> uidCpuStatsByUid = sampleUidCpuStatsByUid();
320
321 EXPECT_CALL(*mMockPackageInfoResolver,
322 getPackageInfosForUids(UnorderedElementsAre(1001234, 1005678)))
323 .WillOnce(Return(packageInfoByUid));
324 EXPECT_CALL(*mMockUidIoStatsCollector, deltaStats()).WillOnce(Return(uidIoStatsByUid));
325 EXPECT_CALL(*mMockUidProcStatsCollector, deltaStats()).WillOnce(Return(uidProcStatsByUid));
326 EXPECT_CALL(*mMockUidCpuStatsCollector, deltaStats()).WillOnce(Return(uidCpuStatsByUid));
327
328 ASSERT_RESULT_OK(mUidStatsCollector->collect());
329
330 std::vector<UidStats> expected = sampleUidStats();
331 expected[0].ioStats = {};
332
333 auto actual = mUidStatsCollector->deltaStats();
334
335 EXPECT_THAT(actual, UnorderedElementsAreArray(UidStatsMatchers(expected)))
336 << "Delta UID stats doesn't match.\nExpected: " << toString(expected)
337 << "\nActual: " << toString(actual);
338
339 actual = mUidStatsCollector->latestStats();
340
341 EXPECT_THAT(actual, IsEmpty()) << "Latest UID stats isn't empty.\nActual: " << toString(actual);
342 }
343
TEST_F(UidStatsCollectorTest,TestCollectDeltaStatsWithMissingUidProcStats)344 TEST_F(UidStatsCollectorTest, TestCollectDeltaStatsWithMissingUidProcStats) {
345 const std::unordered_map<uid_t, PackageInfo> packageInfoByUid = samplePackageInfoByUid();
346 const std::unordered_map<uid_t, UidIoStats> uidIoStatsByUid = sampleUidIoStatsByUid();
347 std::unordered_map<uid_t, UidProcStats> uidProcStatsByUid = sampleUidProcStatsByUid();
348 uidProcStatsByUid.erase(1001234);
349 const std::unordered_map<uid_t, int64_t> uidCpuStatsByUid = sampleUidCpuStatsByUid();
350
351 EXPECT_CALL(*mMockPackageInfoResolver,
352 getPackageInfosForUids(UnorderedElementsAre(1001234, 1005678)))
353 .WillOnce(Return(packageInfoByUid));
354 EXPECT_CALL(*mMockUidIoStatsCollector, deltaStats()).WillOnce(Return(uidIoStatsByUid));
355 EXPECT_CALL(*mMockUidProcStatsCollector, deltaStats()).WillOnce(Return(uidProcStatsByUid));
356 EXPECT_CALL(*mMockUidCpuStatsCollector, deltaStats()).WillOnce(Return(uidCpuStatsByUid));
357
358 ASSERT_RESULT_OK(mUidStatsCollector->collect());
359
360 std::vector<UidStats> expected = sampleUidStats();
361 expected[0].procStats = {};
362
363 auto actual = mUidStatsCollector->deltaStats();
364
365 EXPECT_THAT(actual, UnorderedElementsAreArray(UidStatsMatchers(expected)))
366 << "Delta UID stats doesn't match.\nExpected: " << toString(expected)
367 << "\nActual: " << toString(actual);
368
369 actual = mUidStatsCollector->latestStats();
370
371 EXPECT_THAT(actual, IsEmpty()) << "Latest UID stats isn't empty.\nActual: " << toString(actual);
372 }
373
TEST_F(UidStatsCollectorTest,TestCollectDeltaStatsWithMissingUidCpuStats)374 TEST_F(UidStatsCollectorTest, TestCollectDeltaStatsWithMissingUidCpuStats) {
375 const std::unordered_map<uid_t, PackageInfo> packageInfoByUid = samplePackageInfoByUid();
376 const std::unordered_map<uid_t, UidIoStats> uidIoStatsByUid = sampleUidIoStatsByUid();
377 const std::unordered_map<uid_t, UidProcStats> uidProcStatsByUid = sampleUidProcStatsByUid();
378
379 EXPECT_CALL(*mMockPackageInfoResolver,
380 getPackageInfosForUids(UnorderedElementsAre(1001234, 1005678)))
381 .WillOnce(Return(packageInfoByUid));
382 EXPECT_CALL(*mMockUidIoStatsCollector, deltaStats()).WillOnce(Return(uidIoStatsByUid));
383 EXPECT_CALL(*mMockUidProcStatsCollector, deltaStats()).WillOnce(Return(uidProcStatsByUid));
384
385 ASSERT_RESULT_OK(mUidStatsCollector->collect());
386
387 std::vector<UidStats> expected = sampleUidStats();
388 // Since no Uid CPU time was recovered from the /proc/uid_cputime/show_uid_stat file, the
389 // collector will default the UID CPU time to the UidProcStats' CPU time.
390 expected[0].cpuTimeMillis = 10;
391
392 auto actual = mUidStatsCollector->deltaStats();
393
394 EXPECT_THAT(actual, UnorderedElementsAreArray(UidStatsMatchers(expected)))
395 << "Delta UID stats doesn't match.\nExpected: " << toString(expected)
396 << "\nActual: " << toString(actual);
397
398 actual = mUidStatsCollector->latestStats();
399
400 EXPECT_THAT(actual, IsEmpty()) << "Latest UID stats isn't empty.\nActual: " << toString(actual);
401 }
402
TEST_F(UidStatsCollectorTest,TestCollectDeltaStatsWithMissingPackageInfo)403 TEST_F(UidStatsCollectorTest, TestCollectDeltaStatsWithMissingPackageInfo) {
404 std::unordered_map<uid_t, PackageInfo> packageInfoByUid = samplePackageInfoByUid();
405 packageInfoByUid.erase(1001234);
406 const std::unordered_map<uid_t, UidIoStats> uidIoStatsByUid = sampleUidIoStatsByUid();
407 const std::unordered_map<uid_t, UidProcStats> uidProcStatsByUid = sampleUidProcStatsByUid();
408 const std::unordered_map<uid_t, int64_t> uidCpuStatsByUid = sampleUidCpuStatsByUid();
409
410 EXPECT_CALL(*mMockPackageInfoResolver,
411 getPackageInfosForUids(UnorderedElementsAre(1001234, 1005678)))
412 .WillOnce(Return(packageInfoByUid));
413 EXPECT_CALL(*mMockUidIoStatsCollector, deltaStats()).WillOnce(Return(uidIoStatsByUid));
414 EXPECT_CALL(*mMockUidProcStatsCollector, deltaStats()).WillOnce(Return(uidProcStatsByUid));
415 EXPECT_CALL(*mMockUidCpuStatsCollector, deltaStats()).WillOnce(Return(uidCpuStatsByUid));
416
417 ASSERT_RESULT_OK(mUidStatsCollector->collect());
418
419 std::vector<UidStats> expected = sampleUidStats();
420 expected[0].packageInfo = constructPackageInfo("", 1001234);
421
422 auto actual = mUidStatsCollector->deltaStats();
423
424 EXPECT_THAT(actual, UnorderedElementsAreArray(UidStatsMatchers(expected)))
425 << "Delta UID stats doesn't match.\nExpected: " << toString(expected)
426 << "\nActual: " << toString(actual);
427
428 actual = mUidStatsCollector->latestStats();
429
430 EXPECT_THAT(actual, IsEmpty()) << "Latest UID stats isn't empty.\nActual: " << toString(actual);
431 }
432
TEST_F(UidStatsCollectorTest,TestUidStatsHasPackageInfo)433 TEST_F(UidStatsCollectorTest, TestUidStatsHasPackageInfo) {
434 std::unordered_map<uid_t, PackageInfo> packageInfoByUid = samplePackageInfoByUid();
435 packageInfoByUid.erase(1001234);
436 const std::unordered_map<uid_t, UidIoStats> uidIoStatsByUid = sampleUidIoStatsByUid();
437 const std::unordered_map<uid_t, UidProcStats> uidProcStatsByUid = sampleUidProcStatsByUid();
438
439 EXPECT_CALL(*mMockPackageInfoResolver,
440 getPackageInfosForUids(UnorderedElementsAre(1001234, 1005678)))
441 .WillOnce(Return(packageInfoByUid));
442 EXPECT_CALL(*mMockUidIoStatsCollector, deltaStats()).WillOnce(Return(uidIoStatsByUid));
443 EXPECT_CALL(*mMockUidProcStatsCollector, deltaStats()).WillOnce(Return(uidProcStatsByUid));
444
445 ASSERT_RESULT_OK(mUidStatsCollector->collect());
446
447 const auto actual = mUidStatsCollector->deltaStats();
448
449 EXPECT_EQ(actual.size(), static_cast<size_t>(2));
450 for (const auto stats : actual) {
451 if (stats.packageInfo.packageIdentifier.uid == 1001234) {
452 EXPECT_FALSE(stats.hasPackageInfo())
453 << "Stats without package info should return false";
454 } else if (stats.packageInfo.packageIdentifier.uid == 1005678) {
455 EXPECT_TRUE(stats.hasPackageInfo()) << "Stats without package info should return true";
456 } else {
457 FAIL() << "Unexpected uid " << stats.packageInfo.packageIdentifier.uid;
458 }
459 }
460 }
461
TEST_F(UidStatsCollectorTest,TestUidStatsGenericPackageName)462 TEST_F(UidStatsCollectorTest, TestUidStatsGenericPackageName) {
463 std::unordered_map<uid_t, PackageInfo> packageInfoByUid = samplePackageInfoByUid();
464 packageInfoByUid.erase(1001234);
465 const std::unordered_map<uid_t, UidIoStats> uidIoStatsByUid = sampleUidIoStatsByUid();
466 const std::unordered_map<uid_t, UidProcStats> uidProcStatsByUid = sampleUidProcStatsByUid();
467
468 EXPECT_CALL(*mMockPackageInfoResolver,
469 getPackageInfosForUids(UnorderedElementsAre(1001234, 1005678)))
470 .WillOnce(Return(packageInfoByUid));
471 EXPECT_CALL(*mMockUidIoStatsCollector, deltaStats()).WillOnce(Return(uidIoStatsByUid));
472 EXPECT_CALL(*mMockUidProcStatsCollector, deltaStats()).WillOnce(Return(uidProcStatsByUid));
473
474 ASSERT_RESULT_OK(mUidStatsCollector->collect());
475
476 const auto actual = mUidStatsCollector->deltaStats();
477
478 EXPECT_EQ(actual.size(), static_cast<size_t>(2));
479 for (const auto stats : actual) {
480 if (stats.packageInfo.packageIdentifier.uid == 1001234) {
481 EXPECT_EQ(stats.genericPackageName(), "1001234")
482 << "Stats without package info should return UID as package name";
483 } else if (stats.packageInfo.packageIdentifier.uid == 1005678) {
484 EXPECT_EQ(stats.genericPackageName(), "kitchensink.app")
485 << "Stats with package info should return corresponding package name";
486 } else {
487 FAIL() << "Unexpected uid " << stats.packageInfo.packageIdentifier.uid;
488 }
489 }
490 }
491
TEST_F(UidStatsCollectorTest,TestUidStatsUid)492 TEST_F(UidStatsCollectorTest, TestUidStatsUid) {
493 std::unordered_map<uid_t, PackageInfo> packageInfoByUid = samplePackageInfoByUid();
494 packageInfoByUid.erase(1001234);
495 const std::unordered_map<uid_t, UidIoStats> uidIoStatsByUid = sampleUidIoStatsByUid();
496 const std::unordered_map<uid_t, UidProcStats> uidProcStatsByUid = sampleUidProcStatsByUid();
497
498 EXPECT_CALL(*mMockPackageInfoResolver,
499 getPackageInfosForUids(UnorderedElementsAre(1001234, 1005678)))
500 .WillOnce(Return(packageInfoByUid));
501 EXPECT_CALL(*mMockUidIoStatsCollector, deltaStats()).WillOnce(Return(uidIoStatsByUid));
502 EXPECT_CALL(*mMockUidProcStatsCollector, deltaStats()).WillOnce(Return(uidProcStatsByUid));
503
504 ASSERT_RESULT_OK(mUidStatsCollector->collect());
505
506 const auto actual = mUidStatsCollector->deltaStats();
507
508 for (const auto stats : actual) {
509 EXPECT_EQ(stats.uid(), static_cast<uid_t>(stats.packageInfo.packageIdentifier.uid));
510 }
511 }
512
513 } // namespace watchdog
514 } // namespace automotive
515 } // namespace android
516