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