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