1 /*
2 * Copyright (c) 2023 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 #include <test_header.h>
18 #include <thread>
19
20 #include "ffrt_inner.h"
21 #include "hgm_task_handle_thread.h"
22 #include "hgm_test_base.h"
23
24 using namespace testing;
25 using namespace testing::ext;
26
27 namespace OHOS {
28 namespace Rosen {
29 class HgmTaskHandleThreadTest : public HgmTestBase {
30 public:
31 static void SetUpTestCase();
32 static void TearDownTestCase();
33 void SetUp();
34 void TearDown();
35 };
36
SetUpTestCase()37 void HgmTaskHandleThreadTest::SetUpTestCase()
38 {
39 HgmTestBase::SetUpTestCase();
40 }
41
TearDownTestCase()42 void HgmTaskHandleThreadTest::TearDownTestCase()
43 {
44 HgmTaskHandleThread::Instance().queue_ = std::make_shared<ffrt::queue>(
45 static_cast<ffrt::queue_type>(ffrt_inner_queue_type_t::ffrt_queue_eventhandler_adapter), "HgmTaskHandleThread",
46 ffrt::queue_attr().qos(ffrt::qos_user_interactive));
47 }
48
SetUp()49 void HgmTaskHandleThreadTest::SetUp()
50 {
51 if (!HgmTaskHandleThread::Instance().queue_) {
52 HgmTaskHandleThread::Instance().queue_ = std::make_shared<ffrt::queue>(
53 static_cast<ffrt::queue_type>(ffrt_inner_queue_type_t::ffrt_queue_eventhandler_adapter),
54 "HgmTaskHandleThread", ffrt::queue_attr().qos(ffrt::qos_user_interactive));
55 }
56 }
57
TearDown()58 void HgmTaskHandleThreadTest::TearDown() {}
59
60 /**
61 * @tc.name: Instance
62 * @tc.desc: Test Instance
63 * @tc.type: FUNC
64 * @tc.require:
65 */
66 HWTEST_F(HgmTaskHandleThreadTest, Instance, TestSize.Level0)
67 {
68 HgmTaskHandleThread& instance1 = HgmTaskHandleThread::Instance();
69 HgmTaskHandleThread& instance2 = HgmTaskHandleThread::Instance();
70 EXPECT_EQ(&instance1, &instance2);
71 }
72
73 /**
74 * @tc.name: PostTask001
75 * @tc.desc: Test PostTask
76 * @tc.type: FUNC
77 * @tc.require:
78 */
79 HWTEST_F(HgmTaskHandleThreadTest, PostTask001, TestSize.Level0)
80 {
81 HgmTaskHandleThread& instance = HgmTaskHandleThread::Instance();
__anon535087620102() 82 std::function<void()> func = []() -> void {};
83 int64_t delayTime = 100;
84
85 EXPECT_NE(instance.queue_, nullptr);
86 auto taskCount = instance.queue_->get_task_cnt();
87 instance.PostTask(func, delayTime);
88 EXPECT_EQ(instance.queue_->get_task_cnt(), taskCount + 1);
89 std::this_thread::sleep_for(std::chrono::milliseconds(delayTime));
90
91 delayTime = -1;
92 instance.PostTask(func, delayTime);
93
94 std::this_thread::sleep_for(std::chrono::milliseconds(10));
95 taskCount = instance.queue_->get_task_cnt();
96 delayTime = UINT64_MAX / 100;
97 instance.PostTask(func, delayTime);
98 EXPECT_EQ(instance.queue_->get_task_cnt(), taskCount + 1);
99
100 instance.queue_ = nullptr;
101 instance.PostTask(func, delayTime);
102 }
103
104 /**
105 * @tc.name: PostTask002
106 * @tc.desc: Test PostTask
107 * @tc.type: FUNC
108 * @tc.require:
109 */
110 HWTEST_F(HgmTaskHandleThreadTest, PostTask002, TestSize.Level0)
111 {
112 HgmTaskHandleThread& instance = HgmTaskHandleThread::Instance();
113 int count = 0;
__anon535087620202()114 instance.PostTask([&count](){ count++; }, 0);
115 std::this_thread::sleep_for(std::chrono::milliseconds(100));
116 EXPECT_EQ(count, 1);
117 }
118
119 /**
120 * @tc.name: PostTask003
121 * @tc.desc: Test PostTask
122 * @tc.type: FUNC
123 * @tc.require:
124 */
125 HWTEST_F(HgmTaskHandleThreadTest, PostTask003, TestSize.Level0)
126 {
127 HgmTaskHandleThread& instance = HgmTaskHandleThread::Instance();
128 int count = 0;
129 const int count1 = 1;
130 const int time = 500;
131 const int time1 = 1000;
132 auto start_time = std::chrono::high_resolution_clock::now();
__anon535087620302()133 instance.PostTask([&count](){ count++; }, time1);
134 std::this_thread::sleep_for(std::chrono::milliseconds(time));
135 std::this_thread::sleep_for(std::chrono::milliseconds(time1));
136 auto end_time = std::chrono::high_resolution_clock::now();
137 EXPECT_EQ(count, count1);
138 EXPECT_GE(std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time).count(), time1);
139 }
140
141 /**
142 * @tc.name: PostSyncTask001
143 * @tc.desc: Test PostSyncTask
144 * @tc.type: FUNC
145 * @tc.require:
146 */
147 HWTEST_F(HgmTaskHandleThreadTest, PostSyncTask001, TestSize.Level0)
148 {
149 HgmTaskHandleThread& instance = HgmTaskHandleThread::Instance();
__anon535087620402() 150 std::function<void()> func = []() -> void {};
151
152 EXPECT_NE(instance.queue_, nullptr);
153 bool res = instance.PostSyncTask(func);
154 EXPECT_TRUE(res);
155
156 instance.queue_ = nullptr;
157 res = instance.PostSyncTask(func);
158 EXPECT_FALSE(res);
159 }
160
161 /**
162 * @tc.name: PostEvent001
163 * @tc.desc: Test PostEvent
164 * @tc.type: FUNC
165 * @tc.require:
166 */
167 HWTEST_F(HgmTaskHandleThreadTest, PostEvent001, TestSize.Level0)
168 {
169 HgmTaskHandleThread& instance = HgmTaskHandleThread::Instance();
__anon535087620502() 170 std::function<void()> func = []() -> void {};
171 int64_t delayTime = 1000;
172 std::string eventId = "eventId";
173
174 EXPECT_NE(instance.queue_, nullptr);
175 auto taskCount = instance.queue_->get_task_cnt();
176 instance.PostEvent(eventId, func, delayTime);
177 EXPECT_EQ(instance.queue_->get_task_cnt(), taskCount + 1);
178
179 delayTime = -1;
180 instance.PostEvent(eventId, func, delayTime);
181 std::this_thread::sleep_for(std::chrono::milliseconds(200));
182 EXPECT_EQ(instance.queue_->get_task_cnt(), taskCount + 1);
183
184 delayTime = UINT64_MAX / 100;
185 instance.PostEvent(eventId, func, delayTime);
186 EXPECT_EQ(instance.queue_->get_task_cnt(), taskCount + 2);
187
188 instance.RemoveEvent(eventId);
189 EXPECT_EQ(instance.queue_->get_task_cnt(), taskCount);
190
191 instance.queue_ = nullptr;
192 instance.PostEvent(eventId, func, delayTime);
193 }
194
195 /**
196 * @tc.name: RemoveEvent001
197 * @tc.desc: Test RemoveEvent
198 * @tc.type: FUNC
199 * @tc.require:
200 */
201 HWTEST_F(HgmTaskHandleThreadTest, RemoveEvent001, TestSize.Level0)
202 {
203 HgmTaskHandleThread& instance = HgmTaskHandleThread::Instance();
__anon535087620602() 204 std::function<void()> func = []() -> void {};
205 int64_t delayTime = 5000;
206 std::string eventId = "eventId";
207
208 EXPECT_NE(instance.queue_, nullptr);
209 auto taskCount = instance.queue_->get_task_cnt();
210 instance.PostEvent(eventId, func, delayTime);
211 EXPECT_EQ(instance.queue_->get_task_cnt(), taskCount + 1);
212 instance.RemoveEvent(eventId);
213 EXPECT_EQ(instance.queue_->get_task_cnt(), taskCount);
214
215 instance.queue_ = nullptr;
216 instance.RemoveEvent(eventId);
217 }
218
219 /**
220 * @tc.name: DetectMultiThreadingCalls
221 * @tc.desc: Test DetectMultiThreadingCalls
222 * @tc.type: FUNC
223 * @tc.require:IB3MVN
224 */
225 HWTEST_F(HgmTaskHandleThreadTest, DetectMultiThreadingCalls, TestSize.Level0)
226 {
227 HgmTaskHandleThread& instance = HgmTaskHandleThread::Instance();
228 instance.DetectMultiThreadingCalls();
229 int32_t curThreadId = instance.curThreadId_;
230 instance.DetectMultiThreadingCalls();
231 EXPECT_EQ(curThreadId, instance.curThreadId_);
__anon535087620702() 232 std::thread([&instance]() { instance.DetectMultiThreadingCalls(); }).join();
233 EXPECT_NE(curThreadId, instance.curThreadId_);
234 }
235 } // namespace Rosen
236 } // namespace OHOS
237