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 ::aidl::android::automotive::watchdog::internal::PackageInfo;
40 using ::aidl::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) {}
~UidStatsCollectorPeer()160 ~UidStatsCollectorPeer() { mCollector.clear(); }
161
setPackageInfoResolver(const std::shared_ptr<PackageInfoResolverInterface> & packageInfoResolver)162 void setPackageInfoResolver(const std::shared_ptr<PackageInfoResolverInterface>&
163 packageInfoResolver) {
164 mCollector->mPackageInfoResolver = packageInfoResolver;
165 }
166
setUidIoStatsCollector(const sp<UidIoStatsCollectorInterface> & uidIoStatsCollector)167 void setUidIoStatsCollector(const sp<UidIoStatsCollectorInterface>& uidIoStatsCollector) {
168 mCollector->mUidIoStatsCollector = uidIoStatsCollector;
169 }
170
setUidProcStatsCollector(const sp<UidProcStatsCollectorInterface> & uidProcStatsCollector)171 void setUidProcStatsCollector(const sp<UidProcStatsCollectorInterface>& uidProcStatsCollector) {
172 mCollector->mUidProcStatsCollector = uidProcStatsCollector;
173 }
174
setUidCpuStatsCollector(const sp<UidCpuStatsCollectorInterface> & uidCpuStatsCollector)175 void setUidCpuStatsCollector(const sp<UidCpuStatsCollectorInterface>& uidCpuStatsCollector) {
176 mCollector->mUidCpuStatsCollector = uidCpuStatsCollector;
177 }
178
179 private:
180 sp<UidStatsCollector> mCollector;
181 };
182
183 } // namespace internal
184
185 class UidStatsCollectorTest : public ::testing::Test {
186 protected:
SetUp()187 virtual void SetUp() {
188 mUidStatsCollector = sp<UidStatsCollector>::make();
189 mUidStatsCollectorPeer = sp<internal::UidStatsCollectorPeer>::make(mUidStatsCollector);
190 mMockPackageInfoResolver = std::make_shared<MockPackageInfoResolver>();
191 mMockUidIoStatsCollector = sp<MockUidIoStatsCollector>::make();
192 mMockUidProcStatsCollector = sp<MockUidProcStatsCollector>::make();
193 mMockUidCpuStatsCollector = sp<MockUidCpuStatsCollector>::make();
194 mUidStatsCollectorPeer->setPackageInfoResolver(mMockPackageInfoResolver);
195 mUidStatsCollectorPeer->setUidIoStatsCollector(mMockUidIoStatsCollector);
196 mUidStatsCollectorPeer->setUidProcStatsCollector(mMockUidProcStatsCollector);
197 mUidStatsCollectorPeer->setUidCpuStatsCollector(mMockUidCpuStatsCollector);
198 }
199
TearDown()200 virtual void TearDown() {
201 mUidStatsCollector.clear();
202 mUidStatsCollectorPeer.clear();
203 mMockPackageInfoResolver.reset();
204 mMockUidIoStatsCollector.clear();
205 mMockUidProcStatsCollector.clear();
206 mMockUidCpuStatsCollector.clear();
207 }
208
209 sp<UidStatsCollector> mUidStatsCollector;
210 sp<internal::UidStatsCollectorPeer> mUidStatsCollectorPeer;
211 std::shared_ptr<MockPackageInfoResolver> mMockPackageInfoResolver;
212 sp<MockUidIoStatsCollector> mMockUidIoStatsCollector;
213 sp<MockUidProcStatsCollector> mMockUidProcStatsCollector;
214 sp<MockUidCpuStatsCollector> mMockUidCpuStatsCollector;
215 };
216
TEST_F(UidStatsCollectorTest,TestInit)217 TEST_F(UidStatsCollectorTest, TestInit) {
218 EXPECT_CALL(*mMockUidIoStatsCollector, init()).Times(1);
219 EXPECT_CALL(*mMockUidProcStatsCollector, init()).Times(1);
220
221 mUidStatsCollector->init();
222 }
223
TEST_F(UidStatsCollectorTest,TestCollect)224 TEST_F(UidStatsCollectorTest, TestCollect) {
225 EXPECT_CALL(*mMockUidIoStatsCollector, enabled()).WillOnce(Return(true));
226 EXPECT_CALL(*mMockUidProcStatsCollector, enabled()).WillOnce(Return(true));
227
228 EXPECT_CALL(*mMockUidIoStatsCollector, collect()).WillOnce(Return(Result<void>()));
229 EXPECT_CALL(*mMockUidProcStatsCollector, collect()).WillOnce(Return(Result<void>()));
230
231 EXPECT_CALL(*mMockUidIoStatsCollector, latestStats())
232 .WillOnce(Return(std::unordered_map<uid_t, UidIoStats>()));
233 EXPECT_CALL(*mMockUidProcStatsCollector, latestStats())
234 .WillOnce(Return(std::unordered_map<uid_t, UidProcStats>()));
235
236 EXPECT_CALL(*mMockUidIoStatsCollector, deltaStats())
237 .WillOnce(Return(std::unordered_map<uid_t, UidIoStats>()));
238 EXPECT_CALL(*mMockUidProcStatsCollector, deltaStats())
239 .WillOnce(Return(std::unordered_map<uid_t, UidProcStats>()));
240
241 ASSERT_RESULT_OK(mUidStatsCollector->collect());
242 }
243
TEST_F(UidStatsCollectorTest,TestFailsCollectOnUidIoStatsCollectorError)244 TEST_F(UidStatsCollectorTest, TestFailsCollectOnUidIoStatsCollectorError) {
245 Result<void> errorResult = Error() << "Failed to collect per-UID I/O stats";
246 EXPECT_CALL(*mMockUidIoStatsCollector, collect()).WillOnce(Return(errorResult));
247
248 ASSERT_FALSE(mUidStatsCollector->collect().ok())
249 << "Must fail to collect when per-UID I/O stats collector fails";
250 }
251
TEST_F(UidStatsCollectorTest,TestFailsCollectOnUidProcStatsCollectorError)252 TEST_F(UidStatsCollectorTest, TestFailsCollectOnUidProcStatsCollectorError) {
253 Result<void> errorResult = Error() << "Failed to collect per-UID proc stats";
254 EXPECT_CALL(*mMockUidProcStatsCollector, collect()).WillOnce(Return(errorResult));
255
256 ASSERT_FALSE(mUidStatsCollector->collect().ok())
257 << "Must fail to collect when per-UID proc stats collector fails";
258 }
259
TEST_F(UidStatsCollectorTest,TestCollectLatestStats)260 TEST_F(UidStatsCollectorTest, TestCollectLatestStats) {
261 const std::unordered_map<uid_t, PackageInfo> packageInfoByUid = samplePackageInfoByUid();
262 const std::unordered_map<uid_t, UidIoStats> uidIoStatsByUid = sampleUidIoStatsByUid();
263 const std::unordered_map<uid_t, UidProcStats> uidProcStatsByUid = sampleUidProcStatsByUid();
264 const std::unordered_map<uid_t, int64_t> uidCpuStatsByUid = sampleUidCpuStatsByUid();
265
266 EXPECT_CALL(*mMockPackageInfoResolver,
267 getPackageInfosForUids(UnorderedElementsAre(1001234, 1005678)))
268 .WillOnce(Return(packageInfoByUid));
269 EXPECT_CALL(*mMockUidIoStatsCollector, latestStats()).WillOnce(Return(uidIoStatsByUid));
270 EXPECT_CALL(*mMockUidProcStatsCollector, latestStats()).WillOnce(Return(uidProcStatsByUid));
271 EXPECT_CALL(*mMockUidCpuStatsCollector, latestStats()).WillOnce(Return(uidCpuStatsByUid));
272
273 ASSERT_RESULT_OK(mUidStatsCollector->collect());
274
275 const std::vector<UidStats> expected = sampleUidStats();
276
277 auto actual = mUidStatsCollector->latestStats();
278
279 EXPECT_THAT(actual, UnorderedElementsAreArray(UidStatsMatchers(expected)))
280 << "Latest UID stats doesn't match.\nExpected: " << toString(expected)
281 << "\nActual: " << toString(actual);
282
283 actual = mUidStatsCollector->deltaStats();
284
285 EXPECT_THAT(actual, IsEmpty()) << "Delta UID stats isn't empty.\nActual: " << toString(actual);
286 }
287
TEST_F(UidStatsCollectorTest,TestCollectDeltaStats)288 TEST_F(UidStatsCollectorTest, TestCollectDeltaStats) {
289 const std::unordered_map<uid_t, PackageInfo> packageInfoByUid = samplePackageInfoByUid();
290 const std::unordered_map<uid_t, UidIoStats> uidIoStatsByUid = sampleUidIoStatsByUid();
291 const std::unordered_map<uid_t, UidProcStats> uidProcStatsByUid = sampleUidProcStatsByUid();
292 const std::unordered_map<uid_t, int64_t> uidCpuStatsByUid = sampleUidCpuStatsByUid();
293
294 EXPECT_CALL(*mMockPackageInfoResolver,
295 getPackageInfosForUids(UnorderedElementsAre(1001234, 1005678)))
296 .WillOnce(Return(packageInfoByUid));
297 EXPECT_CALL(*mMockUidIoStatsCollector, deltaStats()).WillOnce(Return(uidIoStatsByUid));
298 EXPECT_CALL(*mMockUidProcStatsCollector, deltaStats()).WillOnce(Return(uidProcStatsByUid));
299 EXPECT_CALL(*mMockUidCpuStatsCollector, deltaStats()).WillOnce(Return(uidCpuStatsByUid));
300
301 ASSERT_RESULT_OK(mUidStatsCollector->collect());
302
303 const std::vector<UidStats> expected = sampleUidStats();
304
305 auto actual = mUidStatsCollector->deltaStats();
306
307 EXPECT_THAT(actual, UnorderedElementsAreArray(UidStatsMatchers(expected)))
308 << "Delta UID stats doesn't match.\nExpected: " << toString(expected)
309 << "\nActual: " << toString(actual);
310
311 actual = mUidStatsCollector->latestStats();
312
313 EXPECT_THAT(actual, IsEmpty()) << "Latest UID stats isn't empty.\nActual: " << toString(actual);
314 }
315
TEST_F(UidStatsCollectorTest,TestCollectDeltaStatsWithMissingUidIoStats)316 TEST_F(UidStatsCollectorTest, TestCollectDeltaStatsWithMissingUidIoStats) {
317 const std::unordered_map<uid_t, PackageInfo> packageInfoByUid = samplePackageInfoByUid();
318 std::unordered_map<uid_t, UidIoStats> uidIoStatsByUid = sampleUidIoStatsByUid();
319 uidIoStatsByUid.erase(1001234);
320 const std::unordered_map<uid_t, UidProcStats> uidProcStatsByUid = sampleUidProcStatsByUid();
321 const std::unordered_map<uid_t, int64_t> uidCpuStatsByUid = sampleUidCpuStatsByUid();
322
323 EXPECT_CALL(*mMockPackageInfoResolver,
324 getPackageInfosForUids(UnorderedElementsAre(1001234, 1005678)))
325 .WillOnce(Return(packageInfoByUid));
326 EXPECT_CALL(*mMockUidIoStatsCollector, deltaStats()).WillOnce(Return(uidIoStatsByUid));
327 EXPECT_CALL(*mMockUidProcStatsCollector, deltaStats()).WillOnce(Return(uidProcStatsByUid));
328 EXPECT_CALL(*mMockUidCpuStatsCollector, deltaStats()).WillOnce(Return(uidCpuStatsByUid));
329
330 ASSERT_RESULT_OK(mUidStatsCollector->collect());
331
332 std::vector<UidStats> expected = sampleUidStats();
333 expected[0].ioStats = {};
334
335 auto actual = mUidStatsCollector->deltaStats();
336
337 EXPECT_THAT(actual, UnorderedElementsAreArray(UidStatsMatchers(expected)))
338 << "Delta UID stats doesn't match.\nExpected: " << toString(expected)
339 << "\nActual: " << toString(actual);
340
341 actual = mUidStatsCollector->latestStats();
342
343 EXPECT_THAT(actual, IsEmpty()) << "Latest UID stats isn't empty.\nActual: " << toString(actual);
344 }
345
TEST_F(UidStatsCollectorTest,TestCollectDeltaStatsWithMissingUidProcStats)346 TEST_F(UidStatsCollectorTest, TestCollectDeltaStatsWithMissingUidProcStats) {
347 const std::unordered_map<uid_t, PackageInfo> packageInfoByUid = samplePackageInfoByUid();
348 const std::unordered_map<uid_t, UidIoStats> uidIoStatsByUid = sampleUidIoStatsByUid();
349 std::unordered_map<uid_t, UidProcStats> uidProcStatsByUid = sampleUidProcStatsByUid();
350 uidProcStatsByUid.erase(1001234);
351 const std::unordered_map<uid_t, int64_t> uidCpuStatsByUid = sampleUidCpuStatsByUid();
352
353 EXPECT_CALL(*mMockPackageInfoResolver,
354 getPackageInfosForUids(UnorderedElementsAre(1001234, 1005678)))
355 .WillOnce(Return(packageInfoByUid));
356 EXPECT_CALL(*mMockUidIoStatsCollector, deltaStats()).WillOnce(Return(uidIoStatsByUid));
357 EXPECT_CALL(*mMockUidProcStatsCollector, deltaStats()).WillOnce(Return(uidProcStatsByUid));
358 EXPECT_CALL(*mMockUidCpuStatsCollector, deltaStats()).WillOnce(Return(uidCpuStatsByUid));
359
360 ASSERT_RESULT_OK(mUidStatsCollector->collect());
361
362 std::vector<UidStats> expected = sampleUidStats();
363 expected[0].procStats = {};
364
365 auto actual = mUidStatsCollector->deltaStats();
366
367 EXPECT_THAT(actual, UnorderedElementsAreArray(UidStatsMatchers(expected)))
368 << "Delta UID stats doesn't match.\nExpected: " << toString(expected)
369 << "\nActual: " << toString(actual);
370
371 actual = mUidStatsCollector->latestStats();
372
373 EXPECT_THAT(actual, IsEmpty()) << "Latest UID stats isn't empty.\nActual: " << toString(actual);
374 }
375
TEST_F(UidStatsCollectorTest,TestCollectDeltaStatsWithMissingUidCpuStats)376 TEST_F(UidStatsCollectorTest, TestCollectDeltaStatsWithMissingUidCpuStats) {
377 const std::unordered_map<uid_t, PackageInfo> packageInfoByUid = samplePackageInfoByUid();
378 const std::unordered_map<uid_t, UidIoStats> uidIoStatsByUid = sampleUidIoStatsByUid();
379 const std::unordered_map<uid_t, UidProcStats> uidProcStatsByUid = sampleUidProcStatsByUid();
380
381 EXPECT_CALL(*mMockPackageInfoResolver,
382 getPackageInfosForUids(UnorderedElementsAre(1001234, 1005678)))
383 .WillOnce(Return(packageInfoByUid));
384 EXPECT_CALL(*mMockUidIoStatsCollector, deltaStats()).WillOnce(Return(uidIoStatsByUid));
385 EXPECT_CALL(*mMockUidProcStatsCollector, deltaStats()).WillOnce(Return(uidProcStatsByUid));
386
387 ASSERT_RESULT_OK(mUidStatsCollector->collect());
388
389 std::vector<UidStats> expected = sampleUidStats();
390 // Since no Uid CPU time was recovered from the /proc/uid_cputime/show_uid_stat file, the
391 // collector will default the UID CPU time to the UidProcStats' CPU time.
392 expected[0].cpuTimeMillis = 10;
393
394 auto actual = mUidStatsCollector->deltaStats();
395
396 EXPECT_THAT(actual, UnorderedElementsAreArray(UidStatsMatchers(expected)))
397 << "Delta UID stats doesn't match.\nExpected: " << toString(expected)
398 << "\nActual: " << toString(actual);
399
400 actual = mUidStatsCollector->latestStats();
401
402 EXPECT_THAT(actual, IsEmpty()) << "Latest UID stats isn't empty.\nActual: " << toString(actual);
403 }
404
TEST_F(UidStatsCollectorTest,TestCollectDeltaStatsWithMissingPackageInfo)405 TEST_F(UidStatsCollectorTest, TestCollectDeltaStatsWithMissingPackageInfo) {
406 std::unordered_map<uid_t, PackageInfo> packageInfoByUid = samplePackageInfoByUid();
407 packageInfoByUid.erase(1001234);
408 const std::unordered_map<uid_t, UidIoStats> uidIoStatsByUid = sampleUidIoStatsByUid();
409 const std::unordered_map<uid_t, UidProcStats> uidProcStatsByUid = sampleUidProcStatsByUid();
410 const std::unordered_map<uid_t, int64_t> uidCpuStatsByUid = sampleUidCpuStatsByUid();
411
412 EXPECT_CALL(*mMockPackageInfoResolver,
413 getPackageInfosForUids(UnorderedElementsAre(1001234, 1005678)))
414 .WillOnce(Return(packageInfoByUid));
415 EXPECT_CALL(*mMockUidIoStatsCollector, deltaStats()).WillOnce(Return(uidIoStatsByUid));
416 EXPECT_CALL(*mMockUidProcStatsCollector, deltaStats()).WillOnce(Return(uidProcStatsByUid));
417 EXPECT_CALL(*mMockUidCpuStatsCollector, deltaStats()).WillOnce(Return(uidCpuStatsByUid));
418
419 ASSERT_RESULT_OK(mUidStatsCollector->collect());
420
421 std::vector<UidStats> expected = sampleUidStats();
422 expected[0].packageInfo = constructPackageInfo("", 1001234);
423
424 auto actual = mUidStatsCollector->deltaStats();
425
426 EXPECT_THAT(actual, UnorderedElementsAreArray(UidStatsMatchers(expected)))
427 << "Delta UID stats doesn't match.\nExpected: " << toString(expected)
428 << "\nActual: " << toString(actual);
429
430 actual = mUidStatsCollector->latestStats();
431
432 EXPECT_THAT(actual, IsEmpty()) << "Latest UID stats isn't empty.\nActual: " << toString(actual);
433 }
434
TEST_F(UidStatsCollectorTest,TestUidStatsHasPackageInfo)435 TEST_F(UidStatsCollectorTest, TestUidStatsHasPackageInfo) {
436 std::unordered_map<uid_t, PackageInfo> packageInfoByUid = samplePackageInfoByUid();
437 packageInfoByUid.erase(1001234);
438 const std::unordered_map<uid_t, UidIoStats> uidIoStatsByUid = sampleUidIoStatsByUid();
439 const std::unordered_map<uid_t, UidProcStats> uidProcStatsByUid = sampleUidProcStatsByUid();
440
441 EXPECT_CALL(*mMockPackageInfoResolver,
442 getPackageInfosForUids(UnorderedElementsAre(1001234, 1005678)))
443 .WillOnce(Return(packageInfoByUid));
444 EXPECT_CALL(*mMockUidIoStatsCollector, deltaStats()).WillOnce(Return(uidIoStatsByUid));
445 EXPECT_CALL(*mMockUidProcStatsCollector, deltaStats()).WillOnce(Return(uidProcStatsByUid));
446
447 ASSERT_RESULT_OK(mUidStatsCollector->collect());
448
449 const auto actual = mUidStatsCollector->deltaStats();
450
451 EXPECT_EQ(actual.size(), static_cast<size_t>(2));
452 for (const auto stats : actual) {
453 if (stats.packageInfo.packageIdentifier.uid == 1001234) {
454 EXPECT_FALSE(stats.hasPackageInfo())
455 << "Stats without package info should return false";
456 } else if (stats.packageInfo.packageIdentifier.uid == 1005678) {
457 EXPECT_TRUE(stats.hasPackageInfo()) << "Stats without package info should return true";
458 } else {
459 FAIL() << "Unexpected uid " << stats.packageInfo.packageIdentifier.uid;
460 }
461 }
462 }
463
TEST_F(UidStatsCollectorTest,TestUidStatsGenericPackageName)464 TEST_F(UidStatsCollectorTest, TestUidStatsGenericPackageName) {
465 std::unordered_map<uid_t, PackageInfo> packageInfoByUid = samplePackageInfoByUid();
466 packageInfoByUid.erase(1001234);
467 const std::unordered_map<uid_t, UidIoStats> uidIoStatsByUid = sampleUidIoStatsByUid();
468 const std::unordered_map<uid_t, UidProcStats> uidProcStatsByUid = sampleUidProcStatsByUid();
469
470 EXPECT_CALL(*mMockPackageInfoResolver,
471 getPackageInfosForUids(UnorderedElementsAre(1001234, 1005678)))
472 .WillOnce(Return(packageInfoByUid));
473 EXPECT_CALL(*mMockUidIoStatsCollector, deltaStats()).WillOnce(Return(uidIoStatsByUid));
474 EXPECT_CALL(*mMockUidProcStatsCollector, deltaStats()).WillOnce(Return(uidProcStatsByUid));
475
476 ASSERT_RESULT_OK(mUidStatsCollector->collect());
477
478 const auto actual = mUidStatsCollector->deltaStats();
479
480 EXPECT_EQ(actual.size(), static_cast<size_t>(2));
481 for (const auto stats : actual) {
482 if (stats.packageInfo.packageIdentifier.uid == 1001234) {
483 EXPECT_EQ(stats.genericPackageName(), "1001234")
484 << "Stats without package info should return UID as package name";
485 } else if (stats.packageInfo.packageIdentifier.uid == 1005678) {
486 EXPECT_EQ(stats.genericPackageName(), "kitchensink.app")
487 << "Stats with package info should return corresponding package name";
488 } else {
489 FAIL() << "Unexpected uid " << stats.packageInfo.packageIdentifier.uid;
490 }
491 }
492 }
493
TEST_F(UidStatsCollectorTest,TestUidStatsUid)494 TEST_F(UidStatsCollectorTest, TestUidStatsUid) {
495 std::unordered_map<uid_t, PackageInfo> packageInfoByUid = samplePackageInfoByUid();
496 packageInfoByUid.erase(1001234);
497 const std::unordered_map<uid_t, UidIoStats> uidIoStatsByUid = sampleUidIoStatsByUid();
498 const std::unordered_map<uid_t, UidProcStats> uidProcStatsByUid = sampleUidProcStatsByUid();
499
500 EXPECT_CALL(*mMockPackageInfoResolver,
501 getPackageInfosForUids(UnorderedElementsAre(1001234, 1005678)))
502 .WillOnce(Return(packageInfoByUid));
503 EXPECT_CALL(*mMockUidIoStatsCollector, deltaStats()).WillOnce(Return(uidIoStatsByUid));
504 EXPECT_CALL(*mMockUidProcStatsCollector, deltaStats()).WillOnce(Return(uidProcStatsByUid));
505
506 ASSERT_RESULT_OK(mUidStatsCollector->collect());
507
508 const auto actual = mUidStatsCollector->deltaStats();
509
510 for (const auto stats : actual) {
511 EXPECT_EQ(stats.uid(), static_cast<uid_t>(stats.packageInfo.packageIdentifier.uid));
512 }
513 }
514
515 } // namespace watchdog
516 } // namespace automotive
517 } // namespace android
518