1 /*
2 * Copyright (C) 2022 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 #define LOG_TAG "timecheck_tests"
18
19 #include <mediautils/TimeCheck.h>
20
21 #include <atomic>
22 #include <gtest/gtest.h>
23 #include <utils/Log.h>
24
25 using namespace android::mediautils;
26 using namespace std::chrono_literals;
27
28 namespace {
TEST(timecheck_tests,success)29 TEST(timecheck_tests, success) {
30 bool timeoutRegistered = false;
31 float elapsedMsRegistered = 0.f;
32 bool event = false;
33
34 {
35 TimeCheck timeCheck("success",
36 [&event, &timeoutRegistered, &elapsedMsRegistered]
37 (bool timeout, float elapsedMs) {
38 timeoutRegistered = timeout;
39 elapsedMsRegistered = elapsedMs;
40 event = true;
41 }, 1000ms /* timeoutDuration */, {} /* secondChanceDuration */, false /* crash */);
42 }
43 ASSERT_TRUE(event);
44 ASSERT_FALSE(timeoutRegistered);
45 ASSERT_GT(elapsedMsRegistered, 0.f);
46 }
47
TEST(timecheck_tests,timeout)48 TEST(timecheck_tests, timeout) {
49 bool timeoutRegistered = false;
50 float elapsedMsRegistered = 0.f;
51 std::atomic_bool event = false; // seq-cst implies acquire-release
52
53 {
54 TimeCheck timeCheck("timeout",
55 [&event, &timeoutRegistered, &elapsedMsRegistered]
56 (bool timeout, float elapsedMs) {
57 timeoutRegistered = timeout;
58 elapsedMsRegistered = elapsedMs;
59 event = true; // store-release, must be last.
60 }, 1ms /* timeoutDuration */, {} /* secondChanceDuration */, false /* crash */);
61 std::this_thread::sleep_for(100ms);
62 }
63 ASSERT_TRUE(event); // load-acquire, must be first.
64 ASSERT_TRUE(timeoutRegistered); // only called once on failure, not on dealloc.
65 ASSERT_GT(elapsedMsRegistered, 0.f);
66 }
67
68 // Note: We do not test TimeCheck crash because TimeCheck is multithreaded and the
69 // EXPECT_EXIT() signal catching is imperfect due to the gtest fork.
70
71 // Note, the following test is to manually verify the correct thread is aborted.
72 // Due to difficulties with gtest and EXPECT_EXIT, this is difficult to verify
73 // automatically. TODO(b/246446561) Attempt to use EXPECT_EXIT
74
75 #if 0
76 void threadFunction() {
77 bool timeoutRegistered = false;
78 float elapsedMsRegistered = 0.f;
79 std::atomic_bool event = false; // seq-cst implies acquire-release
80 {
81 TimeCheck timeCheck("timeout",
82 [&event, &timeoutRegistered, &elapsedMsRegistered]
83 (bool timeout, float elapsedMs) {
84 timeoutRegistered = timeout;
85 elapsedMsRegistered = elapsedMs;
86 event = true; // store-release, must be last.
87 }, 1ms /* timeoutDuration */, {} /* secondChanceDuration */, true /* crash */);
88 std::this_thread::sleep_for(100ms);
89 ADD_FAILURE();
90 }
91 }
92
93 TEST(timecheck_tests, death) {
94 std::thread mthread{threadFunction};
95 mthread.join();
96 }
97 #endif
98
99 } // namespace
100
101