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