1 /*
2  * Copyright (c) 2021 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 <gtest/gtest.h>
16 #include <pthread.h>
17 #include <sys/eventfd.h>
18 
19 #include "begetctl.h"
20 #include "init.h"
21 #include "init_hashmap.h"
22 #include "init_param.h"
23 #include "init_utils.h"
24 #include "le_epoll.h"
25 #include "le_loop.h"
26 #include "le_socket.h"
27 #include "le_task.h"
28 #include "loop_event.h"
29 #include "param_manager.h"
30 #include "param_message.h"
31 #include "param_utils.h"
32 #include "trigger_manager.h"
33 
34 using namespace testing::ext;
35 using namespace std;
36 
37 using HashTab = struct {
38     HashNodeCompare nodeCompare;
39     HashKeyCompare keyCompare;
40     HashNodeFunction nodeHash;
41     HashKeyFunction keyHash;
42     HashNodeOnFree nodeFree;
43     int maxBucket;
44     uint32_t tableId;
45     HashNode *buckets[0];
46 };
47 
TestHandleTaskEvent(const LoopHandle loop,const TaskHandle task,uint32_t oper)48 static LE_STATUS TestHandleTaskEvent(const LoopHandle loop, const TaskHandle task, uint32_t oper)
49 {
50     return LE_SUCCESS;
51 }
52 
OnReceiveRequest(const TaskHandle task,const uint8_t * buffer,uint32_t nread)53 static void OnReceiveRequest(const TaskHandle task, const uint8_t *buffer, uint32_t nread)
54 {
55     UNUSED(task);
56     UNUSED(buffer);
57     UNUSED(nread);
58 }
59 
ProcessAsyncEvent(const TaskHandle taskHandle,uint64_t eventId,const uint8_t * buffer,uint32_t buffLen)60 static void ProcessAsyncEvent(const TaskHandle taskHandle, uint64_t eventId, const uint8_t *buffer, uint32_t buffLen)
61 {
62     UNUSED(taskHandle);
63     UNUSED(eventId);
64     UNUSED(buffer);
65     UNUSED(buffLen);
66 }
67 
IncomingConnect(LoopHandle loop,TaskHandle server)68 static int IncomingConnect(LoopHandle loop, TaskHandle server)
69 {
70     UNUSED(loop);
71     UNUSED(server);
72     return 0;
73 }
74 
ProcessWatchEventTest(WatcherHandle taskHandle,int fd,uint32_t * events,const void * context)75 static void ProcessWatchEventTest(WatcherHandle taskHandle, int fd, uint32_t *events, const void *context)
76 {
77     UNUSED(taskHandle);
78     UNUSED(fd);
79     UNUSED(events);
80     UNUSED(context);
81 }
82 
83 namespace init_ut {
84 class LoopEventUnittest : public testing::Test {
85 public:
LoopEventUnittest()86     LoopEventUnittest() {};
~LoopEventUnittest()87     virtual ~LoopEventUnittest() {};
SetUpTestCase(void)88     static void SetUpTestCase(void) {};
TearDownTestCase(void)89     static void TearDownTestCase(void) {};
SetUp()90     void SetUp() {};
TearDown()91     void TearDown() {};
TestBody(void)92     void TestBody(void) {};
CreateServerTask()93     int CreateServerTask()
94     {
95         CheckTaskFlags(nullptr, EVENT_WRITE);
96         ParamStreamInfo info = {};
97         info.server = const_cast<char *>(PIPE_NAME);
98         info.close = nullptr;
99         info.recvMessage = nullptr;
100         info.incomingConnect = OnIncomingConnect;
101         return ParamServerCreate(&serverTask_, &info);
102     }
103 
StreamTaskTest()104     void StreamTaskTest ()
105     {
106         LE_StreamInfo streamInfo = {};
107         streamInfo.recvMessage = OnReceiveRequest;
108         streamInfo.baseInfo.flags = TASK_STREAM | TASK_PIPE | TASK_CONNECT | TASK_TEST;
109         streamInfo.server = (char *)"/data/testpipea";
110         TaskHandle clientTaskHandle = nullptr;
111         LE_AcceptStreamClient(LE_GetDefaultLoop(), (TaskHandle)serverTask_, &clientTaskHandle, &streamInfo);
112         if (clientTaskHandle == nullptr) {
113             return;
114         }
115         ((StreamConnectTask *)clientTaskHandle)->stream.base.handleEvent(LE_GetDefaultLoop(),
116             (TaskHandle)clientTaskHandle, 0);
117         ((StreamConnectTask *)clientTaskHandle)->stream.base.handleEvent(LE_GetDefaultLoop(),
118             (TaskHandle)clientTaskHandle, EVENT_READ);
119 
120         TaskHandle clientTaskHandlec = nullptr;
121         streamInfo.baseInfo.flags = TASK_STREAM | TASK_TCP | TASK_SERVER;
122         streamInfo.server = (char *)"0.0.0.0:10110";
123         LE_CreateStreamClient(LE_GetDefaultLoop(), &clientTaskHandlec, &streamInfo);
124         if (clientTaskHandlec == nullptr) {
125             return;
126         }
127         TaskHandle clientTaskHandled = nullptr;
128         streamInfo.baseInfo.flags = TASK_STREAM | TASK_TCP | TASK_CONNECT;
129         streamInfo.server = (char *)"127.0.0.1:10111";
130         LE_CreateStreamClient(LE_GetDefaultLoop(), &clientTaskHandled, &streamInfo);
131         if (clientTaskHandled == nullptr) {
132             return;
133         }
134     }
LeTaskTest()135     void LeTaskTest()
136     {
137         LE_StreamServerInfo info = {};
138         info.baseInfo.flags = TASK_STREAM | TASK_PIPE | TASK_SERVER | TASK_TEST;
139         info.server = (char *)"/data/testpipe";
140         info.baseInfo.close = nullptr;
141         info.incommingConnect = IncomingConnect;
142         LE_CreateStreamServer(LE_GetDefaultLoop(), &serverTask_, &info);
143         if (serverTask_ == nullptr) {
144             return;
145         }
146         ((StreamServerTask *)serverTask_)->base.handleEvent(LE_GetDefaultLoop(), serverTask_, EVENT_READ);
147 
148         uint64_t eventId = 0;
149         ParamStreamInfo paramStreamInfo = {};
150         paramStreamInfo.flags = PARAM_TEST_FLAGS;
151         paramStreamInfo.server = nullptr;
152         paramStreamInfo.close = nullptr;
153         paramStreamInfo.recvMessage = ProcessMessage;
154         paramStreamInfo.incomingConnect = nullptr;
155         ParamTaskPtr client = nullptr;
156         int ret = ParamStreamCreate(&client, serverTask_, &paramStreamInfo, sizeof(ParamWatcher));
157         PARAM_CHECK(ret == 0, return, "Failed to create client");
158 
159         BufferHandle handle = LE_CreateBuffer(LE_GetDefaultLoop(), 1 + sizeof(eventId));
160         LE_Buffer *buffer = (LE_Buffer *)handle;
161         AddBuffer((StreamTask *)client, buffer);
162         ((StreamConnectTask *)client)->stream.base.handleEvent(LE_GetDefaultLoop(), (TaskHandle)(client), EVENT_WRITE);
163         EXPECT_NE(LE_GetSendResult(handle), 0);
164 
165         ParamMessage *request = (ParamMessage *)CreateParamMessage(MSG_SET_PARAM, "name", sizeof(ParamMessage));
166         ((StreamConnectTask *)client)->recvMessage(LE_GetDefaultLoop(), reinterpret_cast<uint8_t *>(request),
167             sizeof(ParamMessage));
168 
169         LE_Buffer *next = nullptr;
170         EXPECT_EQ(GetNextBuffer((StreamTask *)client, next), nullptr);
171         ParamWatcher *watcher = (ParamWatcher *)ParamGetTaskUserData(client);
172         PARAM_CHECK(watcher != nullptr, return, "Failed to get watcher");
173         OH_ListInit(&watcher->triggerHead);
174         LE_FreeBuffer(LE_GetDefaultLoop(), (TaskHandle)client, nullptr);
175         return;
176     }
ProcessEventTest()177     void ProcessEventTest()
178     {
179         ProcessEvent((EventLoop *)LE_GetDefaultLoop(), 1, EVENT_READ);
180         LE_BaseInfo info = {TASK_EVENT, nullptr};
181         int testfd = 65535; // 65535 is not exist fd
182         BaseTask *task = CreateTask(LE_GetDefaultLoop(), testfd, &info, sizeof(StreamClientTask));
183         if (task != nullptr) {
184             task->handleEvent = TestHandleTaskEvent;
185             ProcessEvent((EventLoop *)LE_GetDefaultLoop(), testfd, EVENT_READ);
186         }
187     }
ProcessasynEvent()188     void ProcessasynEvent()
189     {
190         TaskHandle asynHandle = nullptr;
191         LE_CreateAsyncTask(LE_GetDefaultLoop(), &asynHandle, ProcessAsyncEvent);
192         if (asynHandle == nullptr) {
193             return;
194         }
195         ((AsyncEventTask *)asynHandle)->stream.base.handleEvent(LE_GetDefaultLoop(), asynHandle, EVENT_READ);
196         ((AsyncEventTask *)asynHandle)->stream.base.handleEvent(LE_GetDefaultLoop(), asynHandle, EVENT_WRITE);
197         LE_StopAsyncTask(LE_GetDefaultLoop(), asynHandle);
198     }
ProcessWatcherTask()199     void ProcessWatcherTask()
200     {
201         WatcherHandle handle = nullptr;
202         LE_WatchInfo info = {};
203         info.fd = -1;
204         info.flags = WATCHER_ONCE;
205         info.events = EVENT_READ;
206         info.processEvent = ProcessWatchEventTest;
207         LE_StartWatcher(LE_GetDefaultLoop(), &handle, &info, nullptr);
208         if (handle == nullptr) {
209             return;
210         }
211         ((WatcherTask *)handle)->base.handleEvent(LE_GetDefaultLoop(), (TaskHandle)handle, EVENT_READ);
212         ((WatcherTask *)handle)->base.handleEvent(LE_GetDefaultLoop(), (TaskHandle)handle, 0);
213         ((WatcherTask *)handle)->base.flags = WATCHER_ONCE;
214         ((WatcherTask *)handle)->base.handleEvent(LE_GetDefaultLoop(), (TaskHandle)handle, EVENT_READ);
215         LE_RemoveWatcher(LE_GetDefaultLoop(), handle);
216     }
CreateSocketTest()217     void CreateSocketTest()
218     {
219         ParamTaskPtr serverTask = nullptr;
220         LE_StreamServerInfo info = {};
221         info.baseInfo.flags = TASK_PIPE | TASK_CONNECT | TASK_TEST;
222         info.server = (char *)"/data/testpipe";
223         info.baseInfo.close = nullptr;
224         info.incommingConnect = IncomingConnect;
225         info.socketId = 1111; // 1111 is test fd
226         LE_CreateStreamServer(LE_GetDefaultLoop(), &serverTask, &info);
227         EXPECT_NE(serverTask, nullptr);
228         if (serverTask == nullptr) {
229             return;
230         }
231         ((StreamServerTask *)serverTask)->base.taskId.fd = -1;
232         OnIncomingConnect(LE_GetDefaultLoop(), serverTask);
233         LE_GetSocketFd(serverTask);
234         AcceptSocket(-1, TASK_PIPE);
235         AcceptSocket(-1, TASK_TCP);
236         AcceptSocket(-1, TASK_TEST);
237     }
238 
239 private:
240     ParamTaskPtr serverTask_ = nullptr;
241 };
242 
243 HWTEST_F(LoopEventUnittest, Init_LeTaskTest_001, TestSize.Level1)
244 {
245     LoopEventUnittest loopevtest = LoopEventUnittest();
246     loopevtest.LeTaskTest();
247 }
248 HWTEST_F(LoopEventUnittest, Init_TestRunServer_001, TestSize.Level1)
249 {
250     LoopEventUnittest loopevtest = LoopEventUnittest();
251     loopevtest.ProcessEventTest();
252 }
253 HWTEST_F(LoopEventUnittest, Init_TestProcessasynEvent_001, TestSize.Level1)
254 {
255     LoopEventUnittest loopevtest = LoopEventUnittest();
256     loopevtest.ProcessasynEvent();
257 }
258 HWTEST_F(LoopEventUnittest, Init_TestCreateSocketTest_001, TestSize.Level1)
259 {
260     LoopEventUnittest loopevtest = LoopEventUnittest();
261     loopevtest.CreateSocketTest();
262 }
263 HWTEST_F(LoopEventUnittest, Init_TestProcessWatcherTask_001, TestSize.Level1)
264 {
265     LoopEventUnittest loopevtest = LoopEventUnittest();
266     loopevtest.ProcessWatcherTask();
267 }
268 
269 static LoopHandle g_loop = nullptr;
270 static int g_timeCount = 0;
Test_ProcessTimer(const TimerHandle taskHandle,void * context)271 static void Test_ProcessTimer(const TimerHandle taskHandle, void *context)
272 {
273     g_timeCount++;
274     printf("Test_ProcessTimer %d\n", g_timeCount);
275     if (g_timeCount > 1) {
276         LE_StopLoop(g_loop);
277     }
278 }
279 
280 HWTEST_F(LoopEventUnittest, Init_TestLoopAbnormal_001, TestSize.Level1)
281 {
282     LE_StartWatcher(nullptr, nullptr, nullptr, nullptr);
283     LE_WatchInfo info = {};
284         info.fd = -1;
285         info.flags = WATCHER_ONCE;
286         info.events = EVENT_READ;
287         info.processEvent = nullptr;
288     LE_StartWatcher(LE_GetDefaultLoop(), nullptr, &info, nullptr);
289     LE_StartWatcher(LE_GetDefaultLoop(), nullptr, nullptr, nullptr);
290 }
291 
292 HWTEST_F(LoopEventUnittest, Init_TestLoopIdle_001, TestSize.Level1)
293 {
294     int ret = LE_DelayProc(LE_GetDefaultLoop(), nullptr, nullptr);
295     ASSERT_NE(ret, 0);
296     LE_DelIdle(nullptr);
297 }
298 
299 HWTEST_F(LoopEventUnittest, Init_TestLEFreeBuffer_001, TestSize.Level1)
300 {
301     uint64_t eventId = 0;
302     BufferHandle handle = LE_CreateBuffer(LE_GetDefaultLoop(), 1 + sizeof(eventId));
303     ASSERT_NE(handle, nullptr);
304     LE_FreeBuffer(LE_GetDefaultLoop(), nullptr, handle);
305 }
306 }  // namespace init_ut
307