Update benchmark tool for testing dbus 89/308589/6
authorjh9216.park <jh9216.park@samsung.com>
Thu, 28 Mar 2024 01:47:12 +0000 (21:47 -0400)
committerjh9216.park <jh9216.park@samsung.com>
Thu, 28 Mar 2024 07:40:31 +0000 (03:40 -0400)
Change-Id: I8c3179af8c3c6a6ea5e89a36592dc04bea894324
Signed-off-by: jh9216.park <jh9216.park@samsung.com>
18 files changed:
CMakeLists.txt
benchmark/server/CMakeLists.txt
benchmark/server/dbus/CMakeLists.txt [new file with mode: 0644]
benchmark/server/dbus/log-private.hh [new file with mode: 0644]
benchmark/server/dbus/main.cc [new file with mode: 0644]
benchmark/server/dbus/rpc-port-benchmark.conf [new file with mode: 0644]
benchmark/server/tidl/BenchmarkStub.cc [moved from benchmark/server/BenchmarkStub.cc with 100% similarity]
benchmark/server/tidl/BenchmarkStub.h [moved from benchmark/server/BenchmarkStub.h with 100% similarity]
benchmark/server/tidl/CMakeLists.txt [new file with mode: 0644]
benchmark/server/tidl/log-private.hh [moved from benchmark/server/log-private.hh with 100% similarity]
benchmark/server/tidl/main.cc [moved from benchmark/server/main.cc with 100% similarity]
benchmark/tool/dbus-proxy.cc [new file with mode: 0644]
benchmark/tool/dbus-proxy.hh [new file with mode: 0644]
benchmark/tool/main.cc
benchmark/tool/options.cc
benchmark/tool/options.hh
packaging/rpc-port.spec
socket_test/tool/main.cc [new file with mode: 0644]

index 9e9387d..6047848 100644 (file)
@@ -29,6 +29,7 @@ SET(TARGET_RPC_PORT "rpc-port")
 SET(TARGET_RPC_PORT_UNITTESTS "rpc-port_unittests")
 SET(TARGET_RPC_PORT_UTIL "rpc-port-util")
 SET(TARGET_BENCHMARK_SERVER "rpc-port-benchmark-server")
+SET(TARGET_BENCHMARK_SERVER_DBUS "rpc-port-benchmark-server-dbus")
 SET(TARGET_BENCHMARK_TOOL "rpc-port-benchmark-tool")
 
 ENABLE_TESTING()
