sensord: fix coding rule violations
[platform/core/system/sensord.git] / src / sensorctl / testcase / unit_ipc.cpp
1 /*
2  * sensorctl
3  *
4  * Copyright (c) 2017 Samsung Electronics Co., Ltd.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 #include <unistd.h>
21 #include <string.h>
22 #include <sensor_internal.h>
23
24 #include "shared/channel.h"
25 #include "shared/channel_handler.h"
26 #include "shared/ipc_client.h"
27 #include "shared/ipc_server.h"
28
29 #include "log.h"
30 #include "test_bench.h"
31
32 using namespace ipc;
33
34 #define MAX_BUF_SIZE 4096
35 #define TEST_PATH "/run/.sensord_test.socket"
36 #define SLEEP_1S sleep(1)
37
38 typedef bool (*process_func_t)(const char *msg, int size, int count);
39
40 static pid_t run_process(process_func_t func, const char *msg, int size, int count)
41 {
42         pid_t pid = fork();
43         if (pid < 0)
44                 return -1;
45
46         if (pid == 0) {
47                 if (!func(msg, size, count))
48                         _E("Failed to run process\n");
49                 exit(0);
50         }
51
52         return pid;
53 }
54
55 class test_echo_server_handler : public channel_handler
56 {
57 public:
58         void connected(channel *ch) {}
59         void disconnected(channel *ch) {}
60         void read(channel *ch, message &msg)
61         {
62                 char buf[MAX_BUF_SIZE];
63
64                 message *reply = new(std::nothrow) message();
65                 RETM_IF(!reply, "Failed to allocate memory");
66
67                 msg.disclose(buf);
68                 reply->enclose(buf, MAX_BUF_SIZE);
69
70                 ch->send(reply);
71         }
72         void read_complete(channel *ch) {}
73         void error_caught(channel *ch, int error) {}
74 };
75
76 /* IPC Echo Server */
77 static bool run_ipc_server_echo(const char *str, int size, int count)
78 {
79         event_loop eloop;
80
81         ipc_server server(TEST_PATH);
82         test_echo_server_handler handler;
83
84         server.set_option("max_connection", 10);
85         server.set_option(SO_TYPE, SOCK_STREAM);
86         server.bind(&handler, &eloop);
87
88         eloop.run(18000);
89         server.close();
90
91         return true;
92 }
93
94 class test_client_handler_30_1M : public channel_handler
95 {
96 public:
97         void connected(channel *ch) {}
98         void disconnected(channel *ch) {}
99         void read(channel *ch, message &msg) {}
100         void read_complete(channel *ch) {}
101         void error_caught(channel *ch, int error) {}
102 };
103
104 /* IPC Client Sleep Test(4096Kb * 1024) */
105 static bool run_ipc_client_sleep_1s(const char *str, int size, int count)
106 {
107         ipc_client client(TEST_PATH);
108         test_client_handler_30_1M client_handler;
109
110         channel *ch = client.connect(&client_handler, NULL);
111         ASSERT_NE(ch, 0);
112
113         message msg;
114         message reply;
115         char buf[MAX_BUF_SIZE] = {'1', '1', '1', };
116
117         msg.enclose(buf, MAX_BUF_SIZE);
118
119         SLEEP_1S;
120         ch->send_sync(&msg);
121
122         /* Test */
123         SLEEP_1S;
124
125         ch->read_sync(reply);
126         reply.disclose(buf);
127
128         int ret = strncmp(buf, "111", 3);
129         ASSERT_EQ(ret, 0);
130         ASSERT_EQ(reply.size(), MAX_BUF_SIZE);
131
132         ch->disconnect();
133         delete ch;
134
135         return true;
136 }
137
138 /* IPC Client With Small Buffer Test(4096Kb * 1024) */
139 static bool run_ipc_client_small_buffer(const char *str, int size, int count)
140 {
141         ipc_client client(TEST_PATH);
142         test_client_handler_30_1M client_handler;
143
144         channel *ch = client.connect(&client_handler, NULL);
145         ASSERT_NE(ch, 0);
146
147         int ret;
148         message msg;
149         message reply;
150         char buf[MAX_BUF_SIZE] = {'1', '1', '1', };
151
152         msg.enclose(buf, MAX_BUF_SIZE);
153
154         SLEEP_1S;
155
156         int buf_size;
157         ch->get_option(SO_RCVBUF, buf_size);
158         _I("Before: Buffer size : %d\n", buf_size);
159
160         ch->set_option(SO_RCVBUF, buf_size/2048);
161         ch->get_option(SO_RCVBUF, buf_size);
162         _I("After:  Buffer size : %d\n", buf_size);
163
164         for (int i = 0; i < 1024; ++i) {
165                 ch->send_sync(&msg);
166                 ch->read_sync(reply);
167         }
168
169         reply.disclose(buf);
170
171         ret = strncmp(buf, "111", 3);
172         ASSERT_EQ(ret, 0);
173         ASSERT_EQ(reply.size(), MAX_BUF_SIZE);
174
175         ch->disconnect();
176         delete ch;
177
178         return true;
179 }
180
181 /* IPC Client Test(4K * 256) */
182 static bool run_ipc_client_1M(const char *str, int size, int count)
183 {
184         ipc_client client(TEST_PATH);
185         test_client_handler_30_1M client_handler;
186
187         channel *ch = client.connect(&client_handler, NULL);
188         ASSERT_NE(ch, 0);
189
190         int ret;
191         message msg;
192         message reply;
193         char buf[MAX_BUF_SIZE] = {'1', '1', '1', };
194
195         msg.enclose(buf, MAX_BUF_SIZE);
196
197         SLEEP_1S;
198
199         for (int i = 0; i < 256; ++i) {
200                 ch->send_sync(&msg);
201                 ch->read_sync(reply);
202         }
203
204         reply.disclose(buf);
205
206         ret = strncmp(buf, "111", 3);
207         ASSERT_EQ(ret, 0);
208         ASSERT_EQ(reply.size(), MAX_BUF_SIZE);
209
210         ch->disconnect();
211         delete ch;
212
213         return true;
214 }
215
216 /* IPC Server Test(Not Echo) */
217 class test_server_handler : public channel_handler
218 {
219 public:
220         void connected(channel *ch) {}
221         void disconnected(channel *ch) {}
222         void read(channel *ch, message &msg)
223         {
224                 char buf[MAX_BUF_SIZE];
225                 msg.disclose(buf);
226
227                 message *reply = new(std::nothrow) message();
228                 if (!reply) return;
229
230                 reply->enclose("TEXTTEXTTEXTTEXT", 16);
231                 ch->send(reply);
232         }
233         void read_complete(channel *ch) {}
234         void error_caught(channel *ch, int error) {}
235 };
236
237 static bool run_ipc_server(const char *str, int size, int count)
238 {
239         event_loop eloop;
240
241         ipc_server server(TEST_PATH);
242         test_server_handler handler;
243
244         server.set_option("max_connection", 10);
245         server.set_option(SO_TYPE, SOCK_STREAM);
246         server.bind(&handler, &eloop);
247
248         /* run main loop for 5 seconds */
249         eloop.run(5000);
250
251         server.close();
252
253         return true;
254 }
255
256 /* IPC Client Test(Not Echo) */
257 class test_client_handler : public channel_handler
258 {
259 public:
260         void connected(channel *ch) {}
261         void disconnected(channel *ch) {}
262         void read(channel *ch, message &msg) {}
263         void read_complete(channel *ch) {}
264         void error_caught(channel *ch, int error) {}
265 };
266
267 static bool run_ipc_client_2_channel_message(const char *str, int size, int count)
268 {
269         ipc_client client(TEST_PATH);
270         test_client_handler client_handler;
271         channel *ch[2];
272         int ret;
273         message msg;
274         message reply;
275         char buf[MAX_BUF_SIZE];
276
277         ch[0] = client.connect(&client_handler, NULL);
278         ASSERT_NE(ch[0], 0);
279
280         msg.enclose("TESTTESTTEST", 12);
281         ch[0]->send_sync(&msg);
282         SLEEP_1S;
283         ch[0]->read_sync(reply);
284         reply.disclose(buf);
285         ret = strncmp(buf, "TEXTTEXTTEXTTEXT", 16);
286         ASSERT_EQ(ret, 0);
287
288         ch[1] = client.connect(&client_handler, NULL);
289         ASSERT_NE(ch[1], 0);
290
291         msg.enclose("TESTTESTTEST", 12);
292         ch[1]->send_sync(&msg);
293         SLEEP_1S;
294         ch[1]->read_sync(reply);
295         reply.disclose(buf);
296         ret = strncmp(buf, "TEXTTEXTTEXTTEXT", 16);
297         ASSERT_EQ(ret, 0);
298
299         ch[0]->disconnect();
300         ch[1]->disconnect();
301         delete ch[0];
302         delete ch[1];
303
304         return true;
305 }
306
307 static bool run_ipc_client_2_channel(const char *str, int size, int count)
308 {
309         ipc_client client(TEST_PATH);
310         test_client_handler client_handler;
311         channel *ch[2];
312
313         ch[0] = client.connect(&client_handler, NULL);
314         ASSERT_NE(ch[0], 0);
315         ch[1] = client.connect(&client_handler, NULL);
316         ASSERT_NE(ch[1], 0);
317         ASSERT_NE(ch[1], ch[0]);
318
319         ch[0]->disconnect();
320         ch[1]->disconnect();
321         delete ch[0];
322         delete ch[1];
323
324         return true;
325 }
326
327 static bool run_ipc_client(const char *str, int size, int count)
328 {
329         ipc_client client(TEST_PATH);
330         test_client_handler client_handler;
331
332         channel *ch = client.connect(&client_handler, NULL);
333         ASSERT_NE(ch, 0);
334
335         int ret;
336         message msg;
337         message reply;
338         char buf[MAX_BUF_SIZE];
339
340         msg.enclose("TESTTESTTEST", 12);
341         ch->send_sync(&msg);
342
343         SLEEP_1S;
344
345         ch->read_sync(reply);
346         reply.disclose(buf);
347
348         ret = strncmp(buf, "TEXTTEXTTEXTTEXT", 16);
349         ASSERT_EQ(ret, 0);
350
351         ch->disconnect();
352         delete ch;
353
354         return true;
355 }
356
357 /**
358  * @brief   Test 3 client + 1 client which sleeps 1 seconds
359  */
360 TESTCASE(sensor_ipc, 3_client_with_1s_sleep_client_p)
361 {
362         pid_t pid = run_process(run_ipc_server_echo, NULL, 0, 0);
363         EXPECT_GE(pid, 0);
364
365         SLEEP_1S;
366
367         for (int i = 0; i < 3; ++i) {
368                 pid = run_process(run_ipc_client_1M, NULL, 0, 0);
369                 EXPECT_GE(pid, 0);
370         }
371
372         bool ret = run_ipc_client_sleep_1s(NULL, 0, 0);
373         ASSERT_TRUE(ret);
374
375         SLEEP_1S;
376
377         return true;
378 }
379
380 /**
381  * @brief   Test 3 client + 1 client which has small recv buffer(2240)
382  */
383 TESTCASE(sensor_ipc, 3_client_with_small_buffer_client_p)
384 {
385         pid_t pid = run_process(run_ipc_server_echo, NULL, 0, 0);
386         EXPECT_GE(pid, 0);
387
388         SLEEP_1S;
389
390         for (int i = 0; i < 3; ++i) {
391                 pid = run_process(run_ipc_client_1M, NULL, 0, 0);
392                 EXPECT_GE(pid, 0);
393         }
394
395         bool ret = run_ipc_client_small_buffer(NULL, 0, 0);
396         ASSERT_TRUE(ret);
397
398         SLEEP_1S;
399
400         return true;
401 }
402
403 /**
404  * @brief   Test 30 ipc_client with 1M message
405  */
406 TESTCASE(sensor_ipc, 30_client_with_1M_message_p)
407 {
408         pid_t pid = run_process(run_ipc_server_echo, NULL, 0, 0);
409         EXPECT_GE(pid, 0);
410
411         SLEEP_1S;
412
413         for (int i = 0; i < 30; ++i) {
414                 pid = run_process(run_ipc_client_1M, NULL, 0, 0);
415                 EXPECT_GE(pid, 0);
416         }
417
418         bool ret = run_ipc_client_1M(NULL, 0, 0);
419         ASSERT_TRUE(ret);
420
421         SLEEP_1S;
422
423         return true;
424 }
425
426 /**
427  * @brief   Test 2 channel of 1 client with message
428  */
429 TESTCASE(sensor_ipc, 1_client_with_2_channel_message_p)
430 {
431         pid_t pid = run_process(run_ipc_server, NULL, 0, 0);
432         EXPECT_GE(pid, 0);
433
434         SLEEP_1S;
435
436         bool ret = run_ipc_client_2_channel_message(NULL, 0, 0);
437         ASSERT_TRUE(ret);
438
439         SLEEP_1S;
440
441         return true;
442 }
443
444 /**
445  * @brief   Test 2 channel of 1 client
446  */
447 TESTCASE(sensor_ipc, 1_client_2_channel_simple_p)
448 {
449         pid_t pid = run_process(run_ipc_server, NULL, 0, 0);
450         EXPECT_GE(pid, 0);
451
452         SLEEP_1S;
453
454         bool ret = run_ipc_client_2_channel(NULL, 0, 0);
455         ASSERT_TRUE(ret);
456
457         SLEEP_1S;
458
459         return true;
460 }
461
462 /**
463  * @brief   Test 100 ipc_client
464  */
465 TESTCASE(sensor_ipc, 100_client_p)
466 {
467         pid_t pid = run_process(run_ipc_server, NULL, 0, 0);
468         EXPECT_GE(pid, 0);
469
470         SLEEP_1S;
471
472         for (int i = 0; i < 99; ++i) {
473                 pid = run_process(run_ipc_client, NULL, 0, 0);
474                 EXPECT_GE(pid, 0);
475         }
476
477         bool ret = run_ipc_client(NULL, 0, 0);
478         ASSERT_TRUE(ret);
479
480         SLEEP_1S;
481
482         return true;
483 }
484
485 /**
486  * @brief   Test 2 ipc_client
487  */
488 TESTCASE(sensor_ipc, 2_client_p)
489 {
490         pid_t pid = run_process(run_ipc_server, NULL, 0, 0);
491         EXPECT_GE(pid, 0);
492
493         SLEEP_1S;
494
495         pid = run_process(run_ipc_client, NULL, 0, 0);
496         EXPECT_GE(pid, 0);
497
498         bool ret = run_ipc_client(NULL, 0, 0);
499         ASSERT_TRUE(ret);
500
501         SLEEP_1S;
502
503         return true;
504 }
505
506 /**
507  * @brief   Test ipc_client/ipc_server class
508  * @details 1. connect/disconnect
509  *          2. send "TEST" message from client to server
510  *          3. check that message in server handler
511  */
512 TESTCASE(sensor_ipc, server_client_basic_p)
513 {
514         pid_t pid = run_process(run_ipc_server, NULL, 0, 0);
515         EXPECT_GE(pid, 0);
516
517         SLEEP_1S;
518
519         bool ret = run_ipc_client(NULL, 0, 0);
520         ASSERT_TRUE(ret);
521
522         SLEEP_1S;
523
524         return true;
525 }