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