index cff54c1..015cdef 100644 (file)
@@ -1,22 +1,2 @@
-AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} BENCHMARK_SERVER_SRCS)
-
-ADD_EXECUTABLE(${TARGET_BENCHMARK_SERVER} ${BENCHMARK_SERVER_SRCS})
-
-TARGET_INCLUDE_DIRECTORIES(${TARGET_BENCHMARK_SERVER} PUBLIC
-  ${CMAKE_CURRENT_SOURCE_DIR}
-  ${CMAKE_CURRENT_SOURCE_DIR}/../../include/)
-
-APPLY_PKG_CONFIG(${TARGET_BENCHMARK_SERVER} PUBLIC
-  AUL_DEPS
-  DLOG_DEPS
-  GLIB_DEPS
-)
-
-TARGET_LINK_LIBRARIES(${TARGET_BENCHMARK_SERVER} PUBLIC
-  ${TARGET_RPC_PORT} "-lpthread")
-SET_TARGET_PROPERTIES(${TARGET_BENCHMARK_SERVER} PROPERTIES
-  COMPILE_FLAGS "-fPIE")
-SET_TARGET_PROPERTIES(${TARGET_BENCHMARK_SERVER} PROPERTIES
-  LINK_FLAGS "-pie")
-
-INSTALL(TARGETS ${TARGET_BENCHMARK_SERVER} DESTINATION bin)
+ADD_SUBDIRECTORY(tidl)
+ADD_SUBDIRECTORY(dbus)
diff --git a/benchmark/server/dbus/CMakeLists.txt b/benchmark/server/dbus/CMakeLists.txt
new file mode 100644 (file)
index 0000000..509fe88
--- /dev/null
@@ -0,0 +1,23 @@
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} BENCHMARK_SERVER_DBUS_SRCS)
+
+ADD_EXECUTABLE(${TARGET_BENCHMARK_SERVER_DBUS} ${BENCHMARK_SERVER_DBUS_SRCS})
+
+TARGET_INCLUDE_DIRECTORIES(${TARGET_BENCHMARK_SERVER_DBUS} PUBLIC
+  ${CMAKE_CURRENT_SOURCE_DIR}
+  ${CMAKE_CURRENT_SOURCE_DIR}/../../../include/)
+
+APPLY_PKG_CONFIG(${TARGET_BENCHMARK_SERVER_DBUS} PUBLIC
+  DLOG_DEPS
+  GLIB_DEPS
+  GIO_DEPS
+)
+
+TARGET_LINK_LIBRARIES(${TARGET_BENCHMARK_SERVER_DBUS} PUBLIC
+  ${TARGET_RPC_PORT} "-lpthread")
+SET_TARGET_PROPERTIES(${TARGET_BENCHMARK_SERVER_DBUS} PROPERTIES
+  COMPILE_FLAGS "-fPIE")
+SET_TARGET_PROPERTIES(${TARGET_BENCHMARK_SERVER_DBUS} PROPERTIES
+  LINK_FLAGS "-pie")
+
+INSTALL(TARGETS ${TARGET_BENCHMARK_SERVER_DBUS} DESTINATION bin)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/rpc-port-benchmark.conf DESTINATION /etc/dbus-1/system.d)
diff --git a/benchmark/server/dbus/log-private.hh b/benchmark/server/dbus/log-private.hh
new file mode 100644 (file)
index 0000000..98ffafa
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2022 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.
+ */
+
+#ifndef LOG_PRIVATE_HH_
+#define LOG_PRIVATE_HH_
+
+#include <dlog.h>
+
+#undef LOG_TAG
+#define LOG_TAG "RPC_PORT_BENCHMARK_SERVER_DBUS"
+
+#undef _E
+#define _E LOGE
+
+#undef _W
+#define _W LOGW
+
+#undef _I
+#define _I LOGI
+
+#undef _D
+#define _D LOGD
+
+#endif  // LOG_PRIVATE_HH_
diff --git a/benchmark/server/dbus/main.cc b/benchmark/server/dbus/main.cc
new file mode 100644 (file)
index 0000000..fc2390e
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2024 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 <glib.h>
+#include <gio/gio.h>
+
+#include <string_view>
+#include <string>
+
+#include "log-private.hh"
+
+namespace {
+
+constexpr const char BUS_NAME[] = "tizen.appfw.rpcport.benchmark.dbus";
+constexpr const char OBJECT_PATH[] = "/tizen/appfw/rpcport/benchmark/dbus";
+
+constexpr const char INTROSPECTION_XML[] = R"__dbus(
+<node>
+  <interface name='tizen.appfw.rpcport.benchmark.dbus'>
+    <method name='Test'>
+      <arg type='s' name='data' direction='in'/>
+      <arg type='i' name='ret' direction='out'/>
+      </method>
+  </interface>
+</node>
+)__dbus";
+
+class MainLoop {
+ public:
+  MainLoop() {
+    loop_ = g_main_loop_new(nullptr, FALSE);
+  }
+
+  ~MainLoop() {
+    g_main_loop_unref(loop_);
+    if (introspection_data_)
+      g_dbus_node_info_unref(introspection_data_);
+  }
+
+  int OnTest(std::string data) {
+    return 0;
+  }
+
+  void OnBusAcquired(GDBusConnection* connection, const gchar* name) {
+    _I("bus acquired(%s)", name);
+
+    static const GDBusInterfaceVTable interface_vtable = {
+      [](GDBusConnection *connection,
+          const gchar *sender, const gchar *object_path,
+          const gchar *interface_name, const gchar *method_name,
+          GVariant *parameters, GDBusMethodInvocation *invocation,
+          gpointer user_data) {
+        if (std::string_view(method_name) == "Test") {
+          char* data = nullptr;
+          g_variant_get(parameters, "(&s)", &data);
+          auto* obj = static_cast<MainLoop*>(user_data);
+          int ret = obj->OnTest(data);
+
+          GVariant* param = g_variant_new("(i)", ret);
+          g_dbus_method_invocation_return_value(invocation, param);
+        }
+      },
+      nullptr,
+      nullptr
+    };
+
+    GError* error = nullptr;
+    guint reg_id = g_dbus_connection_register_object(connection,
+        OBJECT_PATH,
+        introspection_data_->interfaces[0],
+        &interface_vtable,
+        this, nullptr, &error);
+    if (reg_id == 0) {
+      _E("g_dbus_connection_register_object error(%s)", error ? error->message : "");
+      g_error_free(error);
+    }
+  }
+
+  void Run() {
+    GError* error = nullptr;
+    introspection_data_ = g_dbus_node_info_new_for_xml(INTROSPECTION_XML,
+        &error);
+    if (!introspection_data_) {
+      _E("g_dbus_node_info_new_for_xml error(%s)", error ? error->message : "");
+      g_error_free(error);
+      return;
+    }
+
+    guint owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
+        BUS_NAME,
+        G_BUS_NAME_OWNER_FLAGS_NONE,
+        [](GDBusConnection* connection, const gchar* name,
+            gpointer user_data) {
+          auto* obj = static_cast<MainLoop*>(user_data);
+          obj->OnBusAcquired(connection, name);
+        },
+        [](GDBusConnection* connection,
+            const gchar* name, gpointer user_data) {
+          _I("name acquired(%s)", name);
+        },
+        [](GDBusConnection* connection,
+            const gchar* name, gpointer user_data) {
+          _I("name lost(%s)", name);
+        },
+        this, nullptr);
+    if (!owner_id) {
+      _E("g_bus_own_name error");
+      g_dbus_node_info_unref(introspection_data_);
+      return;
+    }
+
+    g_main_loop_run(loop_);
+  }
+
+  void Quit() {
+    g_main_loop_quit(loop_);
+  }
+
+ private:
+  GMainLoop* loop_ = nullptr;
+  GDBusNodeInfo* introspection_data_ = nullptr;
+};
+
+}  // namespace
+
+int main(int argc, char** argv) {
+  MainLoop loop;
+  loop.Run();
+  return 0;
+}
diff --git a/benchmark/server/dbus/rpc-port-benchmark.conf b/benchmark/server/dbus/rpc-port-benchmark.conf
new file mode 100644 (file)
index 0000000..43c9b55
--- /dev/null
@@ -0,0 +1,11 @@
+<!DOCTYPE busconfig PUBLIC
+"-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
+"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
+
+<busconfig>
+       <policy context="default">
+               <allow own="tizen.appfw.rpcport.benchmark.dbus" />
+               <allow send_destination="tizen.appfw.rpcport.benchmark.dbus"
+     send_interface="tizen.appfw.rpcport.benchmark.dbus" send_type="method_call" />
+       </policy>
+</busconfig>
diff --git a/benchmark/server/tidl/CMakeLists.txt b/benchmark/server/tidl/CMakeLists.txt
new file mode 100644 (file)
index 0000000..ae94d6e
--- /dev/null
@@ -0,0 +1,22 @@
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} BENCHMARK_SERVER_SRCS)
+
+ADD_EXECUTABLE(${TARGET_BENCHMARK_SERVER} ${BENCHMARK_SERVER_SRCS})
+
+TARGET_INCLUDE_DIRECTORIES(${TARGET_BENCHMARK_SERVER} PUBLIC
+  ${CMAKE_CURRENT_SOURCE_DIR}
+  ${CMAKE_CURRENT_SOURCE_DIR}/../../../include/)
+
+APPLY_PKG_CONFIG(${TARGET_BENCHMARK_SERVER} PUBLIC
+  AUL_DEPS
+  DLOG_DEPS
+  GLIB_DEPS
+)
+
+TARGET_LINK_LIBRARIES(${TARGET_BENCHMARK_SERVER} PUBLIC
+  ${TARGET_RPC_PORT} "-lpthread")
+SET_TARGET_PROPERTIES(${TARGET_BENCHMARK_SERVER} PROPERTIES
+  COMPILE_FLAGS "-fPIE")
+SET_TARGET_PROPERTIES(${TARGET_BENCHMARK_SERVER} PROPERTIES
+  LINK_FLAGS "-pie")
+
+INSTALL(TARGETS ${TARGET_BENCHMARK_SERVER} DESTINATION bin)
diff --git a/benchmark/tool/dbus-proxy.cc b/benchmark/tool/dbus-proxy.cc
new file mode 100644 (file)
index 0000000..82f5b23
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2024 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 "dbus-proxy.hh"
+#include "log-private.hh"
+
+namespace rpc_port {
+namespace benchmark {
+
+namespace {
+
+constexpr const char BUS_NAME[] = "tizen.appfw.rpcport.benchmark.dbus";
+constexpr const char OBJECT_PATH[] = "/tizen/appfw/rpcport/benchmark/dbus";
+constexpr const char INTERFACE_NAME[] = "tizen.appfw.rpcport.benchmark.dbus";
+
+}
+
+DbusProxy::DbusProxy() {
+}
+
+void DbusProxy::Connect() {
+  if (system_conn_ != nullptr)
+    return;
+
+  GError* error = nullptr;
+  system_conn_ = g_bus_get_sync(G_BUS_TYPE_SYSTEM, nullptr, &error);
+  if (system_conn_ == nullptr) {
+    _E("g_bus_get_sync() is failed. error(%s)",
+        error ? error->message : "Unknown");
+    g_clear_error(&error);
+  }
+}
+
+int DbusProxy::Test(std::string data) const {
+  auto* msg = g_dbus_message_new_method_call(BUS_NAME,
+        OBJECT_PATH, INTERFACE_NAME, "Test");
+  if (msg == nullptr) {
+    _E("g_dbus_message_new_method_call() is failed");
+    return -1;
+  }
+  std::unique_ptr<GDBusMessage, decltype(g_object_unref)*> msg_auto(
+      msg, g_object_unref);
+
+  g_dbus_message_set_body(msg, g_variant_new("(s)", data.c_str()));
+  GError* error = nullptr;
+  auto* reply = g_dbus_connection_send_message_with_reply_sync(system_conn_, msg,
+      G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, nullptr, nullptr, &error);
+  if (reply == nullptr || error != nullptr) {
+    _E("g_dbus_connection_send_message_with_reply_sync() is failed. error(%s)",
+        error ? error->message : "Unknown");
+    g_clear_error(&error);
+    return -1;
+  }
+  std::unique_ptr<GDBusMessage, decltype(g_object_unref)*> reply_auto(
+      reply, g_object_unref);
+
+  auto* body = g_dbus_message_get_body(reply);
+  if (body == nullptr) {
+    _E("g_dbus_message_get_body() is failed");
+    return -1;
+  }
+
+  int ret = -1;
+  g_variant_get(body, "(i)", &ret);
+  return ret;
+}
+
+}  // namespace benchmark
+}  // namespace rpc_port
diff --git a/benchmark/tool/dbus-proxy.hh b/benchmark/tool/dbus-proxy.hh
new file mode 100644 (file)
index 0000000..7c5f4c4
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2024 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.
+ */
+
+#ifndef DBUS_PROXY_HH_
+#define DBUS_PROXY_HH_
+
+#include <string>
+#include <memory>
+
+#include <gio/gio.h>
+#include <glib.h>
+
+namespace rpc_port {
+namespace benchmark {
+
+class DbusProxy {
+ public:
+  DbusProxy();
+
+  void Connect();
+  int Test(std::string data) const;
+
+ private:
+  GDBusConnection* system_conn_ = nullptr;
+};
+
+}  // namespace benchmark
+}  // namespace rpc_port
+
+#endif  // DBUS_PROXY_HH_
index 1fae0e2..d21d150 100644 (file)
 #include "log-private.hh"
 #include "options.hh"
 #include "BenchmarkProxy.h"
