1fa7767c5Sopenharmony_ci/* 2fa7767c5Sopenharmony_ci * Copyright (c) 2021-2021 Huawei Device Co., Ltd. 3fa7767c5Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4fa7767c5Sopenharmony_ci * you may not use this file except in compliance with the License. 5fa7767c5Sopenharmony_ci * You may obtain a copy of the License at 6fa7767c5Sopenharmony_ci * 7fa7767c5Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8fa7767c5Sopenharmony_ci * 9fa7767c5Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10fa7767c5Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11fa7767c5Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12fa7767c5Sopenharmony_ci * See the License for the specific language governing permissions and 13fa7767c5Sopenharmony_ci * limitations under the License. 14fa7767c5Sopenharmony_ci */ 15fa7767c5Sopenharmony_ci 16fa7767c5Sopenharmony_ci#include "gtest/gtest.h" 17fa7767c5Sopenharmony_ci#define private public 18fa7767c5Sopenharmony_ci#define protected public 19fa7767c5Sopenharmony_ci 20fa7767c5Sopenharmony_ci#undef UNIT_TEST 21fa7767c5Sopenharmony_ci 22fa7767c5Sopenharmony_ci#include <atomic> // NOLINT 23fa7767c5Sopenharmony_ci#include <chrono> // NOLINT 24fa7767c5Sopenharmony_ci#include <iostream> // NOLINT 25fa7767c5Sopenharmony_ci#include <memory> // NOLINT 26fa7767c5Sopenharmony_ci#include "foundation/osal/base/synchronizer.h" 27fa7767c5Sopenharmony_ci#include "foundation/osal/thread/task.h" 28fa7767c5Sopenharmony_ci#include "foundation/pre_defines.h" 29fa7767c5Sopenharmony_ci 30fa7767c5Sopenharmony_ciusing namespace testing::ext; 31fa7767c5Sopenharmony_ci 32fa7767c5Sopenharmony_cinamespace OHOS { 33fa7767c5Sopenharmony_cinamespace Media { 34fa7767c5Sopenharmony_cinamespace Test { 35fa7767c5Sopenharmony_ciusing namespace OSAL; 36fa7767c5Sopenharmony_ci 37fa7767c5Sopenharmony_ciclass TestSynchronizer : public ::testing::Test { 38fa7767c5Sopenharmony_cipublic: 39fa7767c5Sopenharmony_ci void SetUp() override 40fa7767c5Sopenharmony_ci { 41fa7767c5Sopenharmony_ci task1 = std::make_shared<Task>("workTask1"); 42fa7767c5Sopenharmony_ci task2 = std::make_shared<Task>("workTask2"); 43fa7767c5Sopenharmony_ci task3 = std::make_shared<Task>("workTask3"); 44fa7767c5Sopenharmony_ci isDataRcved = false; 45fa7767c5Sopenharmony_ci isStarted = false; 46fa7767c5Sopenharmony_ci } 47fa7767c5Sopenharmony_ci 48fa7767c5Sopenharmony_ci void TearDown() override 49fa7767c5Sopenharmony_ci { 50fa7767c5Sopenharmony_ci } 51fa7767c5Sopenharmony_ci 52fa7767c5Sopenharmony_ci std::shared_ptr<Task> task1; 53fa7767c5Sopenharmony_ci std::shared_ptr<Task> task2; 54fa7767c5Sopenharmony_ci std::shared_ptr<Task> task3; 55fa7767c5Sopenharmony_ci std::atomic<bool> isDataRcved; 56fa7767c5Sopenharmony_ci std::atomic<bool> isStarted; 57fa7767c5Sopenharmony_ci static Synchronizer<int, int> synchronizer; 58fa7767c5Sopenharmony_ci}; 59fa7767c5Sopenharmony_ci 60fa7767c5Sopenharmony_ciSynchronizer<int, int> TestSynchronizer::synchronizer("sync"); 61fa7767c5Sopenharmony_ci 62fa7767c5Sopenharmony_ciHWTEST_F(TestSynchronizer, test_waitfor_fail, TestSize.Level1) 63fa7767c5Sopenharmony_ci{ 64fa7767c5Sopenharmony_ci int syncId = 0; 65fa7767c5Sopenharmony_ci task1->RegisterHandler([this, syncId] { 66fa7767c5Sopenharmony_ci UNUSED_VARIABLE(this); 67fa7767c5Sopenharmony_ci synchronizer.Notify(syncId, 1234); 68fa7767c5Sopenharmony_ci }); 69fa7767c5Sopenharmony_ci int timeoutMs = 100; 70fa7767c5Sopenharmony_ci auto start = std::chrono::high_resolution_clock::now(); 71fa7767c5Sopenharmony_ci auto rtv = synchronizer.WaitFor( 72fa7767c5Sopenharmony_ci syncId, [] {}, timeoutMs); 73fa7767c5Sopenharmony_ci auto end = std::chrono::high_resolution_clock::now(); 74fa7767c5Sopenharmony_ci auto diff = static_cast<std::chrono::duration<double>>(end - start).count() * 1000; 75fa7767c5Sopenharmony_ci EXPECT_EQ(false, rtv); 76fa7767c5Sopenharmony_ci EXPECT_TRUE((std::abs(static_cast<int>(diff) - timeoutMs) < 25) || (diff < 5)); 77fa7767c5Sopenharmony_ci std::cout << "TestSynchronizer time diff: " << diff << std::endl; 78fa7767c5Sopenharmony_ci} 79fa7767c5Sopenharmony_ci 80fa7767c5Sopenharmony_ciHWTEST_F(TestSynchronizer, test_waitfor_succ, TestSize.Level1) 81fa7767c5Sopenharmony_ci{ 82fa7767c5Sopenharmony_ci int syncId = 0; 83fa7767c5Sopenharmony_ci task1->RegisterHandler([this, syncId] { 84fa7767c5Sopenharmony_ci UNUSED_VARIABLE(this); 85fa7767c5Sopenharmony_ci synchronizer.Notify(syncId, 1234); 86fa7767c5Sopenharmony_ci }); 87fa7767c5Sopenharmony_ci task1->Start(); 88fa7767c5Sopenharmony_ci int timeoutMs = 1000; 89fa7767c5Sopenharmony_ci auto rtv = synchronizer.WaitFor( 90fa7767c5Sopenharmony_ci syncId, [] {}, timeoutMs); 91fa7767c5Sopenharmony_ci EXPECT_EQ(true, rtv); 92fa7767c5Sopenharmony_ci} 93fa7767c5Sopenharmony_ci 94fa7767c5Sopenharmony_ciHWTEST_F(TestSynchronizer, test_waitfor_with_result_succ, TestSize.Level1) 95fa7767c5Sopenharmony_ci{ 96fa7767c5Sopenharmony_ci int syncId = 0; 97fa7767c5Sopenharmony_ci int expect = 1234; 98fa7767c5Sopenharmony_ci task1->RegisterHandler([this, syncId, expect] { 99fa7767c5Sopenharmony_ci UNUSED_VARIABLE(this); 100fa7767c5Sopenharmony_ci synchronizer.Notify(syncId, expect); 101fa7767c5Sopenharmony_ci }); 102fa7767c5Sopenharmony_ci task1->Start(); 103fa7767c5Sopenharmony_ci int timeoutMs = 1000; 104fa7767c5Sopenharmony_ci int result = 0; 105fa7767c5Sopenharmony_ci auto rtv = synchronizer.WaitFor( 106fa7767c5Sopenharmony_ci syncId, [] { return true; }, timeoutMs, result); 107fa7767c5Sopenharmony_ci EXPECT_EQ(true, rtv); 108fa7767c5Sopenharmony_ci EXPECT_EQ(expect, result); 109fa7767c5Sopenharmony_ci} 110fa7767c5Sopenharmony_ci 111fa7767c5Sopenharmony_ciHWTEST_F(TestSynchronizer, test_wait_succ, TestSize.Level1) 112fa7767c5Sopenharmony_ci{ 113fa7767c5Sopenharmony_ci int syncId = 0; 114fa7767c5Sopenharmony_ci int result = 0; 115fa7767c5Sopenharmony_ci int expect = 1234; 116fa7767c5Sopenharmony_ci task1->RegisterHandler([this, syncId, &result] { 117fa7767c5Sopenharmony_ci UNUSED_VARIABLE(this); 118fa7767c5Sopenharmony_ci if (!isDataRcved.load()) { 119fa7767c5Sopenharmony_ci synchronizer.Wait( 120fa7767c5Sopenharmony_ci syncId, [] {}, result); 121fa7767c5Sopenharmony_ci isDataRcved = true; 122fa7767c5Sopenharmony_ci } 123fa7767c5Sopenharmony_ci }); 124fa7767c5Sopenharmony_ci task1->Start(); 125fa7767c5Sopenharmony_ci task2->RegisterHandler([this, syncId, expect] { 126fa7767c5Sopenharmony_ci UNUSED_VARIABLE(this); 127fa7767c5Sopenharmony_ci synchronizer.Notify(syncId, expect); 128fa7767c5Sopenharmony_ci }); 129fa7767c5Sopenharmony_ci task2->Start(); 130fa7767c5Sopenharmony_ci while (!isDataRcved.load()) {} 131fa7767c5Sopenharmony_ci EXPECT_EQ(expect, result); 132fa7767c5Sopenharmony_ci} 133fa7767c5Sopenharmony_ci} // namespace Test 134fa7767c5Sopenharmony_ci} // namespace Media 135fa7767c5Sopenharmony_ci} // namespace OHOS