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