+#include "dbus-proxy.hh"
 
 namespace {
 
 #define SERVER_PROC_NAME "org.tizen.appfw.rpc_port.benchmark"
 #define SERVER_BIN "/usr/bin/rpc-port-benchmark-server"
+#define SERVER_BIN_DBUS "/usr/bin/rpc-port-benchmark-server-dbus"
 
 namespace bp = rpc_port::BenchmarkProxy::proxy;
 
@@ -69,17 +71,21 @@ class Tester {
       return;
     }
 
-    ExecuteServer();
-    proxy_.reset(new bp::Benchmark(&listener_, SERVER_PROC_NAME));
-
-    try {
-      proxy_->Connect(true);
-    } catch (const bp::Exception& e) {
-      std::cerr << "Connect() failed" << std::endl;
-      return;
-    } catch (const std::exception& e) {
-      std::cerr << "Connect() failed. " << e.what() << std::endl;
-      return;
+    ExecuteServer(options_->IsDbus());
+    if (options_->IsDbus()) {
+      dbus_proxy_.Connect();
+    } else {
+      proxy_.reset(new bp::Benchmark(&listener_, SERVER_PROC_NAME));
+
+      try {
+        proxy_->Connect(true);
+      } catch (const bp::Exception& e) {
+        std::cerr << "Connect() failed" << std::endl;
+        return;
+      } catch (const std::exception& e) {
+        std::cerr << "Connect() failed. " << e.what() << std::endl;
+        return;
+      }
     }
 
     printf("%15s\t%15s\t%15s\t\t%15s\t\t%15s\n", "Iterations", "Data size",
@@ -111,6 +117,7 @@ class Tester {
  private:
   void DoTest(int iters, int size) {
     bool is_func = options_->IsFunction();
+    bool is_dbus = options_->IsDbus();
 
     StartTime();
     for (int i = 0; i < iters; i++) {
@@ -124,6 +131,16 @@ class Tester {
         continue;
       }
 
+      if (is_dbus) {
+        int ret = dbus_proxy_.Test(std::string(size, 'a'));
+        if (ret != 0) {
+          _E("Invalid return");
+          break;
+        }
+
+        continue;
+      }
+
       int ret = proxy_->Test(std::string(size, 'a'));
       if (ret != 0) {
         _E("Invalid return");
@@ -151,14 +168,20 @@ class Tester {
         sec.count(), t, l);
   }
 
-  void ExecuteServer() {
+  void ExecuteServer(bool is_dbus) {
     server_pid_ = fork();
     if (server_pid_ == 0) {
       setsid();
-
-      char bin[] = { SERVER_BIN };
-      char* argv[] = { bin, nullptr, nullptr };
-      int ret = execv(argv[0], argv);
+      int ret;
+      if (is_dbus) {
+        char bin[] = { SERVER_BIN_DBUS };
+        char* argv[] = { bin, nullptr, nullptr };
+        ret = execv(argv[0], argv);
+      } else {
+        char bin[] = { SERVER_BIN };
+        char* argv[] = { bin, nullptr, nullptr };
+        ret = execv(argv[0], argv);
+      }
       if (ret < 0) {
         std::cerr << "execv() is failed. errno: " << errno << std::endl;
         exit(-1);
@@ -178,6 +201,7 @@ class Tester {
   ConnectionListener listener_;
   std::chrono::system_clock::time_point start_;
   pid_t server_pid_ = -1;
+  rpc_port::benchmark::DbusProxy dbus_proxy_;
 };
 
 }  // namespace
index 38d9166..e4ab4b4 100644 (file)
@@ -35,6 +35,7 @@ Help Options:
 
 Additional Options:
   -f, --funcation                     Use function call instead of RPC
+  -d, --dbus                          Use Dbus method instead of TIDL RPC
   -a, --all                           Test pre-defined test-cases
   -i, --interations=<Iterations>      Iterations
   -s, --size=<Data size>              Data size (byte)
@@ -68,12 +69,13 @@ std::unique_ptr<Options> Options::Parse(int argc, char** argv) {
     {"iterations", required_argument, nullptr, 'i'},
     {"size", required_argument, nullptr, 's'},
     {"function", no_argument, nullptr, 'f'},
+    {"dbus", no_argument, nullptr, 'd'},
     {"all", no_argument, nullptr, 'a'},
     {0, 0, 0, 0}
   };
 
   while (true) {
-    int c = getopt_long(argc, argv, "vhfai:s:", long_options,
+    int c = getopt_long(argc, argv, "vhfdai:s:", long_options,
         &option_index);
     if (c == -1)
       break;
@@ -105,6 +107,11 @@ std::unique_ptr<Options> Options::Parse(int argc, char** argv) {
         options->is_function_ = true;
         break;
 
+      case 'd':
+        opt[OPT_DBUS] = true;
+        options->is_dbus_ = true;
+        break;
+
       case 'a':
         opt[OPT_ALL] = true;
         options->is_all_ = true;
index 3b8fd4c..1a560f5 100644 (file)
@@ -46,6 +46,10 @@ class Options {
     return is_all_;
   }
 
+  bool IsDbus() const {
+    return is_dbus_;
+  }
+
  private:
   enum Cmd {
     CMD_VERSION,
@@ -58,6 +62,7 @@ class Options {
     OPT_SIZE,
     OPT_ALL,
     OPT_FUNCTION,
+    OPT_DBUS,
     OPT_MAX
   };
 
@@ -71,6 +76,7 @@ class Options {
   std::string help_;
   bool is_function_ = false;
   bool is_all_ = false;
+  bool is_dbus_ = false;
 };
 
 }  // namespace benchmark
index 3da2551..998234b 100644 (file)
@@ -153,10 +153,12 @@ install -m 0755 run-unittest.sh %{buildroot}%{_bindir}/tizen-unittests/%{name}/
 
 %files
 %manifest %{name}.manifest
+%config %{_sysconfdir}/dbus-1/system.d/rpc-port-benchmark.conf
 %attr(0644,root,root) %{_libdir}/lib%{name}.so.*
 %license LICENSE.APLv2
 %{_bindir}/rpc-port-util
 %{_bindir}/rpc-port-benchmark-server
+%{_bindir}/rpc-port-benchmark-server-dbus
 %{_bindir}/rpc-port-benchmark-tool
 %config %{_sysconfdir}/dbus-1/system.d/rpc-port.conf
 
diff --git a/socket_test/tool/main.cc b/socket_test/tool/main.cc
new file mode 100644 (file)
index 0000000..7241d29
--- /dev/null
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2022 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 <sys/socket.h>
+#include <sys/types.h>
+#include <sys/un.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include <chrono>
+#include <iostream>
+#include <rpc-port-parcel.h>
+
+#include "log-private.hh"
+
+namespace {
+
+constexpr const char SOCKET_PATH[] = "/run/.socket_test";
+
+class ClientSocket {
+ public:
+  ClientSocket() {
+    fd_ = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
+  }
+
+  ~ClientSocket() {
+    if (!IsClosed())
+      Close();
+  }
+
+  void Close() {
+    if (fd_ > -1) {
+      close(fd_);
+      fd_ = -1;
+    }
+  }
+
+  int Connect(const std::string& endpoint) {
+    struct sockaddr_un sockaddr = { 0, };
+    sockaddr.sun_family = AF_UNIX;
+    snprintf(sockaddr.sun_path, sizeof(sockaddr.sun_path), "%s",
+        endpoint.c_str());
+    struct sockaddr* sockaddr_ptr = reinterpret_cast<struct sockaddr*>(&sockaddr);
+    socklen_t len = sizeof(sockaddr);
+    int ret = connect(fd_, sockaddr_ptr, len);
+    if (ret < 0) {
+      ret = -errno;
+      _E("connect() is failed. errno(%d)", errno);
+      return ret;
+    }
+
+    return 0;
+  }
+
+  int Send(const void* buf, unsigned int size) {
+    const unsigned char* buffer = static_cast<const unsigned char*>(buf);
+    size_t len = size;
+    while (len) {
+      ssize_t bytes = send(fd_, buffer, len, MSG_NOSIGNAL);
+      if (bytes < 0) {
+        int ret = -errno;
+        _E("send() is failed. fd(%d), errno(%d)", fd_, errno);
+        return ret;
+      }
+
+      len -= bytes;
+      buffer += bytes;
+    }
+
+    return 0;
+  }
+
+  int Receive(void* buf, unsigned int size) {
+    unsigned char* buffer = static_cast<unsigned char*>(buf);
+    size_t len = size;
+    while (len) {
+      ssize_t bytes = read(fd_, buffer, len);
+      if (bytes == 0) {
+        _W("EOF. fd(%d)", fd_);
+        return -EIO;
+      }
+
+      if (bytes < 0)
+        return -errno;
+
+      len -= bytes;
+      buffer += bytes;
+    }
+
+    return 0;
+  }
+
+  bool IsClosed() {
+    return fd_ < 0 ? true : false;
+  }
+
+ private:
+  int fd_ = -1;
+};
+
+std::chrono::system_clock::time_point start_;
+
+void StartTime() {
+  start_ = std::chrono::system_clock::now();
+}
+
+void EndTime(int iters, int size) {
+  std::chrono::duration<double> sec = std::chrono::system_clock::now() - start_;
+  double t = size * iters * 8 / sec.count() / 1024 / 1024;
+  double l = sec.count() * 1000 / iters;
+
+  printf("%10d\t%10dByte\t%15.4fs\t%15.4fMb/s\t%15.4fms\n", iters, size,
+      sec.count(), t, l);
+}
+
+void DoTest(ClientSocket& sk, int iters, int size) {
+  StartTime();
+  rpc_port_parcel_h p;
+  rpc_port_parcel_create(&p);
+  for (int i = 0; i < iters; i++) {
+    
+    
+    std::string data(size, 'a');
+    rpc_port_parcel_write_string(p, data.c_str());
+
+    int ret = -1;
+    sk.Send(&size, sizeof(size));
+    sk.Send(data.c_str(), size);
+    sk.Receive(&ret, sizeof(ret));
+    if (ret != 9216) {
+      _E("Invalid return");
+      exit(1);
+    }
+  }
+  rpc_port_parcel_destroy(p);
+  EndTime(iters, size);
+}
+
+}
+
+int main(int argc, char** argv) {
+  ClientSocket sk;
+  sk.Connect(SOCKET_PATH);
+
+  printf("%15s\t%15s\t%15s\t\t%15s\t\t%15s\n", "Iterations", "Data size",
+      "Time", "Throughput", "Latency");
+  DoTest(sk, 4000, 10);
+  DoTest(sk, 4000, 20);
+  DoTest(sk, 4000, 100);
+  DoTest(sk, 4000, 200);
+  DoTest(sk, 2000, 1000);
+  DoTest(sk, 2000, 2000);
+  DoTest(sk, 1000, 10000);
+  DoTest(sk, 1000, 20000);
+  DoTest(sk, 1000, 30000);
+  DoTest(sk, 1000, 40000);
+  DoTest(sk, 1000, 50000);
+  DoTest(sk, 1000, 60000);
+  DoTest(sk, 500, 100000);
+
+  return 0;
+}