1 // Copyright (C) 2022 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include <gmock/gmock.h>
16 #include <gtest/gtest.h>
17 
18 #include "aemu/base/HealthMonitor.h"
19 
20 #include <chrono>
21 #include <limits>
22 #include <vector>
23 
24 #include "aemu/base/testing/TestClock.h"
25 #include "aemu/base/Metrics.h"
26 
27 namespace emugl {
28 
29 using android::base::MetricEventHang;
30 using android::base::MetricEventType;
31 using android::base::MetricEventUnHang;
32 using android::base::MetricsLogger;
33 using android::base::TestClock;
34 using emugl::kDefaultIntervalMs;
35 using emugl::kDefaultTimeoutMs;
36 using ::testing::_;
37 using ::testing::AllOf;
38 using ::testing::ByMove;
39 using ::testing::Contains;
40 using ::testing::DoAll;
41 using ::testing::Eq;
42 using ::testing::Field;
43 using ::testing::Ge;
44 using ::testing::HasSubstr;
45 using ::testing::InSequence;
46 using ::testing::IsNull;
47 using ::testing::Key;
48 using ::testing::Le;
49 using ::testing::MockFunction;
50 using ::testing::Ne;
51 using ::testing::Optional;
52 using ::testing::Pair;
53 using ::testing::Pointee;
54 using ::testing::Ref;
55 using ::testing::Return;
56 using ::testing::SaveArg;
57 using ::testing::StrEq;
58 using ::testing::Test;
59 using ::testing::VariantWith;
60 
61 class HealthMonitorTest : public Test {
62    protected:
63     class MockLogger : public MetricsLogger {
64        public:
65         MOCK_METHOD(void, logMetricEvent, (MetricEventType eventType), (override));
66         MOCK_METHOD(void, setCrashAnnotation, (const char* key, const char* value),
67                     (override));  // Unused
68     };
69 
HealthMonitorTest()70     HealthMonitorTest() : healthMonitor(logger, SToMs(1)) { TestClock::reset(); }
71 
~HealthMonitorTest()72     ~HealthMonitorTest() { step(1); }
73 
step(int seconds)74     void step(int seconds) {
75         for (int i = 0; i < seconds; i++) {
76             TestClock::advance(1);
77             healthMonitor.poll().wait();
78         }
79     }
80 
SToMs(int seconds)81     int SToMs(int seconds) { return seconds * 1'000; }
82 
83     int defaultHangThresholdS = 5;
84     MockLogger logger;
85     HealthMonitor<TestClock> healthMonitor;
86 };
87 
TEST_F(HealthMonitorTest,badTimeoutTimeTest)88 TEST_F(HealthMonitorTest, badTimeoutTimeTest) {
89     int expectedHangThresholdS = 2;
90     int expectedHangDurationS = 5;
91     {
92         InSequence s;
93         EXPECT_CALL(logger, logMetricEvent(VariantWith<MetricEventHang>(_))).Times(1);
94         EXPECT_CALL(logger,
95                     logMetricEvent(VariantWith<MetricEventUnHang>(Field(
96                         &MetricEventUnHang::hung_ms, AllOf(Ge(SToMs(expectedHangDurationS - 1)),
97                                                            Le(SToMs(expectedHangDurationS + 1)))))))
98             .Times(1);
99     }
100 
101     auto id =
102         healthMonitor.startMonitoringTask(std::make_unique<EventHangMetadata>(), std::nullopt, 1);
103     step(expectedHangThresholdS + expectedHangDurationS);
104     healthMonitor.stopMonitoringTask(id);
105 }
106 
TEST_F(HealthMonitorTest,startTouchEndEventsTest)107 TEST_F(HealthMonitorTest, startTouchEndEventsTest) {
108     EXPECT_CALL(logger, logMetricEvent(_)).Times(0);
109 
110     auto id = healthMonitor.startMonitoringTask(std::make_unique<EventHangMetadata>());
111     step(defaultHangThresholdS - 1);
112     healthMonitor.touchMonitoredTask(id);
113     step(defaultHangThresholdS - 1);
114     healthMonitor.stopMonitoringTask(id);
115 }
116 
TEST_F(HealthMonitorTest,hangingStartEventTest)117 TEST_F(HealthMonitorTest, hangingStartEventTest) {
118     EXPECT_CALL(logger, logMetricEvent(VariantWith<MetricEventHang>(_))).Times(1);
119 
120     healthMonitor.startMonitoringTask(std::make_unique<EventHangMetadata>());
121     step(defaultHangThresholdS + 1);
122 }
123 
TEST_F(HealthMonitorTest,lateEndEventTest)124 TEST_F(HealthMonitorTest, lateEndEventTest) {
125     int expectedHangDurationS = 5;
126     {
127         InSequence s;
128         EXPECT_CALL(logger, logMetricEvent(VariantWith<MetricEventHang>(_))).Times(1);
129         EXPECT_CALL(logger,
130                     logMetricEvent(VariantWith<MetricEventUnHang>(Field(
131                         &MetricEventUnHang::hung_ms, AllOf(Ge(SToMs(expectedHangDurationS - 1)),
132                                                            Le(SToMs(expectedHangDurationS + 1)))))))
133             .Times(1);
134     }
135 
136     auto id = healthMonitor.startMonitoringTask(std::make_unique<EventHangMetadata>());
137     step(defaultHangThresholdS + expectedHangDurationS);
138     healthMonitor.stopMonitoringTask(id);
139 }
140 
TEST_F(HealthMonitorTest,taskHangsTwiceTest)141 TEST_F(HealthMonitorTest, taskHangsTwiceTest) {
142     int expectedHangDurationS1 = 3;
143     int expectedHangDurationS2 = 5;
144     {
145         InSequence s;
146         EXPECT_CALL(logger, logMetricEvent(VariantWith<MetricEventHang>(_))).Times(1);
147         EXPECT_CALL(
148             logger,
149             logMetricEvent(VariantWith<MetricEventUnHang>(
150                 Field(&MetricEventUnHang::hung_ms, AllOf(Ge(SToMs(expectedHangDurationS1 - 1)),
151                                                          Le(SToMs(expectedHangDurationS1 + 1)))))))
152             .Times(1);
153         EXPECT_CALL(logger, logMetricEvent(VariantWith<MetricEventHang>(_))).Times(1);
154         EXPECT_CALL(
155             logger,
156             logMetricEvent(VariantWith<MetricEventUnHang>(
157                 Field(&MetricEventUnHang::hung_ms, AllOf(Ge(SToMs(expectedHangDurationS2 - 1)),
158                                                          Le(SToMs(expectedHangDurationS2 + 1)))))))
159             .Times(1);
160     }
161 
162     auto id = healthMonitor.startMonitoringTask(std::make_unique<EventHangMetadata>());
163     step(defaultHangThresholdS + expectedHangDurationS1);
164     healthMonitor.touchMonitoredTask(id);
165     step(defaultHangThresholdS + expectedHangDurationS2);
166     healthMonitor.stopMonitoringTask(id);
167 }
168 
TEST_F(HealthMonitorTest,taskHangsThriceTest)169 TEST_F(HealthMonitorTest, taskHangsThriceTest) {
170     int expectedHangDurationS1 = 3;
171     int expectedHangDurationS2 = 5;
172     int expectedHangDurationS3 = 3;
173     {
174         InSequence s;
175         EXPECT_CALL(logger, logMetricEvent(VariantWith<MetricEventHang>(_))).Times(1);
176         EXPECT_CALL(
177             logger,
178             logMetricEvent(VariantWith<MetricEventUnHang>(
179                 Field(&MetricEventUnHang::hung_ms, AllOf(Ge(SToMs(expectedHangDurationS1 - 1)),
180                                                          Le(SToMs(expectedHangDurationS1 + 1)))))))
181             .Times(1);
182         EXPECT_CALL(logger, logMetricEvent(VariantWith<MetricEventHang>(_))).Times(1);
183         EXPECT_CALL(
184             logger,
185             logMetricEvent(VariantWith<MetricEventUnHang>(
186                 Field(&MetricEventUnHang::hung_ms, AllOf(Ge(SToMs(expectedHangDurationS2 - 1)),
187                                                          Le(SToMs(expectedHangDurationS2 + 1)))))))
188             .Times(1);
189         EXPECT_CALL(logger, logMetricEvent(VariantWith<MetricEventHang>(_))).Times(1);
190         EXPECT_CALL(
191             logger,
192             logMetricEvent(VariantWith<MetricEventUnHang>(
193                 Field(&MetricEventUnHang::hung_ms, AllOf(Ge(SToMs(expectedHangDurationS3 - 1)),
194                                                          Le(SToMs(expectedHangDurationS3 + 1)))))))
195             .Times(1);
196     }
197 
198     auto id = healthMonitor.startMonitoringTask(std::make_unique<EventHangMetadata>());
199     step(defaultHangThresholdS + expectedHangDurationS1);
200     healthMonitor.touchMonitoredTask(id);
201     step(defaultHangThresholdS + expectedHangDurationS2);
202     healthMonitor.touchMonitoredTask(id);
203     step(defaultHangThresholdS + expectedHangDurationS3);
204     healthMonitor.stopMonitoringTask(id);
205 }
206 
TEST_F(HealthMonitorTest,multipleHangingTasksTest)207 TEST_F(HealthMonitorTest, multipleHangingTasksTest) {
208     {
209         InSequence s;
210         EXPECT_CALL(logger, logMetricEvent(VariantWith<MetricEventHang>(
211                                 Field(&MetricEventHang::otherHungTasks, 0))))
212             .Times(1);
213         EXPECT_CALL(logger, logMetricEvent(VariantWith<MetricEventHang>(
214                                 Field(&MetricEventHang::otherHungTasks, 1))))
215             .Times(1);
216         EXPECT_CALL(logger, logMetricEvent(VariantWith<MetricEventHang>(
217                                 Field(&MetricEventHang::otherHungTasks, 2))))
218             .Times(1);
219         EXPECT_CALL(logger, logMetricEvent(VariantWith<MetricEventHang>(
220                                 Field(&MetricEventHang::otherHungTasks, 3))))
221             .Times(1);
222     }
223 
224     healthMonitor.startMonitoringTask(std::make_unique<EventHangMetadata>());
225     TestClock::advance(0.2);
226     healthMonitor.startMonitoringTask(std::make_unique<EventHangMetadata>());
227     TestClock::advance(0.2);
228     healthMonitor.startMonitoringTask(std::make_unique<EventHangMetadata>());
229     TestClock::advance(0.2);
230     healthMonitor.startMonitoringTask(std::make_unique<EventHangMetadata>());
231     step(defaultHangThresholdS + 1);
232 }
233 
TEST_F(HealthMonitorTest,oneHangingTaskOutOfTwoTest)234 TEST_F(HealthMonitorTest, oneHangingTaskOutOfTwoTest) {
235     EXPECT_CALL(logger, logMetricEvent(VariantWith<MetricEventHang>(_))).Times(1);
236 
237     healthMonitor.startMonitoringTask(std::make_unique<EventHangMetadata>());
238     auto id2 = healthMonitor.startMonitoringTask(std::make_unique<EventHangMetadata>());
239     step(defaultHangThresholdS - 1);
240     healthMonitor.stopMonitoringTask(id2);
241     step(2);
242 }
243 
TEST_F(HealthMonitorTest,twoTasksHangNonOverlappingTest)244 TEST_F(HealthMonitorTest, twoTasksHangNonOverlappingTest) {
245     int expectedHangDurationS1 = 5;
246     int hangThresholdS2 = 10;
247     int expectedHangDurationS2 = 2;
248     {
249         InSequence s;
250         EXPECT_CALL(logger, logMetricEvent(VariantWith<MetricEventHang>(_))).Times(1);
251         EXPECT_CALL(
252             logger,
253             logMetricEvent(VariantWith<MetricEventUnHang>(
254                 Field(&MetricEventUnHang::hung_ms, AllOf(Ge(SToMs(expectedHangDurationS1 - 1)),
255                                                          Le(SToMs(expectedHangDurationS1 + 1)))))))
256             .Times(1);
257         EXPECT_CALL(logger, logMetricEvent(VariantWith<MetricEventHang>(_))).Times(1);
258         EXPECT_CALL(
259             logger,
260             logMetricEvent(VariantWith<MetricEventUnHang>(
261                 Field(&MetricEventUnHang::hung_ms, AllOf(Ge(SToMs(expectedHangDurationS2 - 1)),
262                                                          Le(SToMs(expectedHangDurationS2 + 1)))))))
263             .Times(1);
264     }
265 
266     auto id = healthMonitor.startMonitoringTask(std::make_unique<EventHangMetadata>());
267     step(defaultHangThresholdS + expectedHangDurationS1);
268     healthMonitor.stopMonitoringTask(id);
269     step(1);
270     id = healthMonitor.startMonitoringTask(std::make_unique<EventHangMetadata>(), std::nullopt,
271                                            SToMs(hangThresholdS2));
272     step(hangThresholdS2 + expectedHangDurationS2);
273     healthMonitor.stopMonitoringTask(id);
274 }
275 
TEST_F(HealthMonitorTest,twoTasksHangOverlappingTest)276 TEST_F(HealthMonitorTest, twoTasksHangOverlappingTest) {
277     int expectedHangDurationS1 = 5;
278     int expectedHangDurationS2 = 8;
279     {
280         InSequence s;
281         EXPECT_CALL(logger, logMetricEvent(VariantWith<MetricEventHang>(
282                                 Field(&MetricEventHang::otherHungTasks, 0))))
283             .Times(1);
284         EXPECT_CALL(logger, logMetricEvent(VariantWith<MetricEventHang>(
285                                 Field(&MetricEventHang::otherHungTasks, 1))))
286             .Times(1);
287         EXPECT_CALL(
288             logger,
289             logMetricEvent(VariantWith<MetricEventUnHang>(
290                 Field(&MetricEventUnHang::hung_ms, AllOf(Ge(SToMs(expectedHangDurationS1 - 1)),
291                                                          Le(SToMs(expectedHangDurationS1 + 1)))))))
292             .Times(1);
293         EXPECT_CALL(
294             logger,
295             logMetricEvent(VariantWith<MetricEventUnHang>(
296                 Field(&MetricEventUnHang::hung_ms, AllOf(Ge(SToMs(expectedHangDurationS2 - 1)),
297                                                          Le(SToMs(expectedHangDurationS2 + 1)))))))
298             .Times(1);
299     }
300 
301     auto id1 = healthMonitor.startMonitoringTask(std::make_unique<EventHangMetadata>());
302     step(3);
303     auto id2 = healthMonitor.startMonitoringTask(std::make_unique<EventHangMetadata>());
304     step(7);
305     healthMonitor.stopMonitoringTask(id1);
306     step(5);
307     healthMonitor.stopMonitoringTask(id2);
308 }
309 
TEST_F(HealthMonitorTest,simultaneousTasks)310 TEST_F(HealthMonitorTest, simultaneousTasks) {
311     int expectedHangDurationS = 5;
312     {
313         InSequence s;
314         EXPECT_CALL(logger, logMetricEvent(VariantWith<MetricEventHang>(
315                                 Field(&MetricEventHang::otherHungTasks, 0))))
316             .Times(1);
317         EXPECT_CALL(logger, logMetricEvent(VariantWith<MetricEventHang>(
318                                 Field(&MetricEventHang::otherHungTasks, 1))))
319             .Times(1);
320         EXPECT_CALL(logger,
321                     logMetricEvent(VariantWith<MetricEventUnHang>(Field(
322                         &MetricEventUnHang::hung_ms, AllOf(Ge(SToMs(expectedHangDurationS - 1)),
323                                                            Le(SToMs(expectedHangDurationS + 1)))))))
324             .Times(1);
325         EXPECT_CALL(logger,
326                     logMetricEvent(VariantWith<MetricEventUnHang>(Field(
327                         &MetricEventUnHang::hung_ms, AllOf(Ge(SToMs(expectedHangDurationS - 1)),
328                                                            Le(SToMs(expectedHangDurationS + 1)))))))
329             .Times(1);
330     }
331     auto id1 = healthMonitor.startMonitoringTask(std::make_unique<EventHangMetadata>());
332     auto id2 = healthMonitor.startMonitoringTask(std::make_unique<EventHangMetadata>());
333     step(defaultHangThresholdS + expectedHangDurationS);
334     healthMonitor.stopMonitoringTask(id1);
335     healthMonitor.stopMonitoringTask(id2);
336 }
337 
TEST_F(HealthMonitorTest,taskHungWithAttachedCallback)338 TEST_F(HealthMonitorTest, taskHungWithAttachedCallback) {
339     MockFunction<std::unique_ptr<HangAnnotations>()> mockCallback;
340     std::unique_ptr<HangAnnotations> testAnnotations = std::make_unique<HangAnnotations>();
341     testAnnotations->insert({{"key1", "value1"}, {"key2", "value2"}});
342     int expectedHangDurationS = 5;
343     {
344         InSequence s;
345         EXPECT_CALL(mockCallback, Call()).WillOnce(Return(ByMove(std::move(testAnnotations))));
346         EXPECT_CALL(logger,
347                     logMetricEvent(VariantWith<MetricEventHang>(Field(
348                         &MetricEventHang::metadata,
349                         Field(&EventHangMetadata::data,
350                               Pointee(AllOf(Contains(Key("key1")), Contains(Key("key2")))))))))
351             .Times(1);
352         EXPECT_CALL(logger,
353                     logMetricEvent(VariantWith<MetricEventUnHang>(Field(
354                         &MetricEventUnHang::hung_ms, AllOf(Ge(SToMs(expectedHangDurationS - 1)),
355                                                            Le(SToMs(expectedHangDurationS + 1)))))))
356             .Times(1);
357     }
358     auto id = healthMonitor.startMonitoringTask(std::make_unique<EventHangMetadata>(),
359                                                 mockCallback.AsStdFunction());
360     step(defaultHangThresholdS + expectedHangDurationS);
361     healthMonitor.stopMonitoringTask(id);
362 }
363 
TEST_F(HealthMonitorTest,healthyTaskWithParent)364 TEST_F(HealthMonitorTest, healthyTaskWithParent) {
365     EXPECT_CALL(logger, logMetricEvent(_)).Times(0);
366 
367     auto id = healthMonitor.startMonitoringTask(std::make_unique<EventHangMetadata>());
368     step(defaultHangThresholdS - 1);
369     auto child = healthMonitor.startMonitoringTask(std::make_unique<EventHangMetadata>(),
370                                                    std::nullopt, kDefaultTimeoutMs, id);
371     step(defaultHangThresholdS - 1);
372     healthMonitor.stopMonitoringTask(child);
373     step(defaultHangThresholdS - 1);
374     healthMonitor.stopMonitoringTask(id);
375 }
376 
TEST_F(HealthMonitorTest,threeChainOfHungTasks)377 TEST_F(HealthMonitorTest, threeChainOfHungTasks) {
378     {
379         InSequence s;
380         EXPECT_CALL(logger, logMetricEvent(
381                                 VariantWith<MetricEventHang>(Field(&MetricEventHang::taskId, 2))))
382             .Times(1);
383         EXPECT_CALL(logger, logMetricEvent(
384                                 VariantWith<MetricEventHang>(Field(&MetricEventHang::taskId, 1))))
385             .Times(1);
386         EXPECT_CALL(logger, logMetricEvent(
387                                 VariantWith<MetricEventHang>(Field(&MetricEventHang::taskId, 0))))
388             .Times(1);
389         EXPECT_CALL(
390             logger,
391             logMetricEvent(VariantWith<MetricEventUnHang>(Field(&MetricEventUnHang::taskId, 2))))
392             .Times(1);
393         EXPECT_CALL(
394             logger,
395             logMetricEvent(VariantWith<MetricEventUnHang>(Field(&MetricEventUnHang::taskId, 1))))
396             .Times(1);
397         EXPECT_CALL(
398             logger,
399             logMetricEvent(VariantWith<MetricEventUnHang>(Field(&MetricEventUnHang::taskId, 0))))
400             .Times(1);
401     }
402 
403     auto id = healthMonitor.startMonitoringTask(std::make_unique<EventHangMetadata>());
404     step(defaultHangThresholdS - 1);
405     auto child = healthMonitor.startMonitoringTask(std::make_unique<EventHangMetadata>(),
406                                                    std::nullopt, kDefaultTimeoutMs, id);
407     step(defaultHangThresholdS - 1);
408     auto grandchild = healthMonitor.startMonitoringTask(std::make_unique<EventHangMetadata>(),
409                                                         std::nullopt, kDefaultTimeoutMs, child);
410     step(defaultHangThresholdS + 1);
411     healthMonitor.touchMonitoredTask(grandchild);
412     step(1);
413     healthMonitor.stopMonitoringTask(grandchild);
414     healthMonitor.stopMonitoringTask(child);
415     healthMonitor.stopMonitoringTask(id);
416 }
417 
TEST_F(HealthMonitorTest,parentEndsBeforeChild)418 TEST_F(HealthMonitorTest, parentEndsBeforeChild) {
419     {
420         InSequence s;
421         EXPECT_CALL(logger, logMetricEvent(
422                                 VariantWith<MetricEventHang>(Field(&MetricEventHang::taskId, 1))))
423             .Times(1);
424         EXPECT_CALL(
425             logger,
426             logMetricEvent(VariantWith<MetricEventUnHang>(Field(&MetricEventUnHang::taskId, 1))))
427             .Times(1);
428     }
429 
430     auto id = healthMonitor.startMonitoringTask(std::make_unique<EventHangMetadata>());
431     step(defaultHangThresholdS - 1);
432     auto child = healthMonitor.startMonitoringTask(std::make_unique<EventHangMetadata>(),
433                                                    std::nullopt, kDefaultTimeoutMs, id);
434     healthMonitor.stopMonitoringTask(id);
435     step(defaultHangThresholdS + 1);
436     healthMonitor.stopMonitoringTask(child);
437 }
438 
TEST_F(HealthMonitorTest,siblingsHangParentStillHealthy)439 TEST_F(HealthMonitorTest, siblingsHangParentStillHealthy) {
440     {
441         InSequence s;
442         EXPECT_CALL(logger, logMetricEvent(
443                                 VariantWith<MetricEventHang>(Field(&MetricEventHang::taskId, 1))))
444             .Times(1);
445         EXPECT_CALL(
446             logger,
447             logMetricEvent(VariantWith<MetricEventUnHang>(Field(&MetricEventUnHang::taskId, 1))))
448             .Times(1);
449         EXPECT_CALL(logger, logMetricEvent(
450                                 VariantWith<MetricEventHang>(Field(&MetricEventHang::taskId, 2))))
451             .Times(1);
452         EXPECT_CALL(
453             logger,
454             logMetricEvent(VariantWith<MetricEventUnHang>(Field(&MetricEventUnHang::taskId, 2))))
455             .Times(1);
456     }
457 
458     auto parent = healthMonitor.startMonitoringTask(std::make_unique<EventHangMetadata>());
459     step(defaultHangThresholdS - 1);
460     /* 1 */ auto child = healthMonitor.startMonitoringTask(std::make_unique<EventHangMetadata>(),
461                                                            std::nullopt, kDefaultTimeoutMs, parent);
462     step(defaultHangThresholdS - 1);
463     /* 2 */ auto secondChild = healthMonitor.startMonitoringTask(
464         std::make_unique<EventHangMetadata>(), std::nullopt, kDefaultTimeoutMs, parent);
465     step(2);
466     healthMonitor.stopMonitoringTask(child);
467     step(defaultHangThresholdS - 1);
468     healthMonitor.stopMonitoringTask(secondChild);
469     healthMonitor.stopMonitoringTask(parent);
470 }
471 
472 class MockHealthMonitor {
473    public:
474     using Id = uint32_t;
475     MOCK_METHOD(
476         Id, startMonitoringTask,
477         (std::unique_ptr<EventHangMetadata> metadata,
478          std::optional<std::function<std::unique_ptr<HangAnnotations>()>> onHangAnnotationsCallback,
479          uint64_t timeout, std::optional<Id>));
480 
481     MOCK_METHOD(void, touchMonitoredTask, (Id));
482     MOCK_METHOD(void, stopMonitoringTask, (Id));
483 };
484 
TEST(HealthMonitorWatchdogBuilderTest,NullPointerTest)485 TEST(HealthMonitorWatchdogBuilderTest, NullPointerTest) {
486     const char message[] = "test message";
487     MockHealthMonitor* monitor = nullptr;
488     auto builder = WATCHDOG_BUILDER(monitor, message);
489     auto watchdog = builder.build();
490     EXPECT_EQ(watchdog->release(), std::nullopt);
491 }
492 
TEST(HealthMonitorWatchdogBuilderTest,NullPointerCallbackTest)493 TEST(HealthMonitorWatchdogBuilderTest, NullPointerCallbackTest) {
494     const char message[] = "test message";
495     MockFunction<std::unique_ptr<HangAnnotations>()> mockOnHangCallback;
496     MockHealthMonitor* monitor = nullptr;
497     WATCHDOG_BUILDER(monitor, "test message")
498         .setOnHangCallback(mockOnHangCallback.AsStdFunction())
499         .build();
500     EXPECT_CALL(mockOnHangCallback, Call()).Times(0);
501 }
502 
TEST(HealthMonitorWatchdogBuilderTest,SimpleBuildTest)503 TEST(HealthMonitorWatchdogBuilderTest, SimpleBuildTest) {
504     // Test simple build function and default values.
505     MockHealthMonitor monitor;
506     MockHealthMonitor::Id taskId = 0x8261;
507 
508     const char message[] = "test message";
509     const int lineLowerBound = __LINE__;
510     auto builder = WATCHDOG_BUILDER(&monitor, message);
511     const int lineUpperBound = __LINE__;
512     auto metadataMatcher = AllOf(
513         Pointee(Field(&EventHangMetadata::file, StrEq(__FILE__))),
514         Pointee(Field(&EventHangMetadata::function, StrEq(__func__))),
515         Pointee(Field(&EventHangMetadata::msg, StrEq(message))),
516         Pointee(Field(&EventHangMetadata::line, AllOf(Ge(lineLowerBound), Le(lineUpperBound)))),
517         Pointee(Field(&EventHangMetadata::threadId, android::base::getCurrentThreadId())),
518         Pointee(Field(&EventHangMetadata::data, IsNull())),
519         Pointee(Field(&EventHangMetadata::hangType, EventHangMetadata::HangType::kOther)));
520     EXPECT_CALL(monitor,
521                 startMonitoringTask(metadataMatcher, Eq(std::nullopt), kDefaultTimeoutMs, _))
522         .Times(1)
523         .WillOnce(Return(taskId));
524     EXPECT_CALL(monitor, stopMonitoringTask(taskId)).Times(1);
525     builder.build();
526 }
527 
528 // Test different setters.
TEST(HealthMonitorWatchdogBuilderTest,HangTypeTest)529 TEST(HealthMonitorWatchdogBuilderTest, HangTypeTest) {
530     MockHealthMonitor monitor;
531     MockHealthMonitor::Id taskId = 0x7213;
532 
533     auto hangType = EventHangMetadata::HangType::kRenderThread;
534     EXPECT_CALL(monitor, startMonitoringTask(Pointee(Field(&EventHangMetadata::hangType, hangType)),
535                                              Eq(std::nullopt), kDefaultTimeoutMs, _))
536         .Times(1)
537         .WillOnce(Return(taskId));
538     EXPECT_CALL(monitor, stopMonitoringTask(taskId)).Times(1);
539     WATCHDOG_BUILDER(&monitor, "test message")
540         .setHangType(EventHangMetadata::HangType::kRenderThread)
541         .build();
542 }
543 
TEST(HealthMonitorWatchdogBuilderTest,TimeoutTest)544 TEST(HealthMonitorWatchdogBuilderTest, TimeoutTest) {
545     MockHealthMonitor monitor;
546     MockHealthMonitor::Id taskId = 0x8749;
547     uint32_t timeoutMs = 5483;
548 
549     EXPECT_CALL(monitor, startMonitoringTask(_, Eq(std::nullopt), timeoutMs, _))
550         .Times(1)
551         .WillOnce(Return(taskId));
552     EXPECT_CALL(monitor, stopMonitoringTask(taskId)).Times(1);
553     WATCHDOG_BUILDER(&monitor, "test message").setTimeoutMs(timeoutMs).build();
554 }
555 
TEST(HealthMonitorWatchdogBuilderTest,OnHangCallbackTest)556 TEST(HealthMonitorWatchdogBuilderTest, OnHangCallbackTest) {
557     MockHealthMonitor monitor;
558     MockHealthMonitor::Id taskId = 0x2810;
559 
560     MockFunction<std::unique_ptr<HangAnnotations>()> mockOnHangCallback;
561     std::optional<std::function<std::unique_ptr<HangAnnotations>()>> actualOnHangCallback;
562 
563     EXPECT_CALL(monitor, startMonitoringTask(_, Ne(std::nullopt), kDefaultTimeoutMs, _))
564         .Times(1)
565         .WillOnce(DoAll(SaveArg<1>(&actualOnHangCallback), Return(taskId)));
566     EXPECT_CALL(monitor, stopMonitoringTask(taskId)).Times(1);
567     WATCHDOG_BUILDER(&monitor, "test message")
568         .setOnHangCallback(mockOnHangCallback.AsStdFunction())
569         .build();
570     EXPECT_CALL(mockOnHangCallback, Call()).Times(1);
571     (*actualOnHangCallback)();
572 }
573 
TEST(HealthMonitorWatchdogBuilderTest,AnnotationsTest)574 TEST(HealthMonitorWatchdogBuilderTest, AnnotationsTest) {
575     MockHealthMonitor monitor;
576     MockHealthMonitor::Id taskId = 0x9271;
577 
578     const char tag[] = "abcxyzalwi1943====";
579     auto annotations = std::make_unique<HangAnnotations>();
580     annotations->insert({{"tag", tag}});
581 
582     EXPECT_CALL(monitor, startMonitoringTask(
583                              Pointee(Field(&EventHangMetadata::data,
584                                            Pointee(Contains(Pair(StrEq("tag"), StrEq(tag)))))),
585                              Eq(std::nullopt), kDefaultTimeoutMs, _))
586         .Times(1)
587         .WillOnce(Return(taskId));
588     EXPECT_CALL(monitor, stopMonitoringTask(taskId)).Times(1);
589     WATCHDOG_BUILDER(&monitor, "test message").setAnnotations(std::move(annotations)).build();
590 }
591 
TEST(HealthMonitorWatchdogBuilderTest,MultipleSettersTest)592 TEST(HealthMonitorWatchdogBuilderTest, MultipleSettersTest) {
593     // Set multiple fields with chaining.
594     MockHealthMonitor monitor;
595     MockHealthMonitor::Id taskId = 0x9271;
596 
597     uint32_t timeoutMs = 5483;
598     auto hangType = EventHangMetadata::HangType::kSyncThread;
599 
600     EXPECT_CALL(monitor, startMonitoringTask(Pointee(Field(&EventHangMetadata::hangType, hangType)),
601                                              Eq(std::nullopt), timeoutMs, _))
602         .Times(1)
603         .WillOnce(Return(taskId));
604     EXPECT_CALL(monitor, stopMonitoringTask(taskId)).Times(1);
605     WATCHDOG_BUILDER(&monitor, "test message")
606         .setHangType(hangType)
607         .setTimeoutMs(timeoutMs)
608         .build();
609 }
610 
TEST(HealthMonitorWatchdogTest,ReleaseTest)611 TEST(HealthMonitorWatchdogTest, ReleaseTest) {
612     MockHealthMonitor monitor;
613     MockHealthMonitor::Id taskId = 0x8271;
614     EXPECT_CALL(monitor, startMonitoringTask(_, Eq(std::nullopt), kDefaultTimeoutMs, _))
615         .Times(1)
616         .WillOnce(Return(taskId));
617 
618     auto watchdog = WATCHDOG_BUILDER(&monitor, "test message").build();
619     EXPECT_THAT(watchdog->release(), Optional(taskId));
620     EXPECT_EQ(watchdog->release(), std::nullopt);
621 
622     EXPECT_CALL(monitor, stopMonitoringTask(_)).Times(0);
623 }
624 
625 }  // namespace emugl
626