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