• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
16 #include <gtest/gtest.h>
17 #include <thread>
18 #include <sys/eventfd.h>
19 #include <cstdarg>
20 
21 #include "begetctl.h"
22 #include "cJSON.h"
23 #include "init.h"
24 #include "init_hashmap.h"
25 #include "init_param.h"
26 #include "init_utils.h"
27 #include "le_epoll.h"
28 #include "le_loop.h"
29 #include "le_socket.h"
30 #include "le_task.h"
31 #include "loop_event.h"
32 #include "param_manager.h"
33 #include "param_message.h"
34 #include "param_utils.h"
35 #include "trigger_manager.h"
36 
37 using namespace testing::ext;
38 using namespace std;
39 
40 namespace init_ut {
41 const std::string TCP_SERVER = "127.0.0.1:7777";
42 const std::string PIPE_SERVER = STARTUP_INIT_UT_PATH "/dev/unix/socket/testsocket";
43 const std::string WATCHER_FILE = STARTUP_INIT_UT_PATH "/test_watcher_file";
44 const std::string FORMAT_STR = "{ \"cmd\":%d, \"message\":\"%s\" }";
45 
46 static LoopHandle g_loopClient_ = nullptr;
47 static LoopHandle g_loopServer_ = nullptr;
48 static int g_maxCount = 0;
49 static int g_timeCount = 0;
50 static int g_cmd = 2;
DecodeMessage(const char * buffer,size_t nread,uint32_t & cmd)51 static void DecodeMessage(const char *buffer, size_t nread, uint32_t &cmd)
52 {
53     cJSON *root = cJSON_ParseWithLength(buffer, nread);
54     if (root == nullptr) {
55         EXPECT_NE(root, nullptr);
56         printf("Invalid message %s  \n", buffer);
57         return;
58     }
59     printf("Message: %s  \n", cJSON_GetStringValue(cJSON_GetObjectItem(root, "message")));
60     cmd = cJSON_GetNumberValue(cJSON_GetObjectItem(root, "cmd"));
61     printf("cmd: %d \n", cmd);
62     cJSON_Delete(root);
63     return;
64 }
65 
SendMessage(const LoopHandle loopHandle,const TaskHandle taskHandle,const char * message,...)66 static void SendMessage(const LoopHandle loopHandle, const TaskHandle taskHandle, const char *message, ...)
67 {
68     uint32_t bufferSize = 1024; // 1024 buffer size
69     BufferHandle handle = LE_CreateBuffer(loopHandle, bufferSize);
70     char *buffer = (char *)LE_GetBufferInfo(handle, nullptr, &bufferSize);
71 
72     va_list vargs;
73     va_start(vargs, message);
74     if (vsnprintf_s(buffer, bufferSize, bufferSize - 1, message, vargs) == -1) {
75         LE_FreeBuffer(loopHandle, taskHandle, handle);
76         va_end(vargs);
77         EXPECT_EQ(1, 0);
78         return;
79     }
80     va_end(vargs);
81     int ret = LE_Send(loopHandle, taskHandle, handle, bufferSize);
82     EXPECT_EQ(ret, 0);
83 }
84 
TestOnClose(const TaskHandle taskHandle)85 static void TestOnClose(const TaskHandle taskHandle)
86 {
87 }
88 
TestOnReceiveRequest(const TaskHandle task,const uint8_t * buffer,uint32_t nread)89 static void TestOnReceiveRequest(const TaskHandle task, const uint8_t *buffer, uint32_t nread)
90 {
91     EXPECT_NE(buffer, nullptr);
92     if (buffer == nullptr) {
93         return;
94     }
95     printf("Server receive message %s \n", reinterpret_cast<const char *>(buffer));
96     uint32_t cmd = 0;
97     DecodeMessage(reinterpret_cast<const char *>(buffer), nread, cmd);
98     SendMessage(g_loopServer_, task, reinterpret_cast<const char *>(buffer));
99 }
100 
TestClientOnReceiveRequest(const TaskHandle task,const uint8_t * buffer,uint32_t nread)101 static void TestClientOnReceiveRequest(const TaskHandle task, const uint8_t *buffer, uint32_t nread)
102 {
103     printf("Client receive message %s \n", reinterpret_cast<const char *>(buffer));
104     EXPECT_NE(buffer, nullptr);
105     if (buffer == nullptr) {
106         return;
107     }
108     uint32_t cmd = 0;
109     DecodeMessage(reinterpret_cast<const char *>(buffer), nread, cmd);
110     if (cmd == 5 || cmd == 2) { // 2 5 close server
111         LE_StopLoop(g_loopClient_);
112     }
113 }
114 
TestSendMessageComplete(const TaskHandle taskHandle,BufferHandle handle)115 static void TestSendMessageComplete(const TaskHandle taskHandle, BufferHandle handle)
116 {
117     printf("SendMessage result %d \n", LE_GetSendResult(handle));
118     uint32_t bufferSize = 1024; // 1024 buffer size
119     char *buffer = (char *)LE_GetBufferInfo(handle, nullptr, &bufferSize);
120     uint32_t cmd = 0;
121     DecodeMessage(reinterpret_cast<const char *>(buffer), bufferSize, cmd);
122     if (cmd == 5) { // 5 close server
123         LE_StopLoop(g_loopServer_);
124     }
125 }
126 
TestTcpIncomingConnect(LoopHandle loop,TaskHandle server)127 static int TestTcpIncomingConnect(LoopHandle loop, TaskHandle server)
128 {
129     PARAM_CHECK(server != nullptr, return -1, "Error server");
130     printf("Tcp connect incoming \n");
131     TaskHandle stream;
132     LE_StreamInfo info = {};
133     info.baseInfo.flags = TASK_STREAM | TASK_TCP | TASK_CONNECT;
134     info.baseInfo.close = TestOnClose;
135     info.baseInfo.userDataSize = 0;
136     info.disConnectComplete = nullptr;
137     info.sendMessageComplete = TestSendMessageComplete;
138     info.recvMessage = TestOnReceiveRequest;
139     LE_STATUS ret = LE_AcceptStreamClient(loop, server, &stream, &info);
140     EXPECT_EQ(ret, 0);
141     return 0;
142 }
143 
TestPipIncomingConnect(LoopHandle loop,TaskHandle server)144 static int TestPipIncomingConnect(LoopHandle loop, TaskHandle server)
145 {
146     PARAM_CHECK(server != nullptr, return -1, "Error server");
147     printf("Pipe connect incoming \n");
148     TaskHandle stream;
149     LE_StreamInfo info = {};
150     info.baseInfo.flags = TASK_STREAM | TASK_PIPE | TASK_CONNECT;
151     info.baseInfo.close = TestOnClose;
152     info.baseInfo.userDataSize = 0;
153     info.disConnectComplete = nullptr;
154     info.sendMessageComplete = TestSendMessageComplete;
155     info.recvMessage = TestOnReceiveRequest;
156     LE_STATUS ret = LE_AcceptStreamClient(loop, server, &stream, &info);
157     EXPECT_EQ(ret, 0);
158     return 0;
159 }
160 
TestConnectComplete(const TaskHandle client)161 static void TestConnectComplete(const TaskHandle client)
162 {
163     printf("Connect complete \n");
164 }
165 
TestDisConnectComplete(const TaskHandle client)166 static void TestDisConnectComplete(const TaskHandle client)
167 {
168     printf("DisConnect complete \n");
169     LE_StopLoop(g_loopClient_);
170 }
171 
TestProcessTimer(const TimerHandle taskHandle,void * context)172 static void TestProcessTimer(const TimerHandle taskHandle, void *context)
173 {
174     g_timeCount++;
175     printf("ProcessTimer %d\n", g_timeCount);
176     if (g_maxCount == 2) { // 2 stop
177         if (g_timeCount >= g_maxCount) {
178             LE_StopLoop(g_loopClient_);
179         }
180     }
181     if (g_maxCount == 3) { // 3 stop timer
182         if (g_timeCount >= g_maxCount) {
183             LE_StopTimer(g_loopClient_, taskHandle);
184             LE_StopLoop(g_loopClient_);
185         }
186     }
187     if (g_maxCount == 10) { // 10 write watcher file
188         FILE *tmpFile = fopen(WATCHER_FILE.c_str(), "wr");
189         if (tmpFile != nullptr) {
190             fprintf(tmpFile, "%s", "test watcher file 22222222222");
191             (void)fflush(tmpFile);
192             fclose(tmpFile);
193         }
194         LE_StopTimer(g_loopClient_, taskHandle);
195         LE_StopLoop(g_loopClient_);
196     }
197 }
198 
ProcessWatchEventTest(WatcherHandle taskHandle,int fd,uint32_t * events,const void * context)199 static void ProcessWatchEventTest(WatcherHandle taskHandle, int fd, uint32_t *events, const void *context)
200 {
201     UNUSED(taskHandle);
202     UNUSED(fd);
203     UNUSED(events);
204     UNUSED(context);
205     printf("Process watcher event \n");
206     LE_StopLoop(g_loopClient_);
207 }
208 
209 class LoopServerUnitTest : public testing::Test {
210 public:
LoopServerUnitTest()211     LoopServerUnitTest() {};
~LoopServerUnitTest()212     virtual ~LoopServerUnitTest() {};
SetUpTestCase(void)213     static void SetUpTestCase(void) {};
TearDownTestCase(void)214     static void TearDownTestCase(void) {};
SetUp()215     void SetUp() {};
TearDown()216     void TearDown() {};
TestBody(void)217     void TestBody(void) {};
218 
219     // for thread to create tcp\pipe server
RunServer(void)220     void RunServer(void)
221     {
222         TaskHandle tcpServer = nullptr;
223         TaskHandle pipeServer = nullptr;
224         LE_STATUS ret = LE_CreateLoop(&g_loopServer_);
225         EXPECT_EQ(ret, 0);
226         // create server for tcp
227         LE_StreamServerInfo info = {};
228         info.baseInfo.flags = TASK_STREAM | TASK_TCP | TASK_SERVER;
229         info.socketId = -1;
230         info.server = const_cast<char *>(TCP_SERVER.c_str());
231         info.baseInfo.close = TestOnClose;
232         info.incommingConnect = TestTcpIncomingConnect;
233         ret = LE_CreateStreamServer(g_loopServer_, &tcpServer, &info);
234         EXPECT_EQ(ret, 0);
235 
236         info.baseInfo.flags = TASK_STREAM | TASK_PIPE | TASK_SERVER;
237         info.socketId = -1;
238         info.server = const_cast<char *>(PIPE_SERVER.c_str());
239         info.baseInfo.close = TestOnClose;
240         info.incommingConnect = TestPipIncomingConnect;
241         ret = LE_CreateStreamServer(g_loopServer_, &pipeServer, &info);
242         EXPECT_EQ(ret, 0);
243 
244         printf("Run server pipeServer_ \n");
245         // run loop for server
246         LE_RunLoop(g_loopServer_);
247 
248         printf("Run server pipeServer_ \n");
249         LE_CloseStreamTask(g_loopServer_, pipeServer);
250         pipeServer = nullptr;
251         LE_CloseStreamTask(g_loopServer_, tcpServer);
252         tcpServer = nullptr;
253         LE_CloseLoop(g_loopServer_);
254         g_loopServer_ = nullptr;
255     }
256 
StartServer()257     void StartServer()
258     {
259         std::thread(&LoopServerUnitTest::RunServer, this).detach();
260         sleep(1);
261     }
262 
CreateConnect(const char * tcpServer,uint32_t flags)263     TaskHandle CreateConnect(const char *tcpServer, uint32_t flags)
264     {
265         if (g_loopClient_ == nullptr) {
266             LE_STATUS ret = LE_CreateLoop(&g_loopClient_);
267             EXPECT_EQ(ret, 0);
268         }
269 
270         TaskHandle task = nullptr;
271         LE_StreamInfo info = {};
272         info.baseInfo.flags = TASK_STREAM | flags | TASK_CONNECT;
273         info.server = const_cast<char *>(tcpServer);
274         info.baseInfo.userDataSize = 0;
275         info.baseInfo.close = TestOnClose;
276         info.disConnectComplete = TestDisConnectComplete;
277         info.connectComplete = TestConnectComplete;
278         info.sendMessageComplete = nullptr;
279         info.recvMessage = TestClientOnReceiveRequest;
280         LE_STATUS status = LE_CreateStreamClient(g_loopClient_, &task, &info);
281         EXPECT_EQ(status, 0);
282         return task;
283     }
284 
CreateWatcherTask(int fd,const char * fileName)285     WatcherHandle CreateWatcherTask(int fd, const char *fileName)
286     {
287         if (g_loopClient_ == nullptr) {
288             LE_STATUS ret = LE_CreateLoop(&g_loopClient_);
289             EXPECT_EQ(ret, 0);
290         }
291         WatcherHandle handle = nullptr;
292         LE_WatchInfo info = {};
293         info.fd = fd;
294         info.flags = WATCHER_ONCE;
295         info.events = EVENT_READ | EVENT_WRITE;
296         info.processEvent = ProcessWatchEventTest;
297         LE_STATUS status = LE_StartWatcher(g_loopClient_, &handle, &info, nullptr);
298         EXPECT_EQ(status, 0);
299         return handle;
300     }
301 
CreateTimerTask(int repeat)302     TimerHandle CreateTimerTask(int repeat)
303     {
304         if (g_loopClient_ == nullptr) {
305             LE_STATUS ret = LE_CreateLoop(&g_loopClient_);
306             EXPECT_EQ(ret, 0);
307         }
308         TimerHandle timer = nullptr;
309         int ret = LE_CreateTimer(g_loopClient_, &timer, TestProcessTimer, nullptr);
310         EXPECT_EQ(ret, 0);
311         ret = LE_StartTimer(g_loopClient_, timer, 500, repeat); // 500 ms
312         EXPECT_EQ(ret, 0);
313         return timer;
314     }
315 private:
316     std::thread *serverThread_ = nullptr;
317 };
318 
319 HWTEST_F(LoopServerUnitTest, Init_TestRunServer_001, TestSize.Level1)
320 {
321     LoopServerUnitTest test;
322     test.StartServer();
323 }
324 
325 HWTEST_F(LoopServerUnitTest, Init_TestPipConnect_001, TestSize.Level1)
326 {
327     g_cmd = 2; // 2 only close client
328     LoopServerUnitTest test;
329     TaskHandle pipe = test.CreateConnect(PIPE_SERVER.c_str(), TASK_PIPE);
330     EXPECT_NE(pipe, nullptr);
331     SendMessage(g_loopClient_, pipe, FORMAT_STR.c_str(), g_cmd, "connect success");
332     LE_RunLoop(g_loopClient_);
333     LE_CloseStreamTask(g_loopClient_, pipe);
334     LE_CloseLoop(g_loopClient_);
335     g_loopClient_ = nullptr;
336 }
337 
338 HWTEST_F(LoopServerUnitTest, Init_TestTcpConnect_001, TestSize.Level1)
339 {
340     g_cmd = 2; // 2 only close client
341     LoopServerUnitTest test;
342     TaskHandle tcp = test.CreateConnect(TCP_SERVER.c_str(), TASK_TCP);
343     EXPECT_NE(tcp, nullptr);
344     SendMessage(g_loopClient_, tcp, FORMAT_STR.c_str(), g_cmd, "connect success");
345     LE_RunLoop(g_loopClient_);
346     LE_CloseStreamTask(g_loopClient_, tcp);
347     LE_CloseLoop(g_loopClient_);
348     g_loopClient_ = nullptr;
349 }
350 
351 HWTEST_F(LoopServerUnitTest, Init_TestTimer_001, TestSize.Level1)
352 {
353     LoopServerUnitTest test;
354     g_maxCount = 2; // 2 stop
355     TimerHandle timer = test.CreateTimerTask(2);
356     EXPECT_NE(timer, nullptr);
357     LE_RunLoop(g_loopClient_);
358     LE_CloseLoop(g_loopClient_);
359     g_loopClient_ = nullptr;
360 }
361 
362 HWTEST_F(LoopServerUnitTest, Init_TestTimer_002, TestSize.Level1)
363 {
364     LoopServerUnitTest test;
365     g_maxCount = 3; // 3 stop timer
366     TimerHandle timer = test.CreateTimerTask(3);
367     EXPECT_NE(timer, nullptr);
368     LE_RunLoop(g_loopClient_);
369     LE_CloseLoop(g_loopClient_);
370     g_loopClient_ = nullptr;
371 }
372 
373 HWTEST_F(LoopServerUnitTest, Init_TestWatcher_001, TestSize.Level1)
374 {
375     int fd = open(WATCHER_FILE.c_str(), O_RDWR | O_CREAT | O_CLOEXEC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
376     if (fd >= 0) {
377         write(fd, WATCHER_FILE.c_str(), WATCHER_FILE.size());
378     }
379     EXPECT_GE(fd, 0);
380     printf("Watcher fd %d \n", fd);
381     LoopServerUnitTest test;
382     WatcherHandle watcher = test.CreateWatcherTask(3, WATCHER_FILE.c_str());
383     EXPECT_NE(watcher, nullptr);
384     g_maxCount = 10; // 10 write watcher file
385     TimerHandle timer = test.CreateTimerTask(1);
386     EXPECT_NE(timer, nullptr);
387 
388     LE_RunLoop(g_loopClient_);
389     LE_RemoveWatcher(g_loopClient_, watcher);
390     close(fd);
391     LE_CloseLoop(g_loopClient_);
392     g_loopClient_ = nullptr;
393 }
394 
395 HWTEST_F(LoopServerUnitTest, Init_TestStopServer_001, TestSize.Level1)
396 {
397     g_cmd = 5; // 5 close server
398     LoopServerUnitTest test;
399     TaskHandle pip = test.CreateConnect(PIPE_SERVER.c_str(), TASK_PIPE);
400     EXPECT_NE(pip, nullptr);
401     SendMessage(g_loopClient_, pip, FORMAT_STR.c_str(), g_cmd, "connect success");
402     LE_RunLoop(g_loopClient_);
403     LE_CloseStreamTask(g_loopClient_, pip);
404     LE_CloseLoop(g_loopClient_);
405     g_loopClient_ = nullptr;
406 }
407 
408 HWTEST_F(LoopServerUnitTest, Init_TestServerTimeout_001, TestSize.Level1)
409 {
410     int flag = TASK_STREAM | TASK_PIPE | TASK_SERVER | TASK_TEST;
411     int serverSock = CreateSocket(flag, "/data/test1pipe");
412     EXPECT_NE(serverSock, -1);
413     int ret = AcceptSocket(serverSock, flag);
414     EXPECT_EQ(ret, -1);
415 }
416 }  // namespace init_ut
417