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 <thread>
17 #include <chrono>
18 #include <gtest/gtest.h>
19 #include "ffrt_inner.h"
20 #include "c/queue_ext.h"
21 #include "../common.h"
22
23 using namespace std;
24 using namespace ffrt;
25 using namespace testing;
26 #ifdef HWTEST_TESTING_EXT_ENABLE
27 using namespace testing::ext;
28 #endif
29
30 class QueueTest : public testing::Test {
31 protected:
SetUpTestCase()32 static void SetUpTestCase()
33 {
34 }
35
TearDownTestCase()36 static void TearDownTestCase()
37 {
38 }
39
SetUp()40 virtual void SetUp()
41 {
42 }
43
TearDown()44 virtual void TearDown()
45 {
46 }
47 };
48
49 #if defined(__clang__)
50 #define OPTIMIZE_OFF __attribute__((optnone))
51 #elif defined(__GNUC__)
52 #define OPTIMIZE_OFF __attribute__((optimize(0)))
53 #else
54 #define OPTIMIZE_OFF
55 #endif
56
57 namespace {
OnePlusForTest(void* data)58 void OPTIMIZE_OFF OnePlusForTest(void* data)
59 {
60 *(int*)data += 1;
61 }
62
PrintForTest(void* data)63 void PrintForTest(void* data)
64 {
65 printf("run no input func PrintForTest\n");
66 }
67
fibonacci(int n)68 int fibonacci(int n)
69 {
70 if (n == 0 || n == 1) {
71 return n;
72 }
73 return fibonacci(n - 1) + fibonacci(n - 2);
74 }
75
FibonacciTest(void* data, int fibnum)76 void FibonacciTest(void* data, int fibnum)
77 {
78 int testnum = fibonacci(fibnum);
79 *(int*)data += testnum;
80 }
81 } // namespace
82
EmptyFunction()83 void EmptyFunction() {}
84 /*
85 * 测试用例名称 : serial_queue_submit_cancel_succ
86 * 测试用例描述:提交、取消串行延时任务成功
87 * 预置条件 :1、调用串行队列创建接口创建队列
88 * 操作步骤 :1、提交串行队列任务并执行
89 * 2、提交延时串行队列任务并执行
90 * 预期结果 :执行成功
91 */
HWTEST_F(QueueTest, serial_queue_submit_cancel_succ, TestSize.Level1)92 HWTEST_F(QueueTest, serial_queue_submit_cancel_succ, TestSize.Level1)
93 {
94 // 创建队列
95 ffrt_queue_attr_t queue_attr;
96 (void)ffrt_queue_attr_init(&queue_attr); // 初始化属性,必须
97 ffrt_queue_t queue_handle = ffrt_queue_create(ffrt_queue_serial, "test_queue", &queue_attr);
98
99 int result = 0;
100 std::function<void()> basicFunc = [&result]() { OnePlusForTest(static_cast<void*>(&result)); };
101 ffrt_queue_submit(queue_handle, create_function_wrapper(basicFunc, ffrt_function_kind_queue), nullptr);
102
103 ffrt_task_handle_t task1 =
104 ffrt_queue_submit_h(queue_handle, create_function_wrapper(basicFunc, ffrt_function_kind_queue), nullptr);
105 ffrt_queue_wait(task1);
106 ffrt_task_handle_destroy(task1); // 销毁task_handle,必须
107 EXPECT_EQ(result, 2);
108
109 ffrt_task_attr_t task_attr;
110 (void)ffrt_task_attr_init(&task_attr); // 初始化task属性,必须
111 ffrt_task_attr_set_delay(&task_attr, 1000); // 设置任务1ms后才执行,非必须
112 ffrt_task_handle_t task2 =
113 ffrt_queue_submit_h(queue_handle, create_function_wrapper(basicFunc, ffrt_function_kind_queue), &task_attr);
114 int cancel = ffrt_queue_cancel(task2);
115 ffrt_task_handle_destroy(task2); // 销毁task_handle,必须
116 ffrt_queue_attr_destroy(&queue_attr);
117 EXPECT_EQ(cancel, 0);
118 EXPECT_EQ(result, 2);
119
120 // 销毁队列
121 ffrt_queue_destroy(queue_handle);
122 }
123
124 /*
125 * 测试用例名称 : serial_queue_create_fail
126 * 测试用例描述:串行队列创建和销毁失败
127 * 预置条件 :1、调用串行队列创建接口创建队列
128 * 操作步骤 :1、调用串行队列创建接口创建队列,type为非串行队列
129 * 2、调用串行队列创建接口创建队列,type为串行队列,但name与attr为nullptr
130 * 3、调用串行队列创建接口创建队列,type为串行队列,但name为nullptr
131 * 预期结果 :1创建失败,2、3创建成功
132 */
HWTEST_F(QueueTest, serial_queue_create_fail, TestSize.Level1)133 HWTEST_F(QueueTest, serial_queue_create_fail, TestSize.Level1)
134 {
135 // input invalid
136 ffrt_queue_t queue_handle = ffrt_queue_create(ffrt_queue_max, nullptr, nullptr);
137 ffrt_queue_destroy(queue_handle);
138 ffrt_queue_destroy(nullptr);
139
140 queue_handle = ffrt_queue_create(ffrt_queue_serial, nullptr, nullptr);
141 EXPECT_EQ(queue_handle == nullptr, 0);
142 ffrt_queue_destroy(queue_handle);
143
144 // succ free
145 ffrt_queue_attr_t queue_attr;
146 (void)ffrt_queue_attr_init(&queue_attr); // attr 缺少 init 无法看护
147 queue_handle = ffrt_queue_create(ffrt_queue_serial, nullptr, &queue_attr);
148 EXPECT_EQ(queue_handle == nullptr, 0);
149 ffrt_queue_attr_destroy(&queue_attr);
150 ffrt_queue_destroy(queue_handle);
151 }
152
153 /*
154 * 测试用例名称 : ffrt_task_attr_set_get_delay
155 * 测试用例描述:测试 ffrt_task_attr_set_get_delay
156 * 操作步骤 :1、调用ffrt_task_attr_set_delay接口设置队列延时时间
157 * 2、使用ffrt_task_attr_get_delay查询时间
158 * 预期结果 :查询结果与设定相同,初始值为0
159 */
HWTEST_F(QueueTest, ffrt_task_attr_set_get_delay, TestSize.Level1)160 HWTEST_F(QueueTest, ffrt_task_attr_set_get_delay, TestSize.Level1)
161 {
162 // succ free
163 ffrt_task_attr_t task_attr;
164 (void)ffrt_task_attr_init(&task_attr); // attr 缺少 init 无法看护
165 // set_attr_delay
166 uint64_t delay = 100;
167 ffrt_task_attr_set_delay(nullptr, delay);
168 ffrt_task_attr_set_delay(&task_attr, delay);
169 // error and return 0
170 delay = ffrt_task_attr_get_delay(nullptr);
171 EXPECT_EQ(delay, 0);
172 delay = ffrt_task_attr_get_delay(&task_attr);
173 EXPECT_EQ(delay, 100);
174 ffrt_task_attr_destroy(&task_attr);
175 }
176
177 /*
178 * 测试用例名称 : serial_queue_task_create_destroy_fail
179 * 测试用例描述:串行任务提交和销毁失败
180 * 操作步骤 :1、直接调用串行队列接口提交空任务,随后销毁任务
181 * 2、调用串行队列创建接口创建队列并提交空任务
182 * 3、调用串行队列创建接口创建队列并提交任务,随后销毁任务
183 * 预期结果 :2提交失败并返回nullptr,3提交成功
184 */
HWTEST_F(QueueTest, serial_queue_task_create_destroy_fail, TestSize.Level1)185 HWTEST_F(QueueTest, serial_queue_task_create_destroy_fail, TestSize.Level1)
186 {
187 // input invalid
188 ffrt_task_handle_t task = ffrt_queue_submit_h(nullptr, nullptr, nullptr);
189 ffrt_task_handle_destroy(task);
190
191 ffrt_queue_attr_t queue_attr;
192 (void)ffrt_queue_attr_init(&queue_attr); // 初始化属性,必须
193 ffrt_queue_t queue_handle = ffrt_queue_create(ffrt_queue_serial, "test_queue", &queue_attr);
194 task = ffrt_queue_submit_h(queue_handle, nullptr, nullptr);
195 EXPECT_EQ(task == nullptr, 1);
196
197 std::function<void()> basicFunc = std::bind(PrintForTest, nullptr);
198 task = ffrt_queue_submit_h(queue_handle, create_function_wrapper(basicFunc, ffrt_function_kind_queue), nullptr);
199 ffrt_queue_wait(task);
200 // succ free
201 EXPECT_EQ(task == nullptr, 0);
202 ffrt_task_handle_destroy(task);
203 ffrt_queue_attr_destroy(&queue_attr);
204 }
205
206 /*
207 * 测试用例名称 : serial_multi_submit_succ
208 * 测试用例描述:循环提交普通任务和延时任务,执行成功
209 * 操作步骤 :1、循环提交普通任务90次
210 * 2、循环提交延时任务20次,取消10次
211 * 预期结果 :总共应执行100+取消前已执行的次数
212 */
HWTEST_F(QueueTest, serial_multi_submit_succ, TestSize.Level1)213 HWTEST_F(QueueTest, serial_multi_submit_succ, TestSize.Level1)
214 {
215 ffrt_queue_attr_t queue_attr;
216 (void)ffrt_queue_attr_init(&queue_attr); // 初始化属性,必须
217 ffrt_queue_t queue_handle = ffrt_queue_create(ffrt_queue_serial, "test_queue", &queue_attr);
218
219 int result = 0;
220 int cancelFailedNum = 0;
221 std::function<void()>&& basicFunc = [&result]() { OnePlusForTest(static_cast<void*>(&result)); };
222 ffrt_task_attr_t task_attr;
223 (void)ffrt_task_attr_init(&task_attr); // 初始化task属性,必须
224 ffrt_task_attr_set_delay(&task_attr, 100); // 设置任务0.1ms后才执行,非必须
225
226 for (int n = 0; n < 10; ++n) {
227 for (int i = 0; i < 9; ++i) {
228 ffrt_queue_submit(queue_handle, create_function_wrapper(basicFunc, ffrt_function_kind_queue), nullptr);
229 }
230
231 ffrt_task_handle_t t1 =
232 ffrt_queue_submit_h(queue_handle, create_function_wrapper(basicFunc, ffrt_function_kind_queue), &task_attr);
233 ffrt_task_handle_t t2 =
234 ffrt_queue_submit_h(queue_handle, create_function_wrapper(basicFunc, ffrt_function_kind_queue), &task_attr);
235 cancelFailedNum += ffrt_queue_cancel(t1);
236 ffrt_task_handle_destroy(t1); // 销毁task_handle,必须
237
238 ffrt_queue_wait(t2);
239 ffrt_task_handle_destroy(t2);
240 }
241
242 EXPECT_EQ(result, (cancelFailedNum + 100));
243 ffrt_queue_attr_destroy(&queue_attr);
244 ffrt_queue_destroy(queue_handle);
245 }
246
247 /*
248 * 测试用例名称 : serial_early_quit_succ
249 * 测试用例描述:主动销毁队列,未执行的任务取消
250 * 操作步骤 :1、提交10000个斐波那契任务
251 2、至少取消1个
252 * 预期结果 :取消成功
253 */
HWTEST_F(QueueTest, serial_early_quit_succ, TestSize.Level1)254 HWTEST_F(QueueTest, serial_early_quit_succ, TestSize.Level1)
255 {
256 ffrt_queue_attr_t queue_attr;
257 (void)ffrt_queue_attr_init(&queue_attr); // 初始化属性,必须
258 ffrt_queue_t queue_handle = ffrt_queue_create(ffrt_queue_serial, "test_queue", &queue_attr);
259 int fibnum = 10;
260 int result = 0;
261 int expect = fibonacci(fibnum);
262 std::function<void()>&& basicFunc = [&result, fibnum]() {
263 FibonacciTest(static_cast<void*>(&result), fibnum);
264 usleep(10);
265 };
266 for (int i = 0; i < 10000; ++i) {
267 ffrt_queue_submit(queue_handle, create_function_wrapper(basicFunc, ffrt_function_kind_queue), nullptr);
268 }
269
270 ffrt_queue_destroy(queue_handle);
271 printf("result = %d\n", result);
272 EXPECT_EQ(result < expect * 10000, 1);
273 }
274
275 /*
276 * 测试用例名称 : serial_double_cancel_failed
277 * 测试用例描述:对一个任务取消两次
278 * 操作步骤 :1、调用串行队列创建接口创建队列,设置延时并提交任务
279 2、调用两次ffrt_queue_cancel取消同一任务
280 * 预期结果 :首次取消成功,第二次取消失败
281 */
282 HWTEST_F(QueueTest, serial_double_cancel_failed, TestSize.Level1)
283 {
284 ffrt_queue_attr_t queue_attr;
285 (void)ffrt_queue_attr_init(&queue_attr); // 初始化属性,必须
286 ffrt_queue_t queue_handle = ffrt_queue_create(ffrt_queue_serial, "test_queue", &queue_attr);
287
288 int result = 0;
289 std::function<void()>&& basicFunc = [&result]() { OnePlusForTest(static_cast<void*>(&result)); };
290 ffrt_task_attr_t task_attr;
291 (void)ffrt_task_attr_init(&task_attr); // 初始化task属性,必须
292 ffrt_task_attr_set_delay(&task_attr, 100); // 设置任务0.1ms后才执行,非必须
293
294 ffrt_task_handle_t t1 =
295 ffrt_queue_submit_h(queue_handle, create_function_wrapper(basicFunc, ffrt_function_kind_queue), &task_attr);
296 int cancel = ffrt_queue_cancel(t1);
297 EXPECT_EQ(cancel, 0);
298 cancel = ffrt_queue_cancel(t1);
299 EXPECT_EQ(cancel, 1);
300 ffrt_task_handle_destroy(t1); // 销毁task_handle,必须
301
302 ffrt_queue_destroy(queue_handle);
303 }
304
305 /*
306 * 测试用例名称 : ffrt_queue_attr_des
307 * 测试用例描述:设置串行队列qos等级,销毁队列attr
308 * 操作步骤 :1、设置队列qos等级,调用串行队列创建接口创建队列
309 2、调用ffrt_queue_attr_destroy接口销毁队列创建的attr
310 * 预期结果 :设置与销毁成功
311 */
312 HWTEST_F(QueueTest, ffrt_queue_attr_des, TestSize.Level1)
313 {
314 ffrt_queue_attr_t queue_attr;
315 (void)ffrt_queue_attr_init(&queue_attr);
316 ffrt_queue_attr_set_qos(&queue_attr, ffrt_qos_background);
317 ffrt_qos_t qos = ffrt_queue_attr_get_qos(&queue_attr);
318 EXPECT_EQ(qos == ffrt_qos_background, 1);
319 ffrt_queue_attr_destroy(&queue_attr);
320 }
321
322 /*
323 * 测试用例名称 : ffrt_queue_delay_timeout
324 * 测试用例描述:任务队列超时,以及延时任务
325 * 操作步骤 :1、设置队列超时时间与超时回调,调用串行队列创建接口创建队列
326 2、设置延时并提交任务
327 * 预期结果 :超时执行回调
328 */
329 HWTEST_F(QueueTest, ffrt_queue_delay_timeout, TestSize.Level1)
330 {
331 int x = 0;
332 std::function<void()>&& basicFunc1 = [&]() {
333 x = x + 1;
334 };
335 ffrt_function_header_t* ffrt_header_t = ffrt::create_function_wrapper((basicFunc1));
336
337 ffrt_queue_attr_t queue_attr;
338 (void)ffrt_queue_attr_init(&queue_attr);
339 ffrt_queue_attr_set_callback(&queue_attr, ffrt_header_t);
340 ffrt_queue_attr_set_timeout(&queue_attr, 2000);
341 uint64_t timeout = ffrt_queue_attr_get_timeout(&queue_attr);
342 EXPECT_EQ(timeout, 2000);
343
344 ffrt_queue_t queue_handle = ffrt_queue_create(ffrt_queue_serial, "test_queue", &queue_attr);
345
346 int result = 0;
347 std::function<void()>&& basicFunc = [&result]() {
348 OnePlusForTest(static_cast<void*>(&result));
349 usleep(3000);
350 };
351 ffrt_task_attr_t task_attr;
352 (void)ffrt_task_attr_init(&task_attr);
353 ffrt_task_attr_set_delay(&task_attr, 1000);
354
355 ffrt_task_handle_t t1 =
356 ffrt_queue_submit_h(queue_handle, create_function_wrapper(basicFunc, ffrt_function_kind_queue), &task_attr);
357
358 ffrt_queue_wait(t1);
359 ffrt_task_handle_destroy(t1);
360 EXPECT_EQ(result, 1);
361 EXPECT_EQ(x, 1);
362 ffrt_queue_destroy(queue_handle);
363 }
364
365 HWTEST_F(QueueTest, ffrt_queue_dfx_api_0001, TestSize.Level1)
366 {
367 // ffrt_queue_attr_set_timeout接口attr为异常值
368 ffrt_queue_attr_t queue_attr;
369 (void)ffrt_queue_attr_init(&queue_attr); // 初始化属性,必须
370 ffrt_queue_attr_set_timeout(nullptr, 10000);
371 uint64_t time = ffrt_queue_attr_get_timeout(&queue_attr);
372 EXPECT_EQ(time, 0);
373 ffrt_queue_t queue_handle = ffrt_queue_create(ffrt_queue_serial, "test_queue", &queue_attr);
374 EXPECT_TRUE(queue_handle != nullptr);
375
376 // 销毁队列
377 ffrt_queue_attr_destroy(&queue_attr);
378 ffrt_queue_destroy(queue_handle);
379 }
380
381 HWTEST_F(QueueTest, ffrt_queue_dfx_api_0002, TestSize.Level1)
382 {
383 // ffrt_queue_attr_get_timeout接口attr为异常值
384 ffrt_queue_attr_t queue_attr;
385 (void)ffrt_queue_attr_init(&queue_attr); // 初始化属性,必须
386 ffrt_queue_attr_set_timeout(&queue_attr, 10000);
387 uint64_t time = ffrt_queue_attr_get_timeout(nullptr);
388 EXPECT_EQ(time, 0);
389 time = ffrt_queue_attr_get_timeout(&queue_attr);
390 EXPECT_EQ(time, 10000);
391 ffrt_queue_t queue_handle = ffrt_queue_create(ffrt_queue_serial, "test_queue", &queue_attr);
392 EXPECT_TRUE(queue_handle != nullptr);
393
394 // 销毁队列
395 ffrt_queue_attr_destroy(&queue_attr);
396 ffrt_queue_destroy(queue_handle);
397 }
398
399 HWTEST_F(QueueTest, ffrt_queue_dfx_api_0003, TestSize.Level1)
400 {
401 // ffrt_queue_attr_set_timeoutCb接口attr为异常值
402 std::function<void()> cbOne = []() { printf("first set callback\n"); };
403
404 ffrt_queue_attr_t queue_attr;
405 (void)ffrt_queue_attr_init(&queue_attr); // 初始化属性,必须
406 ffrt_queue_attr_set_callback(nullptr, ffrt::create_function_wrapper(cbOne, ffrt_function_kind_queue));
407 ffrt_queue_t queue_handle = ffrt_queue_create(ffrt_queue_serial, "test_queue", &queue_attr);
408 EXPECT_TRUE(queue_handle != nullptr);
409
410 // 销毁队列
411 ffrt_queue_attr_destroy(&queue_attr);
412 ffrt_queue_destroy(queue_handle);
413 }
414
415 HWTEST_F(QueueTest, ffrt_queue_dfx_api_0004, TestSize.Level1)
416 {
417 // ffrt_queue_attr_get_timeoutCb接口attr为异常值
418 std::function<void()> cbOne = []() { printf("first set callback\n"); };
419
420 ffrt_queue_attr_t queue_attr;
421 (void)ffrt_queue_attr_init(&queue_attr); // 初始化属性,必须
422 ffrt_queue_attr_set_callback(&queue_attr, ffrt::create_function_wrapper(cbOne, ffrt_function_kind_queue));
423 ffrt_function_header_t* func = ffrt_queue_attr_get_callback(nullptr);
424 EXPECT_TRUE(func == nullptr);
425 func = ffrt_queue_attr_get_callback(&queue_attr);
426 EXPECT_TRUE(func != nullptr);
427 ffrt_queue_t queue_handle = ffrt_queue_create(ffrt_queue_serial, "test_queue", &queue_attr);
428 EXPECT_TRUE(queue_handle != nullptr);
429
430 // 销毁队列
431 ffrt_queue_destroy(queue_handle);
432 ffrt_queue_attr_destroy(&queue_attr);
433 }
434
435 /*
436 * 测试用例名称 : ffrt_task_attr_set_queue_priority
437 * 测试用例描述 : 测试 ffrt_task_attr_set_queue_priority
438 * 操作步骤 : 1、调用ffrt_task_attr_set_queue_priority接口设置队列优先级
439 * 2、使用ffrt_task_attr_get_queue_priority查询优先级
440 * 预期结果 : 查询结果与设定相同,值为3
441 */
442 HWTEST_F(QueueTest, ffrt_task_attr_set_queue_priority, TestSize.Level1)
443 {
444 ffrt_task_attr_t task_attr;
445 (void)ffrt_task_attr_init(&task_attr);
446 ffrt_queue_priority_t priority = ffrt_queue_priority_low;
447 ffrt_task_attr_set_queue_priority(nullptr, priority);
448 ffrt_task_attr_set_queue_priority(&task_attr, priority);
449 priority = ffrt_task_attr_get_queue_priority(nullptr);
450 EXPECT_EQ(priority, ffrt_queue_priority_immediate);
451 priority = ffrt_task_attr_get_queue_priority(&task_attr);
452 EXPECT_EQ(priority, ffrt_queue_priority_low);
453 ffrt_task_attr_destroy(&task_attr);
454 }
455
456 /*
457 * 测试用例名称 : ffrt_queue_attr_set_max_concurrency
458 * 测试用例描述 : 测试 ffrt_queue_attr_set_max_concurrency
459 * 操作步骤 : 1、调用ffrt_queue_attr_set_max_concurrency设置FFRT并行队列,并行度为4
460 * 2、使用ffrt_queue_attr_get_max_concurrency查询并行度
461 * 预期结果 : 查询结果与设定相同,值为4
462 */
463 HWTEST_F(QueueTest, ffrt_queue_attr_set_max_concurrency, TestSize.Level1)
464 {
465 ffrt_queue_attr_t queue_attr;
466 (void)ffrt_queue_attr_init(&queue_attr);
467 uint64_t concurrency = 4;
468 ffrt_queue_attr_set_max_concurrency(nullptr, concurrency);
469 ffrt_queue_attr_set_max_concurrency(&queue_attr, concurrency);
470 concurrency = ffrt_queue_attr_get_max_concurrency(nullptr);
471 EXPECT_EQ(concurrency, 0);
472 concurrency = ffrt_queue_attr_get_max_concurrency(&queue_attr);
473 EXPECT_EQ(concurrency, 4);
474 ffrt_queue_attr_destroy(&queue_attr);
475
476 ffrt_queue_attr_t queue_attr1;
477 (void)ffrt_queue_attr_init(&queue_attr1);
478 concurrency = 0;
479 ffrt_queue_attr_set_max_concurrency(&queue_attr1, concurrency);
480 concurrency = ffrt_queue_attr_get_max_concurrency(&queue_attr1);
481 EXPECT_EQ(concurrency, 1);
482 ffrt_queue_attr_destroy(&queue_attr1);
483 }
484
485 /*
486 * 测试用例名称 : ffrt_queue_has_task
487 * 测试用例描述 : 测试 ffrt_queue_has_task
488 * 操作步骤 : 1、往队列中提交若干任务,其中包含待查询的任务
489 * 2、调用ffrt_queue_has_task查询任务是否在队列中
490 * 预期结果 : 查询结果与预期相同
491 */
492 HWTEST_F(QueueTest, ffrt_queue_has_task, TestSize.Level1)
493 {
494 ffrt_queue_attr_t queue_attr;
495 (void)ffrt_queue_attr_init(&queue_attr); // 初始化属性,必须
496 ffrt_queue_t queue_handle = ffrt_queue_create(ffrt_queue_serial, "test_queue", &queue_attr);
497
498 std::mutex lock;
499 lock.lock();
500 std::function<void()> basicFunc = [&]() { lock.lock(); };
501 std::function<void()> emptyFunc = []() {};
502
503 ffrt_task_attr_t task_attr;
504 ffrt_task_attr_init(&task_attr);
505 ffrt_task_attr_set_name(&task_attr, "basic_function");
506 ffrt_task_handle_t handle = ffrt_queue_submit_h(queue_handle,
507 create_function_wrapper(basicFunc, ffrt_function_kind_queue), &task_attr);
508
509 for (int i = 0; i < 10; i++) {
510 std::string name = "empty_function_" + std::to_string(i);
511 ffrt_task_attr_set_name(&task_attr, name.c_str());
512 ffrt_queue_submit(queue_handle, create_function_wrapper(emptyFunc, ffrt_function_kind_queue), &task_attr);
513 }
514
515 // 全字匹配
516 for (int i = 0; i < 10; i++) {
517 std::string name = "empty_function_" + std::to_string(i);
518 bool hasEmptyTask = ffrt_queue_has_task(queue_handle, name.c_str());
519 EXPECT_EQ(hasEmptyTask, true);
520 }
521
522 // 正则匹配
523 bool hasEmptyTask = ffrt_queue_has_task(queue_handle, "empty_function_.*");
524 EXPECT_EQ(hasEmptyTask, true);
525
526 hasEmptyTask = ffrt_queue_has_task(queue_handle, "random_function");
527 EXPECT_EQ(hasEmptyTask, false);
528
529 lock.unlock();
530 ffrt_queue_wait(handle);
531
532 ffrt_queue_attr_destroy(&queue_attr);
533 ffrt_queue_destroy(queue_handle);
534 }
535
536 /*
537 * 测试用例名称 : ffrt_queue_cancel_all_and_cancel_by_name
538 * 测试用例描述 : 测试 ffrt_queue_cancel_all、ffrt_queue_cancel_by_name
539 * 操作步骤 : 1、往队列中提交若干任务
540 * 2、调用ffrt_queue_cancel_by_name取消指定任务
541 * 3、调用ffrt_queue_cancel_all取消所有任务
542 * 预期结果 : 任务取消成功
543 */
544 HWTEST_F(QueueTest, ffrt_queue_cancel_all_and_cancel_by_name, TestSize.Level1)
545 {
546 ffrt_queue_attr_t queue_attr;
547 (void)ffrt_queue_attr_init(&queue_attr); // 初始化属性,必须
548 ffrt_queue_t queue_handle = ffrt_queue_create(
549 static_cast<ffrt_queue_type_t>(ffrt_queue_eventhandler_adapter), "test_queue", &queue_attr);
550
551 std::mutex lock;
552 lock.lock();
553 std::function<void()> basicFunc = [&]() { lock.lock(); };
554 std::function<void()> emptyFunc = []() {};
555
556 ffrt_task_attr_t task_attr;
557 ffrt_task_attr_init(&task_attr);
558 ffrt_task_attr_set_name(&task_attr, "basic_function");
559 ffrt_task_handle_t handle = ffrt_queue_submit_h(queue_handle,
560 create_function_wrapper(basicFunc, ffrt_function_kind_queue), &task_attr);
561
562 for (int i = 0; i < 10; i++) {
563 std::string name = "empty_function_" + std::to_string(i);
564 ffrt_task_attr_set_name(&task_attr, name.c_str());
565 ffrt_queue_submit(queue_handle, create_function_wrapper(emptyFunc, ffrt_function_kind_queue), &task_attr);
566 }
567
568 // 测试ffrt_queue_cancel_by_name
569 bool hasEmptyTask = ffrt_queue_has_task(queue_handle, "empty_function_3");
570 EXPECT_EQ(hasEmptyTask, true);
571
572 ffrt_queue_cancel_by_name(queue_handle, "empty_function_3");
573
574 hasEmptyTask = ffrt_queue_has_task(queue_handle, "empty_function_3");
575 EXPECT_EQ(hasEmptyTask, false);
576
577 // 测试ffrt_queue_cancel_all
578 hasEmptyTask = ffrt_queue_has_task(queue_handle, "empty_function_.*");
579 EXPECT_EQ(hasEmptyTask, true);
580
581 bool isIdle = ffrt_queue_is_idle(queue_handle);
582 EXPECT_EQ(isIdle, false);
583
584 ffrt_queue_cancel_all(queue_handle);
585
586 hasEmptyTask = ffrt_queue_has_task(queue_handle, "empty_function_.*");
587 EXPECT_EQ(hasEmptyTask, false);
588
589 lock.unlock();
590 ffrt_queue_cancel_and_wait(queue_handle);
591 ffrt_queue_wait(handle);
592
593 isIdle = ffrt_queue_is_idle(queue_handle);
594 EXPECT_EQ(isIdle, true);
595
596 ffrt_queue_attr_destroy(&queue_attr);
597 ffrt_queue_destroy(queue_handle);
598 }
599
600 /*
601 * 测试用例名称 : ffrt_queue_deque_task_priority_with_greedy
602 * 测试用例描述 : 测试并发队列取任务逻辑
603 * 操作步骤 : 1、往队列中提交不同优先级的若干任务
604 * 预期结果 : 任务按照优先级从高往低执行,每执行5个高优先级任务,就执行一个低优先级任务
605 */
606 HWTEST_F(QueueTest, ffrt_queue_deque_task_priority_with_greedy, TestSize.Level1)
607 {
608 ffrt_queue_attr_t queue_attr;
609 (void)ffrt_queue_attr_init(&queue_attr); // 初始化属性,必须
610 ffrt_queue_t queue_handle = ffrt_queue_create(
611 static_cast<ffrt_queue_type_t>(ffrt_queue_eventhandler_adapter), "test_queue", &queue_attr);
612
613 std::mutex lock;
614 lock.lock();
615 std::function<void()> basicFunc = [&]() { lock.lock(); };
616 std::vector<std::function<void()>> priorityFuncs(5, nullptr);
617 std::vector<int> priorityCount(5, 0);
618 for (int idx = 0; idx < 5; idx++) {
619 priorityFuncs[idx] = [idx, &priorityCount]() {
620 if (idx < 4 && priorityCount[idx + 1] == 0) {
621 priorityCount[idx]++;
622 }
623
624 if (idx == 4 && priorityCount[idx] == 0) {
625 for (int prevIdx = 0; prevIdx < 3; prevIdx++) {
626 if (priorityCount[prevIdx] != 5) {
627 priorityCount[4] = -1;
628 return;
629 }
630 }
631 priorityCount[4] = 1;
632 }
633 };
634 }
635
636 ffrt_task_attr_t task_attr;
637 ffrt_task_attr_init(&task_attr);
638 ffrt_task_attr_set_queue_priority(&task_attr, ffrt_queue_priority_idle);
639 ffrt_queue_submit(queue_handle, create_function_wrapper(basicFunc, ffrt_function_kind_queue), &task_attr);
640
641 ffrt_task_handle_t handle;
642 for (int prio = 0; prio < 5; prio++) {
643 ffrt_task_attr_set_queue_priority(&task_attr, static_cast<ffrt_queue_priority_t>(prio));
644 for (int i = 0; i < 10; i++) {
645 handle = ffrt_queue_submit_h(queue_handle,
646 create_function_wrapper(priorityFuncs[prio], ffrt_function_kind_queue), &task_attr);
647 }
648 }
649
650 lock.unlock();
651 ffrt_queue_wait(handle);
652
653 for (int idx = 0; idx < 3; idx++) {
654 EXPECT_EQ(priorityCount[idx], 5);
655 }
656 EXPECT_EQ(priorityCount[3], 10);
657 EXPECT_EQ(priorityCount[4], 1);
658
659 ffrt_queue_attr_destroy(&queue_attr);
660 ffrt_queue_destroy(queue_handle);
661 }
662
663 /*
664 * 测试用例名称 : ffrt_queue_submit_head
665 * 测试用例描述 : 测试 ffrt_queue_submit_head
666 * 操作步骤 : 1、往队列中提交若干任务
667 * 2、调用ffrt_queue_submit_head提交任务至队头
668 * 预期结果 : 提交到对头的任务优先被执行
669 */
670 HWTEST_F(QueueTest, ffrt_queue_submit_head, TestSize.Level1)
671 {
672 ffrt_queue_attr_t queue_attr;
673 (void)ffrt_queue_attr_init(&queue_attr); // 初始化属性,必须
674 ffrt_queue_t queue_handle = ffrt_queue_create(
675 static_cast<ffrt_queue_type_t>(ffrt_queue_eventhandler_adapter), "test_queue", &queue_attr);
676
677 int result = 0;
678 std::mutex lock;
679 lock.lock();
680 std::function<void()> basicFunc = [&]() { lock.lock(); };
681 std::vector<std::function<void()>> assignFuncs(8, nullptr);
682 std::vector<int> results;
683 std::vector<int> expectResults {6, 2, 1, 4, 3, 5, 8, 7};
684 for (int idx = 0; idx < 8; idx++) {
685 assignFuncs[idx] = [idx, &results]() {
686 results.push_back(idx + 1);
687 };
688 }
689
690 ffrt_task_attr_t task_attr;
691 ffrt_task_attr_init(&task_attr);
692 ffrt_task_attr_set_queue_priority(&task_attr, ffrt_queue_priority_immediate);
693 ffrt_task_attr_set_name(&task_attr, "basic_function");
694 ffrt_queue_submit_head(queue_handle, create_function_wrapper(basicFunc, ffrt_function_kind_queue), &task_attr);
695
696 ffrt_queue_submit_head(queue_handle, create_function_wrapper(assignFuncs[0], ffrt_function_kind_queue), &task_attr);
697 ffrt_queue_submit_head(queue_handle, create_function_wrapper(assignFuncs[1], ffrt_function_kind_queue), &task_attr);
698
699 ffrt_task_attr_set_queue_priority(&task_attr, ffrt_queue_priority_high);
700 ffrt_queue_submit_head(queue_handle, create_function_wrapper(assignFuncs[2], ffrt_function_kind_queue), &task_attr);
701 ffrt_queue_submit_head(queue_handle, create_function_wrapper(assignFuncs[3], ffrt_function_kind_queue), &task_attr);
702
703 ffrt_task_attr_set_queue_priority(&task_attr, ffrt_queue_priority_low);
704 ffrt_queue_submit_head(queue_handle, create_function_wrapper(assignFuncs[4], ffrt_function_kind_queue), &task_attr);
705
706 ffrt_task_attr_set_queue_priority(&task_attr, ffrt_queue_priority_immediate);
707 ffrt_queue_submit_head(queue_handle, create_function_wrapper(assignFuncs[5], ffrt_function_kind_queue), &task_attr);
708
709 ffrt_task_attr_set_queue_priority(&task_attr, ffrt_queue_priority_idle);
710 ffrt_task_handle_t handle = ffrt_queue_submit_head_h(queue_handle,
711 create_function_wrapper(assignFuncs[6], ffrt_function_kind_queue), &task_attr);
712 ffrt_queue_submit_head(queue_handle, create_function_wrapper(assignFuncs[7], ffrt_function_kind_queue), &task_attr);
713
714 lock.unlock();
715 ffrt_queue_wait(handle);
716 EXPECT_EQ(results, expectResults);
717
718 ffrt_queue_attr_destroy(&queue_attr);
719 ffrt_queue_destroy(queue_handle);
720 }
721
722 HWTEST_F(QueueTest, ffrt_eventhandler_interactive_queue, TestSize.Level1)
723 {
724 ffrt_queue_attr_t queue_attr;
725 (void)ffrt_queue_attr_init(&queue_attr); // 初始化属性,必须
726 ffrt_queue_t queue_handle = ffrt_queue_create(
727 static_cast<ffrt_queue_type_t>(ffrt_queue_eventhandler_interactive), "test_queue", &queue_attr);
728 EXPECT_TRUE(queue_handle != nullptr);
729
730 ffrt_queue_attr_destroy(&queue_attr);
731 ffrt_queue_destroy(queue_handle);
732 }
733
734 HWTEST_F(QueueTest, ffrt_get_main_queue, TestSize.Level1)
735 {
736 // ffrt test case begin
737 ffrt::queue *serialQueue = new ffrt::queue("ffrt_normal_queue", {});
738 ffrt_queue_t mainQueue = ffrt_get_main_queue();
739 ffrt_task_attr_t attr;
740 ffrt_task_attr_init(&attr);
741 ffrt_task_attr_set_qos(&attr, ffrt_qos_user_initiated);
742 int result = 0;
743 std::function<void()>&& basicFunc = [&result]() {
744 OnePlusForTest(static_cast<void*>(&result));
745 OnePlusForTest(static_cast<void*>(&result));
746 EXPECT_EQ(result, 2);
747 usleep(3000);
748 };
749
750 ffrt::task_handle handle = serialQueue->submit_h(
751 [&] {
752 result = result + 1;
753 ffrt_queue_submit(mainQueue, ffrt::create_function_wrapper(basicFunc, ffrt_function_kind_queue),
754 &attr);
755 },
756 ffrt::task_attr().qos(3).name("ffrt main_queue."));
757
758 serialQueue->wait(handle);
759 EXPECT_EQ(result, 1);
760 }
761
762 HWTEST_F(QueueTest, ffrt_get_current_queue, TestSize.Level1)
763 {
764 // ffrt test case begin
765 ffrt::queue *serialQueue = new ffrt::queue("ffrt_normal_queue", {});
766 ffrt_queue_t currentQueue = ffrt_get_current_queue();
767 ffrt_task_attr_t attr;
768 ffrt_task_attr_init(&attr);
769 ffrt_task_attr_set_qos(&attr, ffrt_qos_user_initiated);
770 int result = 0;
771 std::function<void()>&& basicFunc = [&result]() {
772 OnePlusForTest(static_cast<void*>(&result));
773 OnePlusForTest(static_cast<void*>(&result));
774 EXPECT_EQ(result, 3);
775 usleep(3000);
776 };
777
778 ffrt::task_handle handle = serialQueue->submit_h(
779 [&] {
780 result = result + 1;
781 ffrt_queue_submit(currentQueue, ffrt::create_function_wrapper(basicFunc, ffrt_function_kind_queue),
782 &attr);
783 },
784 ffrt::task_attr().qos(3).name("ffrt current_queue."));
785
786 serialQueue->wait(handle);
787
788 EXPECT_EQ(result, 1);
789 }