• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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