• 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.Level1)
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.Level1)
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.Level1)
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 
__anonfca50e590102(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.Level1)
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;
__anonfca50e590202() 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.Level1)
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.Level1)
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.Level1)
189 {
190     const uint64_t sleepTime = 250000;
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_concurrent, "test_queue", &queue_attr);
194 
195     auto loop = ffrt_loop_create(queue_handle);
196     EXPECT_NE(loop, nullptr);
197 
198     pthread_t thread;
199     pthread_create(&thread, 0, ThreadFunc, loop);
200 
201     ffrt_loop_stop(loop);
202     usleep(sleepTime);
203     int ret = ffrt_loop_destroy(loop);
204     EXPECT_EQ(ret, 0);
205 
206     ffrt_queue_attr_destroy(&queue_attr);
207     ffrt_queue_destroy(queue_handle);
208 }
209 
210 struct TestData {
211     int fd;
212     uint64_t expected;
213 };
214 
TestCallBack(void * token,uint32_t event)215 static void TestCallBack(void* token, uint32_t event)
216 {
217     struct TestData* testData = reinterpret_cast<TestData*>(token);
218     uint64_t value = 0;
219     ssize_t n = read(testData->fd, &value, sizeof(uint64_t));
220     EXPECT_EQ(n, sizeof(value));
221     EXPECT_EQ(value, testData->expected);
222 }
223 
AddFdListener(void * handler,uint32_t fd,uint32_t event,void * data,ffrt_poller_cb cb)224 int AddFdListener(void* handler, uint32_t fd, uint32_t event, void* data, ffrt_poller_cb cb)
225 {
226     return 0;
227 }
228 
RemoveFdListener(void * handler,uint32_t fd)229 int RemoveFdListener(void* handler, uint32_t fd)
230 {
231     return 0;
232 }
233 
234 HWTEST_F(LoopTest, ffrt_add_and_remove_fd, TestSize.Level1)
235 {
236     ffrt_queue_attr_t queue_attr;
237     (void)ffrt_queue_attr_init(&queue_attr); // 初始化属性,必须
238     ffrt_queue_t queue_handle = ffrt_queue_create(
239         static_cast<ffrt_queue_type_t>(ffrt_queue_eventhandler_interactive), "test_queue", &queue_attr);
240 #ifndef WITH_NO_MOCKER
241     MOCKER(ffrt_get_main_queue).stubs().will(returnValue(queue_handle));
242 #endif
243 
244     EventHandlerAdapter::Instance()->AddFdListener = AddFdListener;
245     EventHandlerAdapter::Instance()->RemoveFdListener = RemoveFdListener;
246 
247     ffrt_queue_t mainQueue = ffrt_get_main_queue();
248     auto loop = ffrt_loop_create(mainQueue);
249     EXPECT_TRUE(loop != nullptr);
250     ffrt_loop_run(loop);
251     int ret = 0;
252     int testFd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
253     uint64_t expected = 0xabacadae;
254     struct TestData testData {.fd = testFd, .expected = expected};
255     ret = ffrt_loop_epoll_ctl(loop, EPOLL_CTL_ADD, testFd, EPOLLIN, (void*)(&testData), TestCallBack);
256     EXPECT_EQ(ret, 0);
257     ssize_t n = write(testFd, &expected, sizeof(uint64_t));
258     EXPECT_EQ(n, sizeof(uint64_t));
259     usleep(25000);
260 
261     ret = ffrt_loop_epoll_ctl(loop, EPOLL_CTL_DEL, testFd, 0, nullptr, nullptr);
262     EXPECT_EQ(ret, 0);
263 
264     ffrt_loop_stop(loop);
265     ffrt_loop_destroy(loop);
266     ffrt_queue_destroy(queue_handle);
267 
268 #ifndef WITH_NO_MOCKER
269     GlobalMockObject::reset();
270     GlobalMockObject::verify();
271 #endif
272 }