• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2020 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 "LooperStub.h"
18 #include "MockDataProcessor.h"
19 #include "MockProcDiskStatsCollector.h"
20 #include "MockProcStatCollector.h"
21 #include "MockUidStatsCollector.h"
22 #include "MockWatchdogServiceHelper.h"
23 #include "ProcStatCollector.h"
24 #include "UidStatsCollector.h"
25 #include "WatchdogPerfService.h"
26 
27 #include <WatchdogProperties.sysprop.h>
28 #include <aidl/android/automotive/watchdog/internal/ResourceOveruseStats.h>
29 #include <aidl/android/automotive/watchdog/internal/ResourceStats.h>
30 #include <aidl/android/automotive/watchdog/internal/ResourceUsageStats.h>
31 #include <aidl/android/automotive/watchdog/internal/SystemSummaryUsageStats.h>
32 #include <aidl/android/automotive/watchdog/internal/UidResourceUsageStats.h>
33 #include <aidl/android/automotive/watchdog/internal/UserState.h>
34 #include <android-base/file.h>
35 #include <android-base/stringprintf.h>
36 #include <android/binder_auto_utils.h>
37 #include <android/binder_interface_utils.h>
38 #include <gmock/gmock.h>
39 #include <utils/RefBase.h>
40 
41 #include <future>  // NOLINT(build/c++11)
42 #include <queue>
43 #include <string>
44 #include <vector>
45 
46 namespace android {
47 namespace automotive {
48 namespace watchdog {
49 
50 namespace {
51 
52 using ::aidl::android::automotive::watchdog::internal::ResourceOveruseStats;
53 using ::aidl::android::automotive::watchdog::internal::ResourceStats;
54 using ::aidl::android::automotive::watchdog::internal::ResourceUsageStats;
55 using ::aidl::android::automotive::watchdog::internal::SystemSummaryUsageStats;
56 using ::aidl::android::automotive::watchdog::internal::UidResourceUsageStats;
57 using ::aidl::android::automotive::watchdog::internal::UserState;
58 using ::android::RefBase;
59 using ::android::sp;
60 using ::android::String16;
61 using ::android::wp;
62 using ::android::automotive::watchdog::testing::LooperStub;
63 using ::android::base::Error;
64 using ::android::base::Result;
65 using ::android::base::StringAppendF;
66 using ::testing::_;
67 using ::testing::ByMove;
68 using ::testing::Eq;
69 using ::testing::InSequence;
70 using ::testing::Mock;
71 using ::testing::NiceMock;
72 using ::testing::Return;
73 using ::testing::StrictMock;
74 using ::testing::UnorderedElementsAreArray;
75 
76 constexpr std::chrono::seconds kTestPostSystemEventDuration = 10s;
77 constexpr std::chrono::seconds kTestSystemEventCollectionInterval = 1s;
78 constexpr std::chrono::seconds kTestPeriodicCollectionInterval = 5s;
79 constexpr std::chrono::seconds kTestCustomCollectionInterval = 3s;
80 constexpr std::chrono::seconds kTestCustomCollectionDuration = 11s;
81 constexpr std::chrono::seconds kTestPeriodicMonitorInterval = 2s;
82 constexpr std::chrono::seconds kTestUserSwitchTimeout = 15s;
83 constexpr std::chrono::seconds kTestWakeUpDuration = 20s;
84 
toString(const std::vector<ResourceStats> & resourceStats)85 std::string toString(const std::vector<ResourceStats>& resourceStats) {
86     std::string buffer;
87     StringAppendF(&buffer, "{");
88     for (const auto& stats : resourceStats) {
89         StringAppendF(&buffer, "%s,\n", stats.toString().c_str());
90     }
91     if (buffer.size() > 2) {
92         buffer.resize(buffer.size() - 2);  // Remove ",\n" from last element
93     }
94     StringAppendF(&buffer, "}");
95     return buffer;
96 }
97 
constructResourceUsageStats(int64_t startTimeEpochMillis,const SystemSummaryUsageStats & systemSummaryUsageStats,std::vector<UidResourceUsageStats> uidResourceUsageStats)98 ResourceUsageStats constructResourceUsageStats(
99         int64_t startTimeEpochMillis, const SystemSummaryUsageStats& systemSummaryUsageStats,
100         std::vector<UidResourceUsageStats> uidResourceUsageStats) {
101     ResourceUsageStats resourceUsageStats;
102     resourceUsageStats.startTimeEpochMillis = startTimeEpochMillis;
103     resourceUsageStats.durationInMillis = 1000;
104     resourceUsageStats.systemSummaryUsageStats = systemSummaryUsageStats;
105     resourceUsageStats.uidResourceUsageStats = uidResourceUsageStats;
106 
107     return resourceUsageStats;
108 }
109 
constructResourceStats(const std::optional<ResourceUsageStats> & resourceUsageStats,const std::optional<ResourceOveruseStats> & resourceOveruseStats)110 ResourceStats constructResourceStats(
111         const std::optional<ResourceUsageStats>& resourceUsageStats,
112         const std::optional<ResourceOveruseStats>& resourceOveruseStats) {
113     ResourceStats resourceStats = {};
114     resourceStats.resourceUsageStats = resourceUsageStats;
115     resourceStats.resourceOveruseStats = resourceOveruseStats;
116 
117     return resourceStats;
118 }
119 
120 }  // namespace
121 
122 namespace internal {
123 
124 class WatchdogPerfServicePeer final : public RefBase {
125 public:
WatchdogPerfServicePeer(const sp<WatchdogPerfService> & service)126     explicit WatchdogPerfServicePeer(const sp<WatchdogPerfService>& service) : mService(service) {}
127     WatchdogPerfServicePeer() = delete;
128 
init(const sp<LooperWrapper> & looper,const sp<UidStatsCollectorInterface> & uidStatsCollector,const sp<ProcStatCollectorInterface> & procStatCollector,const sp<ProcDiskStatsCollectorInterface> & procDiskStatsCollector)129     void init(const sp<LooperWrapper>& looper,
130               const sp<UidStatsCollectorInterface>& uidStatsCollector,
131               const sp<ProcStatCollectorInterface>& procStatCollector,
132               const sp<ProcDiskStatsCollectorInterface>& procDiskStatsCollector) {
133         Mutex::Autolock lock(mService->mMutex);
134         mService->mHandlerLooper = looper;
135         mService->mUidStatsCollector = uidStatsCollector;
136         mService->mProcStatCollector = procStatCollector;
137         mService->mProcDiskStatsCollector = procDiskStatsCollector;
138     }
139 
updateIntervals()140     void updateIntervals() {
141         Mutex::Autolock lock(mService->mMutex);
142         mService->mPostSystemEventDurationNs = kTestPostSystemEventDuration;
143         mService->mBoottimeCollection.pollingIntervalNs = kTestSystemEventCollectionInterval;
144         mService->mPeriodicCollection.pollingIntervalNs = kTestPeriodicCollectionInterval;
145         mService->mUserSwitchCollection.pollingIntervalNs = kTestSystemEventCollectionInterval;
146         mService->mPeriodicMonitor.pollingIntervalNs = kTestPeriodicMonitorInterval;
147         mService->mUserSwitchTimeoutNs = kTestUserSwitchTimeout;
148         mService->mWakeUpDurationNs = kTestWakeUpDuration;
149     }
150 
clearPostSystemEventDuration()151     void clearPostSystemEventDuration() {
152         Mutex::Autolock lock(mService->mMutex);
153         mService->mPostSystemEventDurationNs = 0ns;
154     }
155 
getCurrCollectionEvent()156     EventType getCurrCollectionEvent() {
157         Mutex::Autolock lock(mService->mMutex);
158         return mService->mCurrCollectionEvent;
159     }
160 
setCurrCollectionEvent(EventType eventType)161     void setCurrCollectionEvent(EventType eventType) {
162         Mutex::Autolock lock(mService->mMutex);
163         mService->mCurrCollectionEvent = eventType;
164     }
165 
joinCollectionThread()166     std::future<void> joinCollectionThread() {
167         return std::async([&]() {
168             if (mService->mCollectionThread.joinable()) {
169                 mService->mCollectionThread.join();
170             }
171         });
172     }
173 
174 protected:
175     sp<WatchdogPerfService> mService;
176 };
177 
178 }  // namespace internal
179 
180 namespace {
181 
182 class WatchdogPerfServiceTest : public ::testing::Test {
183 protected:
SetUp()184     virtual void SetUp() {
185         mMockUidStatsCollector = sp<MockUidStatsCollector>::make();
186         mMockWatchdogServiceHelper = sp<MockWatchdogServiceHelper>::make();
187         mMockDataProcessor = sp<StrictMock<MockDataProcessor>>::make();
188         mMockProcDiskStatsCollector = sp<NiceMock<MockProcDiskStatsCollector>>::make();
189         mMockProcStatCollector = sp<NiceMock<MockProcStatCollector>>::make();
190         mService = sp<WatchdogPerfService>::make(mMockWatchdogServiceHelper);
191         mServicePeer = sp<internal::WatchdogPerfServicePeer>::make(mService);
192         mLooperStub = sp<LooperStub>::make();
193     }
194 
TearDown()195     virtual void TearDown() {
196         if (auto event = mServicePeer->getCurrCollectionEvent();
197             event != EventType::INIT && event != EventType::TERMINATED) {
198             EXPECT_CALL(*mMockDataProcessor, terminate()).Times(1);
199             mService->terminate();
200         }
201         mService.clear();
202         mServicePeer.clear();
203         mLooperStub.clear();
204         mMockUidStatsCollector.clear();
205         mMockWatchdogServiceHelper.clear();
206         mMockDataProcessor.clear();
207         mMockProcDiskStatsCollector.clear();
208         mMockProcStatCollector.clear();
209     }
210 
startService()211     void startService() {
212         mServicePeer->init(mLooperStub, mMockUidStatsCollector, mMockProcStatCollector,
213                            mMockProcDiskStatsCollector);
214 
215         EXPECT_CALL(*mMockDataProcessor, init()).Times(1);
216         EXPECT_CALL(*mMockDataProcessor, onSystemStartup()).Times(1);
217 
218         ASSERT_RESULT_OK(mService->registerDataProcessor(mMockDataProcessor));
219 
220         EXPECT_CALL(*mMockUidStatsCollector, init()).Times(1);
221         EXPECT_CALL(*mMockProcStatCollector, init()).Times(1);
222         EXPECT_CALL(*mMockProcDiskStatsCollector, init()).Times(1);
223 
224         ASSERT_RESULT_OK(mService->start());
225 
226         mServicePeer->updateIntervals();
227     }
228 
startPeriodicCollection()229     void startPeriodicCollection() {
230         int bootIterations = static_cast<int>(kTestPostSystemEventDuration.count() /
231                                               kTestSystemEventCollectionInterval.count());
232 
233         // Add the boot collection event done during startService()
234         bootIterations += 1;
235 
236         EXPECT_CALL(*mMockUidStatsCollector, collect()).Times(bootIterations);
237         EXPECT_CALL(*mMockProcStatCollector, collect()).Times(bootIterations);
238         EXPECT_CALL(*mMockDataProcessor,
239                     onBoottimeCollection(_, Eq(mMockUidStatsCollector), Eq(mMockProcStatCollector),
240                                          _))
241                 .Times(bootIterations);
242 
243         // Make sure the collection event changes from EventType::INIT to
244         // EventType::BOOT_TIME_COLLECTION.
245         ASSERT_RESULT_OK(mLooperStub->pollCache());
246 
247         // Mark boot complete.
248         ASSERT_RESULT_OK(mService->onBootFinished());
249 
250         // Poll all post boot-time collections
251         for (int i = 1; i < bootIterations; i++) {
252             ASSERT_RESULT_OK(mLooperStub->pollCache());
253         }
254 
255         // Process |SwitchMessage::END_BOOTTIME_COLLECTION| and switch to periodic collection.
256         ASSERT_EQ(mServicePeer->getCurrCollectionEvent(), EventType::PERIODIC_COLLECTION)
257                 << "Invalid collection event";
258 
259         ASSERT_NO_FATAL_FAILURE(verifyAndClearExpectations());
260     }
261 
skipPeriodicMonitorEvents()262     void skipPeriodicMonitorEvents() {
263         EXPECT_CALL(*mMockDataProcessor, onPeriodicMonitor(_, _, _)).Times(2);
264         ASSERT_RESULT_OK(mLooperStub->pollCache());
265         ASSERT_RESULT_OK(mLooperStub->pollCache());
266     }
267 
removePeriodicMonitorEvents()268     void removePeriodicMonitorEvents() {
269         mLooperStub->removeMessages(mService, EventType::PERIODIC_MONITOR);
270     }
271 
skipPeriodicCollection()272     void skipPeriodicCollection() {
273         EXPECT_CALL(*mMockDataProcessor, onPeriodicCollection(_, SystemState::NORMAL_MODE, _, _, _))
274                 .Times(1);
275         ASSERT_RESULT_OK(mLooperStub->pollCache());
276     }
277 
verifyAndClearExpectations()278     void verifyAndClearExpectations() {
279         Mock::VerifyAndClearExpectations(mMockUidStatsCollector.get());
280         Mock::VerifyAndClearExpectations(mMockProcStatCollector.get());
281         Mock::VerifyAndClearExpectations(mMockProcDiskStatsCollector.get());
282         Mock::VerifyAndClearExpectations(mMockDataProcessor.get());
283         Mock::VerifyAndClearExpectations(mMockWatchdogServiceHelper.get());
284     }
285 
286     sp<WatchdogPerfService> mService;
287     sp<internal::WatchdogPerfServicePeer> mServicePeer;
288     sp<LooperStub> mLooperStub;
289     sp<MockUidStatsCollector> mMockUidStatsCollector;
290     sp<MockProcStatCollector> mMockProcStatCollector;
291     sp<MockProcDiskStatsCollector> mMockProcDiskStatsCollector;
292     sp<MockWatchdogServiceHelper> mMockWatchdogServiceHelper;
293     sp<MockDataProcessor> mMockDataProcessor;
294 };
295 
296 }  // namespace
297 
TEST_F(WatchdogPerfServiceTest,TestServiceStartAndTerminate)298 TEST_F(WatchdogPerfServiceTest, TestServiceStartAndTerminate) {
299     mServicePeer->init(mLooperStub, mMockUidStatsCollector, mMockProcStatCollector,
300                        mMockProcDiskStatsCollector);
301 
302     EXPECT_CALL(*mMockDataProcessor, init()).Times(1);
303     EXPECT_CALL(*mMockDataProcessor, onSystemStartup()).Times(1);
304 
305     ASSERT_RESULT_OK(mService->registerDataProcessor(mMockDataProcessor));
306 
307     EXPECT_CALL(*mMockUidStatsCollector, init()).Times(1);
308     EXPECT_CALL(*mMockProcStatCollector, init()).Times(1);
309     EXPECT_CALL(*mMockProcDiskStatsCollector, init()).Times(1);
310 
311     ASSERT_RESULT_OK(mService->start());
312 
313     ASSERT_TRUE(mService->mCollectionThread.joinable()) << "Collection thread not created";
314 
315     EXPECT_CALL(*mMockUidStatsCollector, collect()).Times(1);
316     EXPECT_CALL(*mMockProcStatCollector, collect()).Times(1);
317     EXPECT_CALL(*mMockDataProcessor,
318                 onBoottimeCollection(_, Eq(mMockUidStatsCollector), Eq(mMockProcStatCollector), _))
319             .Times(1);
320 
321     ASSERT_RESULT_OK(mLooperStub->pollCache());
322 
323     ASSERT_EQ(mLooperStub->numSecondsElapsed(), 0)
324             << "Boot-time collection didn't start immediately";
325     ASSERT_EQ(mServicePeer->getCurrCollectionEvent(), EventType::BOOT_TIME_COLLECTION)
326             << "Invalid collection event";
327 
328     ASSERT_FALSE(mService->start().ok())
329             << "No error returned when WatchdogPerfService was started more than once";
330 
331     ASSERT_TRUE(sysprop::systemEventCollectionInterval().has_value());
332     ASSERT_EQ(std::chrono::duration_cast<std::chrono::seconds>(
333                       mService->mBoottimeCollection.pollingIntervalNs)
334                       .count(),
335               sysprop::systemEventCollectionInterval().value());
336     ASSERT_TRUE(sysprop::periodicCollectionInterval().has_value());
337     ASSERT_EQ(std::chrono::duration_cast<std::chrono::seconds>(
338                       mService->mPeriodicCollection.pollingIntervalNs)
339                       .count(),
340               sysprop::periodicCollectionInterval().value());
341 
342     EXPECT_CALL(*mMockDataProcessor, terminate()).Times(1);
343 
344     mService->terminate();
345 
346     ASSERT_FALSE(mService->mCollectionThread.joinable()) << "Collection thread did not terminate";
347 }
348 
TEST_F(WatchdogPerfServiceTest,TestValidCollectionSequence)349 TEST_F(WatchdogPerfServiceTest, TestValidCollectionSequence) {
350     ASSERT_NO_FATAL_FAILURE(startService());
351 
352     // #1 Boot-time collection
353     // TODO(b/266008677): Add more data to the ResourceStats.
354     std::optional<ResourceUsageStats> boottimeResourceUsageStats =
355             std::make_optional<ResourceUsageStats>({});
356 
357     EXPECT_CALL(*mMockUidStatsCollector, collect()).Times(1);
358     EXPECT_CALL(*mMockProcStatCollector, collect()).Times(1);
359     EXPECT_CALL(*mMockDataProcessor,
360                 onBoottimeCollection(_, Eq(mMockUidStatsCollector), Eq(mMockProcStatCollector), _))
361             .Times(1)
362             .WillOnce([&](auto, auto, auto, auto* resourceStats) -> Result<void> {
363                 resourceStats->resourceUsageStats = boottimeResourceUsageStats;
364                 return {};
365             });
366     EXPECT_CALL(*mMockWatchdogServiceHelper, isServiceConnected()).Times(1);
367     // Even though the resource stats are not empty the service is not
368     // connected, therefore stats are not sent to CarWatchdogService.
369     EXPECT_CALL(*mMockWatchdogServiceHelper, onLatestResourceStats(_)).Times(0);
370 
371     ASSERT_RESULT_OK(mLooperStub->pollCache());
372 
373     ASSERT_EQ(mLooperStub->numSecondsElapsed(), 0)
374             << "Boot-time collection didn't start immediately";
375     ASSERT_EQ(mServicePeer->getCurrCollectionEvent(), EventType::BOOT_TIME_COLLECTION)
376             << "Invalid collection event";
377     ASSERT_NO_FATAL_FAILURE(verifyAndClearExpectations());
378 
379     // #2 Boot-time collection
380     EXPECT_CALL(*mMockUidStatsCollector, collect()).Times(1);
381     EXPECT_CALL(*mMockProcStatCollector, collect()).Times(1);
382     EXPECT_CALL(*mMockDataProcessor,
383                 onBoottimeCollection(_, Eq(mMockUidStatsCollector), Eq(mMockProcStatCollector), _))
384             .Times(1);
385     EXPECT_CALL(*mMockWatchdogServiceHelper, isServiceConnected()).Times(1);
386     EXPECT_CALL(*mMockWatchdogServiceHelper, onLatestResourceStats(_)).Times(0);
387 
388     ASSERT_RESULT_OK(mLooperStub->pollCache());
389 
390     ASSERT_EQ(mLooperStub->numSecondsElapsed(), kTestSystemEventCollectionInterval.count())
391             << "Subsequent boot-time collection didn't happen at "
392             << kTestSystemEventCollectionInterval.count() << " seconds interval";
393     ASSERT_EQ(mServicePeer->getCurrCollectionEvent(), EventType::BOOT_TIME_COLLECTION)
394             << "Invalid collection event";
395     ASSERT_NO_FATAL_FAILURE(verifyAndClearExpectations());
396 
397     // #3 Post system event collection - boot-time
398     int maxIterations = static_cast<int>(kTestPostSystemEventDuration.count() /
399                                          kTestSystemEventCollectionInterval.count());
400 
401     EXPECT_CALL(*mMockUidStatsCollector, collect()).Times(maxIterations);
402     EXPECT_CALL(*mMockProcStatCollector, collect()).Times(maxIterations);
403     EXPECT_CALL(*mMockDataProcessor,
404                 onBoottimeCollection(_, Eq(mMockUidStatsCollector), Eq(mMockProcStatCollector), _))
405             .Times(maxIterations);
406     EXPECT_CALL(*mMockWatchdogServiceHelper, isServiceConnected()).Times(maxIterations);
407     EXPECT_CALL(*mMockWatchdogServiceHelper, onLatestResourceStats(_)).Times(0);
408 
409     ASSERT_RESULT_OK(mService->onBootFinished());
410 
411     // Poll all post system event collections - boot-time except last
412     for (int i = 0; i < maxIterations - 1; i++) {
413         ASSERT_RESULT_OK(mLooperStub->pollCache());
414 
415         ASSERT_EQ(mLooperStub->numSecondsElapsed(), kTestSystemEventCollectionInterval.count())
416                 << "Subsequent post boot-time collection didn't happen at "
417                 << kTestSystemEventCollectionInterval.count() << " seconds interval";
418         ASSERT_EQ(mServicePeer->getCurrCollectionEvent(), EventType::BOOT_TIME_COLLECTION)
419                 << "Invalid collection event";
420     }
421 
422     // Poll the last post system event collection - boot-time. The last boot-time collection should
423     // switch to periodic collection.
424     ASSERT_RESULT_OK(mLooperStub->pollCache());
425 
426     ASSERT_EQ(mLooperStub->numSecondsElapsed(), kTestSystemEventCollectionInterval.count())
427             << "Last boot-time collection didn't happen immediately after sending "
428             << "END_BOOTTIME_COLLECTION message";
429     ASSERT_EQ(mServicePeer->getCurrCollectionEvent(), EventType::PERIODIC_COLLECTION)
430             << "Invalid collection event";
431     ASSERT_NO_FATAL_FAILURE(verifyAndClearExpectations());
432 
433     // #4 Periodic monitor
434     EXPECT_CALL(*mMockProcDiskStatsCollector, collect()).Times(1);
435     EXPECT_CALL(*mMockDataProcessor, onPeriodicMonitor(_, Eq(mMockProcDiskStatsCollector), _))
436             .Times(1);
437 
438     ASSERT_RESULT_OK(mLooperStub->pollCache());
439 
440     ASSERT_EQ(mLooperStub->numSecondsElapsed(), kTestPeriodicMonitorInterval.count())
441             << "First periodic monitor didn't happen at " << kTestPeriodicMonitorInterval.count()
442             << " seconds interval";
443     ASSERT_NO_FATAL_FAILURE(verifyAndClearExpectations());
444 
445     // #5 Periodic monitor
446     EXPECT_CALL(*mMockProcDiskStatsCollector, collect()).Times(1);
447     EXPECT_CALL(*mMockDataProcessor, onPeriodicMonitor(_, Eq(mMockProcDiskStatsCollector), _))
448             .Times(1);
449 
450     ASSERT_RESULT_OK(mLooperStub->pollCache());
451 
452     ASSERT_EQ(mLooperStub->numSecondsElapsed(), kTestPeriodicMonitorInterval.count())
453             << "Second periodic monitor didn't happen at " << kTestPeriodicMonitorInterval.count()
454             << " seconds interval";
455     ASSERT_NO_FATAL_FAILURE(verifyAndClearExpectations());
456 
457     // #6 Periodic collection
458     std::vector<ResourceStats> actualResourceStats = {};
459     ResourceOveruseStats expectedResourceOveruseStats = {};
460     std::vector<ResourceStats> expectedResourceStats = {
461             // Handle the resource stats send during boottime.
462             constructResourceStats(boottimeResourceUsageStats,
463                                    /*resourceOveruseStats=*/std::nullopt),
464             constructResourceStats(/*resourceUsageStats=*/std::nullopt,
465                                    expectedResourceOveruseStats),
466     };
467     EXPECT_CALL(*mMockUidStatsCollector, collect()).Times(1);
468     EXPECT_CALL(*mMockProcStatCollector, collect()).Times(1);
469     EXPECT_CALL(*mMockDataProcessor,
470                 onPeriodicCollection(_, SystemState::NORMAL_MODE, Eq(mMockUidStatsCollector),
471                                      Eq(mMockProcStatCollector), _))
472             .Times(1)
473             .WillOnce([&](auto, auto, auto, auto, auto* resourceStats) -> Result<void> {
474                 resourceStats->resourceOveruseStats =
475                         std::make_optional<ResourceOveruseStats>(expectedResourceOveruseStats);
476                 return {};
477             });
478     EXPECT_CALL(*mMockWatchdogServiceHelper, isServiceConnected()).Times(1).WillOnce(Return(true));
479     EXPECT_CALL(*mMockWatchdogServiceHelper, onLatestResourceStats(_))
480             .Times(1)
481             .WillOnce([&](auto& resourceStats) -> ndk::ScopedAStatus {
482                 actualResourceStats = resourceStats;
483                 return ndk::ScopedAStatus::ok();
484             });
485 
486     ASSERT_RESULT_OK(mLooperStub->pollCache());
487 
488     ASSERT_EQ(mLooperStub->numSecondsElapsed(), 1)
489             << "First periodic collection didn't happen at 1 second interval";
490     ASSERT_EQ(mServicePeer->getCurrCollectionEvent(), EventType::PERIODIC_COLLECTION)
491             << "Invalid collection event";
492 
493     // Handle the SEND_RESOURCE_STATS message
494     ASSERT_RESULT_OK(mLooperStub->pollCache());
495 
496     ASSERT_EQ(actualResourceStats, expectedResourceStats)
497             << "Expected: " << toString(expectedResourceStats)
498             << "\nActual: " << toString(actualResourceStats);
499 
500     ASSERT_NO_FATAL_FAILURE(verifyAndClearExpectations());
501 
502     std::string customCollectionIntervalStr = std::to_string(kTestCustomCollectionInterval.count());
503     std::string customCollectionDurationStr = std::to_string(kTestCustomCollectionDuration.count());
504     // #7 Custom collection
505     actualResourceStats = {};
506     const char* firstArgs[] = {kStartCustomCollectionFlag, kIntervalFlag,
507                                customCollectionIntervalStr.c_str(), kMaxDurationFlag,
508                                customCollectionDurationStr.c_str()};
509 
510     ASSERT_RESULT_OK(mService->onCustomCollection(-1, firstArgs, /*numArgs=*/5));
511 
512     ResourceUsageStats expectedResourceUsageStats =
513             constructResourceUsageStats(/*startTimeEpochMillis=*/0, /*systemSummaryUsageStats=*/{},
514                                         /*uidResourceUsageStats=*/{});
515     expectedResourceStats = {
516             constructResourceStats(expectedResourceUsageStats,
517                                    /*resourceOveruseStats=*/std::nullopt),
518     };
519 
520     EXPECT_CALL(*mMockUidStatsCollector, collect()).Times(1);
521     EXPECT_CALL(*mMockProcStatCollector, collect()).Times(1);
522     EXPECT_CALL(*mMockDataProcessor,
523                 onCustomCollection(_, SystemState::NORMAL_MODE, _, Eq(mMockUidStatsCollector),
524                                    Eq(mMockProcStatCollector), _))
525             .Times(1)
526             .WillOnce([&](auto, auto, auto, auto, auto, auto* resourceStats) -> Result<void> {
527                 resourceStats->resourceUsageStats =
528                         expectedResourceStats.front().resourceUsageStats;
529                 return {};
530             });
531     EXPECT_CALL(*mMockWatchdogServiceHelper, isServiceConnected()).Times(1).WillOnce(Return(true));
532     EXPECT_CALL(*mMockWatchdogServiceHelper, onLatestResourceStats(_))
533             .Times(1)
534             .WillOnce([&](auto& resourceStats) -> ndk::ScopedAStatus {
535                 actualResourceStats = resourceStats;
536                 return ndk::ScopedAStatus::ok();
537             });
538 
539     ASSERT_RESULT_OK(mLooperStub->pollCache());
540 
541     // Handle the SEND_RESOURCE_STATS message
542     ASSERT_RESULT_OK(mLooperStub->pollCache());
543 
544     ASSERT_EQ(mLooperStub->numSecondsElapsed(), 0) << "Custom collection didn't start immediately";
545     ASSERT_EQ(mServicePeer->getCurrCollectionEvent(), EventType::CUSTOM_COLLECTION)
546             << "Invalid collection event";
547     ASSERT_EQ(actualResourceStats, expectedResourceStats)
548             << "Expected: " << toString(expectedResourceStats)
549             << "\nActual: " << toString(actualResourceStats);
550 
551     ASSERT_NO_FATAL_FAILURE(verifyAndClearExpectations());
552 
553     // #8 Custom collection
554     EXPECT_CALL(*mMockUidStatsCollector, collect()).Times(1);
555     EXPECT_CALL(*mMockProcStatCollector, collect()).Times(1);
556     EXPECT_CALL(*mMockDataProcessor,
557                 onCustomCollection(_, SystemState::NORMAL_MODE, _, Eq(mMockUidStatsCollector),
558                                    Eq(mMockProcStatCollector), _))
559             .Times(1);
560     EXPECT_CALL(*mMockWatchdogServiceHelper, isServiceConnected()).Times(0);
561     EXPECT_CALL(*mMockWatchdogServiceHelper, onLatestResourceStats(_)).Times(0);
562 
563     ASSERT_RESULT_OK(mLooperStub->pollCache());
564 
565     ASSERT_EQ(mLooperStub->numSecondsElapsed(), kTestCustomCollectionInterval.count())
566             << "Subsequent custom collection didn't happen at "
567             << kTestCustomCollectionInterval.count() << " seconds interval";
568     ASSERT_EQ(mServicePeer->getCurrCollectionEvent(), EventType::CUSTOM_COLLECTION)
569             << "Invalid collection event";
570     ASSERT_NO_FATAL_FAILURE(verifyAndClearExpectations());
571 
572     // #9 End custom collection
573     TemporaryFile customDump;
574     {
575         InSequence s;
576         EXPECT_CALL(*mMockDataProcessor, onCustomCollectionDump(customDump.fd)).Times(1);
577         EXPECT_CALL(*mMockDataProcessor, onCustomCollectionDump(-1)).Times(1);
578     }
579 
580     const char* secondArgs[] = {kEndCustomCollectionFlag};
581     ASSERT_RESULT_OK(mService->onCustomCollection(customDump.fd, secondArgs, /*numArgs=*/1));
582     ASSERT_RESULT_OK(mLooperStub->pollCache());
583     ASSERT_EQ(mServicePeer->getCurrCollectionEvent(), EventType::PERIODIC_COLLECTION)
584             << "Invalid collection event";
585 
586     // #10 Switch to periodic collection
587     EXPECT_CALL(*mMockUidStatsCollector, collect()).Times(1);
588     EXPECT_CALL(*mMockProcStatCollector, collect()).Times(1);
589     EXPECT_CALL(*mMockDataProcessor,
590                 onPeriodicCollection(_, SystemState::NORMAL_MODE, Eq(mMockUidStatsCollector),
591                                      Eq(mMockProcStatCollector), _))
592             .Times(1);
593     EXPECT_CALL(*mMockWatchdogServiceHelper, isServiceConnected()).Times(0);
594     EXPECT_CALL(*mMockWatchdogServiceHelper, onLatestResourceStats(_)).Times(0);
595 
596     ASSERT_RESULT_OK(mLooperStub->pollCache());
597 
598     ASSERT_EQ(mLooperStub->numSecondsElapsed(), 0)
599             << "Periodic collection didn't start immediately after ending custom collection";
600     ASSERT_EQ(mServicePeer->getCurrCollectionEvent(), EventType::PERIODIC_COLLECTION)
601             << "Invalid collection event";
602     ASSERT_NO_FATAL_FAILURE(verifyAndClearExpectations());
603 
604     // #11 Periodic monitor.
605     EXPECT_CALL(*mMockProcDiskStatsCollector, collect()).Times(1);
606     EXPECT_CALL(*mMockDataProcessor, onPeriodicMonitor(_, Eq(mMockProcDiskStatsCollector), _))
607             .Times(1);
608 
609     ASSERT_RESULT_OK(mLooperStub->pollCache());
610 
611     ASSERT_EQ(mLooperStub->numSecondsElapsed(), kTestPeriodicMonitorInterval.count());
612     ASSERT_NO_FATAL_FAILURE(verifyAndClearExpectations());
613 
614     EXPECT_CALL(*mMockDataProcessor, terminate()).Times(1);
615 }
616 
TEST_F(WatchdogPerfServiceTest,TestCollectionTerminatesOnZeroEnabledCollectors)617 TEST_F(WatchdogPerfServiceTest, TestCollectionTerminatesOnZeroEnabledCollectors) {
618     ASSERT_NO_FATAL_FAILURE(startService());
619 
620     ON_CALL(*mMockUidStatsCollector, enabled()).WillByDefault(Return(false));
621     ON_CALL(*mMockProcStatCollector, enabled()).WillByDefault(Return(false));
622 
623     // Collection should terminate and call data processor's terminate method on error.
624     EXPECT_CALL(*mMockDataProcessor, terminate()).Times(1);
625 
626     ASSERT_RESULT_OK(mLooperStub->pollCache());
627 
628     ASSERT_EQ(mServicePeer->joinCollectionThread().wait_for(1s), std::future_status::ready)
629             << "Collection thread didn't terminate within 1 second.";
630     ASSERT_EQ(mServicePeer->getCurrCollectionEvent(), EventType::TERMINATED);
631 }
632 
TEST_F(WatchdogPerfServiceTest,TestCollectionTerminatesOnDataCollectorError)633 TEST_F(WatchdogPerfServiceTest, TestCollectionTerminatesOnDataCollectorError) {
634     ASSERT_NO_FATAL_FAILURE(startService());
635 
636     // Inject data collector error.
637     Result<void> errorRes = Error() << "Failed to collect data";
638     EXPECT_CALL(*mMockUidStatsCollector, collect()).WillOnce(Return(errorRes));
639 
640     // Collection should terminate and call data processor's terminate method on error.
641     EXPECT_CALL(*mMockDataProcessor, terminate()).Times(1);
642 
643     ASSERT_RESULT_OK(mLooperStub->pollCache());
644 
645     ASSERT_EQ(mServicePeer->joinCollectionThread().wait_for(1s), std::future_status::ready)
646             << "Collection thread didn't terminate within 1 second.";
647     ASSERT_EQ(mServicePeer->getCurrCollectionEvent(), EventType::TERMINATED);
648 }
649 
TEST_F(WatchdogPerfServiceTest,TestCollectionTerminatesOnDataProcessorError)650 TEST_F(WatchdogPerfServiceTest, TestCollectionTerminatesOnDataProcessorError) {
651     ASSERT_NO_FATAL_FAILURE(startService());
652 
653     // Inject data processor error.
654     Result<void> errorRes = Error() << "Failed to process data";
655     EXPECT_CALL(*mMockDataProcessor,
656                 onBoottimeCollection(_, Eq(mMockUidStatsCollector), Eq(mMockProcStatCollector), _))
657             .WillOnce(Return(errorRes));
658 
659     // Collection should terminate and call data processor's terminate method on error.
660     EXPECT_CALL(*mMockDataProcessor, terminate()).Times(1);
661 
662     ASSERT_RESULT_OK(mLooperStub->pollCache());
663 
664     ASSERT_EQ(mServicePeer->joinCollectionThread().wait_for(1s), std::future_status::ready)
665             << "Collection thread didn't terminate within 1 second.";
666     ASSERT_EQ(mServicePeer->getCurrCollectionEvent(), EventType::TERMINATED);
667 }
668 
TEST_F(WatchdogPerfServiceTest,TestBoottimeCollectionWithNoPostSystemEventDuration)669 TEST_F(WatchdogPerfServiceTest, TestBoottimeCollectionWithNoPostSystemEventDuration) {
670     ASSERT_NO_FATAL_FAILURE(startService());
671 
672     mServicePeer->clearPostSystemEventDuration();
673 
674     // #1 Boot-time collection
675     EXPECT_CALL(*mMockUidStatsCollector, collect()).Times(1);
676     EXPECT_CALL(*mMockProcStatCollector, collect()).Times(1);
677     EXPECT_CALL(*mMockDataProcessor,
678                 onBoottimeCollection(_, Eq(mMockUidStatsCollector), Eq(mMockProcStatCollector), _))
679             .Times(1);
680 
681     ASSERT_RESULT_OK(mLooperStub->pollCache());
682 
683     ASSERT_EQ(mLooperStub->numSecondsElapsed(), 0)
684             << "Boot-time collection didn't start immediately";
685     ASSERT_EQ(mServicePeer->getCurrCollectionEvent(), EventType::BOOT_TIME_COLLECTION)
686             << "Invalid collection event";
687     ASSERT_NO_FATAL_FAILURE(verifyAndClearExpectations());
688 
689     // #2 Boot-time collection
690     EXPECT_CALL(*mMockUidStatsCollector, collect()).Times(1);
691     EXPECT_CALL(*mMockProcStatCollector, collect()).Times(1);
692     EXPECT_CALL(*mMockDataProcessor,
693                 onBoottimeCollection(_, Eq(mMockUidStatsCollector), Eq(mMockProcStatCollector), _))
694             .Times(1);
695 
696     ASSERT_RESULT_OK(mLooperStub->pollCache());
697 
698     ASSERT_EQ(mLooperStub->numSecondsElapsed(), kTestSystemEventCollectionInterval.count())
699             << "Subsequent boot-time collection didn't happen at "
700             << kTestSystemEventCollectionInterval.count() << " seconds interval";
701     ASSERT_EQ(mServicePeer->getCurrCollectionEvent(), EventType::BOOT_TIME_COLLECTION)
702             << "Invalid collection event";
703     ASSERT_NO_FATAL_FAILURE(verifyAndClearExpectations());
704 
705     // #3 Last boot-time collection
706     EXPECT_CALL(*mMockUidStatsCollector, collect()).Times(1);
707     EXPECT_CALL(*mMockProcStatCollector, collect()).Times(1);
708     EXPECT_CALL(*mMockDataProcessor,
709                 onBoottimeCollection(_, Eq(mMockUidStatsCollector), Eq(mMockProcStatCollector), _))
710             .Times(1);
711 
712     ASSERT_RESULT_OK(mService->onBootFinished());
713 
714     ASSERT_RESULT_OK(mLooperStub->pollCache());
715 
716     ASSERT_EQ(mLooperStub->numSecondsElapsed(), 0)
717             << "Last boot-time collection didn't happen immediately after receiving boot complete "
718             << "notification";
719     ASSERT_EQ(mServicePeer->getCurrCollectionEvent(), EventType::PERIODIC_COLLECTION)
720             << "Invalid collection event";
721     ASSERT_NO_FATAL_FAILURE(verifyAndClearExpectations());
722 }
723 
TEST_F(WatchdogPerfServiceTest,TestCustomCollection)724 TEST_F(WatchdogPerfServiceTest, TestCustomCollection) {
725     ASSERT_NO_FATAL_FAILURE(startService());
726 
727     ASSERT_NO_FATAL_FAILURE(startPeriodicCollection());
728 
729     std::string customCollectionIntervalStr = std::to_string(kTestCustomCollectionInterval.count());
730     std::string customCollectionDurationStr = std::to_string(kTestCustomCollectionDuration.count());
731     // Start custom collection with filter packages option.
732     const char* args[] = {kStartCustomCollectionFlag,          kIntervalFlag,
733                           customCollectionIntervalStr.c_str(), kMaxDurationFlag,
734                           customCollectionDurationStr.c_str(), kFilterPackagesFlag,
735                           "android.car.cts,system_server"};
736 
737     ASSERT_RESULT_OK(mService->onCustomCollection(-1, args, /*numArgs=*/7));
738 
739     // Poll until custom collection auto terminates.
740     int maxIterations = static_cast<int>(kTestCustomCollectionDuration.count() /
741                                          kTestCustomCollectionInterval.count());
742     for (int i = 0; i <= maxIterations; ++i) {
743         EXPECT_CALL(*mMockUidStatsCollector, collect()).Times(1);
744         EXPECT_CALL(*mMockProcStatCollector, collect()).Times(1);
745         EXPECT_CALL(*mMockDataProcessor,
746                     onCustomCollection(_, SystemState::NORMAL_MODE,
747                                        UnorderedElementsAreArray(
748                                                {"android.car.cts", "system_server"}),
749                                        Eq(mMockUidStatsCollector), Eq(mMockProcStatCollector), _))
750                 .Times(1);
751 
752         ASSERT_RESULT_OK(mLooperStub->pollCache());
753 
754         int secondsElapsed = (i == 0 ? 0 : kTestCustomCollectionInterval.count());
755         ASSERT_EQ(mLooperStub->numSecondsElapsed(), secondsElapsed)
756                 << "Custom collection didn't happen at " << secondsElapsed
757                 << " seconds interval in iteration " << i;
758         ASSERT_EQ(mServicePeer->getCurrCollectionEvent(), EventType::CUSTOM_COLLECTION)
759                 << "Invalid collection event";
760         ASSERT_NO_FATAL_FAILURE(verifyAndClearExpectations());
761     }
762 
763     EXPECT_CALL(*mMockDataProcessor, onCustomCollectionDump(-1)).Times(1);
764 
765     // Next looper message was injected during startCustomCollection to end the custom collection
766     // after |kTestCustomCollectionDuration|. On processing this message, the custom collection
767     // should auto terminate.
768     ASSERT_RESULT_OK(mLooperStub->pollCache());
769 
770     ASSERT_EQ(mLooperStub->numSecondsElapsed(),
771               kTestCustomCollectionDuration.count() % kTestCustomCollectionInterval.count())
772             << "Custom collection did't end after " << kTestCustomCollectionDuration.count()
773             << " seconds";
774     ASSERT_EQ(mServicePeer->getCurrCollectionEvent(), EventType::PERIODIC_COLLECTION)
775             << "Invalid collection event";
776     EXPECT_CALL(*mMockDataProcessor, terminate()).Times(1);
777 }
778 
TEST_F(WatchdogPerfServiceTest,TestCustomCollectionAlwaysStarts)779 TEST_F(WatchdogPerfServiceTest, TestCustomCollectionAlwaysStarts) {
780     ASSERT_NO_FATAL_FAILURE(startService());
781 
782     ASSERT_NO_FATAL_FAILURE(startPeriodicCollection());
783 
784     for (int eventInt = EventType::BOOT_TIME_COLLECTION; eventInt < EventType::PERIODIC_MONITOR;
785          ++eventInt) {
786         EventType eventType = static_cast<EventType>(eventInt);
787         if (eventType == EventType::CUSTOM_COLLECTION) {
788             continue;
789         }
790         mServicePeer->setCurrCollectionEvent(static_cast<EventType>(eventInt));
791 
792         EXPECT_CALL(*mMockUidStatsCollector, collect()).Times(1);
793         EXPECT_CALL(*mMockProcStatCollector, collect()).Times(1);
794         EXPECT_CALL(*mMockDataProcessor,
795                     onCustomCollection(_, SystemState::NORMAL_MODE,
796                                        UnorderedElementsAreArray(
797                                                {"android.car.cts", "system_server"}),
798                                        Eq(mMockUidStatsCollector), Eq(mMockProcStatCollector), _))
799                 .Times(1);
800 
801         std::string customCollectionIntervalStr =
802                 std::to_string(kTestCustomCollectionInterval.count());
803         std::string customCollectionDurationStr =
804                 std::to_string(kTestCustomCollectionDuration.count());
805         // Start custom collection with filter packages option.
806         const char* args[] = {kStartCustomCollectionFlag,          kIntervalFlag,
807                               customCollectionIntervalStr.c_str(), kMaxDurationFlag,
808                               customCollectionDurationStr.c_str(), kFilterPackagesFlag,
809                               "android.car.cts,system_server"};
810 
811         ASSERT_RESULT_OK(mService->onCustomCollection(-1, args, /*numArgs=*/7));
812 
813         ASSERT_RESULT_OK(mLooperStub->pollCache());
814 
815         ASSERT_EQ(mLooperStub->numSecondsElapsed(), 0)
816                 << "Custom collection didn't happen immediately";
817         ASSERT_EQ(mServicePeer->getCurrCollectionEvent(), EventType::CUSTOM_COLLECTION)
818                 << "Invalid collection event";
819         ASSERT_NO_FATAL_FAILURE(verifyAndClearExpectations());
820     }
821 }
822 
TEST_F(WatchdogPerfServiceTest,TestUserSwitchCollection)823 TEST_F(WatchdogPerfServiceTest, TestUserSwitchCollection) {
824     ASSERT_NO_FATAL_FAILURE(startService());
825 
826     ASSERT_NO_FATAL_FAILURE(startPeriodicCollection());
827 
828     userid_t fromUserId = 0;
829     userid_t toUserId = 100;
830 
831     // #1 Start user switch collection
832     EXPECT_CALL(*mMockUidStatsCollector, collect()).Times(1);
833     EXPECT_CALL(*mMockProcStatCollector, collect()).Times(1);
834     EXPECT_CALL(*mMockDataProcessor,
835                 onUserSwitchCollection(_, Eq(fromUserId), Eq(toUserId), Eq(mMockUidStatsCollector),
836                                        Eq(mMockProcStatCollector)))
837             .Times(1);
838 
839     ASSERT_RESULT_OK(mService->onUserStateChange(100, UserState::USER_STATE_SWITCHING));
840 
841     ASSERT_RESULT_OK(mLooperStub->pollCache());
842 
843     ASSERT_EQ(mLooperStub->numSecondsElapsed(), 0)
844             << "User switch collection didn't start immediately";
845     ASSERT_EQ(mServicePeer->getCurrCollectionEvent(), EventType::USER_SWITCH_COLLECTION)
846             << "Invalid collection event";
847     ASSERT_NO_FATAL_FAILURE(verifyAndClearExpectations());
848 
849     // #2 User switch collection
850     EXPECT_CALL(*mMockUidStatsCollector, collect()).Times(1);
851     EXPECT_CALL(*mMockProcStatCollector, collect()).Times(1);
852     EXPECT_CALL(*mMockDataProcessor,
853                 onUserSwitchCollection(_, Eq(fromUserId), Eq(toUserId), Eq(mMockUidStatsCollector),
854                                        Eq(mMockProcStatCollector)))
855             .Times(1);
856 
857     ASSERT_RESULT_OK(mLooperStub->pollCache());
858 
859     ASSERT_EQ(mLooperStub->numSecondsElapsed(), kTestSystemEventCollectionInterval.count())
860             << "Subsequent user switch collection didn't happen at "
861             << kTestSystemEventCollectionInterval.count() << " seconds interval";
862     ASSERT_EQ(mServicePeer->getCurrCollectionEvent(), EventType::USER_SWITCH_COLLECTION)
863             << "Invalid collection event";
864     ASSERT_NO_FATAL_FAILURE(verifyAndClearExpectations());
865 
866     // #3 Post system event collection - user switch
867     int maxIterations = static_cast<int>(kTestPostSystemEventDuration.count() /
868                                          kTestSystemEventCollectionInterval.count());
869 
870     EXPECT_CALL(*mMockUidStatsCollector, collect()).Times(maxIterations);
871     EXPECT_CALL(*mMockProcStatCollector, collect()).Times(maxIterations);
872     EXPECT_CALL(*mMockDataProcessor,
873                 onUserSwitchCollection(_, Eq(fromUserId), Eq(toUserId), Eq(mMockUidStatsCollector),
874                                        Eq(mMockProcStatCollector)))
875             .Times(maxIterations);
876 
877     ASSERT_RESULT_OK(mService->onUserStateChange(100, UserState::USER_STATE_POST_UNLOCKED));
878 
879     // Poll all post user switch collections except last
880     for (int i = 0; i < maxIterations - 1; ++i) {
881         ASSERT_RESULT_OK(mLooperStub->pollCache());
882 
883         ASSERT_EQ(mLooperStub->numSecondsElapsed(), kTestSystemEventCollectionInterval.count())
884                 << "Subsequent post system event collection - user switch didn't happen at "
885                 << kTestSystemEventCollectionInterval.count() << " seconds interval";
886         ASSERT_EQ(mServicePeer->getCurrCollectionEvent(), EventType::USER_SWITCH_COLLECTION)
887                 << "Invalid collection event";
888     }
889 
890     // Poll the last post system event collection - user switch. The last user switch collection
891     // event should switch to periodic collection.
892     ASSERT_RESULT_OK(mLooperStub->pollCache());
893 
894     ASSERT_EQ(mLooperStub->numSecondsElapsed(), kTestSystemEventCollectionInterval.count())
895             << "Last user switch collection didn't happen immediately after sending "
896             << "END_USER_SWITCH_COLLECTION message";
897     ASSERT_EQ(mServicePeer->getCurrCollectionEvent(), EventType::PERIODIC_COLLECTION)
898             << "Invalid collection event";
899     ASSERT_NO_FATAL_FAILURE(verifyAndClearExpectations());
900 }
901 
TEST_F(WatchdogPerfServiceTest,TestUserSwitchCollectionWithDelayedUnlocking)902 TEST_F(WatchdogPerfServiceTest, TestUserSwitchCollectionWithDelayedUnlocking) {
903     ASSERT_NO_FATAL_FAILURE(startService());
904 
905     ASSERT_NO_FATAL_FAILURE(startPeriodicCollection());
906 
907     userid_t fromUserId = 0;
908     userid_t toUserId = 100;
909 
910     // #1 Start user switch collection
911     EXPECT_CALL(*mMockUidStatsCollector, collect()).Times(1);
912     EXPECT_CALL(*mMockProcStatCollector, collect()).Times(1);
913     EXPECT_CALL(*mMockDataProcessor,
914                 onUserSwitchCollection(_, Eq(fromUserId), Eq(toUserId), Eq(mMockUidStatsCollector),
915                                        Eq(mMockProcStatCollector)))
916             .Times(1);
917 
918     ASSERT_RESULT_OK(mService->onUserStateChange(100, UserState::USER_STATE_SWITCHING));
919 
920     ASSERT_RESULT_OK(mLooperStub->pollCache());
921 
922     ASSERT_EQ(mLooperStub->numSecondsElapsed(), 0)
923             << "User switch collection didn't start immediately";
924     ASSERT_EQ(mServicePeer->getCurrCollectionEvent(), EventType::USER_SWITCH_COLLECTION)
925             << "Invalid collection event";
926     ASSERT_NO_FATAL_FAILURE(verifyAndClearExpectations());
927 
928     // #2 User switch collections before timeout
929     int maxIterations = static_cast<int>(kTestUserSwitchTimeout.count() /
930                                          kTestSystemEventCollectionInterval.count());
931 
932     EXPECT_CALL(*mMockUidStatsCollector, collect()).Times(maxIterations);
933     EXPECT_CALL(*mMockProcStatCollector, collect()).Times(maxIterations);
934     EXPECT_CALL(*mMockDataProcessor,
935                 onUserSwitchCollection(_, Eq(fromUserId), Eq(toUserId), Eq(mMockUidStatsCollector),
936                                        Eq(mMockProcStatCollector)))
937             .Times(maxIterations);
938 
939     // Poll all user switch collections except last
940     for (int i = 0; i < maxIterations - 1; i++) {
941         ASSERT_RESULT_OK(mLooperStub->pollCache());
942 
943         ASSERT_EQ(mLooperStub->numSecondsElapsed(), kTestSystemEventCollectionInterval.count())
944                 << "Subsequent user switch collection didn't happen at "
945                 << kTestSystemEventCollectionInterval.count() << " seconds interval";
946         ASSERT_EQ(mServicePeer->getCurrCollectionEvent(), EventType::USER_SWITCH_COLLECTION)
947                 << "Invalid collection event";
948     }
949 
950     // Poll the last user switch collection. The last user switch collection event should start
951     // periodic collection.
952     ASSERT_RESULT_OK(mLooperStub->pollCache());
953 
954     ASSERT_EQ(mLooperStub->numSecondsElapsed(), kTestSystemEventCollectionInterval.count())
955             << "Last user switch collection didn't happen immediately after sending "
956             << "END_USER_SWITCH_COLLECTION message";
957     ASSERT_EQ(mServicePeer->getCurrCollectionEvent(), EventType::PERIODIC_COLLECTION)
958             << "Invalid collection event";
959     ASSERT_NO_FATAL_FAILURE(verifyAndClearExpectations());
960 
961     // #3 Start user switch collection with unlocking signal
962     EXPECT_CALL(*mMockUidStatsCollector, collect()).Times(1);
963     EXPECT_CALL(*mMockProcStatCollector, collect()).Times(1);
964     EXPECT_CALL(*mMockDataProcessor,
965                 onUserSwitchCollection(_, Eq(fromUserId), Eq(toUserId), Eq(mMockUidStatsCollector),
966                                        Eq(mMockProcStatCollector)))
967             .Times(1);
968 
969     ASSERT_RESULT_OK(mService->onUserStateChange(100, UserState::USER_STATE_UNLOCKING));
970 
971     ASSERT_RESULT_OK(mLooperStub->pollCache());
972 
973     ASSERT_EQ(mLooperStub->numSecondsElapsed(), 0)
974             << "User switch collection didn't start immediately";
975     ASSERT_EQ(mServicePeer->getCurrCollectionEvent(), EventType::USER_SWITCH_COLLECTION)
976             << "Invalid collection event";
977     ASSERT_NO_FATAL_FAILURE(verifyAndClearExpectations());
978 
979     // #4 User switch collections after unlocking
980     EXPECT_CALL(*mMockUidStatsCollector, collect()).Times(1);
981     EXPECT_CALL(*mMockProcStatCollector, collect()).Times(1);
982     EXPECT_CALL(*mMockDataProcessor,
983                 onUserSwitchCollection(_, Eq(fromUserId), Eq(toUserId), Eq(mMockUidStatsCollector),
984                                        Eq(mMockProcStatCollector)))
985             .Times(1);
986 
987     ASSERT_RESULT_OK(mLooperStub->pollCache());
988 
989     ASSERT_EQ(mLooperStub->numSecondsElapsed(), kTestSystemEventCollectionInterval.count())
990             << "Subsequent user switch collection didn't happen at "
991             << kTestSystemEventCollectionInterval.count() << " seconds interval";
992     ASSERT_EQ(mServicePeer->getCurrCollectionEvent(), EventType::USER_SWITCH_COLLECTION)
993             << "Invalid collection event";
994     ASSERT_NO_FATAL_FAILURE(verifyAndClearExpectations());
995 
996     // #5 Post system event collection - user switch
997     maxIterations = static_cast<int>(kTestPostSystemEventDuration.count() /
998                                      kTestSystemEventCollectionInterval.count());
999 
1000     EXPECT_CALL(*mMockUidStatsCollector, collect()).Times(maxIterations);
1001     EXPECT_CALL(*mMockProcStatCollector, collect()).Times(maxIterations);
1002     EXPECT_CALL(*mMockDataProcessor,
1003                 onUserSwitchCollection(_, Eq(fromUserId), Eq(toUserId), Eq(mMockUidStatsCollector),
1004                                        Eq(mMockProcStatCollector)))
1005             .Times(maxIterations);
1006 
1007     ASSERT_RESULT_OK(mService->onUserStateChange(100, UserState::USER_STATE_POST_UNLOCKED));
1008 
1009     // Poll all post user switch collections except last
1010     for (int i = 0; i < maxIterations - 1; ++i) {
1011         ASSERT_RESULT_OK(mLooperStub->pollCache());
1012 
1013         ASSERT_EQ(mLooperStub->numSecondsElapsed(), kTestSystemEventCollectionInterval.count())
1014                 << "Subsequent post user switch collection didn't happen at "
1015                 << kTestSystemEventCollectionInterval.count() << " seconds interval";
1016         ASSERT_EQ(mServicePeer->getCurrCollectionEvent(), EventType::USER_SWITCH_COLLECTION)
1017                 << "Invalid collection event";
1018     }
1019 
1020     // Poll the last post user switch collection
1021     ASSERT_RESULT_OK(mLooperStub->pollCache());
1022 
1023     ASSERT_EQ(mLooperStub->numSecondsElapsed(), kTestSystemEventCollectionInterval.count())
1024             << "Last user switch collection didn't happen immediately after sending "
1025             << "END_USER_SWITCH_COLLECTION message";
1026     ASSERT_EQ(mServicePeer->getCurrCollectionEvent(), EventType::PERIODIC_COLLECTION)
1027             << "Invalid collection event";
1028     ASSERT_NO_FATAL_FAILURE(verifyAndClearExpectations());
1029 }
1030 
TEST_F(WatchdogPerfServiceTest,TestUserSwitchEventDuringUserSwitchCollection)1031 TEST_F(WatchdogPerfServiceTest, TestUserSwitchEventDuringUserSwitchCollection) {
1032     ASSERT_NO_FATAL_FAILURE(startService());
1033 
1034     ASSERT_NO_FATAL_FAILURE(startPeriodicCollection());
1035 
1036     userid_t fromUserId = 0;
1037     userid_t toUserId = 100;
1038 
1039     // #1 Start user switch collection
1040     EXPECT_CALL(*mMockUidStatsCollector, collect()).Times(2);
1041     EXPECT_CALL(*mMockProcStatCollector, collect()).Times(2);
1042     EXPECT_CALL(*mMockDataProcessor,
1043                 onUserSwitchCollection(_, Eq(fromUserId), Eq(toUserId), Eq(mMockUidStatsCollector),
1044                                        Eq(mMockProcStatCollector)))
1045             .Times(2);
1046 
1047     ASSERT_RESULT_OK(mService->onUserStateChange(toUserId, UserState::USER_STATE_SWITCHING));
1048 
1049     ASSERT_RESULT_OK(mLooperStub->pollCache());
1050 
1051     ASSERT_EQ(mLooperStub->numSecondsElapsed(), 0)
1052             << "User switch collection didn't start immediately";
1053     ASSERT_EQ(mServicePeer->getCurrCollectionEvent(), EventType::USER_SWITCH_COLLECTION)
1054             << "Invalid collection event";
1055 
1056     // #2 User switch collection
1057     ASSERT_RESULT_OK(mLooperStub->pollCache());
1058 
1059     ASSERT_EQ(mLooperStub->numSecondsElapsed(), kTestSystemEventCollectionInterval.count())
1060             << "Subsequent user switch collection didn't happen at "
1061             << kTestSystemEventCollectionInterval.count() << " seconds interval";
1062     ASSERT_EQ(mServicePeer->getCurrCollectionEvent(), EventType::USER_SWITCH_COLLECTION)
1063             << "Invalid collection event";
1064     ASSERT_NO_FATAL_FAILURE(verifyAndClearExpectations());
1065 
1066     // #3 Start new user switch collection during prev user switch event
1067     userid_t newFromUserId = 100;
1068     userid_t newToUserId = 101;
1069 
1070     EXPECT_CALL(*mMockUidStatsCollector, collect()).Times(1);
1071     EXPECT_CALL(*mMockProcStatCollector, collect()).Times(1);
1072     EXPECT_CALL(*mMockDataProcessor,
1073                 onUserSwitchCollection(_, Eq(newFromUserId), Eq(newToUserId),
1074                                        Eq(mMockUidStatsCollector), Eq(mMockProcStatCollector)))
1075             .Times(1);
1076 
1077     ASSERT_RESULT_OK(mService->onUserStateChange(newToUserId, UserState::USER_STATE_SWITCHING));
1078 
1079     ASSERT_RESULT_OK(mLooperStub->pollCache());
1080 
1081     ASSERT_EQ(mLooperStub->numSecondsElapsed(), 0)
1082             << "New user switch collection didn't start immediately";
1083     ASSERT_EQ(mServicePeer->getCurrCollectionEvent(), EventType::USER_SWITCH_COLLECTION)
1084             << "Invalid collection event";
1085     ASSERT_NO_FATAL_FAILURE(verifyAndClearExpectations());
1086 
1087     // #4 New user switch collection
1088     EXPECT_CALL(*mMockUidStatsCollector, collect()).Times(1);
1089     EXPECT_CALL(*mMockProcStatCollector, collect()).Times(1);
1090     EXPECT_CALL(*mMockDataProcessor,
1091                 onUserSwitchCollection(_, Eq(newFromUserId), Eq(newToUserId),
1092                                        Eq(mMockUidStatsCollector), Eq(mMockProcStatCollector)))
1093             .Times(1);
1094 
1095     ASSERT_RESULT_OK(mLooperStub->pollCache());
1096 
1097     ASSERT_EQ(mLooperStub->numSecondsElapsed(), kTestSystemEventCollectionInterval.count())
1098             << "Subsequent new user switch collection didn't happen at "
1099             << kTestSystemEventCollectionInterval.count() << " seconds interval";
1100     ASSERT_EQ(mServicePeer->getCurrCollectionEvent(), EventType::USER_SWITCH_COLLECTION)
1101             << "Invalid collection event";
1102     ASSERT_NO_FATAL_FAILURE(verifyAndClearExpectations());
1103 
1104     // #5 Post system event collection - new user switch
1105     int maxIterations = static_cast<int>(kTestPostSystemEventDuration.count() /
1106                                          kTestSystemEventCollectionInterval.count());
1107 
1108     EXPECT_CALL(*mMockUidStatsCollector, collect()).Times(maxIterations);
1109     EXPECT_CALL(*mMockProcStatCollector, collect()).Times(maxIterations);
1110     EXPECT_CALL(*mMockDataProcessor,
1111                 onUserSwitchCollection(_, Eq(newFromUserId), Eq(newToUserId),
1112                                        Eq(mMockUidStatsCollector), Eq(mMockProcStatCollector)))
1113             .Times(maxIterations);
1114 
1115     ASSERT_RESULT_OK(mService->onUserStateChange(newToUserId, UserState::USER_STATE_POST_UNLOCKED));
1116 
1117     // Poll all post user switch collections except last
1118     for (int i = 0; i < maxIterations - 1; ++i) {
1119         ASSERT_RESULT_OK(mLooperStub->pollCache());
1120 
1121         ASSERT_EQ(mLooperStub->numSecondsElapsed(), kTestSystemEventCollectionInterval.count())
1122                 << "Subsequent post system event collection -  new user switch didn't happen at "
1123                 << kTestSystemEventCollectionInterval.count() << " seconds interval";
1124         ASSERT_EQ(mServicePeer->getCurrCollectionEvent(), EventType::USER_SWITCH_COLLECTION)
1125                 << "Invalid collection event";
1126     }
1127 
1128     // Poll the last post system event collection - user switch. The last user switch collection
1129     // event should switch to periodic collection.
1130     ASSERT_RESULT_OK(mLooperStub->pollCache());
1131 
1132     ASSERT_EQ(mLooperStub->numSecondsElapsed(), kTestSystemEventCollectionInterval.count())
1133             << "Last new user switch collection didn't happen immediately after sending "
1134             << "END_USER_SWITCH_COLLECTION message";
1135     ASSERT_EQ(mServicePeer->getCurrCollectionEvent(), EventType::PERIODIC_COLLECTION)
1136             << "Invalid collection event";
1137     ASSERT_NO_FATAL_FAILURE(verifyAndClearExpectations());
1138 }
1139 
TEST_F(WatchdogPerfServiceTest,TestUserSwitchCollectionWithTwoTimeouts)1140 TEST_F(WatchdogPerfServiceTest, TestUserSwitchCollectionWithTwoTimeouts) {
1141     ASSERT_NO_FATAL_FAILURE(startService());
1142 
1143     ASSERT_NO_FATAL_FAILURE(startPeriodicCollection());
1144 
1145     userid_t fromUserId = 0;
1146     userid_t toUserId = 100;
1147 
1148     // #1 Start user switch collection
1149     EXPECT_CALL(*mMockUidStatsCollector, collect()).Times(1);
1150     EXPECT_CALL(*mMockProcStatCollector, collect()).Times(1);
1151     EXPECT_CALL(*mMockDataProcessor,
1152                 onUserSwitchCollection(_, Eq(fromUserId), Eq(toUserId), Eq(mMockUidStatsCollector),
1153                                        Eq(mMockProcStatCollector)))
1154             .Times(1);
1155 
1156     ASSERT_RESULT_OK(mService->onUserStateChange(100, UserState::USER_STATE_SWITCHING));
1157 
1158     ASSERT_RESULT_OK(mLooperStub->pollCache());
1159 
1160     ASSERT_EQ(mLooperStub->numSecondsElapsed(), 0)
1161             << "User switch collection didn't start immediately";
1162     ASSERT_EQ(mServicePeer->getCurrCollectionEvent(), EventType::USER_SWITCH_COLLECTION)
1163             << "Invalid collection event";
1164     ASSERT_NO_FATAL_FAILURE(verifyAndClearExpectations());
1165 
1166     // #2 User switch collections before timeout
1167     int maxIterations = static_cast<int>(kTestUserSwitchTimeout.count() /
1168                                          kTestSystemEventCollectionInterval.count());
1169 
1170     EXPECT_CALL(*mMockUidStatsCollector, collect()).Times(maxIterations);
1171     EXPECT_CALL(*mMockProcStatCollector, collect()).Times(maxIterations);
1172     EXPECT_CALL(*mMockDataProcessor,
1173                 onUserSwitchCollection(_, Eq(fromUserId), Eq(toUserId), Eq(mMockUidStatsCollector),
1174                                        Eq(mMockProcStatCollector)))
1175             .Times(maxIterations);
1176 
1177     // Poll all user switch collections except last
1178     for (int i = 0; i < maxIterations - 1; ++i) {
1179         ASSERT_RESULT_OK(mLooperStub->pollCache());
1180 
1181         ASSERT_EQ(mLooperStub->numSecondsElapsed(), kTestSystemEventCollectionInterval.count())
1182                 << "Subsequent post user switch collection didn't happen at "
1183                 << kTestSystemEventCollectionInterval.count() << " seconds interval";
1184         ASSERT_EQ(mServicePeer->getCurrCollectionEvent(), EventType::USER_SWITCH_COLLECTION)
1185                 << "Invalid collection event";
1186     }
1187 
1188     // Poll the last user switch collection
1189     ASSERT_RESULT_OK(mLooperStub->pollCache());
1190 
1191     ASSERT_EQ(mLooperStub->numSecondsElapsed(), kTestSystemEventCollectionInterval.count())
1192             << "Last user switch collection didn't happen immediately after sending "
1193             << "END_USER_SWITCH_COLLECTION message";
1194     ASSERT_EQ(mServicePeer->getCurrCollectionEvent(), EventType::PERIODIC_COLLECTION)
1195             << "Invalid collection event";
1196     ASSERT_NO_FATAL_FAILURE(verifyAndClearExpectations());
1197 
1198     // #3 Start user switch collection with unlocking signal
1199     EXPECT_CALL(*mMockUidStatsCollector, collect()).Times(1);
1200     EXPECT_CALL(*mMockProcStatCollector, collect()).Times(1);
1201     EXPECT_CALL(*mMockDataProcessor,
1202                 onUserSwitchCollection(_, Eq(fromUserId), Eq(toUserId), Eq(mMockUidStatsCollector),
1203                                        Eq(mMockProcStatCollector)))
1204             .Times(1);
1205 
1206     ASSERT_RESULT_OK(mService->onUserStateChange(100, UserState::USER_STATE_UNLOCKING));
1207 
1208     ASSERT_RESULT_OK(mLooperStub->pollCache());
1209 
1210     ASSERT_EQ(mLooperStub->numSecondsElapsed(), 0)
1211             << "User switch collection didn't start immediately";
1212     ASSERT_EQ(mServicePeer->getCurrCollectionEvent(), EventType::USER_SWITCH_COLLECTION)
1213             << "Invalid collection event";
1214     ASSERT_NO_FATAL_FAILURE(verifyAndClearExpectations());
1215 
1216     // #4 User switch collections after unlocking
1217     maxIterations = static_cast<int>(kTestUserSwitchTimeout.count() /
1218                                      kTestSystemEventCollectionInterval.count());
1219 
1220     EXPECT_CALL(*mMockUidStatsCollector, collect()).Times(maxIterations);
1221     EXPECT_CALL(*mMockProcStatCollector, collect()).Times(maxIterations);
1222     EXPECT_CALL(*mMockDataProcessor,
1223                 onUserSwitchCollection(_, Eq(fromUserId), Eq(toUserId), Eq(mMockUidStatsCollector),
1224                                        Eq(mMockProcStatCollector)))
1225             .Times(maxIterations);
1226 
1227     // Poll all post user switch collections except last
1228     for (int i = 0; i < maxIterations - 1; ++i) {
1229         ASSERT_RESULT_OK(mLooperStub->pollCache());
1230 
1231         ASSERT_EQ(mLooperStub->numSecondsElapsed(), kTestSystemEventCollectionInterval.count())
1232                 << "Subsequent post user switch collection didn't happen at "
1233                 << kTestSystemEventCollectionInterval.count() << " seconds interval";
1234         ASSERT_EQ(mServicePeer->getCurrCollectionEvent(), EventType::USER_SWITCH_COLLECTION)
1235                 << "Invalid collection event";
1236     }
1237 
1238     // Poll the last post user switch collection
1239     ASSERT_RESULT_OK(mLooperStub->pollCache());
1240 
1241     ASSERT_EQ(mLooperStub->numSecondsElapsed(), kTestSystemEventCollectionInterval.count())
1242             << "Last user switch collection didn't happen immediately after sending "
1243             << "END_USER_SWITCH_COLLECTION message";
1244     ASSERT_EQ(mServicePeer->getCurrCollectionEvent(), EventType::PERIODIC_COLLECTION)
1245             << "Invalid collection event";
1246     ASSERT_NO_FATAL_FAILURE(verifyAndClearExpectations());
1247 }
1248 
TEST_F(WatchdogPerfServiceTest,TestUserSwitchCollectionUserUnlockingWithNoPrevTimeout)1249 TEST_F(WatchdogPerfServiceTest, TestUserSwitchCollectionUserUnlockingWithNoPrevTimeout) {
1250     ASSERT_NO_FATAL_FAILURE(startService());
1251     ASSERT_NO_FATAL_FAILURE(startPeriodicCollection());
1252     ASSERT_NO_FATAL_FAILURE(skipPeriodicMonitorEvents());
1253 
1254     EXPECT_CALL(*mMockUidStatsCollector, collect()).Times(1);
1255     EXPECT_CALL(*mMockProcStatCollector, collect()).Times(1);
1256     EXPECT_CALL(*mMockDataProcessor,
1257                 onPeriodicCollection(_, SystemState::NORMAL_MODE, Eq(mMockUidStatsCollector),
1258                                      Eq(mMockProcStatCollector), _))
1259             .Times(1);
1260     EXPECT_CALL(*mMockDataProcessor, onUserSwitchCollection(_, _, _, _, _)).Times(0);
1261 
1262     ASSERT_RESULT_OK(mService->onUserStateChange(100, UserState::USER_STATE_UNLOCKING));
1263 
1264     ASSERT_RESULT_OK(mLooperStub->pollCache());
1265 
1266     ASSERT_EQ(mLooperStub->numSecondsElapsed(), 1)
1267             << "First periodic collection didn't happen at 1 second interval";
1268     ASSERT_EQ(mServicePeer->getCurrCollectionEvent(), EventType::PERIODIC_COLLECTION)
1269             << "Invalid collection event";
1270     ASSERT_NO_FATAL_FAILURE(verifyAndClearExpectations());
1271 }
1272 
TEST_F(WatchdogPerfServiceTest,TestIgnoreUserSwitchCollectionDuringCustomCollection)1273 TEST_F(WatchdogPerfServiceTest, TestIgnoreUserSwitchCollectionDuringCustomCollection) {
1274     ASSERT_NO_FATAL_FAILURE(startService());
1275 
1276     ASSERT_NO_FATAL_FAILURE(startPeriodicCollection());
1277 
1278     userid_t fromUserId = 0;
1279     userid_t toUserId = 100;
1280 
1281     // Start custom collection
1282     std::string customCollectionIntervalStr = std::to_string(kTestCustomCollectionInterval.count());
1283     std::string customCollectionDurationStr = std::to_string(kTestCustomCollectionDuration.count());
1284 
1285     const char* firstArgs[] = {kStartCustomCollectionFlag, kIntervalFlag,
1286                                customCollectionIntervalStr.c_str(), kMaxDurationFlag,
1287                                customCollectionDurationStr.c_str()};
1288 
1289     ASSERT_RESULT_OK(mService->onCustomCollection(-1, firstArgs, /*numArgs=*/5));
1290 
1291     EXPECT_CALL(*mMockUidStatsCollector, collect()).Times(2);
1292     EXPECT_CALL(*mMockProcStatCollector, collect()).Times(2);
1293     EXPECT_CALL(*mMockDataProcessor,
1294                 onCustomCollection(_, SystemState::NORMAL_MODE, _, Eq(mMockUidStatsCollector),
1295                                    Eq(mMockProcStatCollector), _))
1296             .Times(2);
1297     EXPECT_CALL(*mMockDataProcessor,
1298                 onUserSwitchCollection(_, Eq(fromUserId), Eq(toUserId), Eq(mMockUidStatsCollector),
1299                                        Eq(mMockProcStatCollector)))
1300             .Times(0);
1301 
1302     ASSERT_RESULT_OK(mLooperStub->pollCache());
1303 
1304     ASSERT_EQ(mLooperStub->numSecondsElapsed(), 0) << "Custom collection didn't start immediately";
1305     ASSERT_EQ(mServicePeer->getCurrCollectionEvent(), EventType::CUSTOM_COLLECTION)
1306             << "Invalid collection event";
1307 
1308     // Custom collection while user switch signal is received
1309     ASSERT_RESULT_OK(mService->onUserStateChange(100, UserState::USER_STATE_SWITCHING));
1310 
1311     // Continued custom collection
1312     ASSERT_RESULT_OK(mLooperStub->pollCache());
1313 
1314     ASSERT_EQ(mLooperStub->numSecondsElapsed(), kTestCustomCollectionInterval.count())
1315             << "Subsequent custom collection didn't happen at "
1316             << kTestCustomCollectionInterval.count() << " seconds interval";
1317     ASSERT_EQ(mServicePeer->getCurrCollectionEvent(), EventType::CUSTOM_COLLECTION)
1318             << "Invalid collection event";
1319     ASSERT_NO_FATAL_FAILURE(verifyAndClearExpectations());
1320 }
1321 
TEST_F(WatchdogPerfServiceTest,TestWakeUpCollection)1322 TEST_F(WatchdogPerfServiceTest, TestWakeUpCollection) {
1323     ASSERT_NO_FATAL_FAILURE(startService());
1324 
1325     ASSERT_NO_FATAL_FAILURE(startPeriodicCollection());
1326 
1327     // #1 Wake up collection
1328     EXPECT_CALL(*mMockUidStatsCollector, collect()).Times(1);
1329     EXPECT_CALL(*mMockProcStatCollector, collect()).Times(1);
1330     EXPECT_CALL(*mMockDataProcessor, onSystemStartup()).Times(1);
1331     EXPECT_CALL(*mMockDataProcessor,
1332                 onWakeUpCollection(_, Eq(mMockUidStatsCollector), Eq(mMockProcStatCollector)))
1333             .Times(1);
1334 
1335     ASSERT_RESULT_OK(mService->onSuspendExit());
1336 
1337     ASSERT_RESULT_OK(mLooperStub->pollCache());
1338 
1339     ASSERT_EQ(mLooperStub->numSecondsElapsed(), 0) << "Wake up collection didn't start immediately";
1340     ASSERT_EQ(mServicePeer->getCurrCollectionEvent(), EventType::WAKE_UP_COLLECTION)
1341             << "Invalid collection event";
1342     ASSERT_NO_FATAL_FAILURE(verifyAndClearExpectations());
1343 
1344     // #2 Wake up collections before duration expires
1345     int maxIterations = static_cast<int>(kTestWakeUpDuration.count() /
1346                                          kTestSystemEventCollectionInterval.count());
1347 
1348     EXPECT_CALL(*mMockUidStatsCollector, collect()).Times(maxIterations);
1349     EXPECT_CALL(*mMockProcStatCollector, collect()).Times(maxIterations);
1350     EXPECT_CALL(*mMockDataProcessor,
1351                 onWakeUpCollection(_, Eq(mMockUidStatsCollector), Eq(mMockProcStatCollector)))
1352             .Times(maxIterations);
1353 
1354     // Poll all remaining wake up collections except last
1355     for (int i = 0; i < maxIterations - 1; ++i) {
1356         ASSERT_RESULT_OK(mLooperStub->pollCache());
1357 
1358         ASSERT_EQ(mLooperStub->numSecondsElapsed(), kTestSystemEventCollectionInterval.count())
1359                 << "Subsequent wake up collection didn't happen at "
1360                 << kTestSystemEventCollectionInterval.count() << " seconds interval";
1361         ASSERT_EQ(mServicePeer->getCurrCollectionEvent(), EventType::WAKE_UP_COLLECTION)
1362                 << "Invalid collection event";
1363     }
1364 
1365     // Suspend exit signal should be ignored since already running wake up collection.
1366     ASSERT_RESULT_OK(mService->onSuspendExit());
1367 
1368     // Poll the last wake up collection
1369     ASSERT_RESULT_OK(mLooperStub->pollCache());
1370 
1371     ASSERT_EQ(mLooperStub->numSecondsElapsed(), kTestSystemEventCollectionInterval.count())
1372             << "Last wake up collection didn't happen immediately after sending "
1373             << "END_WAKE_UP_COLLECTION message";
1374     ASSERT_EQ(mServicePeer->getCurrCollectionEvent(), EventType::PERIODIC_COLLECTION)
1375             << "Invalid collection event";
1376     ASSERT_NO_FATAL_FAILURE(verifyAndClearExpectations());
1377 }
1378 
TEST_F(WatchdogPerfServiceTest,TestWakeUpCollectionDuringCustomCollection)1379 TEST_F(WatchdogPerfServiceTest, TestWakeUpCollectionDuringCustomCollection) {
1380     ASSERT_NO_FATAL_FAILURE(startService());
1381 
1382     ASSERT_NO_FATAL_FAILURE(startPeriodicCollection());
1383 
1384     // Start custom collection
1385     std::string customCollectionIntervalStr = std::to_string(kTestCustomCollectionInterval.count());
1386     std::string customCollectionDurationStr = std::to_string(kTestCustomCollectionDuration.count());
1387 
1388     const char* firstArgs[] = {kStartCustomCollectionFlag, kIntervalFlag,
1389                                customCollectionIntervalStr.c_str(), kMaxDurationFlag,
1390                                customCollectionDurationStr.c_str()};
1391 
1392     ASSERT_RESULT_OK(mService->onCustomCollection(-1, firstArgs, /*numArgs=*/5));
1393 
1394     EXPECT_CALL(*mMockUidStatsCollector, collect()).Times(2);
1395     EXPECT_CALL(*mMockProcStatCollector, collect()).Times(2);
1396     EXPECT_CALL(*mMockDataProcessor,
1397                 onCustomCollection(_, SystemState::NORMAL_MODE, _, Eq(mMockUidStatsCollector),
1398                                    Eq(mMockProcStatCollector), _))
1399             .Times(2);
1400     EXPECT_CALL(*mMockDataProcessor,
1401                 onWakeUpCollection(_, Eq(mMockUidStatsCollector), Eq(mMockProcStatCollector)))
1402             .Times(0);
1403 
1404     ASSERT_RESULT_OK(mLooperStub->pollCache());
1405 
1406     ASSERT_EQ(mLooperStub->numSecondsElapsed(), 0) << "Custom collection didn't start immediately";
1407     ASSERT_EQ(mServicePeer->getCurrCollectionEvent(), EventType::CUSTOM_COLLECTION)
1408             << "Invalid collection event";
1409 
1410     // Custom collection while suspend exit signal is received
1411     ASSERT_RESULT_OK(mService->onSuspendExit());
1412 
1413     // Continued custom collection
1414     ASSERT_RESULT_OK(mLooperStub->pollCache());
1415 
1416     ASSERT_EQ(mLooperStub->numSecondsElapsed(), kTestCustomCollectionInterval.count())
1417             << "Subsequent custom collection didn't happen at "
1418             << kTestCustomCollectionInterval.count() << " seconds interval";
1419     ASSERT_EQ(mServicePeer->getCurrCollectionEvent(), EventType::CUSTOM_COLLECTION)
1420             << "Invalid collection event";
1421     ASSERT_NO_FATAL_FAILURE(verifyAndClearExpectations());
1422 }
1423 
TEST_F(WatchdogPerfServiceTest,TestPeriodicMonitorRequestsCollection)1424 TEST_F(WatchdogPerfServiceTest, TestPeriodicMonitorRequestsCollection) {
1425     ASSERT_NO_FATAL_FAILURE(startService());
1426 
1427     ASSERT_NO_FATAL_FAILURE(startPeriodicCollection());
1428 
1429     // Periodic monitor issuing an alert to start new collection.
1430     EXPECT_CALL(*mMockProcDiskStatsCollector, collect()).Times(1);
1431     EXPECT_CALL(*mMockDataProcessor, onPeriodicMonitor(_, Eq(mMockProcDiskStatsCollector), _))
1432             .WillOnce([&](auto, auto, const auto& alertHandler) -> Result<void> {
1433                 alertHandler();
1434                 return {};
1435             });
1436 
1437     ASSERT_RESULT_OK(mLooperStub->pollCache());
1438 
1439     ASSERT_EQ(mLooperStub->numSecondsElapsed(), kTestPeriodicMonitorInterval.count())
1440             << "First periodic monitor didn't happen at " << kTestPeriodicMonitorInterval.count()
1441             << " seconds interval";
1442     ASSERT_NO_FATAL_FAILURE(verifyAndClearExpectations());
1443 
1444     EXPECT_CALL(*mMockUidStatsCollector, collect()).Times(1);
1445     EXPECT_CALL(*mMockProcStatCollector, collect()).Times(1);
1446     EXPECT_CALL(*mMockDataProcessor,
1447                 onPeriodicCollection(_, SystemState::NORMAL_MODE, Eq(mMockUidStatsCollector),
1448                                      Eq(mMockProcStatCollector), _))
1449             .Times(1);
1450 
1451     ASSERT_RESULT_OK(mLooperStub->pollCache());
1452 
1453     ASSERT_EQ(mLooperStub->numSecondsElapsed(), 0)
1454             << "First periodic collection didn't happen immediately after the alert";
1455 
1456     ASSERT_NO_FATAL_FAILURE(verifyAndClearExpectations());
1457 
1458     EXPECT_CALL(*mMockDataProcessor, terminate()).Times(1);
1459 }
1460 
TEST_F(WatchdogPerfServiceTest,TestShutdownEnter)1461 TEST_F(WatchdogPerfServiceTest, TestShutdownEnter) {
1462     ASSERT_NO_FATAL_FAILURE(startService());
1463 
1464     // Start boot-time collection
1465     EXPECT_CALL(*mMockUidStatsCollector, collect()).Times(1);
1466     EXPECT_CALL(*mMockProcStatCollector, collect()).Times(1);
1467     EXPECT_CALL(*mMockDataProcessor,
1468                 onBoottimeCollection(_, Eq(mMockUidStatsCollector), Eq(mMockProcStatCollector), _))
1469             .Times(1);
1470 
1471     ASSERT_RESULT_OK(mLooperStub->pollCache());
1472 
1473     ASSERT_EQ(mLooperStub->numSecondsElapsed(), 0)
1474             << "Boot-time collection didn't start immediately";
1475     ASSERT_EQ(mServicePeer->getCurrCollectionEvent(), EventType::BOOT_TIME_COLLECTION)
1476             << "Invalid collection event";
1477     ASSERT_NO_FATAL_FAILURE(verifyAndClearExpectations());
1478 
1479     ASSERT_RESULT_OK(mService->onShutdownEnter());
1480 
1481     // Switch to periodic collection
1482     EXPECT_CALL(*mMockUidStatsCollector, collect()).Times(1);
1483     EXPECT_CALL(*mMockProcStatCollector, collect()).Times(1);
1484     EXPECT_CALL(*mMockDataProcessor,
1485                 onPeriodicCollection(_, SystemState::NORMAL_MODE, Eq(mMockUidStatsCollector),
1486                                      Eq(mMockProcStatCollector), _))
1487             .Times(1);
1488 
1489     ASSERT_RESULT_OK(mLooperStub->pollCache());
1490 
1491     ASSERT_EQ(mLooperStub->numSecondsElapsed(), 0)
1492             << "Periodic collection didn't start immediately after receiving shutdown enter signal";
1493     ASSERT_EQ(mServicePeer->getCurrCollectionEvent(), EventType::PERIODIC_COLLECTION)
1494             << "Invalid collection event";
1495     ASSERT_NO_FATAL_FAILURE(verifyAndClearExpectations());
1496 }
1497 
TEST_F(WatchdogPerfServiceTest,TestShutdownEnterWithCustomCollection)1498 TEST_F(WatchdogPerfServiceTest, TestShutdownEnterWithCustomCollection) {
1499     ASSERT_NO_FATAL_FAILURE(startService());
1500 
1501     ASSERT_NO_FATAL_FAILURE(startPeriodicCollection());
1502 
1503     // Start custom collection
1504     std::string customCollectionIntervalStr = std::to_string(kTestCustomCollectionInterval.count());
1505     std::string customCollectionDurationStr = std::to_string(kTestCustomCollectionDuration.count());
1506     const char* firstArgs[] = {kStartCustomCollectionFlag, kIntervalFlag,
1507                                customCollectionIntervalStr.c_str(), kMaxDurationFlag,
1508                                customCollectionDurationStr.c_str()};
1509 
1510     ASSERT_RESULT_OK(mService->onCustomCollection(-1, firstArgs, /*numArgs=*/5));
1511 
1512     EXPECT_CALL(*mMockUidStatsCollector, collect()).Times(1);
1513     EXPECT_CALL(*mMockProcStatCollector, collect()).Times(1);
1514     EXPECT_CALL(*mMockDataProcessor,
1515                 onCustomCollection(_, SystemState::NORMAL_MODE, _, Eq(mMockUidStatsCollector),
1516                                    Eq(mMockProcStatCollector), _))
1517             .Times(1);
1518 
1519     ASSERT_RESULT_OK(mLooperStub->pollCache());
1520 
1521     ASSERT_EQ(mLooperStub->numSecondsElapsed(), 0) << "Custom collection didn't start immediately";
1522     ASSERT_EQ(mServicePeer->getCurrCollectionEvent(), EventType::CUSTOM_COLLECTION)
1523             << "Invalid collection event";
1524     ASSERT_NO_FATAL_FAILURE(verifyAndClearExpectations());
1525 
1526     // Suspend in middle of custom collection
1527     ASSERT_RESULT_OK(mService->onShutdownEnter());
1528 
1529     // Custom collection
1530     EXPECT_CALL(*mMockUidStatsCollector, collect()).Times(1);
1531     EXPECT_CALL(*mMockProcStatCollector, collect()).Times(1);
1532     EXPECT_CALL(*mMockDataProcessor,
1533                 onCustomCollection(_, SystemState::NORMAL_MODE, _, Eq(mMockUidStatsCollector),
1534                                    Eq(mMockProcStatCollector), _))
1535             .Times(1);
1536 
1537     ASSERT_RESULT_OK(mLooperStub->pollCache());
1538 
1539     ASSERT_EQ(mLooperStub->numSecondsElapsed(), kTestCustomCollectionInterval.count())
1540             << "Subsequent custom collection didn't happen at "
1541             << kTestCustomCollectionInterval.count() << " seconds interval";
1542     ASSERT_EQ(mServicePeer->getCurrCollectionEvent(), EventType::CUSTOM_COLLECTION)
1543             << "Invalid collection event";
1544     ASSERT_NO_FATAL_FAILURE(verifyAndClearExpectations());
1545 }
1546 
TEST_F(WatchdogPerfServiceTest,TestSystemStateSwitch)1547 TEST_F(WatchdogPerfServiceTest, TestSystemStateSwitch) {
1548     ASSERT_NO_FATAL_FAILURE(startService());
1549 
1550     ASSERT_NO_FATAL_FAILURE(startPeriodicCollection());
1551     ASSERT_NO_FATAL_FAILURE(skipPeriodicMonitorEvents());
1552 
1553     EXPECT_CALL(*mMockDataProcessor, onPeriodicCollection(_, SystemState::NORMAL_MODE, _, _, _))
1554             .Times(1);
1555 
1556     ASSERT_RESULT_OK(mLooperStub->pollCache());
1557 
1558     ASSERT_NO_FATAL_FAILURE(verifyAndClearExpectations());
1559 
1560     ASSERT_NO_FATAL_FAILURE(skipPeriodicMonitorEvents());
1561 
1562     mService->setSystemState(SystemState::GARAGE_MODE);
1563 
1564     EXPECT_CALL(*mMockDataProcessor, onPeriodicCollection(_, SystemState::GARAGE_MODE, _, _, _))
1565             .Times(1);
1566 
1567     ASSERT_RESULT_OK(mLooperStub->pollCache());
1568 
1569     ASSERT_NO_FATAL_FAILURE(verifyAndClearExpectations());
1570 
1571     ASSERT_NO_FATAL_FAILURE(skipPeriodicMonitorEvents());
1572 
1573     mService->setSystemState(SystemState::NORMAL_MODE);
1574 
1575     EXPECT_CALL(*mMockDataProcessor, onPeriodicCollection(_, SystemState::NORMAL_MODE, _, _, _))
1576             .Times(1);
1577 
1578     ASSERT_RESULT_OK(mLooperStub->pollCache());
1579 
1580     ASSERT_NO_FATAL_FAILURE(verifyAndClearExpectations());
1581 
1582     EXPECT_CALL(*mMockDataProcessor, terminate()).Times(1);
1583 }
1584 
TEST_F(WatchdogPerfServiceTest,TestHandlesInvalidDumpArguments)1585 TEST_F(WatchdogPerfServiceTest, TestHandlesInvalidDumpArguments) {
1586     ASSERT_NO_FATAL_FAILURE(startService());
1587 
1588     ASSERT_NO_FATAL_FAILURE(startPeriodicCollection());
1589 
1590     const char* firstArgs[] = {kStartCustomCollectionFlag, "Invalid flag", "Invalid value"};
1591 
1592     ASSERT_FALSE(mService->onCustomCollection(-1, firstArgs, /*numArgs=*/3).ok());
1593 
1594     const char* secondArgs[] = {kStartCustomCollectionFlag, kIntervalFlag, "Invalid interval"};
1595 
1596     ASSERT_FALSE(mService->onCustomCollection(-1, secondArgs, /*numArgs=*/3).ok());
1597 
1598     const char* thirdArgs[] = {kStartCustomCollectionFlag, kMaxDurationFlag, "Invalid duration"};
1599 
1600     ASSERT_FALSE(mService->onCustomCollection(-1, thirdArgs, /*numArgs=*/3).ok());
1601 
1602     const char* fourthArgs[] = {kEndCustomCollectionFlag, kMaxDurationFlag, "10"};
1603 
1604     ASSERT_FALSE(mService->onCustomCollection(-1, fourthArgs, /*numArgs=*/3).ok());
1605 
1606     const char* fifthArgs[] = {"Invalid flag"};
1607 
1608     ASSERT_FALSE(mService->onCustomCollection(-1, fifthArgs, /*numArgs=*/1).ok());
1609 }
1610 
TEST_F(WatchdogPerfServiceTest,TestOnCarWatchdogServiceRegistered)1611 TEST_F(WatchdogPerfServiceTest, TestOnCarWatchdogServiceRegistered) {
1612     ASSERT_NO_FATAL_FAILURE(startService());
1613     ASSERT_NO_FATAL_FAILURE(startPeriodicCollection());
1614     ASSERT_NO_FATAL_FAILURE(skipPeriodicMonitorEvents());
1615     ASSERT_NO_FATAL_FAILURE(skipPeriodicCollection());
1616 
1617     // Expect because the next pollCache call will result in an onPeriodicMonitor call
1618     // because no message is sent to process unsent resource stats
1619     EXPECT_CALL(*mMockDataProcessor, onPeriodicMonitor(_, _, _)).Times(1);
1620     EXPECT_CALL(*mMockDataProcessor, onCarWatchdogServiceRegistered()).Times(1);
1621     EXPECT_CALL(*mMockWatchdogServiceHelper, onLatestResourceStats(_)).Times(0);
1622 
1623     mService->onCarWatchdogServiceRegistered();
1624 
1625     ASSERT_RESULT_OK(mLooperStub->pollCache());
1626 
1627     ASSERT_NO_FATAL_FAILURE(verifyAndClearExpectations());
1628 }
1629 
TEST_F(WatchdogPerfServiceTest,TestOnCarWatchdogServiceRegisteredWithUnsentResourceStats)1630 TEST_F(WatchdogPerfServiceTest, TestOnCarWatchdogServiceRegisteredWithUnsentResourceStats) {
1631     ASSERT_NO_FATAL_FAILURE(startService());
1632     ASSERT_NO_FATAL_FAILURE(startPeriodicCollection());
1633     ASSERT_NO_FATAL_FAILURE(skipPeriodicMonitorEvents());
1634 
1635     EXPECT_CALL(*mMockUidStatsCollector, collect()).Times(1);
1636     EXPECT_CALL(*mMockProcStatCollector, collect()).Times(1);
1637     EXPECT_CALL(*mMockDataProcessor, onCarWatchdogServiceRegistered()).Times(1);
1638     EXPECT_CALL(*mMockDataProcessor,
1639                 onPeriodicCollection(_, SystemState::NORMAL_MODE, Eq(mMockUidStatsCollector),
1640                                      Eq(mMockProcStatCollector), _))
1641             .Times(1)
1642             .WillOnce([&](auto, auto, auto, auto, auto* resourceStats) -> Result<void> {
1643                 resourceStats->resourceOveruseStats = std::make_optional<ResourceOveruseStats>({});
1644                 return {};
1645             });
1646     EXPECT_CALL(*mMockWatchdogServiceHelper, isServiceConnected()).Times(1).WillOnce(Return(false));
1647     // Called when CarWatchdogService is registered
1648     EXPECT_CALL(*mMockWatchdogServiceHelper, onLatestResourceStats(_))
1649             .Times(1)
1650             .WillOnce(Return(ByMove(ndk::ScopedAStatus::ok())));
1651 
1652     // Handle the periodic collection
1653     ASSERT_RESULT_OK(mLooperStub->pollCache());
1654 
1655     mService->onCarWatchdogServiceRegistered();
1656 
1657     ASSERT_RESULT_OK(mLooperStub->pollCache());
1658 
1659     ASSERT_NO_FATAL_FAILURE(verifyAndClearExpectations());
1660 }
1661 
TEST_F(WatchdogPerfServiceTest,TestUnsentResourceStatsEviction)1662 TEST_F(WatchdogPerfServiceTest, TestUnsentResourceStatsEviction) {
1663     ASSERT_NO_FATAL_FAILURE(startService());
1664     ASSERT_NO_FATAL_FAILURE(startPeriodicCollection());
1665     ASSERT_NO_FATAL_FAILURE(skipPeriodicMonitorEvents());
1666 
1667     EXPECT_CALL(*mMockUidStatsCollector, collect()).Times(1);
1668     EXPECT_CALL(*mMockProcStatCollector, collect()).Times(1);
1669     EXPECT_CALL(*mMockDataProcessor, onCarWatchdogServiceRegistered()).Times(1);
1670     EXPECT_CALL(*mMockDataProcessor,
1671                 onPeriodicCollection(_, SystemState::NORMAL_MODE, Eq(mMockUidStatsCollector),
1672                                      Eq(mMockProcStatCollector), _))
1673             .Times(1)
1674             .WillOnce([&](auto, auto, auto, auto, auto* resourceStats) -> Result<void> {
1675                 resourceStats->resourceOveruseStats = std::make_optional<ResourceOveruseStats>({});
1676                 return {};
1677             });
1678     EXPECT_CALL(*mMockWatchdogServiceHelper, isServiceConnected()).Times(1).WillOnce(Return(false));
1679     // Should not be called once CarWatchdogService is registered
1680     EXPECT_CALL(*mMockWatchdogServiceHelper, onLatestResourceStats(_)).Times(0);
1681 
1682     // Handle the periodic collection
1683     ASSERT_RESULT_OK(mLooperStub->pollCache());
1684 
1685     // Increment time so that the unsent resource stat is evicted
1686     mLooperStub->incrementTime(kPrevUnsentResourceStatsMaxDurationNs);
1687 
1688     mService->onCarWatchdogServiceRegistered();
1689 
1690     ASSERT_RESULT_OK(mLooperStub->pollCache());
1691 
1692     ASSERT_NO_FATAL_FAILURE(verifyAndClearExpectations());
1693 }
1694 
TEST_F(WatchdogPerfServiceTest,TestUnsentResourceStatsMaxCacheSize)1695 TEST_F(WatchdogPerfServiceTest, TestUnsentResourceStatsMaxCacheSize) {
1696     ASSERT_NO_FATAL_FAILURE(startService());
1697     ASSERT_NO_FATAL_FAILURE(startPeriodicCollection());
1698     ASSERT_NO_FATAL_FAILURE(removePeriodicMonitorEvents());
1699 
1700     int32_t maxCacheSize = 10;
1701 
1702     std::vector<ResourceStats> expectedResourceStats = {};
1703 
1704     // Handle the periodic collections.
1705     for (int64_t i = 0; i < maxCacheSize; ++i) {
1706         expectedResourceStats.push_back(ResourceStats{
1707                 .resourceUsageStats = std::make_optional<ResourceUsageStats>({
1708                         .startTimeEpochMillis = i,
1709                 }),
1710         });
1711 
1712         EXPECT_CALL(*mMockUidStatsCollector, collect()).Times(1);
1713         EXPECT_CALL(*mMockProcStatCollector, collect()).Times(1);
1714         EXPECT_CALL(*mMockDataProcessor,
1715                     onPeriodicCollection(_, SystemState::NORMAL_MODE, Eq(mMockUidStatsCollector),
1716                                          Eq(mMockProcStatCollector), _))
1717                 .Times(1)
1718                 .WillOnce([&](auto, auto, auto, auto, auto* resourceStats) -> Result<void> {
1719                     resourceStats->resourceUsageStats =
1720                             expectedResourceStats.back().resourceUsageStats;
1721                     return {};
1722                 });
1723         EXPECT_CALL(*mMockWatchdogServiceHelper, isServiceConnected())
1724                 .Times(1)
1725                 .WillRepeatedly(Return(false));
1726 
1727         ASSERT_RESULT_OK(mLooperStub->pollCache());
1728     }
1729 
1730     ASSERT_NO_FATAL_FAILURE(verifyAndClearExpectations());
1731 
1732     // The first resource stats should be evicted.
1733     expectedResourceStats.erase(expectedResourceStats.begin());
1734 
1735     expectedResourceStats.push_back(ResourceStats{
1736             .resourceUsageStats = std::make_optional<ResourceUsageStats>({
1737                     .startTimeEpochMillis = maxCacheSize,
1738             }),
1739     });
1740 
1741     std::vector<ResourceStats> actualResourceStats;
1742 
1743     EXPECT_CALL(*mMockUidStatsCollector, collect()).Times(1);
1744     EXPECT_CALL(*mMockProcStatCollector, collect()).Times(1);
1745     EXPECT_CALL(*mMockDataProcessor,
1746                 onPeriodicCollection(_, SystemState::NORMAL_MODE, Eq(mMockUidStatsCollector),
1747                                      Eq(mMockProcStatCollector), _))
1748             .Times(1)
1749             .WillRepeatedly([&](auto, auto, auto, auto, auto* resourceStats) -> Result<void> {
1750                 resourceStats->resourceUsageStats = expectedResourceStats.back().resourceUsageStats;
1751                 return {};
1752             });
1753     EXPECT_CALL(*mMockWatchdogServiceHelper, isServiceConnected()).Times(1).WillOnce(Return(true));
1754     EXPECT_CALL(*mMockWatchdogServiceHelper, onLatestResourceStats(_))
1755             .Times(1)
1756             .WillOnce([&](auto unsentStats) -> ndk::ScopedAStatus {
1757                 actualResourceStats = unsentStats;
1758                 return ndk::ScopedAStatus::ok();
1759             });
1760 
1761     // Handle an extra periodic collection, where unsent resource cache should
1762     // evict the oldest stats.
1763     ASSERT_RESULT_OK(mLooperStub->pollCache());
1764 
1765     // Handle the SEND_RESOURCE_STATS message.
1766     ASSERT_RESULT_OK(mLooperStub->pollCache());
1767 
1768     ASSERT_NO_FATAL_FAILURE(verifyAndClearExpectations());
1769     ASSERT_EQ(actualResourceStats, expectedResourceStats)
1770             << "Expected: " << toString(expectedResourceStats)
1771             << "\nActual: " << toString(actualResourceStats);
1772 }
1773 
1774 }  // namespace watchdog
1775 }  // namespace automotive
1776 }  // namespace android
1777