sensord: ipc: add unit testcases 81/123181/3
authorkibak.yoon <kibak.yoon@samsung.com>
Wed, 5 Apr 2017 01:29:52 +0000 (10:29 +0900)
committerKibak Yoon <kibak.yoon@samsung.com>
Wed, 5 Apr 2017 01:48:10 +0000 (18:48 -0700)
- test a connection between ipc_client and ipc_server
- test 2 clients
- test 100 clients
- test 1 client with 2 channels
- test 30 clients with large message
- test 3 normal client and 1 client with small recv buffer
- test 3 normal client and 1 client witch sleeps 10 seconds

Change-Id: I33b2e782872b51d42fc4a68b84bd5d6fe758964f
Signed-off-by: kibak.yoon <kibak.yoon@samsung.com>
src/sensorctl/testcase/unit_ipc.cpp [new file with mode: 0644]

diff --git a/src/sensorctl/testcase/unit_ipc.cpp b/src/sensorctl/testcase/unit_ipc.cpp
new file mode 100644 (file)
index 0000000..4528562
--- /dev/null
@@ -0,0 +1,524 @@
+/*
+ * sensorctl
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <unistd.h>
+#include <string.h>
+#include <sensor_internal.h>
+
+#include "shared/channel.h"
+#include "shared/channel_handler.h"
+#include "shared/ipc_client.h"
+#include "shared/ipc_server.h"
+
+#include "log.h"
+#include "test_bench.h"
+
+using namespace ipc;
+
+#define MAX_BUF_SIZE 4096
+#define TEST_PATH "/run/.sensord_test.socket"
+
+typedef bool (*process_func_t)(const char *msg, int size, int count);
+
+static pid_t run_process(process_func_t func, const char *msg, int size, int count)
+{
+       pid_t pid = fork();
+       if (pid < 0)
+               return -1;
+
+       if (pid == 0) {
+               if (!func(msg, size, count))
+                       _E("Failed to run process\n");
+               exit(0);
+       }
+
+       return pid;
+}
+
+class test_echo_server_handler : public channel_handler
+{
+public:
+       void connected(channel *ch) {}
+       void disconnected(channel *ch) {}
+       void read(channel *ch, message &msg)
+       {
+               char buf[MAX_BUF_SIZE];
+
+               message *reply = new(std::nothrow) message();
+               RETM_IF(!reply, "Failed to allocate memory");
+
+               msg.disclose(buf);
+               reply->enclose(buf, MAX_BUF_SIZE);
+
+               ch->send(reply);
+       }
+       void read_complete(channel *ch) {}
+       void error_caught(channel *ch, int error) {}
+};
+
+/* IPC Echo Server */
+static bool run_ipc_server_echo(const char *str, int size, int count)
+{
+       event_loop eloop;
+
+       ipc_server server(TEST_PATH);
+       test_echo_server_handler handler;
+
+       server.set_option("max_connection", 10);
+       server.set_option(SO_TYPE, SOCK_STREAM);
+       server.bind(&handler, &eloop);
+
+       eloop.run(18000);
+       server.close();
+
+       return true;
+}
+
+class test_client_handler_30_1M : public channel_handler
+{
+public:
+       void connected(channel *ch) {}
+       void disconnected(channel *ch) {}
+       void read(channel *ch, message &msg) {}
+       void read_complete(channel *ch) {}
+       void error_caught(channel *ch, int error) {}
+};
+
+/* IPC Client Sleep Test(4096Kb * 1024) */
+static bool run_ipc_client_sleep_10s(const char *str, int size, int count)
+{
+       ipc_client client(TEST_PATH);
+       test_client_handler_30_1M client_handler;
+
+       channel *ch = client.connect(&client_handler, NULL);
+       ASSERT_NE(ch, 0);
+
+       message msg;
+       message reply;
+       char buf[MAX_BUF_SIZE] = {'1', '1', '1',};
+
+       msg.enclose(buf, MAX_BUF_SIZE);
+
+       usleep(10000);
+       ch->send_sync(&msg);
+
+       /* Test */
+       sleep(1);
+
+       ch->read_sync(reply);
+       reply.disclose(buf);
+
+       int ret = strncmp(buf, "111", 3);
+       ASSERT_EQ(ret, 0);
+       ASSERT_EQ(reply.size(), MAX_BUF_SIZE);
+
+       ch->disconnect();
+       delete ch;
+
+       return true;
+}
+
+/* IPC Client With Small Buffer Test(4096Kb * 1024) */
+static bool run_ipc_client_small_buffer(const char *str, int size, int count)
+{
+       ipc_client client(TEST_PATH);
+       test_client_handler_30_1M client_handler;
+
+       channel *ch = client.connect(&client_handler, NULL);
+       ASSERT_NE(ch, 0);
+
+       int ret;
+       message msg;
+       message reply;
+       char buf[MAX_BUF_SIZE] = {'1', '1', '1',};
+
+       msg.enclose(buf, MAX_BUF_SIZE);
+
+       usleep(10000);
+
+       int buf_size;
+       ch->get_option(SO_RCVBUF, buf_size);
+       _I("Before: Buffer size : %d\n", buf_size);
+
+       ch->set_option(SO_RCVBUF, buf_size/2048);
+       ch->get_option(SO_RCVBUF, buf_size);
+       _I("After:  Buffer size : %d\n", buf_size);
+
+       for (int i = 0; i < 1024; ++i) {
+               ch->send_sync(&msg);
+               ch->read_sync(reply);
+       }
+
+       reply.disclose(buf);
+
+       ret = strncmp(buf, "111", 3);
+       ASSERT_EQ(ret, 0);
+       ASSERT_EQ(reply.size(), MAX_BUF_SIZE);
+
+       ch->disconnect();
+       delete ch;
+
+       return true;
+}
+
+/* IPC Client Test(4K * 256) */
+static bool run_ipc_client_1M(const char *str, int size, int count)
+{
+       ipc_client client(TEST_PATH);
+       test_client_handler_30_1M client_handler;
+
+       channel *ch = client.connect(&client_handler, NULL);
+       ASSERT_NE(ch, 0);
+
+       int ret;
+       message msg;
+       message reply;
+       char buf[MAX_BUF_SIZE] = {'1', '1', '1',};
+
+       msg.enclose(buf, MAX_BUF_SIZE);
+
+       usleep(10000);
+
+       for (int i = 0; i < 256; ++i) {
+               ch->send_sync(&msg);
+               ch->read_sync(reply);
+       }
+
+       reply.disclose(buf);
+
+       ret = strncmp(buf, "111", 3);
+       ASSERT_EQ(ret, 0);
+       ASSERT_EQ(reply.size(), MAX_BUF_SIZE);
+
+       ch->disconnect();
+       delete ch;
+
+       return true;
+}
+
+/* IPC Server Test(Not Echo) */
+class test_server_handler : public channel_handler
+{
+public:
+       void connected(channel *ch) {}
+       void disconnected(channel *ch) {}
+       void read(channel *ch, message &msg)
+       {
+               char buf[MAX_BUF_SIZE];
+               msg.disclose(buf);
+
+               message *reply = new(std::nothrow) message();
+               if (!reply) return;
+
+               reply->enclose("TEXTTEXTTEXTTEXT", 16);
+               ch->send(reply);
+       }
+       void read_complete(channel *ch) {}
+       void error_caught(channel *ch, int error) {}
+};
+
+static bool run_ipc_server(const char *str, int size, int count)
+{
+       event_loop eloop;
+
+       ipc_server server(TEST_PATH);
+       test_server_handler handler;
+
+       server.set_option("max_connection", 10);
+       server.set_option(SO_TYPE, SOCK_STREAM);
+       server.bind(&handler, &eloop);
+
+       /* run main loop for 5 seconds */
+       eloop.run(5000);
+
+       server.close();
+
+       return true;
+}
+
+/* IPC Client Test(Not Echo) */
+class test_client_handler : public channel_handler
+{
+public:
+       void connected(channel *ch) {}
+       void disconnected(channel *ch) {}
+       void read(channel *ch, message &msg) {}
+       void read_complete(channel *ch) {}
+       void error_caught(channel *ch, int error) {}
+};
+
+static bool run_ipc_client_2_channel_message(const char *str, int size, int count)
+{
+       ipc_client client(TEST_PATH);
+       test_client_handler client_handler;
+       channel *ch[2];
+       int ret;
+       message msg;
+       message reply;
+       char buf[MAX_BUF_SIZE];
+
+       ch[0] = client.connect(&client_handler, NULL);
+       ASSERT_NE(ch[0], 0);
+
+       msg.enclose("TESTTESTTEST", 12);
+       ch[0]->send_sync(&msg);
+       usleep(100000);
+       ch[0]->read_sync(reply);
+       reply.disclose(buf);
+       ret = strncmp(buf, "TEXTTEXTTEXTTEXT", 16);
+       ASSERT_EQ(ret, 0);
+
+       ch[1] = client.connect(&client_handler, NULL);
+       ASSERT_NE(ch[1], 0);
+
+       msg.enclose("TESTTESTTEST", 12);
+       ch[1]->send_sync(&msg);
+       usleep(100000);
+       ch[1]->read_sync(reply);
+       reply.disclose(buf);
+       ret = strncmp(buf, "TEXTTEXTTEXTTEXT", 16);
+       ASSERT_EQ(ret, 0);
+
+       ch[0]->disconnect();
+       ch[1]->disconnect();
+       delete ch[0];
+       delete ch[1];
+
+       return true;
+}
+
+static bool run_ipc_client_2_channel(const char *str, int size, int count)
+{
+       ipc_client client(TEST_PATH);
+       test_client_handler client_handler;
+       channel *ch[2];
+
+       ch[0] = client.connect(&client_handler, NULL);
+       ASSERT_NE(ch[0], 0);
+       ch[1] = client.connect(&client_handler, NULL);
+       ASSERT_NE(ch[1], 0);
+       ASSERT_NE(ch[1], ch[0]);
+
+       ch[0]->disconnect();
+       ch[1]->disconnect();
+       delete ch[0];
+       delete ch[1];
+
+       return true;
+}
+
+static bool run_ipc_client(const char *str, int size, int count)
+{
+       ipc_client client(TEST_PATH);
+       test_client_handler client_handler;
+
+       channel *ch = client.connect(&client_handler, NULL);
+       ASSERT_NE(ch, 0);
+
+       int ret;
+       message msg;
+       message reply;
+       char buf[MAX_BUF_SIZE];
+
+       msg.enclose("TESTTESTTEST", 12);
+       ch->send_sync(&msg);
+
+       usleep(100000);
+
+       ch->read_sync(reply);
+       reply.disclose(buf);
+
+       ret = strncmp(buf, "TEXTTEXTTEXTTEXT", 16);
+       ASSERT_EQ(ret, 0);
+
+       ch->disconnect();
+       delete ch;
+
+       return true;
+}
+
+/**
+ * @brief   Test 3 client + 1 client which sleeps 10 seconds
+ */
+TESTCASE(sensor_ipc_client_sleep_1s, sleep_1s_p)
+{
+       pid_t pid = run_process(run_ipc_server_echo, NULL, 0, 0);
+       EXPECT_GE(pid, 0);
+
+       usleep(100000);
+
+       for (int i = 0; i < 3; ++i) {
+               pid = run_process(run_ipc_client_1M, NULL, 0, 0);
+               EXPECT_GE(pid, 0);
+       }
+
+       bool ret = run_ipc_client_sleep_10s(NULL, 0, 0);
+       ASSERT_TRUE(ret);
+
+       usleep(100000);
+
+       return true;
+}
+
+/**
+ * @brief   Test 3 client + 1 client which has small recv buffer
+ */
+TESTCASE(sensor_ipc_client_small_2240, ipc_client_small_2240_p)
+{
+       pid_t pid = run_process(run_ipc_server_echo, NULL, 0, 0);
+       EXPECT_GE(pid, 0);
+
+       usleep(100000);
+
+       for (int i = 0; i < 3; ++i) {
+               pid = run_process(run_ipc_client_1M, NULL, 0, 0);
+               EXPECT_GE(pid, 0);
+       }
+
+       bool ret = run_ipc_client_small_buffer(NULL, 0, 0);
+       ASSERT_TRUE(ret);
+
+       usleep(100000);
+
+       return true;
+}
+
+/**
+ * @brief   Test 30 ipc_client with 1M message
+ */
+TESTCASE(sensor_ipc_30_client_1M, ipc_client_p_30_1M)
+{
+       pid_t pid = run_process(run_ipc_server_echo, NULL, 0, 0);
+       EXPECT_GE(pid, 0);
+
+       usleep(100000);
+
+       for (int i = 0; i < 30; ++i) {
+               pid = run_process(run_ipc_client_1M, NULL, 0, 0);
+               EXPECT_GE(pid, 0);
+       }
+
+       bool ret = run_ipc_client_1M(NULL, 0, 0);
+       ASSERT_TRUE(ret);
+
+       usleep(100000);
+
+       return true;
+}
+
+/**
+ * @brief   Test 2 channel of 1 client with message
+ */
+TESTCASE(sensor_ipc_client_2_channel_message, 2_channel_message_p)
+{
+       pid_t pid = run_process(run_ipc_server, NULL, 0, 0);
+       EXPECT_GE(pid, 0);
+
+       usleep(100000);
+
+       bool ret = run_ipc_client_2_channel_message(NULL, 0, 0);
+       ASSERT_TRUE(ret);
+
+       usleep(100000);
+
+       return true;
+}
+
+/**
+ * @brief   Test 2 channel of 1 client
+ */
+TESTCASE(sensor_ipc_client_2_channel, 2_channel_p)
+{
+       pid_t pid = run_process(run_ipc_server, NULL, 0, 0);
+       EXPECT_GE(pid, 0);
+
+       usleep(100000);
+
+       bool ret = run_ipc_client_2_channel(NULL, 0, 0);
+       ASSERT_TRUE(ret);
+
+       usleep(100000);
+
+       return true;
+}
+
+/**
+ * @brief   Test 100 ipc_client
+ */
+TESTCASE(sensor_ipc_100_client, ipc_client_p_100)
+{
+       pid_t pid = run_process(run_ipc_server, NULL, 0, 0);
+       EXPECT_GE(pid, 0);
+
+       usleep(100000);
+
+       for (int i = 0; i < 99; ++i) {
+               pid = run_process(run_ipc_client, NULL, 0, 0);
+               EXPECT_GE(pid, 0);
+       }
+
+       bool ret = run_ipc_client(NULL, 0, 0);
+       ASSERT_TRUE(ret);
+
+       usleep(100000);
+
+       return true;
+}
+
+/**
+ * @brief   Test 2 ipc_client
+ */
+TESTCASE(sensor_ipc_2_client, ipc_client_p_2)
+{
+       pid_t pid = run_process(run_ipc_server, NULL, 0, 0);
+       EXPECT_GE(pid, 0);
+
+       usleep(100000);
+
+       pid = run_process(run_ipc_client, NULL, 0, 0);
+       EXPECT_GE(pid, 0);
+
+       bool ret = run_ipc_client(NULL, 0, 0);
+       ASSERT_TRUE(ret);
+
+       usleep(100000);
+
+       return true;
+}
+
+/**
+ * @brief   Test ipc_client/ipc_server class
+ * @details 1. connect/disconnect
+ *          2. send "TEST" message from client to server
+ *          3. check that message in server handler
+ */
+TESTCASE(sensor_ipc_client_0, ipc_client_p_0)
+{
+       pid_t pid = run_process(run_ipc_server, NULL, 0, 0);
+       EXPECT_GE(pid, 0);
+
+       usleep(100000);
+
+       bool ret = run_ipc_client(NULL, 0, 0);
+       ASSERT_TRUE(ret);
+
+       usleep(100000);
+
+       return true;
+}