1/* 2 * Copyright (c) 2021-2021 Huawei Device Co., Ltd. 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 16#include "gtest/gtest.h" 17#define private public 18#define protected public 19 20#undef UNIT_TEST 21 22#include <atomic> // NOLINT 23#include <chrono> // NOLINT 24#include <iostream> // NOLINT 25#include <memory> // NOLINT 26#include "foundation/osal/base/synchronizer.h" 27#include "foundation/osal/thread/task.h" 28#include "foundation/pre_defines.h" 29 30using namespace testing::ext; 31 32namespace OHOS { 33namespace Media { 34namespace Test { 35using namespace OSAL; 36 37class TestSynchronizer : public ::testing::Test { 38public: 39 void SetUp() override 40 { 41 task1 = std::make_shared<Task>("workTask1"); 42 task2 = std::make_shared<Task>("workTask2"); 43 task3 = std::make_shared<Task>("workTask3"); 44 isDataRcved = false; 45 isStarted = false; 46 } 47 48 void TearDown() override 49 { 50 } 51 52 std::shared_ptr<Task> task1; 53 std::shared_ptr<Task> task2; 54 std::shared_ptr<Task> task3; 55 std::atomic<bool> isDataRcved; 56 std::atomic<bool> isStarted; 57 static Synchronizer<int, int> synchronizer; 58}; 59 60Synchronizer<int, int> TestSynchronizer::synchronizer("sync"); 61 62HWTEST_F(TestSynchronizer, test_waitfor_fail, TestSize.Level1) 63{ 64 int syncId = 0; 65 task1->RegisterHandler([this, syncId] { 66 UNUSED_VARIABLE(this); 67 synchronizer.Notify(syncId, 1234); 68 }); 69 int timeoutMs = 100; 70 auto start = std::chrono::high_resolution_clock::now(); 71 auto rtv = synchronizer.WaitFor( 72 syncId, [] {}, timeoutMs); 73 auto end = std::chrono::high_resolution_clock::now(); 74 auto diff = static_cast<std::chrono::duration<double>>(end - start).count() * 1000; 75 EXPECT_EQ(false, rtv); 76 EXPECT_TRUE((std::abs(static_cast<int>(diff) - timeoutMs) < 25) || (diff < 5)); 77 std::cout << "TestSynchronizer time diff: " << diff << std::endl; 78} 79 80HWTEST_F(TestSynchronizer, test_waitfor_succ, TestSize.Level1) 81{ 82 int syncId = 0; 83 task1->RegisterHandler([this, syncId] { 84 UNUSED_VARIABLE(this); 85 synchronizer.Notify(syncId, 1234); 86 }); 87 task1->Start(); 88 int timeoutMs = 1000; 89 auto rtv = synchronizer.WaitFor( 90 syncId, [] {}, timeoutMs); 91 EXPECT_EQ(true, rtv); 92} 93 94HWTEST_F(TestSynchronizer, test_waitfor_with_result_succ, TestSize.Level1) 95{ 96 int syncId = 0; 97 int expect = 1234; 98 task1->RegisterHandler([this, syncId, expect] { 99 UNUSED_VARIABLE(this); 100 synchronizer.Notify(syncId, expect); 101 }); 102 task1->Start(); 103 int timeoutMs = 1000; 104 int result = 0; 105 auto rtv = synchronizer.WaitFor( 106 syncId, [] { return true; }, timeoutMs, result); 107 EXPECT_EQ(true, rtv); 108 EXPECT_EQ(expect, result); 109} 110 111HWTEST_F(TestSynchronizer, test_wait_succ, TestSize.Level1) 112{ 113 int syncId = 0; 114 int result = 0; 115 int expect = 1234; 116 task1->RegisterHandler([this, syncId, &result] { 117 UNUSED_VARIABLE(this); 118 if (!isDataRcved.load()) { 119 synchronizer.Wait( 120 syncId, [] {}, result); 121 isDataRcved = true; 122 } 123 }); 124 task1->Start(); 125 task2->RegisterHandler([this, syncId, expect] { 126 UNUSED_VARIABLE(this); 127 synchronizer.Notify(syncId, expect); 128 }); 129 task2->Start(); 130 while (!isDataRcved.load()) {} 131 EXPECT_EQ(expect, result); 132} 133} // namespace Test 134} // namespace Media 135} // namespace OHOS