• 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 
16 #include <thread>
17 #include <chrono>
18 #include <gtest/gtest.h>
19 #ifndef WITH_NO_MOCKER
20 #include <mockcpp/mockcpp.hpp>
21 #endif
22 #include <sys/epoll.h>
23 #include <sys/eventfd.h>
24 #include "ffrt_inner.h"
25 #include "c/loop.h"
26 #include "util/event_handler_adapter.h"
27 #include "../common.h"
28 
29 using namespace std;
30 using namespace ffrt;
31 using namespace testing;
32 #ifdef HWTEST_TESTING_EXT_ENABLE
33 using namespace testing::ext;
34 #endif
35 
36 class LoopTest : public testing::Test {
37 protected:
SetUpTestCase()38     static void SetUpTestCase()
39     {
40     }
41 
TearDownTestCase()42     static void TearDownTestCase()
43     {
44     }
45 
SetUp()46     void SetUp() override
47     {
48         ffrt_task_timeout_set_threshold(1);
49     }
50 
TearDown()51     void TearDown() override
52     {
53     }
54 };
55 
ThreadFunc(void * p)56 void* ThreadFunc(void* p)
57 {
58     int ret = ffrt_loop_run(p);
59     EXPECT_EQ(ret, 0);
60     return nullptr;
61 }
62 
63 /*
64  * 测试用例名称:loop_null_queue_create_fail
65  * 测试用例描述:非法队列创建loop失败
66  * 预置条件    :无
67  * 操作步骤    :1、创建loop失败
68  *
69  * 预期结果    :创建失败
70  */
71 HWTEST_F(LoopTest, loop_null_queue_create_fail, TestSize.Level0)
72 {
73     auto loop = ffrt_loop_create(nullptr);
74     EXPECT_EQ(loop, nullptr);
75 }
76 
77 /*
78  * 测试用例名称:loop_serial_queue_create_succ
79  * 测试用例描述:serial队列创建loop失败
80  * 预置条件    :1、调用串行队列创建接口创建serial队列
81  * 操作步骤    :1、创建loop
82  *
83  * 预期结果    :创建失败
84  */
85 HWTEST_F(LoopTest, loop_serial_queue_create_succ, TestSize.Level0)
86 {
87     ffrt_queue_attr_t queue_attr;
88     (void)ffrt_queue_attr_init(&queue_attr);
89     ffrt_queue_t queue_handle = ffrt_queue_create(ffrt_queue_serial, "test_queue", &queue_attr);
90 
91     auto loop = ffrt_loop_create(queue_handle);
92     EXPECT_EQ(loop, nullptr);
93 
94     ffrt_queue_attr_destroy(&queue_attr);
95     ffrt_queue_destroy(queue_handle);
96 }
97 
98 /*
99  * 测试用例名称:loop_concurrent_queue_create_succ
100  * 测试用例描述:无任务concurrent队列创建loop成功
101  * 预置条件    :1、调用串行队列创建接口创建concurrent队列
102  * 操作步骤    :1、创建loop
103  *
104  * 预期结果    :执行成功
105  */
106 HWTEST_F(LoopTest, loop_concurrent_queue_create_succ, TestSize.Level0)
107 {
108     ffrt_queue_attr_t queue_attr;
109     (void)ffrt_queue_attr_init(&queue_attr);
110     ffrt_queue_t queue_handle = ffrt_queue_create(ffrt_queue_concurrent, "test_queue", &queue_attr);
111 
112     auto loop = ffrt_loop_create(queue_handle);
113     EXPECT_NE(loop, nullptr);
114 
__anon60a6da7b0102(void* data) 115     int timerHandle = ffrt_loop_timer_start(loop, 10 * 1000, nullptr, [] (void* data) {}, false);
116     EXPECT_NE(timerHandle, -1);
117 
118     EXPECT_NE(ffrt_loop_timer_stop(loop, timerHandle), -1);
119 
120     int ret = ffrt_loop_destroy(loop);
121     EXPECT_EQ(ret, 0);
122 
123     ffrt_queue_attr_destroy(&queue_attr);
124     ffrt_queue_destroy(queue_handle);
125 }
126 
127 /*
128  * 测试用例名称:loop_concurrent_queue_create_fail
129  * 测试用例描述:有任务队列创建loop失败
130  * 预置条件    :1、调用串行队列创建接口创建concurrent队列
131  *              2、创建loop前向队列提交任务
132  * 操作步骤    :1、创建loop
133  *
134  * 预期结果    :创建失败
135  */
136 HWTEST_F(LoopTest, loop_concurrent_queue_create_fail, TestSize.Level0)
137 {
138     ffrt_queue_attr_t queue_attr;
139     (void)ffrt_queue_attr_init(&queue_attr);
140     ffrt_queue_t queue_handle = ffrt_queue_create(ffrt_queue_concurrent, "test_queue", &queue_attr);
141 
142     int result1 = 0;
__anon60a6da7b0202() 143     std::function<void()>&& basicFunc1 = [&result1]() { result1 += 10; };
144     ffrt_queue_submit(queue_handle, create_function_wrapper(basicFunc1, ffrt_function_kind_queue), nullptr);
145 
146     auto loop = ffrt_loop_create(queue_handle);
147     EXPECT_EQ(loop, nullptr);
148 
149     ffrt_queue_attr_destroy(&queue_attr);
150     ffrt_queue_destroy(queue_handle);
151 }
152 
153 /*
154  * 测试用例名称:loop_run_fail
155  * 测试用例描述:非法loop run失败
156  * 操作步骤    :1、执行loop run
157  *
158  * 预期结果    :执行失败
159  */
160 HWTEST_F(LoopTest, loop_run_fail, TestSize.Level0)
161 {
162     int ret = ffrt_loop_run(nullptr);
163     EXPECT_NE(ret, 0);
164 }
165 
166 /*
167  * 测试用例名称:loop_destroy_fail
168  * 测试用例描述:非法loop destroy失败
169  * 操作步骤    :1、执行loop run
170  *
171  * 预期结果    :执行失败
172  */
173 HWTEST_F(LoopTest, loop_destroy_fail, TestSize.Level0)
174 {
175     int ret = ffrt_loop_destroy(nullptr);
176     EXPECT_NE(ret, 0);
177 }
178 
179 /*
180  * 测试用例名称:loop_run_destroy_success
181  * 测试用例描述:正常loop run成功、destroy
182  * 预置条件    :1、调用串行队列创建接口创建concurrent队列
183  *              2、用队列创建loop
184  * 操作步骤    :1、启动线程执行loop run
185  *              2、销毁loop成功
186  * 预期结果    :执行成功
187  */
188 HWTEST_F(LoopTest, loop_run_destroy_success, TestSize.Level0)
189 {
190     ffrt_queue_attr_t queue_attr;
191     (void)ffrt_queue_attr_init(&queue_attr);
192     ffrt_queue_t queue_handle = ffrt_queue_create(ffrt_queue_concurrent, "test_queue", &queue_attr);
193 
194     auto loop = ffrt_loop_create(queue_handle);
195     EXPECT_NE(loop, nullptr);
196 
197     pthread_t thread;
198     int createRet = pthread_create(&thread, 0, ThreadFunc, loop);
199     if (createRet != 0) {
200         printf("pthread_create failed!");
201         ffrt_loop_destroy(loop);
202         ffrt_queue_attr_destroy(&queue_attr);
203         ffrt_queue_destroy(queue_handle);
204         return;
205     }
206 
207     ffrt_loop_stop(loop);
208     pthread_join(thread, nullptr);
209     int ret = ffrt_loop_destroy(loop);
210     EXPECT_EQ(ret, 0);
211 
212     ffrt_queue_attr_destroy(&queue_attr);
213     ffrt_queue_destroy(queue_handle);
214 }
215 
216 struct TestData {
217     int fd;
218     uint64_t expected;
219 };
220 
TestCallBack(void * token,uint32_t event)221 static void TestCallBack(void* token, uint32_t event)
222 {
223     struct TestData* testData = reinterpret_cast<TestData*>(token);
224     uint64_t value = 0;
225     ssize_t n = read(testData->fd, &value, sizeof(uint64_t));
226     EXPECT_EQ(n, sizeof(value));
227     EXPECT_EQ(value, testData->expected);
228 }
229 
AddFdListener(void * handler,uint32_t fd,uint32_t event,void * data,ffrt_poller_cb cb)230 int AddFdListener(void* handler, uint32_t fd, uint32_t event, void* data, ffrt_poller_cb cb)
231 {
232     return 0;
233 }
234 
RemoveFdListener(void * handler,uint32_t fd)235 int RemoveFdListener(void* handler, uint32_t fd)
236 {
237     return 0;
238 }
239 #if !defined(LIB_EVENT_HANDLER_DNE)
240 HWTEST_F(LoopTest, ffrt_add_and_remove_fd, TestSize.Level0)
241 {
242     ffrt_queue_attr_t queue_attr;
243     (void)ffrt_queue_attr_init(&queue_attr); // 初始化属性,必须
244     ffrt_queue_t queue_handle = ffrt_queue_create(
245         static_cast<ffrt_queue_type_t>(ffrt_queue_eventhandler_interactive), "test_queue", &queue_attr);
246 #ifndef WITH_NO_MOCKER
247     MOCKER(ffrt_get_main_queue).stubs().will(returnValue(queue_handle));
248 #endif
249 
250     EventHandlerAdapter::Instance()->AddFdListener = AddFdListener;
251     EventHandlerAdapter::Instance()->RemoveFdListener = RemoveFdListener;
252 
253     ffrt_queue_t mainQueue = ffrt_get_main_queue();
254     auto loop = ffrt_loop_create(mainQueue);
255     EXPECT_TRUE(loop != nullptr);
256     ffrt_loop_run(loop);
257     int ret = 0;
258     int testFd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
259     uint64_t expected = 0xabacadae;
260     struct TestData testData {.fd = testFd, .expected = expected};
261     ret = ffrt_loop_epoll_ctl(loop, EPOLL_CTL_ADD, testFd, EPOLLIN, (void*)(&testData), TestCallBack);
262     EXPECT_EQ(ret, 0);
263     ssize_t n = write(testFd, &expected, sizeof(uint64_t));
264     EXPECT_EQ(n, sizeof(uint64_t));
265     usleep(25000);
266 
267     ret = ffrt_loop_epoll_ctl(loop, EPOLL_CTL_DEL, testFd, 0, nullptr, nullptr);
268     EXPECT_EQ(ret, 0);
269 
270     ffrt_loop_stop(loop);
271     ffrt_loop_destroy(loop);
272     ffrt_queue_destroy(queue_handle);
273 
274 #ifndef WITH_NO_MOCKER
275     GlobalMockObject::reset();
276     GlobalMockObject::verify();
277 #endif
278 }
279 #endif
280