• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <array>
16 #include <gtest/gtest.h>
17 #include <regex>
18 #include <thread>
19 #include "c/ffrt_dump.h"
20 #include "dfx/log/ffrt_log_api.h"
21 #include "ffrt_inner.h"
22 #include "securec.h"
23 #include "util.h"
24 #include "../common.h"
25 
26 static const int BUFFER_SIZE = 120000;
27 static const int SLEEP_MS = 3 * 1000;
28 static const int TASK_NUM_9 = 9;
29 static const int TASK_NUM_10 = 10;
30 static const int TASK_NUM_29 = 29;
31 static const int TASK_NUM_40 = 40;
32 static const int TASK_NUM_600 = 600;
33 static const int TASK_NUM_610 = 610;
34 static const int THREAD_SIZE = 10 * 1024 * 1024;
35 
36 using namespace std;
37 using namespace ffrt;
38 using namespace testing;
39 #ifdef HWTEST_TESTING_EXT_ENABLE
40 using namespace testing::ext;
41 #endif
42 
43 class QueueDumpTest : public testing::Test {
44 protected:
SetUpTestCase()45     static void SetUpTestCase()
46     {
47     }
48 
TearDownTestCase()49     static void TearDownTestCase()
50     {
51     }
52 
SetUp()53     void SetUp() override
54     {
55     }
56 
TearDown()57     void TearDown() override
58     {
59     }
60 };
61 
62 int g_cnt = 0;
__anoncce87c790102() 63 std::function<void()>&& basicFunc = []() { g_cnt += 1; };
__anoncce87c790202() 64 std::function<void()>&& sleepFunc = []() { std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_MS)); };
65 
Task1MatchFunc(void * buf)66 void *Task1MatchFunc(void *buf)
67 {
68     std::string str((char *)buf);
69     std::regex pattern(R"(eventHandler1 Current Running: start at (\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d{3}), Event \{ send thread = (\d+), send time = (\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d{3}), handle time = (\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d{3}), task name = (.*task1.*) \}
70 eventHandler1 History event queue information:
71 (eventHandler1 No. (\d+) : Event \{ send thread = (\d+), send time = (\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d{3}), handle time = (\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d{3}), trigger time = (\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d{3}), complete time = (\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d{3}), task name = (.*task1.*) \}
72 ){10}eventHandler1 Immediate priority event queue information:
73 eventHandler1 Total size of Immediate events : 0
74 eventHandler1 High priority event queue information:
75 eventHandler1 Total size of High events : 0
76 eventHandler1 Low priority event queue information:
77 eventHandler1 Total size of Low events : 0
78 eventHandler1 Idle priority event queue information:
79 eventHandler1 Total size of Idle events : 0
80 eventHandler1 Vip priority event queue information:
81 eventHandler1 Total size of Vip events : 0
82 eventHandler1 Total event size : 0
83 )");
84     EXPECT_TRUE(std::regex_match(str, pattern));
85     return nullptr;
86 }
87 
QueueDumpMatchFunc(void * (* ThreadFunc)(void *),void * buf)88 static void QueueDumpMatchFunc(void*(*ThreadFunc)(void*), void *buf)
89 {
90     pthread_t thread;
91     pthread_attr_t queue_attr;
92     pthread_attr_init(&queue_attr);
93     pthread_attr_setstacksize(&queue_attr, THREAD_SIZE);
94     pthread_create(&thread, &queue_attr, ThreadFunc, buf);
95     pthread_join(thread, nullptr);
96 }
97 
QueueDumpTask1Test(ffrt_queue_t & queue_handle,char * buf)98 static void QueueDumpTask1Test(ffrt_queue_t& queue_handle, char* buf)
99 {
100     ffrt_task_attr_t task_attr;
101     (void)ffrt_task_attr_init(&task_attr);
102     ffrt_task_attr_set_name(&task_attr, "task1");
103     for (int i = 0; i < TASK_NUM_9; ++i) {
104         ffrt_queue_submit(queue_handle, create_function_wrapper(basicFunc, ffrt_function_kind_queue), &task_attr);
105     }
106     ffrt_task_handle_t t =
107         ffrt_queue_submit_h(queue_handle, create_function_wrapper(basicFunc, ffrt_function_kind_queue), &task_attr);
108     ffrt_queue_wait(t);
109     EXPECT_EQ(g_cnt, TASK_NUM_10);
110     // dump队列信息
111     int ret = ffrt_queue_dump(queue_handle, "eventHandler1", buf, BUFFER_SIZE, true);
112     EXPECT_TRUE(ret > 0);
113     // 预期dump信息:
114     // 1.tag为eventHandler1
115     // 2.当前执行任务名称为task1
116     // 3.有10条历史执行的任务,且任务名称都是task1
117     // 4.无剩余未执行的任务
118     QueueDumpMatchFunc(Task1MatchFunc, buf);
119 
120     ffrt_task_handle_destroy(t);
121     ffrt_task_attr_destroy(&task_attr);
122 }
123 
Task2MatchFunc(void * buf)124 void *Task2MatchFunc(void *buf)
125 {
126     std::string str((char *)buf);
127     std::regex pattern(R"(eventHandler2 Current Running: start at (\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d{3}), Event \{ send thread = (\d+), send time = (\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d{3}), handle time = (\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d{3}), task name = (.*task2.*) \}
128 eventHandler2 History event queue information:
129 (eventHandler2 No. (\d+) : Event \{ send thread = (\d+), send time = (\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d{3}), handle time = (\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d{3}), trigger time = (\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d{3}), complete time = (\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d{3}), task name = ([^\}]*?) \}
130 ){32}eventHandler2 Immediate priority event queue information:
131 eventHandler2 Total size of Immediate events : 0
132 eventHandler2 High priority event queue information:
133 eventHandler2 Total size of High events : 0
134 eventHandler2 Low priority event queue information:
135 eventHandler2 Total size of Low events : 0
136 eventHandler2 Idle priority event queue information:
137 eventHandler2 Total size of Idle events : 0
138 eventHandler2 Vip priority event queue information:
139 eventHandler2 Total size of Vip events : 0
140 eventHandler2 Total event size : 0
141 )");
142     EXPECT_TRUE(std::regex_match(str, pattern));
143     return nullptr;
144 }
145 
QueueDumpTask2Test(ffrt_queue_t & queue_handle,char * buf)146 static void QueueDumpTask2Test(ffrt_queue_t& queue_handle, char* buf)
147 {
148     ffrt_task_attr_t task_attr;
149     (void)ffrt_task_attr_init(&task_attr);
150     ffrt_task_attr_set_name(&task_attr, "task2");
151     for (int i = 0; i < TASK_NUM_29; ++i) {
152         ffrt_queue_submit(queue_handle, create_function_wrapper(basicFunc, ffrt_function_kind_queue), &task_attr);
153     }
154     ffrt_task_handle_t t =
155         ffrt_queue_submit_h(queue_handle, create_function_wrapper(basicFunc, ffrt_function_kind_queue), &task_attr);
156     ffrt_queue_wait(t);
157     EXPECT_EQ(g_cnt, TASK_NUM_40);
158     // dump队列信息
159 
160     memset_s(buf, sizeof(char) * BUFFER_SIZE, 0, sizeof(char) * BUFFER_SIZE);
161     int ret = ffrt_queue_dump(queue_handle, "eventHandler2", buf, BUFFER_SIZE, true);
162     EXPECT_TRUE(ret > 0);
163     // 预期dump信息:
164     // 1.tag为eventHandler2
165     // 2.当前执行任务名称为task2
166     // 3.有32条历史执行的任务
167     // 4.无剩余未执行的任务
168     QueueDumpMatchFunc(Task2MatchFunc, buf);
169 
170     ffrt_task_handle_destroy(t);
171     ffrt_task_attr_destroy(&task_attr);
172 }
173 
Task3MatchFunc(void * buf)174 void *Task3MatchFunc(void *buf)
175 {
176     std::string str((char *)buf);
177     std::regex pattern(R"(eventHandler3 Current Running: start at (\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d{3}), Event \{ send thread = (\d+), send time = (\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d{3}), handle time = (\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d{3}), task name = (.*task3.*) \}
178 eventHandler3 History event queue information:
179 (eventHandler3 No. (\d+) : Event \{ send thread = (\d+), send time = (\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d{3}), handle time = (\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d{3}), trigger time = (\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d{3}), complete time = (\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d{3}), task name = ([^\}]*?) \}
180 ){32}eventHandler3 Immediate priority event queue information:
181 eventHandler3 Total size of Immediate events : 0
182 eventHandler3 High priority event queue information:
183 eventHandler3 Total size of High events : 0
184 eventHandler3 Low priority event queue information:
185 eventHandler3 Total size of Low events : 0
186 eventHandler3 Idle priority event queue information:
187 eventHandler3 Total size of Idle events : 0
188 eventHandler3 Vip priority event queue information:
189 eventHandler3 Total size of Vip events : 0
190 eventHandler3 Total event size : 0
191 )");
192     EXPECT_TRUE(std::regex_match(str, pattern));
193     return nullptr;
194 }
195 
QueueDumpTask3Test(ffrt_queue_t & queue_handle,char * buf)196 static void QueueDumpTask3Test(ffrt_queue_t& queue_handle, char* buf)
197 {
198     ffrt_task_attr_t task_attr;
199     (void)ffrt_task_attr_init(&task_attr);
200     ffrt_task_attr_set_name(&task_attr, "task3");
201     ffrt_queue_submit(queue_handle, create_function_wrapper(sleepFunc, ffrt_function_kind_queue), &task_attr);
202     // dump队列信息
203     memset_s(buf, sizeof(char) * BUFFER_SIZE, 0, sizeof(char) * BUFFER_SIZE);
204     int ret = ffrt_queue_dump(queue_handle, "eventHandler3", buf, BUFFER_SIZE, true);
205     EXPECT_TRUE(ret > 0);
206     // 预期dump信息:
207     // 1.tag为eventHandler3
208     // 2.当前执行任务名称为task3
209     // 3.有32条历史执行的任务
210     // 4.无剩余未执行的任务
211     QueueDumpMatchFunc(Task3MatchFunc, buf);
212 
213     ffrt_task_attr_destroy(&task_attr);
214 }
215 
QueueDumpPriorityTest(ffrt_queue_t & queue_handle,ffrt_task_attr_t & task_attr,ffrt_inner_queue_priority_t priority,const char * name)216 static void QueueDumpPriorityTest(ffrt_queue_t& queue_handle, ffrt_task_attr_t& task_attr,
217     ffrt_inner_queue_priority_t priority, const char* name)
218 {
219     (void)ffrt_task_attr_init(&task_attr);
220     ffrt_task_attr_set_queue_priority(&task_attr, static_cast<ffrt_queue_priority_t>(priority));
221     ffrt_task_attr_set_name(&task_attr, name);
222     for (int i = 0; i < TASK_NUM_10; ++i) {
223         ffrt_queue_submit(queue_handle, create_function_wrapper(basicFunc, ffrt_function_kind_queue), &task_attr);
224     }
225 }
226 
PriorityMatchFunc(void * buf)227 void *PriorityMatchFunc(void *buf)
228 {
229     std::string str((char *)buf);
230     std::regex pattern(R"(eventHandler4 Current Running: start at (\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d{3}), Event \{ send thread = (\d+), send time = (\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d{3}), handle time = (\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d{3}), task name = (.*task3.*) \}
231 eventHandler4 History event queue information:
232 (eventHandler4 No. (\d+) : Event \{ send thread = (\d+), send time = (\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d{3}), handle time = (\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d{3}), trigger time = (\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d{3}), complete time = (\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d{3}), task name = ([^\}]*?) \}
233 ){32}eventHandler4 Immediate priority event queue information:
234 (eventHandler4 No. (\d+) : Event \{ send thread = (\d+), send time = (\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d{3}), handle time = (\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d{3}), task name = (.*task4.*) \}
235 ){10}eventHandler4 Total size of Immediate events : 10
236 eventHandler4 High priority event queue information:
237 (eventHandler4 No. (\d+) : Event \{ send thread = (\d+), send time = (\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d{3}), handle time = (\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d{3}), task name = (.*task5.*) \}
238 ){10}eventHandler4 Total size of High events : 10
239 eventHandler4 Low priority event queue information:
240 (eventHandler4 No. (\d+) : Event \{ send thread = (\d+), send time = (\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d{3}), handle time = (\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d{3}), task name = (.*task6.*) \}
241 ){10}eventHandler4 Total size of Low events : 10
242 eventHandler4 Idle priority event queue information:
243 (eventHandler4 No. (\d+) : Event \{ send thread = (\d+), send time = (\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d{3}), handle time = (\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d{3}), task name = (.*task7.*) \}
244 ){10}eventHandler4 Total size of Idle events : 10
245 eventHandler4 Vip priority event queue information:
246 (eventHandler4 No. (\d+) : Event \{ send thread = (\d+), send time = (\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d{3}), handle time = (\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d{3}), task name = (.*task8.*) \}
247 ){10}eventHandler4 Total size of Vip events : 10
248 eventHandler4 Total event size : 50
249 )");
250     EXPECT_TRUE(std::regex_match(str, pattern));
251     return nullptr;
252 }
253 
QueueDumpPriorityTest(ffrt_queue_t & queue_handle,char * buf)254 static void QueueDumpPriorityTest(ffrt_queue_t& queue_handle, char* buf)
255 {
256     ffrt_task_attr_t task_attr4;
257     QueueDumpPriorityTest(queue_handle, task_attr4, ffrt_inner_queue_priority_immediate, "task4");
258     ffrt_task_attr_t task_attr5;
259     QueueDumpPriorityTest(queue_handle, task_attr5, ffrt_inner_queue_priority_high, "task5");
260     ffrt_task_attr_t task_attr6;
261     QueueDumpPriorityTest(queue_handle, task_attr6, ffrt_inner_queue_priority_low, "task6");
262     ffrt_task_attr_t task_attr7;
263     QueueDumpPriorityTest(queue_handle, task_attr7, ffrt_inner_queue_priority_idle, "task7");
264     ffrt_task_attr_t task_attr8;
265     QueueDumpPriorityTest(queue_handle, task_attr8, ffrt_inner_queue_priority_vip, "task8");
266     memset_s(buf, sizeof(char) * BUFFER_SIZE, 0, sizeof(char) * BUFFER_SIZE);
267     int ret = ffrt_queue_dump(queue_handle, "eventHandler4", buf, BUFFER_SIZE, true);
268     EXPECT_TRUE(ret > 0);
269     // 预期dump信息:
270     // 1.tag为eventHandler4
271     // 2.当前执行任务名称为task3
272     // 3.有32条历史执行的任务
273     // 4.5种优先级各有10条任务
274     QueueDumpMatchFunc(PriorityMatchFunc, buf);
275 
276     ffrt_task_attr_destroy(&task_attr4);
277     ffrt_task_attr_destroy(&task_attr5);
278     ffrt_task_attr_destroy(&task_attr6);
279     ffrt_task_attr_destroy(&task_attr7);
280     ffrt_task_attr_destroy(&task_attr8);
281 }
282 
QueueDumpMaxDumpSizeTest(ffrt_queue_t & queue_handle,char * buf)283 static void QueueDumpMaxDumpSizeTest(ffrt_queue_t& queue_handle, char* buf)
284 {
285     ffrt_task_attr_t task_attr;
286     (void)ffrt_task_attr_init(&task_attr);
287     ffrt_task_attr_set_queue_priority(&task_attr, static_cast<ffrt_queue_priority_t>(ffrt_inner_queue_priority_high));
288     ffrt_task_attr_set_name(&task_attr, "task9");
289     for (int i = 0; i < TASK_NUM_600; ++i) {
290         ffrt_queue_submit(queue_handle, create_function_wrapper(basicFunc, ffrt_function_kind_queue), &task_attr);
291     }
292     // dump队列信息
293     memset_s(buf, sizeof(char) * BUFFER_SIZE, 0, sizeof(char) * BUFFER_SIZE);
294     int ret = ffrt_queue_dump(queue_handle, "eventHandler9", buf, BUFFER_SIZE, false);
295     EXPECT_TRUE(ret > 0);
296     ffrt_task_attr_destroy(&task_attr);
297 }
298 
299 /**
300  * @brief queue dump interface user cases
301  */
302 HWTEST_F(QueueDumpTest, queue_dump_case, TestSize.Level1)
303 {
304     // 创建类型为ffrt_queue_eventhandler_adapter的队列
305     ffrt_queue_attr_t queue_attr;
306     (void)ffrt_queue_attr_init(&queue_attr);
307     ffrt_queue_attr_set_max_concurrency(&queue_attr, 1);
308     ffrt_queue_t queue_handle = ffrt_queue_create(static_cast<ffrt_queue_type_t>(ffrt_queue_eventhandler_adapter),
309         "queue_dump", &queue_attr);
310     char* buf = new char[BUFFER_SIZE];
311     // 提交10个任务并等待任务执行完成(任务名称:task1)
312     QueueDumpTask1Test(queue_handle, buf);
313     // 提交30个任务并等待任务执行完成(任务名称:task2)
314     QueueDumpTask2Test(queue_handle, buf);
315     // 提交1个睡眠3s的任务(任务名称:task3)
316     QueueDumpTask3Test(queue_handle, buf);
317     // 5种优先级各提交10个任务
318     QueueDumpPriorityTest(queue_handle, buf);
319     // 提交600个优先级为ffrt_inner_queue_priority_high的任务
320     QueueDumpMaxDumpSizeTest(queue_handle, buf);
321     // 验证ffrt_queue_size_dump结果
322     EXPECT_EQ(ffrt_queue_size_dump(queue_handle, ffrt_inner_queue_priority_immediate), TASK_NUM_10);
323     EXPECT_EQ(ffrt_queue_size_dump(queue_handle, ffrt_inner_queue_priority_high), TASK_NUM_610);
324     EXPECT_EQ(ffrt_queue_size_dump(queue_handle, ffrt_inner_queue_priority_low), TASK_NUM_10);
325     EXPECT_EQ(ffrt_queue_size_dump(queue_handle, ffrt_inner_queue_priority_idle), TASK_NUM_10);
326     EXPECT_EQ(ffrt_queue_size_dump(queue_handle, ffrt_inner_queue_priority_vip), TASK_NUM_10);
327     delete[] buf;
328 
329     ffrt_queue_destroy(queue_handle);
330     ffrt_queue_attr_destroy(&queue_attr);
331 }
332