/* * Copyright (c) 2021-2021 Huawei Device Co., Ltd. * 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. */ #include "gtest/gtest.h" #define private public #define protected public #undef UNIT_TEST #include <atomic> // NOLINT #include <chrono> // NOLINT #include <iostream> // NOLINT #include <memory> // NOLINT #include "foundation/osal/base/synchronizer.h" #include "foundation/osal/thread/task.h" #include "foundation/pre_defines.h" using namespace testing::ext; namespace OHOS { namespace Media { namespace Test { using namespace OSAL; class TestSynchronizer : public ::testing::Test { public: void SetUp() override { task1 = std::make_shared<Task>("workTask1"); task2 = std::make_shared<Task>("workTask2"); task3 = std::make_shared<Task>("workTask3"); isDataRcved = false; isStarted = false; } void TearDown() override { } std::shared_ptr<Task> task1; std::shared_ptr<Task> task2; std::shared_ptr<Task> task3; std::atomic<bool> isDataRcved; std::atomic<bool> isStarted; static Synchronizer<int, int> synchronizer; }; Synchronizer<int, int> TestSynchronizer::synchronizer("sync"); HWTEST_F(TestSynchronizer, test_waitfor_fail, TestSize.Level1) { int syncId = 0; task1->RegisterHandler([this, syncId] { UNUSED_VARIABLE(this); synchronizer.Notify(syncId, 1234); }); int timeoutMs = 100; auto start = std::chrono::high_resolution_clock::now(); auto rtv = synchronizer.WaitFor( syncId, [] {}, timeoutMs); auto end = std::chrono::high_resolution_clock::now(); auto diff = static_cast<std::chrono::duration<double>>(end - start).count() * 1000; EXPECT_EQ(false, rtv); EXPECT_TRUE((std::abs(static_cast<int>(diff) - timeoutMs) < 20) || (diff < 5)); std::cout << "TestSynchronizer time diff: " << diff << std::endl; } HWTEST_F(TestSynchronizer, test_waitfor_succ, TestSize.Level1) { int syncId = 0; task1->RegisterHandler([this, syncId] { UNUSED_VARIABLE(this); synchronizer.Notify(syncId, 1234); }); task1->Start(); int timeoutMs = 1000; auto rtv = synchronizer.WaitFor( syncId, [] {}, timeoutMs); EXPECT_EQ(true, rtv); } HWTEST_F(TestSynchronizer, test_waitfor_with_result_succ, TestSize.Level1) { int syncId = 0; int expect = 1234; task1->RegisterHandler([this, syncId, expect] { UNUSED_VARIABLE(this); synchronizer.Notify(syncId, expect); }); task1->Start(); int timeoutMs = 1000; int result = 0; auto rtv = synchronizer.WaitFor( syncId, [] { return true; }, timeoutMs, result); EXPECT_EQ(true, rtv); EXPECT_EQ(expect, result); } HWTEST_F(TestSynchronizer, test_wait_succ, TestSize.Level1) { int syncId = 0; int result = 0; int expect = 1234; task1->RegisterHandler([this, syncId, &result] { UNUSED_VARIABLE(this); if (!isDataRcved.load()) { synchronizer.Wait( syncId, [] {}, result); isDataRcved = true; } }); task1->Start(); task2->RegisterHandler([this, syncId, expect] { UNUSED_VARIABLE(this); synchronizer.Notify(syncId, expect); }); task2->Start(); while (!isDataRcved.load()) {} EXPECT_EQ(expect, result); } } // namespace Test } // namespace Media } // namespace OHOS