1484543d1Sopenharmony_ci/*
2484543d1Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
3484543d1Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4484543d1Sopenharmony_ci * you may not use this file except in compliance with the License.
5484543d1Sopenharmony_ci * You may obtain a copy of the License at
6484543d1Sopenharmony_ci *
7484543d1Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8484543d1Sopenharmony_ci *
9484543d1Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10484543d1Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11484543d1Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12484543d1Sopenharmony_ci * See the License for the specific language governing permissions and
13484543d1Sopenharmony_ci * limitations under the License.
14484543d1Sopenharmony_ci */
15484543d1Sopenharmony_ci
16484543d1Sopenharmony_ci#include <thread>
17484543d1Sopenharmony_ci#include <chrono>
18484543d1Sopenharmony_ci#include <gtest/gtest.h>
19484543d1Sopenharmony_ci#ifndef WITH_NO_MOCKER
20484543d1Sopenharmony_ci#include <mockcpp/mockcpp.hpp>
21484543d1Sopenharmony_ci#endif
22484543d1Sopenharmony_ci#include <sys/epoll.h>
23484543d1Sopenharmony_ci#include <sys/eventfd.h>
24484543d1Sopenharmony_ci#include "ffrt_inner.h"
25484543d1Sopenharmony_ci#include "c/loop.h"
26484543d1Sopenharmony_ci#include "util/event_handler_adapter.h"
27484543d1Sopenharmony_ci#include "../common.h"
28484543d1Sopenharmony_ci
29484543d1Sopenharmony_ciusing namespace std;
30484543d1Sopenharmony_ciusing namespace ffrt;
31484543d1Sopenharmony_ciusing namespace testing;
32484543d1Sopenharmony_ci#ifdef HWTEST_TESTING_EXT_ENABLE
33484543d1Sopenharmony_ciusing namespace testing::ext;
34484543d1Sopenharmony_ci#endif
35484543d1Sopenharmony_ci
36484543d1Sopenharmony_ciclass LoopTest : public testing::Test {
37484543d1Sopenharmony_ciprotected:
38484543d1Sopenharmony_ci    static void SetUpTestCase()
39484543d1Sopenharmony_ci    {
40484543d1Sopenharmony_ci    }
41484543d1Sopenharmony_ci
42484543d1Sopenharmony_ci    static void TearDownTestCase()
43484543d1Sopenharmony_ci    {
44484543d1Sopenharmony_ci    }
45484543d1Sopenharmony_ci
46484543d1Sopenharmony_ci    virtual void SetUp()
47484543d1Sopenharmony_ci    {
48484543d1Sopenharmony_ci    }
49484543d1Sopenharmony_ci
50484543d1Sopenharmony_ci    virtual void TearDown()
51484543d1Sopenharmony_ci    {
52484543d1Sopenharmony_ci    }
53484543d1Sopenharmony_ci};
54484543d1Sopenharmony_ci
55484543d1Sopenharmony_civoid* ThreadFunc(void* p)
56484543d1Sopenharmony_ci{
57484543d1Sopenharmony_ci    int ret = ffrt_loop_run(p);
58484543d1Sopenharmony_ci    EXPECT_EQ(ret, 0);
59484543d1Sopenharmony_ci    return nullptr;
60484543d1Sopenharmony_ci}
61484543d1Sopenharmony_ci
62484543d1Sopenharmony_ci/*
63484543d1Sopenharmony_ci * 测试用例名称:loop_null_queue_create_fail
64484543d1Sopenharmony_ci * 测试用例描述:非法队列创建loop失败
65484543d1Sopenharmony_ci * 预置条件    :无
66484543d1Sopenharmony_ci * 操作步骤    :1、创建loop失败
67484543d1Sopenharmony_ci *
68484543d1Sopenharmony_ci * 预期结果    :创建失败
69484543d1Sopenharmony_ci */
70484543d1Sopenharmony_ciHWTEST_F(LoopTest, loop_null_queue_create_fail, TestSize.Level1)
71484543d1Sopenharmony_ci{
72484543d1Sopenharmony_ci    auto loop = ffrt_loop_create(nullptr);
73484543d1Sopenharmony_ci    EXPECT_EQ(loop, nullptr);
74484543d1Sopenharmony_ci}
75484543d1Sopenharmony_ci
76484543d1Sopenharmony_ci/*
77484543d1Sopenharmony_ci * 测试用例名称:loop_serial_queue_create_succ
78484543d1Sopenharmony_ci * 测试用例描述:serial队列创建loop失败
79484543d1Sopenharmony_ci * 预置条件    :1、调用串行队列创建接口创建serial队列
80484543d1Sopenharmony_ci * 操作步骤    :1、创建loop
81484543d1Sopenharmony_ci *
82484543d1Sopenharmony_ci * 预期结果    :创建失败
83484543d1Sopenharmony_ci */
84484543d1Sopenharmony_ciHWTEST_F(LoopTest, loop_serial_queue_create_succ, TestSize.Level1)
85484543d1Sopenharmony_ci{
86484543d1Sopenharmony_ci    ffrt_queue_attr_t queue_attr;
87484543d1Sopenharmony_ci    (void)ffrt_queue_attr_init(&queue_attr);
88484543d1Sopenharmony_ci    ffrt_queue_t queue_handle = ffrt_queue_create(ffrt_queue_serial, "test_queue", &queue_attr);
89484543d1Sopenharmony_ci
90484543d1Sopenharmony_ci    auto loop = ffrt_loop_create(queue_handle);
91484543d1Sopenharmony_ci    EXPECT_EQ(loop, nullptr);
92484543d1Sopenharmony_ci
93484543d1Sopenharmony_ci    ffrt_queue_attr_destroy(&queue_attr);
94484543d1Sopenharmony_ci    ffrt_queue_destroy(queue_handle);
95484543d1Sopenharmony_ci}
96484543d1Sopenharmony_ci
97484543d1Sopenharmony_ci/*
98484543d1Sopenharmony_ci * 测试用例名称:loop_concurrent_queue_create_succ
99484543d1Sopenharmony_ci * 测试用例描述:无任务concurrent队列创建loop成功
100484543d1Sopenharmony_ci * 预置条件    :1、调用串行队列创建接口创建concurrent队列
101484543d1Sopenharmony_ci * 操作步骤    :1、创建loop
102484543d1Sopenharmony_ci *
103484543d1Sopenharmony_ci * 预期结果    :执行成功
104484543d1Sopenharmony_ci */
105484543d1Sopenharmony_ciHWTEST_F(LoopTest, loop_concurrent_queue_create_succ, TestSize.Level1)
106484543d1Sopenharmony_ci{
107484543d1Sopenharmony_ci    ffrt_queue_attr_t queue_attr;
108484543d1Sopenharmony_ci    (void)ffrt_queue_attr_init(&queue_attr);
109484543d1Sopenharmony_ci    ffrt_queue_t queue_handle = ffrt_queue_create(ffrt_queue_concurrent, "test_queue", &queue_attr);
110484543d1Sopenharmony_ci
111484543d1Sopenharmony_ci    auto loop = ffrt_loop_create(queue_handle);
112484543d1Sopenharmony_ci    EXPECT_NE(loop, nullptr);
113484543d1Sopenharmony_ci
114484543d1Sopenharmony_ci    int ret = ffrt_loop_destroy(loop);
115484543d1Sopenharmony_ci    EXPECT_EQ(ret, 0);
116484543d1Sopenharmony_ci
117484543d1Sopenharmony_ci    ffrt_queue_attr_destroy(&queue_attr);
118484543d1Sopenharmony_ci    ffrt_queue_destroy(queue_handle);
119484543d1Sopenharmony_ci}
120484543d1Sopenharmony_ci
121484543d1Sopenharmony_ci/*
122484543d1Sopenharmony_ci * 测试用例名称:loop_concurrent_queue_create_fail
123484543d1Sopenharmony_ci * 测试用例描述:有任务队列创建loop失败
124484543d1Sopenharmony_ci * 预置条件    :1、调用串行队列创建接口创建concurrent队列
125484543d1Sopenharmony_ci *              2、创建loop前向队列提交任务
126484543d1Sopenharmony_ci * 操作步骤    :1、创建loop
127484543d1Sopenharmony_ci *
128484543d1Sopenharmony_ci * 预期结果    :创建失败
129484543d1Sopenharmony_ci */
130484543d1Sopenharmony_ciHWTEST_F(LoopTest, loop_concurrent_queue_create_fail, TestSize.Level1)
131484543d1Sopenharmony_ci{
132484543d1Sopenharmony_ci    ffrt_queue_attr_t queue_attr;
133484543d1Sopenharmony_ci    (void)ffrt_queue_attr_init(&queue_attr);
134484543d1Sopenharmony_ci    ffrt_queue_t queue_handle = ffrt_queue_create(ffrt_queue_concurrent, "test_queue", &queue_attr);
135484543d1Sopenharmony_ci
136484543d1Sopenharmony_ci    int result1 = 0;
137484543d1Sopenharmony_ci    std::function<void()>&& basicFunc1 = [&result1]() { result1 += 10; };
138484543d1Sopenharmony_ci    ffrt_queue_submit(queue_handle, create_function_wrapper(basicFunc1, ffrt_function_kind_queue), nullptr);
139484543d1Sopenharmony_ci
140484543d1Sopenharmony_ci    auto loop = ffrt_loop_create(queue_handle);
141484543d1Sopenharmony_ci    EXPECT_EQ(loop, nullptr);
142484543d1Sopenharmony_ci
143484543d1Sopenharmony_ci    ffrt_queue_attr_destroy(&queue_attr);
144484543d1Sopenharmony_ci    ffrt_queue_destroy(queue_handle);
145484543d1Sopenharmony_ci}
146484543d1Sopenharmony_ci
147484543d1Sopenharmony_ci/*
148484543d1Sopenharmony_ci * 测试用例名称:loop_run_fail
149484543d1Sopenharmony_ci * 测试用例描述:非法loop run失败
150484543d1Sopenharmony_ci * 操作步骤    :1、执行loop run
151484543d1Sopenharmony_ci *
152484543d1Sopenharmony_ci * 预期结果    :执行失败
153484543d1Sopenharmony_ci */
154484543d1Sopenharmony_ciHWTEST_F(LoopTest, loop_run_fail, TestSize.Level1)
155484543d1Sopenharmony_ci{
156484543d1Sopenharmony_ci    int ret = ffrt_loop_run(nullptr);
157484543d1Sopenharmony_ci    EXPECT_NE(ret, 0);
158484543d1Sopenharmony_ci}
159484543d1Sopenharmony_ci
160484543d1Sopenharmony_ci/*
161484543d1Sopenharmony_ci * 测试用例名称:loop_destroy_fail
162484543d1Sopenharmony_ci * 测试用例描述:非法loop destroy失败
163484543d1Sopenharmony_ci * 操作步骤    :1、执行loop run
164484543d1Sopenharmony_ci *
165484543d1Sopenharmony_ci * 预期结果    :执行失败
166484543d1Sopenharmony_ci */
167484543d1Sopenharmony_ciHWTEST_F(LoopTest, loop_destroy_fail, TestSize.Level1)
168484543d1Sopenharmony_ci{
169484543d1Sopenharmony_ci    int ret = ffrt_loop_destroy(nullptr);
170484543d1Sopenharmony_ci    EXPECT_NE(ret, 0);
171484543d1Sopenharmony_ci}
172484543d1Sopenharmony_ci
173484543d1Sopenharmony_ci/*
174484543d1Sopenharmony_ci * 测试用例名称:loop_run_destroy_success
175484543d1Sopenharmony_ci * 测试用例描述:正常loop run成功、destroy
176484543d1Sopenharmony_ci * 预置条件    :1、调用串行队列创建接口创建concurrent队列
177484543d1Sopenharmony_ci *              2、用队列创建loop
178484543d1Sopenharmony_ci * 操作步骤    :1、启动线程执行loop run
179484543d1Sopenharmony_ci *              2、销毁loop成功
180484543d1Sopenharmony_ci * 预期结果    :执行成功
181484543d1Sopenharmony_ci */
182484543d1Sopenharmony_ciHWTEST_F(LoopTest, loop_run_destroy_success, TestSize.Level1)
183484543d1Sopenharmony_ci{
184484543d1Sopenharmony_ci    const uint64_t sleepTime = 250000;
185484543d1Sopenharmony_ci    ffrt_queue_attr_t queue_attr;
186484543d1Sopenharmony_ci    (void)ffrt_queue_attr_init(&queue_attr);
187484543d1Sopenharmony_ci    ffrt_queue_t queue_handle = ffrt_queue_create(ffrt_queue_concurrent, "test_queue", &queue_attr);
188484543d1Sopenharmony_ci
189484543d1Sopenharmony_ci    auto loop = ffrt_loop_create(queue_handle);
190484543d1Sopenharmony_ci    EXPECT_NE(loop, nullptr);
191484543d1Sopenharmony_ci
192484543d1Sopenharmony_ci    pthread_t thread;
193484543d1Sopenharmony_ci    pthread_create(&thread, 0, ThreadFunc, loop);
194484543d1Sopenharmony_ci
195484543d1Sopenharmony_ci    ffrt_loop_stop(loop);
196484543d1Sopenharmony_ci    usleep(sleepTime);
197484543d1Sopenharmony_ci    int ret = ffrt_loop_destroy(loop);
198484543d1Sopenharmony_ci    EXPECT_EQ(ret, 0);
199484543d1Sopenharmony_ci
200484543d1Sopenharmony_ci    ffrt_queue_attr_destroy(&queue_attr);
201484543d1Sopenharmony_ci    ffrt_queue_destroy(queue_handle);
202484543d1Sopenharmony_ci}
203484543d1Sopenharmony_ci
204484543d1Sopenharmony_cistruct TestData {
205484543d1Sopenharmony_ci    int fd;
206484543d1Sopenharmony_ci    uint64_t expected;
207484543d1Sopenharmony_ci};
208484543d1Sopenharmony_ci
209484543d1Sopenharmony_cistatic void TestCallBack(void* token, uint32_t event)
210484543d1Sopenharmony_ci{
211484543d1Sopenharmony_ci    struct TestData* testData = reinterpret_cast<TestData*>(token);
212484543d1Sopenharmony_ci    uint64_t value = 0;
213484543d1Sopenharmony_ci    ssize_t n = read(testData->fd, &value, sizeof(uint64_t));
214484543d1Sopenharmony_ci    EXPECT_EQ(n, sizeof(value));
215484543d1Sopenharmony_ci    EXPECT_EQ(value, testData->expected);
216484543d1Sopenharmony_ci}
217484543d1Sopenharmony_ci
218484543d1Sopenharmony_ciint AddFdListener(void* handler, uint32_t fd, uint32_t event, void* data, ffrt_poller_cb cb)
219484543d1Sopenharmony_ci{
220484543d1Sopenharmony_ci    return 0;
221484543d1Sopenharmony_ci}
222484543d1Sopenharmony_ci
223484543d1Sopenharmony_ciint RemoveFdListener(void* handler, uint32_t fd)
224484543d1Sopenharmony_ci{
225484543d1Sopenharmony_ci    return 0;
226484543d1Sopenharmony_ci}
227484543d1Sopenharmony_ci
228484543d1Sopenharmony_ciHWTEST_F(LoopTest, ffrt_add_and_remove_fd, TestSize.Level1)
229484543d1Sopenharmony_ci{
230484543d1Sopenharmony_ci    ffrt_queue_attr_t queue_attr;
231484543d1Sopenharmony_ci    (void)ffrt_queue_attr_init(&queue_attr); // 初始化属性,必须
232484543d1Sopenharmony_ci    ffrt_queue_t queue_handle = ffrt_queue_create(
233484543d1Sopenharmony_ci        static_cast<ffrt_queue_type_t>(ffrt_queue_eventhandler_interactive), "test_queue", &queue_attr);
234484543d1Sopenharmony_ci#ifndef WITH_NO_MOCKER
235484543d1Sopenharmony_ci    MOCKER(ffrt_get_main_queue).stubs().will(returnValue(queue_handle));
236484543d1Sopenharmony_ci#endif
237484543d1Sopenharmony_ci
238484543d1Sopenharmony_ci    EventHandlerAdapter::Instance()->AddFdListener = AddFdListener;
239484543d1Sopenharmony_ci    EventHandlerAdapter::Instance()->RemoveFdListener = RemoveFdListener;
240484543d1Sopenharmony_ci
241484543d1Sopenharmony_ci    ffrt_queue_t mainQueue = ffrt_get_main_queue();
242484543d1Sopenharmony_ci    auto loop = ffrt_loop_create(mainQueue);
243484543d1Sopenharmony_ci    EXPECT_TRUE(loop != nullptr);
244484543d1Sopenharmony_ci    ffrt_loop_run(loop);
245484543d1Sopenharmony_ci    int ret = 0;
246484543d1Sopenharmony_ci    int testFd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
247484543d1Sopenharmony_ci    uint64_t expected = 0xabacadae;
248484543d1Sopenharmony_ci    struct TestData testData {.fd = testFd, .expected = expected};
249484543d1Sopenharmony_ci    ret = ffrt_loop_epoll_ctl(loop, EPOLL_CTL_ADD, testFd, EPOLLIN, (void*)(&testData), TestCallBack);
250484543d1Sopenharmony_ci    EXPECT_EQ(ret, 0);
251484543d1Sopenharmony_ci    ssize_t n = write(testFd, &expected, sizeof(uint64_t));
252484543d1Sopenharmony_ci    EXPECT_EQ(n, sizeof(uint64_t));
253484543d1Sopenharmony_ci    usleep(25000);
254484543d1Sopenharmony_ci
255484543d1Sopenharmony_ci    ret = ffrt_loop_epoll_ctl(loop, EPOLL_CTL_DEL, testFd, 0, nullptr, nullptr);
256484543d1Sopenharmony_ci    EXPECT_EQ(ret, 0);
257484543d1Sopenharmony_ci
258484543d1Sopenharmony_ci    ffrt_loop_stop(loop);
259484543d1Sopenharmony_ci    ffrt_loop_destroy(loop);
260484543d1Sopenharmony_ci
261484543d1Sopenharmony_ci#ifndef WITH_NO_MOCKER
262484543d1Sopenharmony_ci    GlobalMockObject::reset();
263484543d1Sopenharmony_ci    GlobalMockObject::verify();
264484543d1Sopenharmony_ci#endif
265484543d1Sopenharmony_ci}
266