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 
30 using namespace testing::ext;
31 
32 namespace OHOS {
33 namespace Media {
34 namespace Test {
35 using namespace OSAL;
36 
37 class TestSynchronizer : public ::testing::Test {
38 public:
SetUp()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 
TearDown()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 
60 Synchronizer<int, int> TestSynchronizer::synchronizer("sync");
61 
62 HWTEST_F(TestSynchronizer, test_waitfor_fail, TestSize.Level1)
63 {
64     int syncId = 0;
__anon43a178830102null65     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(
__anon43a178830202null72         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) < 20) || (diff < 5));
77     std::cout << "TestSynchronizer time diff: " << diff << std::endl;
78 }
79 
80 HWTEST_F(TestSynchronizer, test_waitfor_succ, TestSize.Level1)
81 {
82     int syncId = 0;
__anon43a178830302null83     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(
__anon43a178830402null90         syncId, [] {}, timeoutMs);
91     EXPECT_EQ(true, rtv);
92 }
93 
94 HWTEST_F(TestSynchronizer, test_waitfor_with_result_succ, TestSize.Level1)
95 {
96     int syncId = 0;
97     int expect = 1234;
__anon43a178830502null98     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(
__anon43a178830602null106         syncId, [] { return true; }, timeoutMs, result);
107     EXPECT_EQ(true, rtv);
108     EXPECT_EQ(expect, result);
109 }
110 
111 HWTEST_F(TestSynchronizer, test_wait_succ, TestSize.Level1)
112 {
113     int syncId = 0;
114     int result = 0;
115     int expect = 1234;
__anon43a178830702null116     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();
__anon43a178830902null125     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