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 "osal/base/synchronizer.h"
27 #include "osal/thread/task.h"
28
29 namespace OHOS {
30 namespace Media {
31 namespace Test {
32 using namespace OSAL;
33
34 class TestSynchronizer : public ::testing::Test {
35 public:
SetUp()36 void SetUp() override
37 {
38 task1 = std::make_shared<Task>("workTask1");
39 task2 = std::make_shared<Task>("workTask2");
40 task3 = std::make_shared<Task>("workTask3");
41 isDataRcved = false;
42 isStarted = false;
43 }
44
TearDown()45 void TearDown() override
46 {
47 }
48
49 std::shared_ptr<Task> task1;
50 std::shared_ptr<Task> task2;
51 std::shared_ptr<Task> task3;
52 std::atomic<bool> isDataRcved;
53 std::atomic<bool> isStarted;
54 static Synchronizer<int, int> synchronizer;
55 };
56
57 Synchronizer<int, int> TestSynchronizer::synchronizer("sync");
58
TEST_F(TestSynchronizer,test_waitfor_fail)59 TEST_F(TestSynchronizer, test_waitfor_fail)
60 {
61 int syncId = 0;
62 task1->RegisterHandler([this, syncId] { synchronizer.Notify(syncId, 1234); });
63 int timeoutMs = 100;
64 auto start = std::chrono::high_resolution_clock::now();
65 auto rtv = synchronizer.WaitFor(
66 syncId, [] {}, timeoutMs);
67 auto end = std::chrono::high_resolution_clock::now();
68 auto diff = static_cast<std::chrono::duration<double>>(end - start).count() * 1000;
69 EXPECT_EQ(false, rtv);
70 EXPECT_TRUE((std::abs(static_cast<int>(diff) - timeoutMs) < 20) || (diff < 5));
71 std::cout << "TestSynchronizer time diff: " << diff << std::endl;
72 }
73
TEST_F(TestSynchronizer,test_waitfor_succ)74 TEST_F(TestSynchronizer, test_waitfor_succ)
75 {
76 int syncId = 0;
77 task1->RegisterHandler([this, syncId] { synchronizer.Notify(syncId, 1234); });
78 task1->Start();
79 int timeoutMs = 1000;
80 auto rtv = synchronizer.WaitFor(
81 syncId, [] {}, timeoutMs);
82 EXPECT_EQ(true, rtv);
83 }
84
TEST_F(TestSynchronizer,test_waitfor_with_result_succ)85 TEST_F(TestSynchronizer, test_waitfor_with_result_succ)
86 {
87 int syncId = 0;
88 int expect = 1234;
89 task1->RegisterHandler([this, syncId, expect] { synchronizer.Notify(syncId, expect); });
90 task1->Start();
91 int timeoutMs = 1000;
92 int result = 0;
93 auto rtv = synchronizer.WaitFor(
94 syncId, [] { return true; }, timeoutMs, result);
95 EXPECT_EQ(true, rtv);
96 EXPECT_EQ(expect, result);
97 }
98
TEST_F(TestSynchronizer,test_wait_succ)99 TEST_F(TestSynchronizer, test_wait_succ)
100 {
101 int syncId = 0;
102 int result = 0;
103 int expect = 1234;
104 task1->RegisterHandler([this, syncId, &result] {
105 if (!isDataRcved.load()) {
106 synchronizer.Wait(
107 syncId, [] {}, result);
108 isDataRcved = true;
109 }
110 });
111 task1->Start();
112 task2->RegisterHandler([this, syncId, expect] { synchronizer.Notify(syncId, expect); });
113 task2->Start();
114 while (!isDataRcved.load()) {}
115 EXPECT_EQ(expect, result);
116 }
117 } // namespace Test
118 } // namespace Media
119 } // namespace OHOS