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