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 #include "queue/base_queue.h"
23 #include "sync/delayed_worker.h"
24 #define private public
25 #include "queue/queue_monitor.h"
26 #undef private
27 #include "util/spmc_queue.h"
28 #include "util/ffrt_facade.h"
29 #include "util/white_list.h"
30
31 using namespace std;
32 using namespace ffrt;
33 using namespace testing;
34 #ifdef HWTEST_TESTING_EXT_ENABLE
35 using namespace testing::ext;
36 #endif
37
38 class QueueTest : public testing::Test {
39 protected:
SetUpTestCase()40 static void SetUpTestCase()
41 {
42 }
43
TearDownTestCase()44 static void TearDownTestCase()
45 {
46 }
47
SetUp()48 void SetUp() override
49 {
50 }
51
TearDown()52 void TearDown() override
53 {
54 }
55 };
56
57 #if defined(__clang__)
58 #define OPTIMIZE_OFF __attribute__((optnone))
59 #elif defined(__GNUC__)
60 #define OPTIMIZE_OFF __attribute__((optimize(0)))
61 #else
62 #define OPTIMIZE_OFF
63 #endif
64
65 namespace {
OnePlusForTest(void * data)66 void OPTIMIZE_OFF OnePlusForTest(void* data)
67 {
68 *(int*)data += 1;
69 }
70
PrintForTest(void * data)71 void PrintForTest(void* data)
72 {
73 printf("run no input func PrintForTest\n");
74 }
75
fibonacci(int n)76 int fibonacci(int n)
77 {
78 if (n == 0 || n == 1) {
79 return n;
80 }
81 return fibonacci(n - 1) + fibonacci(n - 2);
82 }
83
FibonacciTest(void * data,int fibnum)84 void FibonacciTest(void* data, int fibnum)
85 {
86 int testnum = fibonacci(fibnum);
87 *(int*)data += testnum;
88 }
89 } // namespace
90
EmptyFunction()91 void EmptyFunction() {}
92 /*
93 * 测试用例名称 : serial_queue_submit_cancel_succ
94 * 测试用例描述:提交、取消串行延时任务成功
95 * 预置条件 :1、调用串行队列创建接口创建队列
96 * 操作步骤 :1、提交串行队列任务并执行
97 * 2、提交延时串行队列任务并执行
98 * 预期结果 :执行成功
99 */
100 HWTEST_F(QueueTest, serial_queue_submit_cancel_succ, TestSize.Level0)
101 {
102 // 创建队列
103 ffrt_queue_attr_t queue_attr;
104 (void)ffrt_queue_attr_init(&queue_attr); // 初始化属性,必须
105 ffrt_queue_t queue_handle = ffrt_queue_create(ffrt_queue_serial, "test_queue", &queue_attr);
106
107 int result = 0;
__anon5324c4860202() 108 std::function<void()> basicFunc = [&result]() { OnePlusForTest(static_cast<void*>(&result)); };
109 ffrt_queue_submit(queue_handle, create_function_wrapper(basicFunc, ffrt_function_kind_queue), nullptr);
110
111 ffrt_task_handle_t task1 =
112 ffrt_queue_submit_h(queue_handle, create_function_wrapper(basicFunc, ffrt_function_kind_queue), nullptr);
113 ffrt_queue_wait(task1);
114 ffrt_task_handle_destroy(task1); // 销毁task_handle,必须
115 EXPECT_EQ(result, 2);
116
117 ffrt_task_attr_t task_attr;
118 (void)ffrt_task_attr_init(&task_attr); // 初始化task属性,必须
119 ffrt_task_attr_set_delay(&task_attr, 1000); // 设置任务1ms后才执行,非必须
120 ffrt_task_handle_t task2 =
121 ffrt_queue_submit_h(queue_handle, create_function_wrapper(basicFunc, ffrt_function_kind_queue), &task_attr);
122 int cancel = ffrt_queue_cancel(task2);
123 ffrt_task_handle_destroy(task2); // 销毁task_handle,必须
124 ffrt_queue_attr_destroy(&queue_attr);
125 EXPECT_EQ(cancel, 0);
126 EXPECT_EQ(result, 2);
127
128 // 销毁队列
129 ffrt_queue_destroy(queue_handle);
130 }
131
132 /*
133 * 测试用例名称 : serial_queue_create_fail
134 * 测试用例描述:串行队列创建和销毁失败
135 * 预置条件 :1、调用串行队列创建接口创建队列
136 * 操作步骤 :1、调用串行队列创建接口创建队列,type为非串行队列
137 * 2、调用串行队列创建接口创建队列,type为串行队列,但name与attr为nullptr
138 * 3、调用串行队列创建接口创建队列,type为串行队列,但name为nullptr
139 * 预期结果 :1创建失败,2、3创建成功
140 */
141 HWTEST_F(QueueTest, serial_queue_create_fail, TestSize.Level0)
142 {
143 // input invalid
144 ffrt_queue_t queue_handle = ffrt_queue_create(ffrt_queue_max, nullptr, nullptr);
145 ffrt_queue_destroy(queue_handle);
146 ffrt_queue_destroy(nullptr);
147
148 queue_handle = ffrt_queue_create(ffrt_queue_serial, nullptr, nullptr);
149 EXPECT_EQ(queue_handle == nullptr, 0);
150 ffrt_queue_destroy(queue_handle);
151
152 // succ free
153 ffrt_queue_attr_t queue_attr;
154 (void)ffrt_queue_attr_init(&queue_attr); // attr 缺少 init 无法看护
155 queue_handle = ffrt_queue_create(ffrt_queue_serial, nullptr, &queue_attr);
156 EXPECT_EQ(queue_handle == nullptr, 0);
157 ffrt_queue_attr_destroy(&queue_attr);
158 ffrt_queue_destroy(queue_handle);
159 }
160
161 /*
162 * 测试用例名称 : ffrt_task_attr_set_get_delay
163 * 测试用例描述:测试 ffrt_task_attr_set_get_delay
164 * 操作步骤 :1、调用ffrt_task_attr_set_delay接口设置队列延时时间
165 * 2、使用ffrt_task_attr_get_delay查询时间
166 * 预期结果 :查询结果与设定相同,初始值为0
167 */
168 HWTEST_F(QueueTest, ffrt_task_attr_set_get_delay, TestSize.Level0)
169 {
170 // succ free
171 ffrt_task_attr_t task_attr;
172 (void)ffrt_task_attr_init(&task_attr); // attr 缺少 init 无法看护
173 uint64_t maxUsCount = 1000000ULL * 100 * 60 * 60 * 24 * 365; // 100 year
174 ffrt_task_attr_set_delay(&task_attr, UINT64_MAX); // 测试时间溢出截断功能
175 EXPECT_EQ(ffrt_task_attr_get_delay(&task_attr), maxUsCount);
176 // set_attr_delay
177 uint64_t delay = 100;
178 ffrt_task_attr_set_delay(nullptr, delay);
179 ffrt_task_attr_set_delay(&task_attr, delay);
180 // error and return 0
181 delay = ffrt_task_attr_get_delay(nullptr);
182 EXPECT_EQ(delay, 0);
183 delay = ffrt_task_attr_get_delay(&task_attr);
184 EXPECT_EQ(delay, 100);
185 ffrt_task_attr_destroy(&task_attr);
186 }
187
188 /*
189 * 测试用例名称 : serial_queue_task_create_destroy_fail
190 * 测试用例描述:串行任务提交和销毁失败
191 * 操作步骤 :1、直接调用串行队列接口提交空任务,随后销毁任务
192 * 2、调用串行队列创建接口创建队列并提交空任务
193 * 3、调用串行队列创建接口创建队列并提交任务,随后销毁任务
194 * 预期结果 :2提交失败并返回nullptr,3提交成功
195 */
196 HWTEST_F(QueueTest, serial_queue_task_create_destroy_fail, TestSize.Level0)
197 {
198 // input invalid
199 ffrt_task_handle_t task = ffrt_queue_submit_h(nullptr, nullptr, nullptr);
200 ffrt_task_handle_destroy(task);
201
202 ffrt_queue_attr_t queue_attr;
203 (void)ffrt_queue_attr_init(&queue_attr); // 初始化属性,必须
204 ffrt_queue_t queue_handle = ffrt_queue_create(ffrt_queue_serial, "test_queue", &queue_attr);
205 task = ffrt_queue_submit_h(queue_handle, nullptr, nullptr);
206 EXPECT_EQ(task == nullptr, 1);
207
208 std::function<void()> basicFunc = std::bind(PrintForTest, nullptr);
209 task = ffrt_queue_submit_h(queue_handle, create_function_wrapper(basicFunc, ffrt_function_kind_queue), nullptr);
210 ffrt_queue_wait(task);
211 // succ free
212 EXPECT_EQ(task == nullptr, 0);
213 ffrt_task_handle_destroy(task);
214 ffrt_queue_attr_destroy(&queue_attr);
215 ffrt_queue_destroy(queue_handle);
216 }
217
218 /*
219 * 测试用例名称 : serial_multi_submit_succ
220 * 测试用例描述:循环提交普通任务和延时任务,执行成功
221 * 操作步骤 :1、循环提交普通任务90次
222 * 2、循环提交延时任务20次,取消10次
223 * 预期结果 :总共应执行100+取消前已执行的次数
224 */
225 HWTEST_F(QueueTest, serial_multi_submit_succ, TestSize.Level0)
226 {
227 ffrt_queue_attr_t queue_attr;
228 (void)ffrt_queue_attr_init(&queue_attr); // 初始化属性,必须
229 ffrt_queue_t queue_handle = ffrt_queue_create(ffrt_queue_serial, "test_queue", &queue_attr);
230
231 int result = 0;
232 int cancelFailedNum = 0;
__anon5324c4860302() 233 std::function<void()>&& basicFunc = [&result]() { OnePlusForTest(static_cast<void*>(&result)); };
234 ffrt_task_attr_t task_attr;
235 (void)ffrt_task_attr_init(&task_attr); // 初始化task属性,必须
236 ffrt_task_attr_set_delay(&task_attr, 100); // 设置任务0.1ms后才执行,非必须
237
238 for (int n = 0; n < 10; ++n) {
239 for (int i = 0; i < 9; ++i) {
240 ffrt_queue_submit(queue_handle, create_function_wrapper(basicFunc, ffrt_function_kind_queue), nullptr);
241 }
242
243 ffrt_task_handle_t t1 =
244 ffrt_queue_submit_h(queue_handle, create_function_wrapper(basicFunc, ffrt_function_kind_queue), &task_attr);
245 ffrt_task_handle_t t2 =
246 ffrt_queue_submit_h(queue_handle, create_function_wrapper(basicFunc, ffrt_function_kind_queue), &task_attr);
247 cancelFailedNum += ffrt_queue_cancel(t1);
248 ffrt_task_handle_destroy(t1); // 销毁task_handle,必须
249
250 ffrt_queue_wait(t2);
251 ffrt_task_handle_destroy(t2);
252 }
253
254 EXPECT_EQ(result, (cancelFailedNum + 100));
255 ffrt_queue_attr_destroy(&queue_attr);
256 ffrt_queue_destroy(queue_handle);
257 }
258
259 /*
260 * 测试用例名称 : concurrent_multi_submit_succ
261 * 测试用例描述:循环提交普通任务和延时任务,执行成功
262 * 操作步骤 :1、循环提交普通任务90次
263 * 2、循环提交延时任务20次,取消10次
264 * 预期结果 :总共应执行100+取消前已执行的次数
265 */
266 HWTEST_F(QueueTest, concurrent_multi_submit_succ, TestSize.Level0)
267 {
268 ffrt_queue_attr_t queue_attr;
269 (void)ffrt_queue_attr_init(&queue_attr); // 初始化属性,必须
270 ffrt_queue_t queue_handle = ffrt_queue_create(ffrt_queue_concurrent, "test_queue", &queue_attr);
271
272 int result = 0;
273 int cancelFailedNum = 0;
__anon5324c4860402() 274 std::function<void()>&& basicFunc = [&result]() { OnePlusForTest(static_cast<void*>(&result)); };
275 ffrt_task_attr_t task_attr;
276 (void)ffrt_task_attr_init(&task_attr); // 初始化task属性,必须
277 ffrt_task_attr_set_delay(&task_attr, 100); // 设置任务0.1ms后才执行,非必须
278
279 for (int n = 0; n < 10; ++n) {
280 for (int i = 0; i < 9; ++i) {
281 ffrt_queue_submit(queue_handle, create_function_wrapper(basicFunc, ffrt_function_kind_queue), nullptr);
282 }
283
284 ffrt_task_handle_t t1 =
285 ffrt_queue_submit_h(queue_handle, create_function_wrapper(basicFunc, ffrt_function_kind_queue), &task_attr);
286 ffrt_task_handle_t t2 =
287 ffrt_queue_submit_h(queue_handle, create_function_wrapper(basicFunc, ffrt_function_kind_queue), &task_attr);
288 cancelFailedNum += ffrt_queue_cancel(t1);
289 ffrt_task_handle_destroy(t1); // 销毁task_handle,必须
290
291 ffrt_queue_wait(t2);
292 ffrt_task_handle_destroy(t2);
293 }
294
295 EXPECT_EQ(result, (cancelFailedNum + 100));
296 ffrt_queue_attr_destroy(&queue_attr);
297 ffrt_queue_destroy(queue_handle);
298 }
299
300 /*
301 * 测试用例名称 : serial_early_quit_succ
302 * 测试用例描述:主动销毁队列,未执行的任务取消
303 * 操作步骤 :1、提交10000个斐波那契任务
304 2、至少取消1个
305 * 预期结果 :取消成功
306 */
307 HWTEST_F(QueueTest, serial_early_quit_succ, TestSize.Level0)
308 {
309 ffrt_queue_attr_t queue_attr;
310 (void)ffrt_queue_attr_init(&queue_attr); // 初始化属性,必须
311 ffrt_queue_t queue_handle = ffrt_queue_create(ffrt_queue_serial, "test_queue", &queue_attr);
312 int fibnum = 10;
313 int result = 0;
314 int expect = fibonacci(fibnum);
__anon5324c4860502() 315 std::function<void()>&& basicFunc = [&result, fibnum]() {
316 FibonacciTest(static_cast<void*>(&result), fibnum);
317 usleep(10);
318 };
319 for (int i = 0; i < 10000; ++i) {
320 ffrt_queue_submit(queue_handle, create_function_wrapper(basicFunc, ffrt_function_kind_queue), nullptr);
321 }
322
323 ffrt_queue_destroy(queue_handle);
324 printf("result = %d\n", result);
325 EXPECT_EQ(result < expect * 10000, 1);
326 }
327
328 /*
329 * 测试用例名称 : serial_double_cancel_failed
330 * 测试用例描述:对一个任务取消两次
331 * 操作步骤 :1、调用串行队列创建接口创建队列,设置延时并提交任务
332 2、调用两次ffrt_queue_cancel取消同一任务
333 * 预期结果 :首次取消成功,第二次取消失败
334 */
335 HWTEST_F(QueueTest, serial_double_cancel_failed, TestSize.Level0)
336 {
337 ffrt_queue_attr_t queue_attr;
338 (void)ffrt_queue_attr_init(&queue_attr); // 初始化属性,必须
339 ffrt_queue_t queue_handle = ffrt_queue_create(ffrt_queue_serial, "test_queue", &queue_attr);
340
341 int result = 0;
__anon5324c4860602() 342 std::function<void()>&& basicFunc = [&result]() { OnePlusForTest(static_cast<void*>(&result)); };
343 ffrt_task_attr_t task_attr;
344 (void)ffrt_task_attr_init(&task_attr); // 初始化task属性,必须
345 constexpr uint64_t delayMs = 1000 * 100; // 100 milliseconds delay
346 // we delay the task to make sure it does not complete before the first cancel.
347 ffrt_task_attr_set_delay(&task_attr, delayMs);
348
349 ffrt_task_handle_t t1 =
350 ffrt_queue_submit_h(queue_handle, create_function_wrapper(basicFunc, ffrt_function_kind_queue), &task_attr);
351 int cancel = ffrt_queue_cancel(t1);
352 EXPECT_EQ(cancel, 0);
353 cancel = ffrt_queue_cancel(t1);
354 EXPECT_EQ(cancel, 1);
355 ffrt_task_handle_destroy(t1); // 销毁task_handle,必须
356
357 ffrt_queue_destroy(queue_handle);
358 }
359
360 /*
361 * 测试用例名称 : ffrt_queue_attr_des
362 * 测试用例描述:设置串行队列qos等级,销毁队列attr
363 * 操作步骤 :1、设置队列qos等级,调用串行队列创建接口创建队列
364 2、调用ffrt_queue_attr_destroy接口销毁队列创建的attr
365 * 预期结果 :设置与销毁成功
366 */
367 HWTEST_F(QueueTest, ffrt_queue_attr_des, TestSize.Level0)
368 {
369 ffrt_queue_attr_t queue_attr;
370 (void)ffrt_queue_attr_init(&queue_attr);
371 ffrt_queue_attr_set_qos(&queue_attr, ffrt_qos_background);
372 ffrt_qos_t qos = ffrt_queue_attr_get_qos(&queue_attr);
373 EXPECT_EQ(qos == ffrt_qos_background, 1);
374 ffrt_queue_attr_destroy(&queue_attr);
375 }
376
377 HWTEST_F(QueueTest, ffrt_queue_dfx_api_0001, TestSize.Level0)
378 {
379 // ffrt_queue_attr_set_timeout接口attr为异常值
380 ffrt_queue_attr_t queue_attr;
381 (void)ffrt_queue_attr_init(&queue_attr); // 初始化属性,必须
382 ffrt_queue_attr_set_timeout(nullptr, 10000);
383 uint64_t time = ffrt_queue_attr_get_timeout(&queue_attr);
384 EXPECT_EQ(time, 0);
385 ffrt_queue_attr_set_timeout(&queue_attr, UINT64_MAX); // 测试时间溢出截断功能
386 uint64_t maxUsCount = 1000000ULL * 100 * 60 * 60 * 24 * 365; // 100 year
387 EXPECT_EQ(ffrt_queue_attr_get_timeout(&queue_attr), maxUsCount);
388 ffrt_queue_t queue_handle = ffrt_queue_create(ffrt_queue_serial, "test_queue", &queue_attr);
389 EXPECT_TRUE(queue_handle != nullptr);
390
391 // 销毁队列
392 ffrt_queue_attr_destroy(&queue_attr);
393 ffrt_queue_destroy(queue_handle);
394 }
395
396 HWTEST_F(QueueTest, ffrt_queue_dfx_api_0002, TestSize.Level0)
397 {
398 // ffrt_queue_attr_get_timeout接口attr为异常值
399 ffrt_queue_attr_t queue_attr;
400 (void)ffrt_queue_attr_init(&queue_attr); // 初始化属性,必须
401 ffrt_queue_attr_set_timeout(&queue_attr, 10000);
402 uint64_t time = ffrt_queue_attr_get_timeout(nullptr);
403 EXPECT_EQ(time, 0);
404 time = ffrt_queue_attr_get_timeout(&queue_attr);
405 EXPECT_EQ(time, 10000);
406 ffrt_queue_t queue_handle = ffrt_queue_create(ffrt_queue_serial, "test_queue", &queue_attr);
407 EXPECT_TRUE(queue_handle != nullptr);
408
409 // 销毁队列
410 ffrt_queue_attr_destroy(&queue_attr);
411 ffrt_queue_destroy(queue_handle);
412 }
413
414 HWTEST_F(QueueTest, ffrt_queue_dfx_api_0004, TestSize.Level0)
415 {
416 // ffrt_queue_attr_get_timeoutCb接口attr为异常值
__anon5324c4860702() 417 std::function<void()> cbOne = []() { printf("first set callback\n"); };
418
419 ffrt_queue_attr_t queue_attr;
420 (void)ffrt_queue_attr_init(&queue_attr); // 初始化属性,必须
421 ffrt_queue_attr_set_callback(&queue_attr, ffrt::create_function_wrapper(cbOne, ffrt_function_kind_queue));
422 ffrt_function_header_t* func = ffrt_queue_attr_get_callback(nullptr);
423 EXPECT_TRUE(func == nullptr);
424 func = ffrt_queue_attr_get_callback(&queue_attr);
425 EXPECT_TRUE(func != nullptr);
426 ffrt_queue_t queue_handle = ffrt_queue_create(ffrt_queue_serial, "test_queue", &queue_attr);
427 EXPECT_TRUE(queue_handle != nullptr);
428
429 // 销毁队列
430 ffrt_queue_destroy(queue_handle);
431 ffrt_queue_attr_destroy(&queue_attr);
432 }
433
434 /*
435 * 测试用例名称 : get_queue_id_from_task
436 * 测试用例描述 : 从队列任务中读取queueid
437 * 操作步骤 : 1、创建串行队列,提交任务
438 * 2、在任务中读取queueid
439 * 预期结果 : 读取queueid成功
440 */
441 HWTEST_F(QueueTest, get_queue_id_from_task, TestSize.Level0)
442 {
443 int x = 0;
444 queue* testQueue = new queue("test_queue");
__anon5324c4860802null445 auto t = testQueue->submit_h([&] {
446 x++;
447 (void)ffrt::get_queue_id();
448 }, {});
449 testQueue->wait(t);
450 delete testQueue;
451 EXPECT_EQ(x, 1);
452 }
453
454 /*
455 * 测试用例名称 : ffrt_task_attr_set_queue_priority
456 * 测试用例描述 : 测试 ffrt_task_attr_set_queue_priority
457 * 操作步骤 : 1、调用ffrt_task_attr_set_queue_priority接口设置队列优先级
458 * 2、使用ffrt_task_attr_get_queue_priority查询优先级
459 * 预期结果 : 查询结果与设定相同,值为3
460 */
461 HWTEST_F(QueueTest, ffrt_task_attr_set_queue_priority, TestSize.Level0)
462 {
463 ffrt_task_attr_t task_attr;
464 (void)ffrt_task_attr_init(&task_attr);
465 ffrt_queue_priority_t priority = ffrt_queue_priority_low;
466 ffrt_task_attr_set_queue_priority(nullptr, priority);
467 ffrt_task_attr_set_queue_priority(&task_attr, priority);
468 priority = ffrt_task_attr_get_queue_priority(nullptr);
469 EXPECT_EQ(priority, ffrt_queue_priority_immediate);
470 priority = ffrt_task_attr_get_queue_priority(&task_attr);
471 EXPECT_EQ(priority, ffrt_queue_priority_low);
472 ffrt_task_attr_destroy(&task_attr);
473 }
474
475 /*
476 * 测试用例名称 : ffrt_queue_attr_set_max_concurrency
477 * 测试用例描述 : 测试 ffrt_queue_attr_set_max_concurrency
478 * 操作步骤 : 1、调用ffrt_queue_attr_set_max_concurrency设置FFRT并行队列,并行度为4
479 * 2、使用ffrt_queue_attr_get_max_concurrency查询并行度
480 * 预期结果 : 查询结果与设定相同,值为4
481 */
482 HWTEST_F(QueueTest, ffrt_queue_attr_set_max_concurrency, TestSize.Level0)
483 {
484 ffrt_queue_attr_t queue_attr;
485 (void)ffrt_queue_attr_init(&queue_attr);
486 uint64_t concurrency = 4;
487 ffrt_queue_attr_set_max_concurrency(nullptr, concurrency);
488 ffrt_queue_attr_set_max_concurrency(&queue_attr, concurrency);
489 concurrency = ffrt_queue_attr_get_max_concurrency(nullptr);
490 EXPECT_EQ(concurrency, 0);
491 concurrency = ffrt_queue_attr_get_max_concurrency(&queue_attr);
492 EXPECT_EQ(concurrency, 4);
493 ffrt_queue_attr_destroy(&queue_attr);
494
495 ffrt_queue_attr_t queue_attr1;
496 (void)ffrt_queue_attr_init(&queue_attr1);
497 concurrency = 0;
498 ffrt_queue_attr_set_max_concurrency(&queue_attr1, concurrency);
499 concurrency = ffrt_queue_attr_get_max_concurrency(&queue_attr1);
500 EXPECT_EQ(concurrency, 1);
501 ffrt_queue_attr_destroy(&queue_attr1);
502 }
503
504 /*
505 * 测试用例名称 : ffrt_queue_has_task
506 * 测试用例描述 : 测试 ffrt_queue_has_task
507 * 操作步骤 : 1、往队列中提交若干任务,其中包含待查询的任务
508 * 2、调用ffrt_queue_has_task查询任务是否在队列中
509 * 预期结果 : 查询结果与预期相同
510 */
511 HWTEST_F(QueueTest, ffrt_queue_has_task, TestSize.Level0)
512 {
513 ffrt_queue_attr_t queue_attr;
514 (void)ffrt_queue_attr_init(&queue_attr); // 初始化属性,必须
515 ffrt_queue_t queue_handle = ffrt_queue_create(ffrt_queue_serial, "test_queue", &queue_attr);
516
517 std::mutex lock;
518 lock.lock();
__anon5324c4860902() 519 std::function<void()> basicFunc = [&]() { lock.lock(); };
__anon5324c4860a02() 520 std::function<void()> emptyFunc = []() {};
521
522 ffrt_task_attr_t task_attr;
523 ffrt_task_attr_init(&task_attr);
524 ffrt_task_attr_set_name(&task_attr, "basic_function");
525 ffrt_task_handle_t handle = ffrt_queue_submit_h(queue_handle,
526 create_function_wrapper(basicFunc, ffrt_function_kind_queue), &task_attr);
527
528 for (int i = 0; i < 10; i++) {
529 std::string name = "empty_function_" + std::to_string(i);
530 ffrt_task_attr_set_name(&task_attr, name.c_str());
531 ffrt_queue_submit(queue_handle, create_function_wrapper(emptyFunc, ffrt_function_kind_queue), &task_attr);
532 }
533
534 // 全字匹配
535 for (int i = 0; i < 10; i++) {
536 std::string name = "empty_function_" + std::to_string(i);
537 bool hasEmptyTask = ffrt_queue_has_task(queue_handle, name.c_str());
538 EXPECT_EQ(hasEmptyTask, true);
539 }
540
541 // 正则匹配
542 bool hasEmptyTask = ffrt_queue_has_task(queue_handle, "empty_function_.*");
543 EXPECT_EQ(hasEmptyTask, true);
544
545 hasEmptyTask = ffrt_queue_has_task(queue_handle, "random_function");
546 EXPECT_EQ(hasEmptyTask, false);
547
548 lock.unlock();
549 ffrt_queue_wait(handle);
550
551 ffrt_task_handle_destroy(handle);
552 ffrt_task_attr_destroy(&task_attr);
553 ffrt_queue_attr_destroy(&queue_attr);
554 ffrt_queue_destroy(queue_handle);
555 }
556
557 /*
558 * 测试用例名称 : ffrt_queue_cancel_all_and_cancel_by_name
559 * 测试用例描述 : 测试 ffrt_queue_cancel_all、ffrt_queue_cancel_by_name
560 * 操作步骤 : 1、往队列中提交若干任务
561 * 2、调用ffrt_queue_cancel_by_name取消指定任务
562 * 3、调用ffrt_queue_cancel_all取消所有任务
563 * 预期结果 : 任务取消成功
564 */
565 HWTEST_F(QueueTest, ffrt_queue_cancel_all_and_cancel_by_name, TestSize.Level0)
566 {
567 ffrt_queue_attr_t queue_attr;
568 (void)ffrt_queue_attr_init(&queue_attr); // 初始化属性,必须
569 ffrt_queue_t queue_handle = ffrt_queue_create(
570 static_cast<ffrt_queue_type_t>(ffrt_queue_eventhandler_adapter), "test_queue", &queue_attr);
571
572 std::mutex lock;
573 lock.lock();
__anon5324c4860b02() 574 std::function<void()> basicFunc = [&]() { lock.lock(); };
__anon5324c4860c02() 575 std::function<void()> emptyFunc = []() {};
576
577 ffrt_task_attr_t task_attr;
578 ffrt_task_attr_init(&task_attr);
579 ffrt_task_attr_set_name(&task_attr, "basic_function");
580 ffrt_task_handle_t handle = ffrt_queue_submit_h(queue_handle,
581 create_function_wrapper(basicFunc, ffrt_function_kind_queue), &task_attr);
582
583 for (int i = 0; i < 10; i++) {
584 std::string name = "empty_function_" + std::to_string(i);
585 ffrt_task_attr_set_name(&task_attr, name.c_str());
586 ffrt_queue_submit(queue_handle, create_function_wrapper(emptyFunc, ffrt_function_kind_queue), &task_attr);
587 }
588
589 // 测试ffrt_queue_cancel_by_name
590 bool hasEmptyTask = ffrt_queue_has_task(queue_handle, "empty_function_3");
591 EXPECT_EQ(hasEmptyTask, true);
592
593 ffrt_queue_cancel_by_name(queue_handle, "empty_function_3");
594
595 hasEmptyTask = ffrt_queue_has_task(queue_handle, "empty_function_3");
596 EXPECT_EQ(hasEmptyTask, false);
597
598 // 测试ffrt_queue_cancel_all
599 hasEmptyTask = ffrt_queue_has_task(queue_handle, "empty_function_.*");
600 EXPECT_EQ(hasEmptyTask, true);
601
602 bool isIdle = ffrt_queue_is_idle(queue_handle);
603 EXPECT_EQ(isIdle, false);
604
605 ffrt_queue_cancel_all(queue_handle);
606
607 hasEmptyTask = ffrt_queue_has_task(queue_handle, "empty_function_.*");
608 EXPECT_EQ(hasEmptyTask, false);
609
610 lock.unlock();
611 ffrt_queue_cancel_and_wait(queue_handle);
612 ffrt_queue_wait(handle);
613
614 isIdle = ffrt_queue_is_idle(queue_handle);
615 EXPECT_EQ(isIdle, true);
616
617 ffrt_task_attr_destroy(&task_attr);
618 ffrt_task_handle_destroy(handle);
619 ffrt_queue_attr_destroy(&queue_attr);
620 ffrt_queue_destroy(queue_handle);
621 }
622
623 /*
624 * 测试用例名称 : ffrt_queue_submit_head
625 * 测试用例描述 : 测试 ffrt_queue_submit_head
626 * 操作步骤 : 1、往队列中提交若干任务
627 * 2、调用ffrt_queue_submit_head提交任务至队头
628 * 预期结果 : 提交到对头的任务优先被执行
629 */
630 HWTEST_F(QueueTest, ffrt_queue_submit_head, TestSize.Level0)
631 {
632 ffrt_queue_attr_t queue_attr;
633 (void)ffrt_queue_attr_init(&queue_attr); // 初始化属性,必须
634 ffrt_queue_t queue_handle = ffrt_queue_create(
635 static_cast<ffrt_queue_type_t>(ffrt_queue_eventhandler_adapter), "test_queue", &queue_attr);
636
637 int result = 0;
638 std::mutex lock;
639 lock.lock();
__anon5324c4860d02() 640 std::function<void()> basicFunc = [&]() { lock.lock(); };
641 std::vector<std::function<void()>> assignFuncs(8, nullptr);
642 std::vector<int> results;
643 std::vector<int> expectResults {6, 2, 1, 4, 3, 5, 8, 7};
644 for (int idx = 0; idx < 8; idx++) {
__anon5324c4860e02() 645 assignFuncs[idx] = [idx, &results]() {
646 results.push_back(idx + 1);
647 };
648 }
649
650 ffrt_task_attr_t task_attr;
651 ffrt_task_attr_init(&task_attr);
652 ffrt_task_attr_set_queue_priority(&task_attr, ffrt_queue_priority_immediate);
653 ffrt_task_attr_set_name(&task_attr, "basic_function");
654 ffrt_queue_submit_head(queue_handle, create_function_wrapper(basicFunc, ffrt_function_kind_queue), &task_attr);
655
656 ffrt_queue_submit_head(queue_handle, create_function_wrapper(assignFuncs[0], ffrt_function_kind_queue), &task_attr);
657 ffrt_queue_submit_head(queue_handle, create_function_wrapper(assignFuncs[1], ffrt_function_kind_queue), &task_attr);
658
659 ffrt_task_attr_set_queue_priority(&task_attr, ffrt_queue_priority_high);
660 ffrt_queue_submit_head(queue_handle, create_function_wrapper(assignFuncs[2], ffrt_function_kind_queue), &task_attr);
661 ffrt_queue_submit_head(queue_handle, create_function_wrapper(assignFuncs[3], ffrt_function_kind_queue), &task_attr);
662
663 ffrt_task_attr_set_queue_priority(&task_attr, ffrt_queue_priority_low);
664 ffrt_queue_submit_head(queue_handle, create_function_wrapper(assignFuncs[4], ffrt_function_kind_queue), &task_attr);
665
666 ffrt_task_attr_set_queue_priority(&task_attr, ffrt_queue_priority_immediate);
667 ffrt_queue_submit_head(queue_handle, create_function_wrapper(assignFuncs[5], ffrt_function_kind_queue), &task_attr);
668
669 ffrt_task_attr_set_queue_priority(&task_attr, ffrt_queue_priority_idle);
670 ffrt_task_handle_t handle = ffrt_queue_submit_head_h(queue_handle,
671 create_function_wrapper(assignFuncs[6], ffrt_function_kind_queue), &task_attr);
672 ffrt_queue_submit_head(queue_handle, create_function_wrapper(assignFuncs[7], ffrt_function_kind_queue), &task_attr);
673
674 lock.unlock();
675 ffrt_queue_wait(handle);
676 EXPECT_EQ(results, expectResults);
677
678 ffrt_task_attr_destroy(&task_attr);
679 ffrt_task_handle_destroy(handle);
680 ffrt_queue_attr_destroy(&queue_attr);
681 ffrt_queue_destroy(queue_handle);
682 }
683
684 HWTEST_F(QueueTest, ffrt_get_main_queue, TestSize.Level0)
685 {
686 // ffrt test case begin
687 ffrt::queue *serialQueue = new ffrt::queue("ffrt_normal_queue", {});
688 ffrt_queue_t mainQueue = ffrt_get_main_queue();
689 ffrt_task_attr_t attr;
690 ffrt_task_attr_init(&attr);
691 ffrt_task_attr_set_qos(&attr, ffrt_qos_user_initiated);
692 int result = 0;
__anon5324c4860f02() 693 std::function<void()>&& basicFunc = [&result]() {
694 OnePlusForTest(static_cast<void*>(&result));
695 OnePlusForTest(static_cast<void*>(&result));
696 EXPECT_EQ(result, 2);
697 usleep(3000);
698 };
699
700 ffrt::task_handle handle = serialQueue->submit_h(
__anon5324c4861002null701 [&] {
702 result = result + 1;
703 ffrt_queue_submit(mainQueue, ffrt::create_function_wrapper(basicFunc, ffrt_function_kind_queue),
704 &attr);
705 },
706 ffrt::task_attr().qos(3).name("ffrt main_queue."));
707
708 serialQueue->wait(handle);
709 EXPECT_EQ(result, 1);
710 delete serialQueue;
711 usleep(100000);
712 }
713
714 HWTEST_F(QueueTest, get_main_queue, TestSize.Level0)
715 {
716 ffrt::queue *serialQueue = new ffrt::queue("ffrt_normal_queue", {});
717 queue* mainQueue = ffrt::queue::get_main_queue();
718 int result = 0;
__anon5324c4861102() 719 std::function<void()>&& basicFunc = [&result]() {
720 OnePlusForTest(static_cast<void*>(&result));
721 OnePlusForTest(static_cast<void*>(&result));
722 EXPECT_EQ(result, 3);
723 usleep(3000);
724 };
725
726 ffrt::task_handle handle = serialQueue->submit_h(
__anon5324c4861202null727 [&] {
728 result = result + 1;
729 if (mainQueue != nullptr) {
730 mainQueue->submit(basicFunc);
731 }
732 },
733 ffrt::task_attr().qos(3).name("ffrt main_queue."));
734
735 serialQueue->wait(handle);
736 EXPECT_EQ(result, 1);
737 delete serialQueue;
738 usleep(100000);
739 }
740
741 HWTEST_F(QueueTest, ffrt_get_current_queue, TestSize.Level0)
742 {
743 // ffrt test case begin
744 ffrt::queue *serialQueue = new ffrt::queue("ffrt_normal_queue", {});
745 ffrt_queue_t currentQueue = ffrt_get_current_queue();
746 ffrt_task_attr_t attr;
747 ffrt_task_attr_init(&attr);
748 ffrt_task_attr_set_qos(&attr, ffrt_qos_user_initiated);
749 int result = 0;
__anon5324c4861302() 750 std::function<void()>&& basicFunc = [&result]() {
751 OnePlusForTest(static_cast<void*>(&result));
752 OnePlusForTest(static_cast<void*>(&result));
753 EXPECT_EQ(result, 3);
754 usleep(3000);
755 };
756
757 ffrt::task_handle handle = serialQueue->submit_h(
__anon5324c4861402null758 [&] {
759 EXPECT_GT(ffrt::get_queue_id(), 0);
760 result = result + 1;
761 ffrt_queue_submit(currentQueue, ffrt::create_function_wrapper(basicFunc, ffrt_function_kind_queue),
762 &attr);
763 },
764 ffrt::task_attr().qos(3).name("ffrt current_queue."));
765
766 serialQueue->wait(handle);
767
768 EXPECT_EQ(result, 1);
769 delete serialQueue;
770 }
771
772 /*
773 * 测试用例名称 : ffrt_queue_recordtraffic_normal_trigger
774 * 测试用例描述 : 设置串行队列的traffic_interval并生效
775 * 操作步骤 : 1、创建队列
776 * 2、提交堆积任务
777 * 预期结果 : 成功触发流量监控告警
778 */
779 HWTEST_F(QueueTest, ffrt_queue_recordtraffic_normal_trigger, TestSize.Level0)
780 {
781 FFRTFacade::GetDMInstance();
782 FFRTFacade::GetQMInstance().timeoutUs_ = 30000000;
783 ffrt_queue_attr_t queue_attr;
784 ffrt_task_handle_t handle;
785 ffrt_task_attr_t task_attr;
786 int result = 0;
787 (void)ffrt_task_attr_init(&task_attr);
788 (void)ffrt_queue_attr_init(&queue_attr);
789 ffrt_queue_t queue_handle = ffrt_queue_create(ffrt_queue_serial, "test_queue", &queue_attr);
790 ffrt::QueueHandler* queueHandler = reinterpret_cast<ffrt::QueueHandler*>(queue_handle);
791 queueHandler->trafficRecordInterval_ = 1000000;
792 queueHandler->trafficRecord_.nextUpdateTime_ = TimeStampCntvct() + 1000000;
793
__anon5324c4861502() 794 std::function<void()>&& firstFunc = [&result]() {
795 result = result + 1;
796 usleep(1100000);
797 };
__anon5324c4861602() 798 std::function<void()>&& fastFunc = [&result]() {
799 result = result + 1;
800 };
801
802 ffrt_queue_submit(queue_handle, create_function_wrapper(firstFunc, ffrt_function_kind_queue), &task_attr);
803 for (int i = 0; i < 30; i++) {
804 ffrt_queue_submit(queue_handle, create_function_wrapper(fastFunc, ffrt_function_kind_queue), &task_attr);
805 }
806 usleep(1000000);
807 handle = ffrt_queue_submit_h(queue_handle, create_function_wrapper(fastFunc, ffrt_function_kind_queue), &task_attr);
808 ffrt_queue_wait(handle);
809 EXPECT_EQ(result, 32);
810 ffrt_task_handle_destroy(handle);
811 ffrt_queue_attr_destroy(&queue_attr);
812 ffrt_queue_destroy(queue_handle);
813 }
814
815 /*
816 * 测试用例名称 : ffrt_queue_recordtraffic_normal_corner
817 * 测试用例描述 : 串行队列的traffic_interval并生效
818 * 操作步骤 : 1、创建队列
819 * 2、提交堆积任务
820 * 预期结果 : 不触发流量监控告警
821 */
822 HWTEST_F(QueueTest, ffrt_queue_recordtraffic_normal_corner, TestSize.Level0)
823 {
824 ffrt_queue_attr_t queue_attr;
825 const int numTasks = 19;
826 ffrt_task_handle_t handle[numTasks];
827 ffrt_task_attr_t task_attr;
828 int result = 0;
829 (void)ffrt_task_attr_init(&task_attr);
830 (void)ffrt_queue_attr_init(&queue_attr);
831 ffrt_queue_t queue_handle = ffrt_queue_create(ffrt_queue_serial, "test_queue", &queue_attr);
832 ffrt::QueueHandler* queueHandler = reinterpret_cast<ffrt::QueueHandler*>(queue_handle);
833 queueHandler->trafficRecordInterval_ = 1000000;
834 queueHandler->trafficRecord_.nextUpdateTime_ = TimeStampCntvct() + 1000000;
835
__anon5324c4861702() 836 std::function<void()>&& firstFunc = [&result]() {
837 result = result + 1;
838 usleep(1100000);
839 };
__anon5324c4861802() 840 std::function<void()>&& fastFunc = [&result]() {
841 result = result + 1;
842 };
843
844 ffrt_queue_submit(queue_handle, create_function_wrapper(firstFunc, ffrt_function_kind_queue), &task_attr);
845 for (int i = 0; i < numTasks; i++) {
846 ffrt_queue_submit(queue_handle, create_function_wrapper(fastFunc, ffrt_function_kind_queue), &task_attr);
847 }
848 usleep(1000000);
849 ffrt_queue_submit(queue_handle, create_function_wrapper(firstFunc, ffrt_function_kind_queue), &task_attr);
850 for (int i = 0; i < numTasks; i++) {
851 handle[i] = ffrt_queue_submit_h(queue_handle, create_function_wrapper(fastFunc,
852 ffrt_function_kind_queue), &task_attr);
853 }
854 ffrt_queue_wait(handle[numTasks -1]);
855
856 EXPECT_EQ(result, 40);
857 for (int i = 0; i < numTasks; i++) {
858 ffrt_task_handle_destroy(handle[i]);
859 }
860 ffrt_queue_attr_destroy(&queue_attr);
861 ffrt_queue_destroy(queue_handle);
862 }
863
864 /*
865 * 测试用例名称 : ffrt_queue_recordtraffic_delay_trigger
866 * 测试用例描述 : 设置串行队列的traffic_interval并生效
867 * 操作步骤 : 1、创建队列
868 * 2、提交堆积任务
869 * 预期结果 : 成功触发流量监控告警,但不触发上报
870 */
871 HWTEST_F(QueueTest, ffrt_queue_recordtraffic_delay_trigger, TestSize.Level0)
872 {
873 ffrt_queue_attr_t queue_attr;
874 ffrt_task_handle_t handle;
875 ffrt_task_attr_t task_attr;
876 ffrt_task_attr_t task_attr1;
877 int result = 0;
878 (void)ffrt_task_attr_init(&task_attr1);
879 (void)ffrt_task_attr_init(&task_attr);
880 ffrt_task_attr_set_delay(&task_attr, 1200000);
881 (void)ffrt_queue_attr_init(&queue_attr);
882 ffrt_queue_t queue_handle = ffrt_queue_create(ffrt_queue_serial, "test_queue", &queue_attr);
883 ffrt::QueueHandler* queueHandler = reinterpret_cast<ffrt::QueueHandler*>(queue_handle);
884 queueHandler->trafficRecordInterval_ = 1000000;
885 queueHandler->trafficRecord_.nextUpdateTime_ = TimeStampCntvct() + 1000000;
886
__anon5324c4861902() 887 std::function<void()>&& firstFunc = [&result]() {
888 result = result + 1;
889 usleep(1100000);
890 };
__anon5324c4861a02() 891 std::function<void()>&& fastFunc = [&result]() {
892 result = result + 1;
893 };
894
895 ffrt_queue_submit(queue_handle, create_function_wrapper(firstFunc, ffrt_function_kind_queue), &task_attr1);
896 for (int i = 0; i < 30; i++) {
897 ffrt_queue_submit(queue_handle, create_function_wrapper(fastFunc, ffrt_function_kind_queue), &task_attr);
898 }
899 usleep(1000000);
900 handle = ffrt_queue_submit_h(queue_handle, create_function_wrapper(fastFunc,
901 ffrt_function_kind_queue), &task_attr1);
902 ffrt_queue_wait(handle);
903 EXPECT_EQ(result, 2);
904 ffrt_task_handle_destroy(handle);
905 ffrt_queue_attr_destroy(&queue_attr);
906 ffrt_queue_destroy(queue_handle);
907 }
908
MyCallback(uint64_t id,const char * message,uint32_t length)909 void MyCallback(uint64_t id, const char* message, uint32_t length)
910 {
911 FFRT_LOGE("call ffrt_queue_monitor timeout_callback");
912 }
913
914 /*
915 * 测试用例名称 : ffrt_queue_monitor_schedule_timeout
916 * 测试用例描述 : 串行队列QueueMonitor检测到任务调度超时
917 * 操作步骤 : 1、创建队列
918 * 2、提交多个任务占满worker,使得新串行任务等待调度
919 * 预期结果 : 成功触发任务调度超时告警
920 */
921 HWTEST_F(QueueTest, ffrt_queue_monitor_schedule_timeout111, TestSize.Level0)
922 {
923 int x = 0;
924 ffrt_task_timeout_set_cb(MyCallback);
925 ffrt_task_timeout_set_threshold(1000000);
926 ffrt_set_cpu_worker_max_num(ffrt_qos_default, 4);
927 FFRTFacade::GetDMInstance();
928 FFRTFacade::GetQMInstance().timeoutUs_ = 1000000;
929
930 for (int i = 0; i < 9; i++) {
__anon5324c4861b02() 931 ffrt::submit([]() {
932 usleep(1100000);
933 }, {}, {});
934 }
935 queue* testQueue = new queue("test_queue");
936
__anon5324c4861e02null937 auto t = testQueue->submit_h([&x] {
938 FFRT_LOGE("task start"); x = x + 1;}, {});
939 testQueue->wait(t);
940 delete testQueue;
941 EXPECT_EQ(x, 1);
942 ffrt::wait();
943 }
944
945 /*
946 * 测试用例名称 : ffrt_queue_monitor_execute_timeout
947 * 测试用例描述 : 串行队列QueueMonitor检测到任务执行超时
948 * 操作步骤 : 1、创建队列
949 * 2、提交执行时间长任务
950 * 预期结果 : 成功触发任务执行超时告警
951 */
952 HWTEST_F(QueueTest, ffrt_queue_monitor_execute_timeout, TestSize.Level0)
953 {
954 int x = 0;
955 ffrt_task_timeout_set_cb(MyCallback);
956 ffrt_task_timeout_set_threshold(1000);
957 FFRTFacade::GetDMInstance();
958 FFRTFacade::GetQMInstance().timeoutUs_ = 1000000;
959 queue* testQueue = new queue("test_queue");
__anon5324c4861f02null960 auto t = testQueue->submit_h([&x] { x = x + 1; usleep(2000000); FFRT_LOGE("done");}, {});
961 FFRT_LOGE("submitted");
962 testQueue->wait(t);
963 delete testQueue;
964 FFRTFacade::GetQMInstance().timeoutUs_ = 30000000;
965 EXPECT_EQ(x, 1);
966 }
967
968 /*
969 * 测试用例名称 : ffrt_queue_monitor_delay_timeout
970 * 测试用例描述 : 串行队列QueueMonitor检测到任务执行超时
971 * 操作步骤 : 1、创建队列
972 * 2、提交执行时间长任务
973 * 预期结果 : 不触发超时告警
974 */
975 HWTEST_F(QueueTest, ffrt_queue_monitor_delay_timeout, TestSize.Level0)
976 {
977 int x = 0;
978 ffrt_task_timeout_set_cb(MyCallback);
979 ffrt_task_timeout_set_threshold(1000);
980 FFRTFacade::GetDMInstance();
981 FFRTFacade::GetQMInstance().timeoutUs_ = 1000000;
982 queue* testQueue = new queue("test_queue");
983 FFRT_LOGE("submit");
__anon5324c4862002null984 auto t = testQueue->submit_h([&x] { FFRT_LOGE("delay end"); usleep(2100000);
985 x = x + 1;}, task_attr().delay(1200000));
986 testQueue->wait(t);
987 delete testQueue;
988 FFRTFacade::GetQMInstance().timeoutUs_ = 30000000;
989 EXPECT_EQ(x, 1);
990 }
991
992 /*
993 * 测试用例名称 : ffrt_queue_monitor_cancel_timeout
994 * 测试用例描述 : 串行队列QueueMonitor检测到任务执行超时
995 * 操作步骤 : 1、创建队列
996 * 2、提交执行时间长任务
997 * 预期结果 : 不触发超时告警
998 */
999 HWTEST_F(QueueTest, ffrt_queue_monitor_cancel_timeout, TestSize.Level0)
1000 {
1001 int x = 0;
1002 ffrt_task_timeout_set_cb(MyCallback);
1003 ffrt_task_timeout_set_threshold(1000);
1004 FFRTFacade::GetDMInstance();
1005 FFRTFacade::GetQMInstance().timeoutUs_ = 1000000;
1006 queue* testQueue = new queue("test_queue");
1007 FFRT_LOGE("submit");
__anon5324c4862102null1008 testQueue->submit([&x] { x = x + 1; FFRT_LOGE("start"); });
__anon5324c4862202null1009 auto t = testQueue->submit_h([&x] { x = x + 1; FFRT_LOGE("delay start"); }, task_attr().delay(5000000));
1010 testQueue->cancel(t);
1011 testQueue->wait(t);
1012 usleep(1200000);
1013 delete testQueue;
1014 FFRTFacade::GetQMInstance().timeoutUs_ = 30000000;
1015 EXPECT_EQ(x, 1);
1016 }
1017
StallUsImpl(size_t us)1018 static inline void StallUsImpl(size_t us)
1019 {
1020 auto start = std::chrono::system_clock::now();
1021 size_t passed = 0;
1022 while (passed < us) {
1023 passed = std::chrono::duration_cast<std::chrono::microseconds>(
1024 std::chrono::system_clock::now() - start).count();
1025 }
1026 }
1027
stall_us1(size_t us)1028 void stall_us1(size_t us)
1029 {
1030 StallUsImpl(us);
1031 }
1032
1033 /*
1034 * 测试用例名称 : ffrt_queue_monitor_two_stage_timeout
1035 * 测试用例描述 : 串行队列QueueMonitor检测到任务在PENDING和EXECUTING各超时一次
1036 * 操作步骤 : 1、创建队列
1037 * 2、提交执行时间长任务
1038 * 预期结果 : 触发PENDING和EXECUTING各一次的超时告警
1039 */
1040 HWTEST_F(QueueTest, ffrt_queue_monitor_two_stage_timeout, TestSize.Level0)
1041 {
1042 int x = 0;
1043 ffrt_task_timeout_set_cb(MyCallback);
1044 ffrt_task_timeout_set_threshold(1000);
1045 FFRTFacade::GetDMInstance();
1046 FFRTFacade::GetQMInstance().timeoutUs_ = 1000000;
1047
1048 ffrt_set_cpu_worker_max_num(ffrt_qos_default, 1);
1049
1050 ffrt_queue_attr_t queue_attr;
1051 ffrt_queue_attr_init(&queue_attr);
1052 ffrt_queue_t queue_handle = ffrt_queue_create(ffrt_queue_serial, "test_queue", &queue_attr);
1053
__anon5324c4862302null1054 ffrt::submit([] { stall_us1(1300 * 1000); });
__anon5324c4862402null1055 std::function<void()>&& basicFunc = [&x] { x = x + 1; stall_us1(1300 * 1000); FFRT_LOGE("done");};
1056 ffrt_task_handle_t task = ffrt_queue_submit_h(queue_handle,
1057 ffrt::create_function_wrapper(basicFunc, ffrt_function_kind_queue), nullptr);
1058
1059 ffrt_queue_wait(task);
1060 ffrt_task_handle_destroy(task);
1061 ffrt_queue_destroy(queue_handle);
1062 ffrt_task_timeout_set_threshold(30000);
1063 EXPECT_EQ(x, 1);
1064 }
1065
1066 /*
1067 * 测试用例名称 : ffrt_spmc_queue_test
1068 * 测试用例描述 : SPMC无锁队列功能测试
1069 * 预置条件 :创建一个SPMC队列
1070 * 操作步骤 : 1、调用PushTail接口向队列中push若干数据
1071 * 2、创建多个线程,并发地调用PopHead接口从队列中获取数据
1072 * 预期结果 : 数据能够被正确取出
1073 */
1074 HWTEST_F(QueueTest, ffrt_spmc_queue_test, TestSize.Level0)
1075 {
1076 SpmcQueue queue;
1077 EXPECT_EQ(queue.Init(0), -1);
1078 EXPECT_EQ(queue.PushTail(nullptr), -1);
1079 EXPECT_EQ(queue.PopHead(), nullptr);
1080 EXPECT_EQ(queue.Init(128), 0);
1081
1082 int data[128];
1083 for (int i = 0; i < 128; i++) {
1084 data[i] = i;
1085 queue.PushTail(&data[i]);
1086 }
1087 EXPECT_EQ(queue.PushTail(&data[0]), -1);
1088
1089 std::atomic<int> count = 0;
1090 std::vector<std::thread> consumers;
1091 for (int i = 0; i < 16; i++) {
__anon5324c4862502null1092 consumers.emplace_back([&queue, &count] {
1093 int* ret = reinterpret_cast<int*>(queue.PopHead());
1094 while (ret != nullptr) {
1095 count++;
1096 ret = reinterpret_cast<int*>(queue.PopHead());
1097 }
1098 });
1099 }
1100
1101 for (auto& consumer : consumers) {
1102 consumer.join();
1103 }
1104 EXPECT_EQ(count.load(), 128);
1105 }
1106
1107 /*
1108 * 测试用例名称 : ffrt_spmc_queue_pop_head_to_another_queue
1109 * 测试用例描述 : SPMC无锁队列数据迁移功能测试
1110 * 预置条件 :创建一个SPMC源队列,创建一个SPMC目标队列,目标队列容量小于源队列
1111 * 操作步骤 : 1、调用PushTail接口向源队列中push若干数据
1112 * 2、调用PopHeadToAnotherQueue接口向目标队列中迁移小于源队列和目标队列容量的数据
1113 * 3、调用PopHeadToAnotherQueue接口向目标队列中迁移等于目标队列容量的数据
1114 * 4、调用PopHeadToAnotherQueue接口向目标队列中迁移超过源队列容量的数据
1115 * 预期结果 : 1、迁移成功,目标队列中存在和迁移数量相同的数据
1116 * 2、迁移成功,目标队列中存在和目标队列数量相同的数据
1117 * 3、迁移成功,目标队列中存在和源队列数量相同的数据
1118 */
1119 HWTEST_F(QueueTest, ffrt_spmc_queue_pop_head_to_another_queue, TestSize.Level0)
1120 {
1121 SpmcQueue queue;
1122 SpmcQueue dstQueue;
1123 SpmcQueue dstQueue2;
1124 EXPECT_EQ(queue.Init(128), 0);
1125 EXPECT_EQ(dstQueue.Init(64), 0);
1126 EXPECT_EQ(dstQueue2.Init(128), 0);
1127
1128 int data[128];
1129 for (int i = 0; i < 128; i++) {
1130 data[i] = i;
1131 queue.PushTail(&data[i]);
1132 }
1133
1134 EXPECT_EQ(queue.PopHeadToAnotherQueue(dstQueue, 0, nullptr), 0);
1135 EXPECT_EQ(dstQueue.GetLength(), 0);
1136
1137 EXPECT_EQ(queue.PopHeadToAnotherQueue(dstQueue, 32, nullptr), 32);
1138 EXPECT_EQ(dstQueue.GetLength(), 32);
1139
__anon5324c4862602(void* data) 1140 EXPECT_EQ(queue.PopHeadToAnotherQueue(dstQueue, 64, [] (void* data) { EXPECT_NE(data, nullptr); }), 32);
1141 EXPECT_EQ(dstQueue.GetLength(), 64);
1142
1143 EXPECT_EQ(queue.PopHeadToAnotherQueue(dstQueue2, 128, nullptr), 64);
1144 EXPECT_EQ(dstQueue2.GetLength(), 64);
1145 }
1146
1147 HWTEST_F(QueueTest, ffrt_queue_submit_h_f, TestSize.Level0)
1148 {
1149 ffrt_queue_attr_t queue_attr;
1150 (void)ffrt_queue_attr_init(&queue_attr);
1151 ffrt_queue_t queue_handle = ffrt_queue_create(ffrt_queue_serial, "test_queue", &queue_attr);
1152
1153 int result = 0;
1154 ffrt_task_handle_t task = ffrt_queue_submit_h_f(queue_handle, OnePlusForTest, &result, nullptr);
1155 ffrt_queue_wait(task);
1156 ffrt_task_handle_destroy(task);
1157 ffrt_queue_attr_destroy(&queue_attr);
1158 ffrt_queue_destroy(queue_handle);
1159
1160 EXPECT_EQ(result, 1);
1161 }
1162
1163 HWTEST_F(QueueTest, ffrt_queue_submit_f, TestSize.Level0)
1164 {
1165 ffrt_queue_attr_t queue_attr;
1166 (void)ffrt_queue_attr_init(&queue_attr);
1167 ffrt_queue_t queue_handle = ffrt_queue_create(ffrt_queue_serial, "test_queue", &queue_attr);
1168
1169 int result = 0;
1170 ffrt_queue_submit_f(queue_handle, OnePlusForTest, &result, nullptr);
1171 EXPECT_TRUE(queue_handle != nullptr);
1172
1173 ffrt_queue_attr_destroy(&queue_attr);
1174 ffrt_queue_destroy(queue_handle);
1175
1176 EXPECT_EQ(result, 1);
1177 }
1178
1179 /*
1180 * 测试用例名称 : ffrt_queue_concurrent_recordtraffic_delay_trigger
1181 * 测试用例描述 : 设置并行队列的traffic_interval并生效
1182 * 操作步骤 : 1、创建队列
1183 * 2、调用ffrt_queue_attr_set_traffic_interval接口设置并行队列的流量监控窗口
1184 * 3、提交堆积任务
1185 * 预期结果 : 成功触发流量监控告警,但不触发上报
1186 */
1187 HWTEST_F(QueueTest, ffrt_queue_concurrent_recordtraffic_delay_trigger, TestSize.Level1)
1188 {
1189 ffrt_queue_attr_t queue_attr;
1190 ffrt_task_handle_t handle;
1191 ffrt_task_attr_t task_attr;
1192 ffrt_task_attr_t task_attr_1;
1193 std::atomic<int> result = 0;
1194 uint64_t concurrency = 4;
1195 (void)ffrt_task_attr_init(&task_attr_1);
1196 (void)ffrt_task_attr_init(&task_attr);
1197 ffrt_task_attr_set_delay(&task_attr, 1200000);
1198 (void)ffrt_queue_attr_init(&queue_attr);
1199 ffrt_queue_attr_set_max_concurrency(&queue_attr, concurrency);
1200
1201 ffrt_queue_t queue_handle = ffrt_queue_create(ffrt_queue_concurrent, "test_queue", &queue_attr);
1202 ffrt::QueueHandler* queueHandler = reinterpret_cast<ffrt::QueueHandler*>(queue_handle);
1203 queueHandler->trafficRecordInterval_ = 1000000;
1204 queueHandler->trafficRecord_.nextUpdateTime_ = TimeStampCntvct() + 1000000;
__anon5324c4862702() 1205 std::function<void()>&& testFunc = [&result]() {
1206 result = result + 1;
1207 usleep(1100000);
1208 };
__anon5324c4862802() 1209 std::function<void()>&& fastFunc = [&result]() {
1210 result = result + 1;
1211 };
1212
1213 ffrt_queue_submit(queue_handle, create_function_wrapper(testFunc, ffrt_function_kind_queue), &task_attr_1);
1214 for (int i = 0; i < 30; i++) {
1215 ffrt_queue_submit(queue_handle, create_function_wrapper(fastFunc, ffrt_function_kind_queue), &task_attr);
1216 }
1217 usleep(1000000);
1218 handle = ffrt_queue_submit_h(queue_handle,
1219 create_function_wrapper(fastFunc, ffrt_function_kind_queue), &task_attr_1);
1220 ffrt_queue_wait(handle);
1221 EXPECT_EQ(result, 2);
1222 ffrt_queue_attr_destroy(&queue_attr);
1223 ffrt_queue_destroy(queue_handle);
1224 }
1225
1226 /*
1227 * 测试用例名称 : ffrt_queue_concurrent_monitor_schedule_timeout_all
1228 * 测试用例描述 : 并行队列QueueMonitor检测到任务调度超时
1229 * 操作步骤 : 1、创建队列
1230 * 2、提交多个任务占满全部worker,使得新并行任务等待调度
1231 * 预期结果 : 成功触发任务调度超时告警
1232 */
1233 HWTEST_F(QueueTest, ffrt_queue_monitor_concurrent_schedule_timeout_all, TestSize.Level1)
1234 {
1235 ffrt_task_timeout_set_cb(MyCallback);
1236 FFRTFacade::GetDMInstance();
1237 FFRTFacade::GetQMInstance().timeoutUs_ = 1000000;
1238
1239 ffrt::queue* testQueue = new ffrt::queue(ffrt::queue_concurrent,
1240 "concurrent_queue", ffrt::queue_attr().max_concurrency(4));
1241 ffrt_set_cpu_worker_max_num(ffrt_qos_default, 2);
1242 std::atomic<std::uint64_t> y{0};
1243 std::array<ffrt::task_handle, 10> handles;
1244
1245 for (uint32_t i = 0; i < 5; i++) {
1246 handles[i] = testQueue->submit_h(
__anon5324c4862902null1247 [&y] {
1248 usleep(2000000);
1249 y.fetch_add(1);
1250 }, ffrt::task_attr("Slow_Task")
1251 );
1252 }
1253
1254 for (uint32_t i = 5; i < 10; i++) {
1255 handles[i] = testQueue->submit_h(
__anon5324c4862a02null1256 [&y] {
1257 y.fetch_add(1);
1258 usleep(1000000);
1259 }, ffrt::task_attr("Normal_Task")
1260 );
1261 }
1262
1263 for (uint32_t i = 0; i < 10; i++) {
1264 testQueue->wait(handles[i]);
1265 }
1266
1267 EXPECT_EQ(y, 10);
1268 delete testQueue;
1269 }
1270
1271 /*
1272 * 测试用例名称 : ffrt_queue_concurrent_monitor_schedule_timeout_part
1273 * 测试用例描述 : 并行队列QueueMonitor检测到任务调度超时
1274 * 操作步骤 : 1、创建队列
1275 * 2、提交多个任务占满部分worker,使得新并行任务等待调度
1276 * 预期结果 : 成功触发任务调度超时告警
1277 */
1278 HWTEST_F(QueueTest, ffrt_queue_monitor_concurrent_schedule_timeout_part, TestSize.Level1)
1279 {
1280 ffrt_task_timeout_set_cb(MyCallback);
1281 FFRTFacade::GetDMInstance();
1282 FFRTFacade::GetQMInstance().timeoutUs_ = 1000000;
1283
1284 ffrt::queue* testQueue = new ffrt::queue(ffrt::queue_concurrent,
1285 "concurrent_queue", ffrt::queue_attr().max_concurrency(4));
1286 ffrt_set_cpu_worker_max_num(ffrt_qos_default, 2);
1287 std::atomic<std::uint64_t> y{0};
1288 std::array<ffrt::task_handle, 4> handles;
1289
1290 for (uint32_t i = 0; i < 1; i++) {
1291 handles[i] = testQueue->submit_h(
__anon5324c4862b02null1292 [&y] {
1293 y.fetch_add(1);
1294 usleep(4000000);
1295 }, ffrt::task_attr("Slow_Task")
1296 );
1297 }
1298
1299 for (uint32_t i = 1; i < 4; i++) {
1300 handles[i] = testQueue->submit_h(
__anon5324c4862c02null1301 [&y] {
1302 y.fetch_add(1);
1303 usleep(1000000);
1304 }, ffrt::task_attr("Normal_Task")
1305 );
1306 }
1307
1308 for (uint32_t i = 0; i < 4; i++) {
1309 testQueue->wait(handles[i]);
1310 }
1311
1312 EXPECT_EQ(y, 4);
1313 delete testQueue;
1314 }
1315
1316 /*
1317 * 测试用例名称 : ffrt_queue_concurrent_monitor_schedule_timeout_delay
1318 * 测试用例描述 : 并行队列QueueMonitor检测到任务调度超时
1319 * 操作步骤 : 1、创建队列
1320 * 2、提交多个延迟任务,使得新并行任务等待调度
1321 * 预期结果 : 不触发任务调度超时告警
1322 */
1323 HWTEST_F(QueueTest, ffrt_queue_monitor_concurrent_schedule_timeout_delay, TestSize.Level1)
1324 {
1325 ffrt_task_timeout_set_cb(MyCallback);
1326 FFRTFacade::GetDMInstance();
1327 FFRTFacade::GetQMInstance().timeoutUs_ = 1000000;
1328
1329 ffrt::queue* testQueue = new ffrt::queue(ffrt::queue_concurrent,
1330 "concurrent_queue", ffrt::queue_attr().max_concurrency(4));
1331 ffrt_set_cpu_worker_max_num(ffrt_qos_default, 3);
1332 std::atomic<std::uint64_t> y{0};
1333 std::array<ffrt::task_handle, 10> handles;
1334
1335 for (uint32_t i = 0; i < 2; i++) {
1336 handles[i] = testQueue->submit_h(
__anon5324c4862d02null1337 [&y] {
1338 y.fetch_add(1);
1339 }, ffrt::task_attr("Delayed_Task").delay(1100000)
1340 );
1341 }
1342
1343 for (uint32_t i = 2; i < 10; i++) {
1344 handles[i] = testQueue->submit_h(
__anon5324c4862e02null1345 [&y] {
1346 y.fetch_add(1);
1347 }, ffrt::task_attr("Normal_Task")
1348 );
1349 }
1350
1351 for (uint32_t i = 0; i < 10; i++) {
1352 testQueue->wait(handles[i]);
1353 }
1354
1355 EXPECT_EQ(y, 10);
1356 delete testQueue;
1357 }
1358
1359 /*
1360 * 测试用例名称 : ffrt_queue_concurrent_monitor_execute_timeout_all
1361 * 测试用例描述 : 并行队列QueueMonitor检测到任务执行超时
1362 * 操作步骤 : 1、创建队列
1363 * 2、提交执行时间长任务占满全部worker
1364 * 预期结果 : 成功触发任务执行超时告警
1365 */
1366 HWTEST_F(QueueTest, ffrt_queue_monitor_concurrent_execute_timeout_all, TestSize.Level1)
1367 {
1368 ffrt_task_timeout_set_cb(MyCallback);
1369 FFRTFacade::GetDMInstance();
1370 FFRTFacade::GetQMInstance().timeoutUs_ = 1000000;
1371
1372 ffrt::queue* testQueue = new ffrt::queue(ffrt::queue_concurrent,
1373 "concurrent_queue", ffrt::queue_attr().max_concurrency(4));
1374 std::atomic<std::uint64_t> y{0};
1375 std::array<ffrt::task_handle, 20> handles;
1376
1377 for (uint32_t i = 0; i < 4; i++) {
1378 handles[i] = testQueue->submit_h(
__anon5324c4862f02null1379 [&y] {
1380 y.fetch_add(1);
1381 }, ffrt::task_attr("Normal_Task")
1382 );
1383 }
1384
1385 for (uint32_t i = 4; i < 15; i++) {
1386 handles[i] = testQueue->submit_h(
__anon5324c4863002null1387 [&y] {
1388 y.fetch_add(1);
1389 usleep(1100000);
1390 }, ffrt::task_attr("Slow_Task")
1391 );
1392 }
1393
1394 for (uint32_t i = 15; i < 20; i++) {
__anon5324c4863102() 1395 ffrt::submit([&]() {
1396 y.fetch_add(1);
1397 }, ffrt::task_attr("Normal_Task")
1398 );
1399 }
1400 for (uint32_t i = 4; i < 15; i++) {
1401 testQueue->wait(handles[i]);
1402 }
1403
1404 EXPECT_EQ(y, 20);
1405 delete testQueue;
1406 }
1407
1408 /*
1409 * 测试用例名称 : ffrt_queue_concurrent_monitor_cancel_timeout_all
1410 * 测试用例描述 : 并行队列QueueMonitor检测到任务超时
1411 * 操作步骤 : 1、创建队列
1412 * 2、先提交多个延迟任务占满全部worker,再执行前取消
1413 * 预期结果 : 不触发任务调度超时告警
1414 */
1415 HWTEST_F(QueueTest, ffrt_queue_monitor_concurrent_cancel_timeout_all, TestSize.Level1)
1416 {
1417 ffrt_task_timeout_set_cb(MyCallback);
1418 FFRTFacade::GetDMInstance();
1419 FFRTFacade::GetQMInstance().timeoutUs_ = 1000000;
1420
1421 ffrt::queue* testQueue = new ffrt::queue(ffrt::queue_concurrent,
1422 "concurrent_queue", ffrt::queue_attr().max_concurrency(4));
1423 ffrt_set_cpu_worker_max_num(ffrt_qos_default, 2);
1424 std::atomic<std::uint64_t> y{0};
1425 std::array<ffrt::task_handle, 10> handles;
1426
1427 for (uint32_t i = 0; i < 2; i++) {
1428 handles[i] = testQueue->submit_h(
__anon5324c4863202null1429 [&y] {
1430 y.fetch_add(1);
1431 }, ffrt::task_attr("Delayed_Task").delay(3000000)
1432 );
1433 }
1434 testQueue->cancel(handles[0]);
1435 testQueue->cancel(handles[1]);
1436
1437 for (uint32_t i = 2; i < 10; i++) {
1438 handles[i] = testQueue->submit_h(
__anon5324c4863302null1439 [&y] {
1440 y.fetch_add(1);
1441 }, ffrt::task_attr("Normal_Task")
1442 );
1443 }
1444
1445 for (uint32_t i = 2; i < 10; i++) {
1446 testQueue->wait(handles[i]);
1447 }
1448
1449 EXPECT_EQ(y, 8);
1450 delete testQueue;
1451 }
1452
1453 /*
1454 * 测试用例名称 : ffrt_queue_concurrent_monitor_mixed_conditions_timeout
1455 * 测试用例描述 : 并行队列QueueMonitor检测到任务超时
1456 * 操作步骤 : 1、创建队列
1457 * 2、先提交多个延迟任务占满全部worker,再执行前取消
1458 * 预期结果 : 不触发任务超时告警
1459 */
1460 HWTEST_F(QueueTest, ffrt_queue_monitor_concurrent_mixed_conditions_timeout, TestSize.Level1)
1461 {
1462 ffrt_task_timeout_set_cb(MyCallback);
1463 FFRTFacade::GetDMInstance();
1464 FFRTFacade::GetQMInstance().timeoutUs_ = 1000000;
1465
1466 ffrt::queue* testQueue = new ffrt::queue(ffrt::queue_concurrent,
1467 "concurrent_queue", ffrt::queue_attr().max_concurrency(4));
1468 std::atomic<std::uint64_t> y{0};
1469 std::array<ffrt::task_handle, 12> handles;
1470
1471 for (uint32_t i = 0; i < 2; i++) {
1472 handles[i] = testQueue->submit_h(
__anon5324c4863402null1473 [&y] {
1474 y.fetch_add(1);
1475 }, ffrt::task_attr("Delayed_Task").delay(3000000)
1476 );
1477 }
1478 testQueue->cancel(handles[0]);
1479
1480 for (uint32_t i = 2; i < 7; i++) {
1481 handles[i] = testQueue->submit_h(
__anon5324c4863502null1482 [&y] {
1483 y.fetch_add(1);
1484 usleep(2000000);
1485 }, ffrt::task_attr("Slow_Task")
1486 );
1487 }
1488
1489 for (uint32_t i = 7; i < 12; i++) {
1490 handles[i] = testQueue->submit_h(
__anon5324c4863602null1491 [&y] {
1492 y.fetch_add(1);
1493 usleep(1000000);
1494 }, ffrt::task_attr("Normal_Task")
1495 );
1496 }
1497
1498 for (uint32_t i = 1; i < 12; i++) {
1499 testQueue->wait(handles[i]);
1500 }
1501
1502 EXPECT_EQ(y, 11);
1503 delete testQueue;
1504 FFRTFacade::GetQMInstance().timeoutUs_ = 30000000;
1505 }
1506
1507 HWTEST_F(QueueTest, submit_task_while_concurrency_queue_waiting_all_test, TestSize.Level1)
1508 {
1509 ffrt::queue* testQueue = new ffrt::queue(ffrt::queue_concurrent,
1510 "concurrent_queue", ffrt::queue_attr().max_concurrency(4));
1511 bool notify = false;
1512 int waitingTaskCount = 0;
1513 std::atomic<int> submitThreadTaskCount = 0;
1514 std::mutex lock;
1515 std::condition_variable cv;
1516 for (int i = 0; i < 16; i++) {
__anon5324c4863702null1517 testQueue->submit([&] {
1518 std::unique_lock lk(lock);
1519 cv.wait(lk, [&] { return notify; });
1520 waitingTaskCount++;
1521 EXPECT_EQ(submitThreadTaskCount.load(), 0);
1522 });
1523 }
1524
1525 std::mutex threadMutex;
__anon5324c4863902null1526 std::thread waitingThread([&] {
1527 std::unique_lock tm(threadMutex);
1528 EXPECT_EQ(ffrt_concurrent_queue_wait_all(*reinterpret_cast<ffrt_queue_t*>(testQueue)), 0);
1529 });
1530
__anon5324c4863a02null1531 std::thread submitThread([&] {
1532 while (threadMutex.try_lock()) {
1533 threadMutex.unlock();
1534 std::this_thread::yield();
1535 }
1536 usleep(100 * 1000);
1537
1538 EXPECT_EQ(ffrt_concurrent_queue_wait_all(*reinterpret_cast<ffrt_queue_t*>(testQueue)), 1);
1539 for (int i = 0; i < 16; i++) {
1540 testQueue->submit([&] {
1541 submitThreadTaskCount.fetch_add(1);
1542 });
1543 }
1544 });
1545
1546 submitThread.join();
1547 EXPECT_EQ(submitThreadTaskCount.load(), 0);
1548
1549 {
1550 std::unique_lock lk(lock);
1551 notify = true;
1552 cv.notify_all();
1553 }
1554 waitingThread.join();
1555 EXPECT_EQ(waitingTaskCount, 16);
1556
1557 EXPECT_EQ(ffrt_concurrent_queue_wait_all(*reinterpret_cast<ffrt_queue_t*>(testQueue)), 0);
1558 EXPECT_EQ(submitThreadTaskCount.load(), 16);
1559 }
1560 /*
1561 * 测试用例名称 : ffrt_queue_cancel_with_ffrt_skip_fail
1562 * 测试用例描述 : 使用ffrt::skip接口取消队列任务,返回失败
1563 * 操作步骤 : 1、创建队列
1564 * 2、提交延时的队列任务,同时调用skip接口取消队列任务
1565 * 预期结果 : 队列任务取消失败,任务成功执行
1566 */
1567 HWTEST_F(QueueTest, ffrt_queue_cancel_with_ffrt_skip_fail, TestSize.Level0)
1568 {
1569 ffrt::queue* testQueue = new ffrt::queue(ffrt::queue_concurrent,
1570 "concurrent_queue", ffrt::queue_attr().max_concurrency(4));
1571 int result = 0;
__anon5324c4863c02null1572 auto handle = testQueue->submit_h([&result] {
1573 result++;
1574 }, ffrt::task_attr("Delayed_Task").delay(1100000));
1575
1576 EXPECT_EQ(ffrt::skip(handle), ffrt_error);
1577 testQueue->wait(handle);
1578
1579 EXPECT_EQ(result, 1);
1580 delete testQueue;
1581 }
1582
1583 /*
1584 * 测试用例名称 : ffrt_queue_with_legacy_mode
1585 * 测试用例描述 : 队列设置leagcymode为true,验证任务不在协程上执行
1586 * 操作步骤 : 1、创建队列, attr设置legacymode为true
1587 * 2、提交队列任务,验证当前是在线程上执行任务
1588 * 预期结果 : 任务成功执行,任务在线程上执行
1589 */
1590 HWTEST_F(QueueTest, ffrt_queue_with_legacy_mode, TestSize.Level0)
1591 {
1592 ffrt::queue* testQueue = new ffrt::queue(ffrt::queue_concurrent,
1593 "concurrent_legacy_queue", ffrt::queue_attr().thread_mode(true));
1594 int result = 0;
__anon5324c4863d02null1595 auto handle = testQueue->submit_h([&result] {
1596 ffrt::TaskBase* task = ffrt::ExecuteCtx::Cur()->task;
1597 EXPECT_EQ(static_cast<ffrt::QueueTask*>(task)->coRoutine, nullptr);
1598 EXPECT_EQ(static_cast<ffrt::QueueTask*>(task)->threadMode_, true);
1599 result++;
1600 }, ffrt::task_attr("Task_on_Thread"));
1601
1602 testQueue->wait(handle);
1603
1604 EXPECT_EQ(result, 1);
1605 delete testQueue;
1606 }
1607
1608 /*
1609 * 测试用例名称 : ffrt_queue_with_legacy_mode_off
1610 * 测试用例描述 : 队列设置leagcymode为true,验证任务在协程上执行
1611 * 操作步骤 : 1、创建队列, attr设置legacymode为false
1612 * 2、提交队列任务,验证当前是在协程上执行任务
1613 * 预期结果 : 任务成功执行,任务在协程上执行
1614 */
1615 HWTEST_F(QueueTest, ffrt_queue_with_legacy_mode_off, TestSize.Level0)
1616 {
1617 ffrt::queue* testQueue = new ffrt::queue(ffrt::queue_concurrent,
1618 "concurrent_normal_queue", ffrt::queue_attr());
1619 int result = 0;
__anon5324c4863e02null1620 auto handle = testQueue->submit_h([&result] {
1621 ffrt::TaskBase* task = ffrt::ExecuteCtx::Cur()->task;
1622 if (USE_COROUTINE) {
1623 EXPECT_NE(static_cast<ffrt::QueueTask*>(task)->coRoutine, nullptr);
1624 } else {
1625 EXPECT_EQ(static_cast<ffrt::QueueTask*>(task)->coRoutine, nullptr);
1626 }
1627 EXPECT_EQ(static_cast<ffrt::QueueTask*>(task)->threadMode_, false);
1628 result++;
1629 }, ffrt::task_attr("Task_on_Coroutine"));
1630
1631 testQueue->wait(handle);
1632
1633 EXPECT_EQ(result, 1);
1634 delete testQueue;
1635 }
1636
1637 /*
1638 * 测试用例名称 : ffrt_queue_with_legacy_mode_mutex
1639 * 测试用例描述 : 队列设置leagcymode为true,任务等锁并解锁后,判断任务之前状态是线程阻塞
1640 * 操作步骤 : 1、创建队列, attr设置legacymode为true
1641 * 2、提交延时的队列任务,验证当前是在线程上执行任务
1642 * 预期结果 : 任务成功执行,能够正确使用线程方式阻塞
1643 */
1644 HWTEST_F(QueueTest, ffrt_queue_with_legacy_mode_mutex, TestSize.Level0)
1645 {
1646 ffrt::queue* testQueue = new ffrt::queue(ffrt::queue_serial,
1647 "serial_legacy_queue", ffrt::queue_attr().thread_mode(true));
1648
1649 ffrt::mutex mtx;
1650 int result = 0;
1651 std::atomic<bool> flag = false;
1652
__anon5324c4863f02null1653 auto handle = testQueue->submit_h([&] {
1654 flag = true;
1655 while (flag) {
1656 usleep(100);
1657 }
1658 mtx.lock();
1659 ffrt::TaskBase* task = ffrt::ExecuteCtx::Cur()->task;
1660 EXPECT_EQ(task->preStatus, ffrt::TaskStatus::THREAD_BLOCK);
1661 EXPECT_EQ(static_cast<ffrt::QueueTask*>(task)->threadMode_, true);
1662 result++;
1663 }, ffrt::task_attr("Task_on_Thread"));
1664
1665 while (!flag) {
1666 usleep(100);
1667 }
1668
1669 {
1670 std::lock_guard lg(mtx);
1671 flag = false;
1672 usleep(10000);
1673 }
1674
1675 testQueue->wait(handle);
1676
1677 EXPECT_EQ(result, 1);
1678 delete testQueue;
1679 }
1680
1681
1682 /*
1683 * 测试用例名称 : ffrt_eventhandler_adapter_queue_get_task_cnt
1684 * 测试用例描述 : eventhandler adapter队列获取任务数量
1685 * 预置条件 :创建一个eventhandler adapter队列
1686 * 操作步骤 : 1、调用get_task_cnt接口
1687 * 2、提交若干延时任务后,再次调用get_task_cnt接口
1688 * 预期结果 : 1、初始get_task_cnt返回0,后续get_task_cnt返回提交的任务数
1689 * 2、提交延时任务后,get_task_cnt返回提交的任务数
1690 */
1691 HWTEST_F(QueueTest, ffrt_eventhandler_adapter_queue_get_task_cnt, TestSize.Level0)
1692 {
1693 std::shared_ptr<queue> testQueue = std::make_shared<queue>(
1694 static_cast<queue_type>(ffrt_inner_queue_type_t::ffrt_queue_eventhandler_adapter), "test_queue"
1695 );
1696 EXPECT_EQ(testQueue->get_task_cnt(), 0);
1697
1698 for (int i = 0; i < 10; i++) {
__anon5324c4864002null1699 testQueue->submit([] { int x = 0; }, task_attr().delay(10 * 1000 * 1000));
1700 EXPECT_EQ(testQueue->get_task_cnt(), i + 1);
1701 }
1702
1703 testQueue = nullptr;
1704 }
1705