| /* |
| * Copyright (C) 2022 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #define LOG_TAG "timecheck_tests" |
| |
| #include <mediautils/TimeCheck.h> |
| |
| #include <atomic> |
| #include <gtest/gtest.h> |
| #include <utils/Log.h> |
| |
| using namespace android::mediautils; |
| using namespace std::chrono_literals; |
| |
| namespace { |
| TEST(timecheck_tests, success) { |
| bool timeoutRegistered = false; |
| float elapsedMsRegistered = 0.f; |
| bool event = false; |
| |
| { |
| TimeCheck timeCheck("success", |
| [&event, &timeoutRegistered, &elapsedMsRegistered] |
| (bool timeout, float elapsedMs) { |
| timeoutRegistered = timeout; |
| elapsedMsRegistered = elapsedMs; |
| event = true; |
| }, 1000ms /* timeoutDuration */, {} /* secondChanceDuration */, false /* crash */); |
| } |
| ASSERT_TRUE(event); |
| ASSERT_FALSE(timeoutRegistered); |
| ASSERT_GT(elapsedMsRegistered, 0.f); |
| } |
| |
| TEST(timecheck_tests, timeout) { |
| bool timeoutRegistered = false; |
| float elapsedMsRegistered = 0.f; |
| std::atomic_bool event = false; // seq-cst implies acquire-release |
| |
| { |
| TimeCheck timeCheck("timeout", |
| [&event, &timeoutRegistered, &elapsedMsRegistered] |
| (bool timeout, float elapsedMs) { |
| timeoutRegistered = timeout; |
| elapsedMsRegistered = elapsedMs; |
| event = true; // store-release, must be last. |
| }, 1ms /* timeoutDuration */, {} /* secondChanceDuration */, false /* crash */); |
| std::this_thread::sleep_for(100ms); |
| } |
| ASSERT_TRUE(event); // load-acquire, must be first. |
| ASSERT_TRUE(timeoutRegistered); // only called once on failure, not on dealloc. |
| ASSERT_GT(elapsedMsRegistered, 0.f); |
| } |
| |
| // Note: We do not test TimeCheck crash because TimeCheck is multithreaded and the |
| // EXPECT_EXIT() signal catching is imperfect due to the gtest fork. |
| |
| // Note, the following test is to manually verify the correct thread is aborted. |
| // Due to difficulties with gtest and EXPECT_EXIT, this is difficult to verify |
| // automatically. TODO(b/246446561) Attempt to use EXPECT_EXIT |
| |
| #if 0 |
| void threadFunction() { |
| bool timeoutRegistered = false; |
| float elapsedMsRegistered = 0.f; |
| std::atomic_bool event = false; // seq-cst implies acquire-release |
| { |
| TimeCheck timeCheck("timeout", |
| [&event, &timeoutRegistered, &elapsedMsRegistered] |
| (bool timeout, float elapsedMs) { |
| timeoutRegistered = timeout; |
| elapsedMsRegistered = elapsedMs; |
| event = true; // store-release, must be last. |
| }, 1ms /* timeoutDuration */, {} /* secondChanceDuration */, true /* crash */); |
| std::this_thread::sleep_for(100ms); |
| ADD_FAILURE(); |
| } |
| } |
| |
| TEST(timecheck_tests, death) { |
| std::thread mthread{threadFunction}; |
| mthread.join(); |
| } |
| #endif |
| |
| } // namespace |
| |