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 #include "ffrt_utils_test.h"
16 
17 #include "ffrt_utils.h"
18 
19 namespace OHOS {
20 namespace PowerMgr {
21 namespace Test {
22 using namespace testing::ext;
23 /**
24  * @tc.name: FFRTUtilsTest001
25  * @tc.desc: test submit task
26  * @tc.type: FUNC
27  */
28 HWTEST_F(FFRTUtilsTest, FFRTUtilsTest001, TestSize.Level1)
29 {
30     int32_t x = 0;
__anone73078890102() 31     FFRTTask task = [&]() {
32         x = 2;
33     };
34     FFRTUtils::SubmitTask(task); // submit an async task
35     ffrt::wait(); // wait async task finish
36     EXPECT_EQ(x, 2);
37 }
38 
39 /**
40  * @tc.name: FFRTUtilsTest002
41  * @tc.desc: test submit task sync
42  * @tc.type: FUNC
43  */
44 HWTEST_F(FFRTUtilsTest, FFRTUtilsTest002, TestSize.Level1)
45 {
46     int32_t x = 0;
__anone73078890202() 47     FFRTTask task = [&]() {
48         x = 2;
49     };
50     FFRTUtils::SubmitTaskSync(task); // submit a sync task
51     EXPECT_EQ(x, 2);
52 }
53 
54 /**
55  * @tc.name: FFRTUtilsTest003
56  * @tc.desc: test submit queue tasks
57  * @tc.type: FUNC
58  */
59 HWTEST_F(FFRTUtilsTest, FFRTUtilsTest003, TestSize.Level1)
60 {
61     int x = 0;
__anone73078890302() 62     FFRTTask task1 = [&]() {
63         ffrt::this_task::sleep_for(std::chrono::milliseconds(1));
64         x = 2;
65     };
__anone73078890402() 66     FFRTTask task2 = [&]() {
67         ffrt::this_task::sleep_for(std::chrono::milliseconds(30));
68         x += 2;
69     };
__anone73078890502() 70     FFRTTask task3 = [&]() {
71         ffrt::this_task::sleep_for(std::chrono::milliseconds(50));
72         x += 2;
73     };
74 
75     FFRTQueue queue("test_power_ffrt_queue");
76     FFRTUtils::SubmitQueueTasks({task1, task2, task3}, queue); // submit batch tasks to a queue
77 
78     ffrt::this_task::sleep_for(std::chrono::milliseconds(10));
79     EXPECT_EQ(x, 2); // task1 finished
80 
81     ffrt::this_task::sleep_for(std::chrono::milliseconds(50));
82     EXPECT_EQ(x, 4); // task2 finished
83 
84     ffrt::this_task::sleep_for(std::chrono::milliseconds(80));
85     EXPECT_EQ(x, 6); // task3 finished
86 }
87 
88 /**
89  * @tc.name: FFRTUtilsTest004
90  * @tc.desc: test submit delay task
91  * @tc.type: FUNC
92  */
93 HWTEST_F(FFRTUtilsTest, FFRTUtilsTest004, TestSize.Level1)
94 {
95     int x = 0;
__anone73078890602() 96     FFRTTask task = [&]() {
97         x = 2;
98     };
99 
100     FFRTQueue queue("test_power_ffrt_queue");
101     FFRTUtils::SubmitDelayTask(task, 10, queue); // submit delay task to a queue
102 
103     ffrt::this_task::sleep_for(std::chrono::milliseconds(5));
104     EXPECT_EQ(x, 0); // task not executed
105 
106     ffrt::this_task::sleep_for(std::chrono::milliseconds(7));
107     EXPECT_EQ(x, 2); // task finished
108 }
109 
110 /**
111  * @tc.name: FFRTUtilsTest005
112  * @tc.desc: test cancel delay task
113  * @tc.type: FUNC
114  */
115 HWTEST_F(FFRTUtilsTest, FFRTUtilsTest005, TestSize.Level1)
116 {
117     int x = 0;
__anone73078890702() 118     FFRTTask task = [&]() {
119         x = 2;
120     };
121 
122     FFRTQueue queue("test_power_ffrt_queue");
123     auto handle = FFRTUtils::SubmitDelayTask(task, 10, queue); // submit delay task to a queue
124 
125     ffrt::this_task::sleep_for(std::chrono::milliseconds(5));
126     EXPECT_EQ(x, 0); // task not executed
127 
128     FFRTUtils::CancelTask(handle, queue); // cancel the delay task from the queue
129     EXPECT_EQ(x, 0); // task not executed
130 
131     ffrt::this_task::sleep_for(std::chrono::milliseconds(10));
132     EXPECT_EQ(x, 0); // task not executed, because it is already canceled
133 }
134 
135 /**
136  * @tc.name: FFRTUtilsTest006
137  * @tc.desc: test submit timeout task and the task is executed successfully
138  * @tc.type: FUNC
139  */
140 HWTEST_F(FFRTUtilsTest, FFRTUtilsTest006, TestSize.Level1)
141 {
142     int x = 0;
__anone73078890802() 143     FFRTTask task = [&]() {
144         ffrt::this_task::sleep_for(std::chrono::milliseconds(5)); // task sleep 5ms
145         x = 2;
146     };
147     bool ret = FFRTUtils::SubmitTimeoutTask(task, 10); // task time out is 10ms
148     EXPECT_TRUE(ret); // task will not timeout
149     EXPECT_EQ(x, 2); // task finished
150 }
151 
152 /**
153  * @tc.name: FFRTUtilsTest007
154  * @tc.desc: test submit timeout task and the task execution times out
155  * @tc.type: FUNC
156  */
157 HWTEST_F(FFRTUtilsTest, FFRTUtilsTest007, TestSize.Level1)
158 {
159     int x = 0;
__anone73078890902() 160     FFRTTask task = [&]() {
161         ffrt::this_task::sleep_for(std::chrono::milliseconds(10)); // task sleep 10ms
162         x = 2;
163     };
164     bool ret = FFRTUtils::SubmitTimeoutTask(task, 5); // task time out is 5ms
165     EXPECT_FALSE(ret); // task will timeout
166     EXPECT_EQ(x, 0); // task not finished
167 }
168 
169 /**
170  * @tc.name: FFRTMutexTest001
171  * @tc.desc: test submit tasks with mutex
172  * @tc.type: FUNC
173  */
174 HWTEST_F(FFRTUtilsTest, FFRTMutexTest001, TestSize.Level1)
175 {
176     auto mutex = FFRTMutex();
177     std::unique_lock lock(mutex);
__anone73078890a02() 178     FFRTTask task1 = [&mutex]() {
179         std::unique_lock lock(mutex, std::try_to_lock);
180         EXPECT_FALSE(lock.owns_lock());
181     };
__anone73078890b02() 182     FFRTTask task2 = [&mutex]() {
183         std::unique_lock lock(mutex, std::try_to_lock);
184         EXPECT_TRUE(lock.owns_lock());
185     };
186     FFRTUtils::SubmitTaskSync(task1);
187     lock.unlock();
188     FFRTUtils::SubmitTaskSync(task2);
189     EXPECT_TRUE(lock.try_lock());
190 }
191 
192 /**
193  * @tc.name: FFRTMutexTest002
194  * @tc.desc: test mutex map
195  * @tc.type: FUNC
196  */
197 HWTEST_F(FFRTUtilsTest, FFRTMutexTest002, TestSize.Level1)
198 {
199     constexpr uint32_t MUTEX_ID_A = 1;
200     FFRTMutexMap mutexMap;
201     int data = 0;
__anone73078890c02() 202     FFRTTask taskA = [&mutexMap, &data]() {
203         mutexMap.Lock(MUTEX_ID_A);
204         data = 1;
205         mutexMap.Unlock(MUTEX_ID_A);
206     };
207 
208     mutexMap.Lock(MUTEX_ID_A);
209     FFRTUtils::SubmitTask(taskA);
210     ffrt::this_task::sleep_for(std::chrono::milliseconds(50));
211     // taskA is waiting for lock, data is not changed
212     EXPECT_EQ(data, 0);
213     mutexMap.Unlock(MUTEX_ID_A);
214     ffrt::this_task::sleep_for(std::chrono::milliseconds(50));
215     // tanskA changed data to 1
216     EXPECT_EQ(data, 1);
217 }
218 
219 /**
220  * @tc.name: FFRTMutexTest003
221  * @tc.desc: test mutex map, different mutex are independent
222  * @tc.type: FUNC
223  */
224 HWTEST_F(FFRTUtilsTest, FFRTMutexTest003, TestSize.Level1)
225 {
226     constexpr uint32_t MUTEX_ID_A = 1;
227     constexpr uint32_t MUTEX_ID_B = 2;
228     FFRTMutexMap mutexMap;
229     int data = 0;
230 
__anone73078890d02() 231     FFRTTask taskA = [&mutexMap, &data]() {
232         mutexMap.Lock(MUTEX_ID_A);
233         data = 1;
234         mutexMap.Unlock(MUTEX_ID_A);
235     };
236 
237     mutexMap.Lock(MUTEX_ID_B);
238     FFRTUtils::SubmitTask(taskA);
239     ffrt::this_task::sleep_for(std::chrono::milliseconds(50));
240     // tanskA changed data to 1
241     EXPECT_EQ(data, 1);
242     mutexMap.Unlock(MUTEX_ID_B);
243 }
244 
245 /**
246  * @tc.name: FFRTTimerTest001
247  * @tc.desc: test FFRTTimer CancelTimer
248  * @tc.type: FUNC
249  */
250 HWTEST_F(FFRTUtilsTest, FFRTTimerTest001, TestSize.Level1)
251 {
252     constexpr uint32_t TIMER_ID_A = 1;
253     constexpr uint32_t TIMER_ID_B = 2;
254     constexpr uint32_t TIMER_ID_C = 3;
255     FFRTTimer timer;
256     int data = 0;
257 
__anone73078890e02() 258     FFRTTask taskA = [&data]() {
259         data = 1;
260     };
261 
__anone73078890f02() 262     FFRTTask taskB = [&data]() {
263         data = 2;
264     };
265 
__anone73078891002() 266     FFRTTask taskC = [&data]() {
267         data = 3;
268     };
269 
270     timer.SetTimer(TIMER_ID_A, taskA, 50);
271     timer.SetTimer(TIMER_ID_B, taskB, 60);
272     timer.SetTimer(TIMER_ID_C, taskC, 70);
273     timer.CancelAllTimer();
274     ffrt::this_task::sleep_for(std::chrono::milliseconds(100));
275     // data is not changed
276     EXPECT_EQ(data, 0);
277 
278     timer.SetTimer(TIMER_ID_A, taskA, 50);
279     timer.SetTimer(TIMER_ID_B, taskB, 60);
280     timer.SetTimer(TIMER_ID_C, taskC, 70);
281     timer.Clear();
282     ffrt::this_task::sleep_for(std::chrono::milliseconds(100));
283     // data is not changed
284     EXPECT_EQ(data, 0);
285 
286     timer.SetTimer(TIMER_ID_A, taskA, 50);
287     timer.SetTimer(TIMER_ID_B, taskB, 60);
288     timer.SetTimer(TIMER_ID_C, taskC, 70);
289     timer.CancelTimer(TIMER_ID_B);
290     timer.CancelTimer(TIMER_ID_C);
291     ffrt::this_task::sleep_for(std::chrono::milliseconds(100));
292     // taskA changed data to 1, taskB and taskC are canceled
293     EXPECT_EQ(data, 1);
294 }
295 
296 /**
297  * @tc.name: FFRTTimerTest002
298  * @tc.desc: test FFRTTimer GetTaskId
299  * @tc.type: FUNC
300  */
301 HWTEST_F(FFRTUtilsTest, FFRTTimerTest002, TestSize.Level1)
302 {
303     FFRTMutexMap mutexMap;
304     FFRTTimer timer;
305 
306     constexpr uint32_t TIMER_ID_A = 1;
307     constexpr uint32_t TIMER_COUNT = 10;
308     int count = 0;
309 
__anone73078891102() 310     FFRTTask taskA = [&count, &mutexMap]() {
311         mutexMap.Lock(TIMER_ID_A);
312         count++;
313         mutexMap.Unlock(TIMER_ID_A);
314     };
315 
316     for (int i = 0; i < TIMER_COUNT; i++) {
317         timer.SetTimer(TIMER_ID_A, taskA, 50);
318     }
319     ffrt::this_task::sleep_for(std::chrono::milliseconds(100));
320     // only the last timer is run, count should be 1
321     EXPECT_EQ(count, 1);
322     EXPECT_EQ(timer.GetTaskId(TIMER_ID_A), TIMER_COUNT);
323 
324     timer.Clear();
325     // task id is set to 0 in Clear()
326     EXPECT_EQ(timer.GetTaskId(TIMER_ID_A), 0);
327 }
328 } // namespace Test
329 } // namespace PowerMgr
330 } // namespace OHOS
331