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