[Edge] Add mqtt hybrid unittest
authorgichan <gichan2.jang@samsung.com>
Thu, 11 Aug 2022 06:36:49 +0000 (15:36 +0900)
committerjaeyun-jung <39614140+jaeyun-jung@users.noreply.github.com>
Fri, 12 Aug 2022 02:21:37 +0000 (11:21 +0900)
 - Add mqtt hybrid unittest.

Signed-off-by: gichan <gichan2.jang@samsung.com>
CMakeLists.txt
packaging/nnstreamer-edge.spec
src/libnnstreamer-edge/nnstreamer-edge-mqtt.c
tests/unittest_nnstreamer-edge.cc

index ae8891ec225ea32a4c1e5dfd7abd7d8cd54f9f25..8e8c22167726805f05d6dac3ff8e0f73a4d65a6f 100644 (file)
@@ -15,6 +15,7 @@ SET(CMAKE_CXX_STANDARD 14)
 SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Werror")
 SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -pthread -fPIE -fPIC -g")
 SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DENABLE_MQTT=1")
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DENABLE_MQTT=1")
 
 IF (ENABLE_DEBUG)
     SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DDEBUG=1")
index 61830ada4db6417435931f4fd2a9bb5034b6b05e..5586cee89841b6e3d0524cf552627271e92a292b 100644 (file)
@@ -21,6 +21,7 @@ BuildRequires:  glib2-devel
 
 %if 0%{?unit_test}
 BuildRequires:  gtest-devel
+BuildRequires:  procps
 
 %if 0%{?testcoverage}
 BuildRequires: lcov
index 1403061b5fda9c97ff1a1ac27f42259f8bb8ff72..5991c73e6638e010a63574ddcb2b2935854a0b92 100644 (file)
@@ -268,6 +268,7 @@ nns_edge_mqtt_connect (nns_edge_h edge_h, const char *topic)
       g_mutex_unlock (&bh->mqtt_mutex);
       nns_edge_loge ("Failed to connect to MQTT broker."
           "Please check broker is running status or broker host address.");
+      ret = NNS_EDGE_ERROR_CONNECTION_FAILURE;
       goto error;
     }
   }
@@ -475,6 +476,11 @@ nns_edge_mqtt_get_message (nns_edge_h edge_h, char **msg)
     return NNS_EDGE_ERROR_INVALID_PARAMETER;
   }
 
+  if (!msg) {
+    nns_edge_loge ("Invalid param, given msg param is invalid.");
+    return NNS_EDGE_ERROR_INVALID_PARAMETER;
+  }
+
   bh = (nns_edge_broker_s *) eh->broker_h;
 
   *msg = g_async_queue_timeout_pop (bh->server_list, DEFAULT_SUB_TIMEOUT);
index 02f7a37f9549b7b52b6b8b635d5115e1f5037ad8..025670b202ba84af1ca92d5c68211cb16bbf206a 100644 (file)
@@ -2815,6 +2815,458 @@ TEST(edgeMeta, deserializeInvalidParam03_n)
   free (data);\r
 }\r
 \r
+/**\r
+ * @brief Edge event callback for test.\r
+ */\r
+static int\r
+_test_edge_hybrid_event_cb (nns_edge_event_h event_h, void *user_data)\r
+{\r
+  ne_test_data_s *_td = (ne_test_data_s *) user_data;\r
+  nns_edge_event_e event = NNS_EDGE_EVENT_UNKNOWN;\r
+  nns_edge_data_h data_h;\r
+  void *data;\r
+  size_t data_len;\r
+  char *val;\r
+  unsigned int i, count;\r
+  int ret;\r
+\r
+  if (!_td) {\r
+    /* Cannot update event status. */\r
+    return NNS_EDGE_ERROR_NONE;\r
+  }\r
+\r
+  ret = nns_edge_event_get_type (event_h, &event);\r
+  EXPECT_EQ (ret, NNS_EDGE_ERROR_NONE);\r
+\r
+  switch (event) {\r
+    case NNS_EDGE_EVENT_NEW_DATA_RECEIVED:\r
+      _td->received++;\r
+\r
+      ret = nns_edge_event_parse_new_data (event_h, &data_h);\r
+      EXPECT_EQ (ret, NNS_EDGE_ERROR_NONE);\r
+\r
+      /* Compare metadata */\r
+      ret = nns_edge_data_get_info (data_h, "test-key", &val);\r
+      EXPECT_EQ (ret, NNS_EDGE_ERROR_NONE);\r
+      EXPECT_STREQ (val, "test-value");\r
+      nns_edge_free (val);\r
+\r
+      if (_td->is_server) {\r
+        /**\r
+         * @note This is test code, responding to client.\r
+         * Recommend not to call edge API in event callback.\r
+         */\r
+        ret = nns_edge_publish (_td->handle, data_h);\r
+        EXPECT_EQ (ret, NNS_EDGE_ERROR_NONE);\r
+      } else {\r
+        /* Compare received data */\r
+        ret = nns_edge_data_get_count (data_h, &count);\r
+        EXPECT_EQ (ret, NNS_EDGE_ERROR_NONE);\r
+        ret = nns_edge_data_get (data_h, 0, &data, &data_len);\r
+        EXPECT_EQ (ret, NNS_EDGE_ERROR_NONE);\r
+\r
+        EXPECT_EQ (count, 1U);\r
+        for (i = 0; i < 10U; i++)\r
+          EXPECT_EQ (((unsigned int *) data)[i], i);\r
+      }\r
+\r
+      ret = nns_edge_data_destroy (data_h);\r
+      EXPECT_EQ (ret, NNS_EDGE_ERROR_NONE);\r
+      break;\r
+    default:\r
+      break;\r
+  }\r
+\r
+  return NNS_EDGE_ERROR_NONE;\r
+}\r
+\r
+/**\r
+ * @brief Check whether MQTT broker is running or not.\r
+ */\r
+static int\r
+_check_mqtt_broker ()\r
+{\r
+  int ret = 0;\r
+\r
+  ret = system ("ps aux | grep mosquitto | grep -v grep");\r
+  if (0 != ret) {\r
+    nns_edge_loge ("MQTT broker is not running. Skip query hybrid test.");\r
+    ret = -1;\r
+  }\r
+\r
+  return ret;\r
+}\r
+\r
+/**\r
+ * @brief Connect to the local host using the information received from mqtt.\r
+ */\r
+TEST(edgeMqtt, connectLocal)\r
+{\r
+  nns_edge_h server_h, client_h;\r
+  ne_test_data_s *_td_server, *_td_client;\r
+  nns_edge_data_h data_h;\r
+  pthread_t server_thread, client_thread;\r
+  pthread_attr_t attr;\r
+  size_t data_len;\r
+  void *data;\r
+  unsigned int i, retry;\r
+  int ret = 0;\r
+  char *val;\r
+\r
+  if (0 != _check_mqtt_broker ())\r
+    return;\r
+\r
+  _td_server = _get_test_data (true);\r
+  _td_client = _get_test_data (false);\r
+\r
+  /* Prepare server (127.0.0.1:port) */\r
+  nns_edge_create_handle ("temp-server", NNS_EDGE_CONNECT_TYPE_HYBRID, NNS_EDGE_FLAG_RECV | NNS_EDGE_FLAG_SEND | NNS_EDGE_FLAG_SERVER, &server_h);\r
+  nns_edge_set_event_callback (server_h, _test_edge_hybrid_event_cb, _td_server);\r
+  nns_edge_set_info (server_h, "HOST", "localhost");\r
+  nns_edge_set_info (server_h, "PORT", "0");\r
+  nns_edge_set_info (server_h, "DEST_HOST", "tcp://localhost");\r
+  nns_edge_set_info (server_h, "DEST_PORT", "1883");\r
+  nns_edge_set_info (server_h, "TOPIC", "temp-mqtt-topic");\r
+  nns_edge_set_info (server_h, "CAPS", "test server");\r
+  _td_server->handle = server_h;\r
+\r
+  /* Prepare client */\r
+  nns_edge_create_handle ("temp-client", NNS_EDGE_CONNECT_TYPE_HYBRID, NNS_EDGE_FLAG_RECV | NNS_EDGE_FLAG_SEND, &client_h);\r
+  nns_edge_set_event_callback (client_h, _test_edge_hybrid_event_cb, _td_client);\r
+  nns_edge_set_info (client_h, "CAPS", "test client");\r
+  nns_edge_set_info (client_h, "HOST", "localhost");\r
+  nns_edge_set_info (client_h, "port", "0");\r
+  nns_edge_set_info (client_h, "TOPIC", "temp-mqtt-topic");\r
+  _td_client->handle = client_h;\r
+\r
+  /* Start server/client thread */\r
+  pthread_attr_init (&attr);\r
+  pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);\r
+  pthread_create (&server_thread, &attr, _test_edge_thread, _td_server);\r
+  pthread_create (&client_thread, &attr, _test_edge_thread, _td_client);\r
+  pthread_attr_destroy (&attr);\r
+\r
+  /* Wait for server/client thread */\r
+  do {\r
+    usleep (20000);\r
+  } while (!g_main_loop_is_running (_td_server->loop));\r
+\r
+  do {\r
+    usleep (20000);\r
+  } while (!g_main_loop_is_running (_td_client->loop));\r
+\r
+  ret = nns_edge_connect (client_h, "tcp://localhost", 1883);\r
+  EXPECT_EQ (ret, NNS_EDGE_ERROR_NONE);\r
+  usleep (10000);\r
+\r
+  sleep (2);\r
+\r
+  /* Send request to server */\r
+  data_len = 10U * sizeof (unsigned int);\r
+  data = malloc (data_len);\r
+  ASSERT_TRUE (data != NULL);\r
+\r
+  for (i = 0; i < 10U; i++)\r
+    ((unsigned int *) data)[i] = i;\r
+\r
+  ret = nns_edge_data_create (&data_h);\r
+  EXPECT_EQ (ret, NNS_EDGE_ERROR_NONE);\r
+\r
+  ret = nns_edge_data_add (data_h, data, data_len, nns_edge_free);\r
+  EXPECT_EQ (ret, NNS_EDGE_ERROR_NONE);\r
+\r
+  nns_edge_get_info (client_h, "client_id", &val);\r
+  nns_edge_data_set_info (data_h, "client_id", val);\r
+  g_free (val);\r
+\r
+  ret = nns_edge_data_set_info (data_h, "test-key", "test-value");\r
+  EXPECT_EQ (ret, NNS_EDGE_ERROR_NONE);\r
+\r
+  for (i = 0; i < 5U; i++) {\r
+    ret = nns_edge_publish (client_h, data_h);\r
+    EXPECT_EQ (ret, NNS_EDGE_ERROR_NONE);\r
+    usleep (10000);\r
+  }\r
+\r
+  ret = nns_edge_data_destroy (data_h);\r
+  EXPECT_EQ (ret, NNS_EDGE_ERROR_NONE);\r
+\r
+  /* Wait for responding data (20 seconds) */\r
+  retry = 0U;\r
+  do {\r
+    usleep (100000);\r
+    if (_td_client->received > 0)\r
+      break;\r
+  } while (retry++ < 200U);\r
+\r
+  g_main_loop_quit (_td_server->loop);\r
+  g_main_loop_quit (_td_client->loop);\r
+\r
+  ret = nns_edge_release_handle (server_h);\r
+  EXPECT_EQ (ret, NNS_EDGE_ERROR_NONE);\r
+  ret = nns_edge_release_handle (client_h);\r
+  EXPECT_EQ (ret, NNS_EDGE_ERROR_NONE);\r
+\r
+  EXPECT_TRUE (_td_server->received > 0);\r
+  EXPECT_TRUE (_td_client->received > 0);\r
+\r
+  _free_test_data (_td_server);\r
+  _free_test_data (_td_client);\r
+}\r
+\r
+\r
+/**\r
+ * @brief Connect to the mqtt broker with invalid param.\r
+ */\r
+TEST(edgeMqtt, connectInvalidParam_n)\r
+{\r
+  int ret = -1;\r
+  if (0 != _check_mqtt_broker ())\r
+    return;\r
+\r
+  ret = nns_edge_mqtt_connect (NULL);\r
+  EXPECT_NE (ret, NNS_EDGE_ERROR_NONE);\r
+}\r
+\r
+/**\r
+ * @brief Connect to the mqtt broker with invalid hostaddress.\r
+ */\r
+TEST(edgeMqtt, connectInvalidParam2_n)\r
+{\r
+  int ret = -1;\r
+  nns_edge_h edge_h;\r
+\r
+  if (0 != _check_mqtt_broker ())\r
+    return;\r
+\r
+  ret = nns_edge_create_handle ("temp-server", NNS_EDGE_CONNECT_TYPE_HYBRID, NNS_EDGE_FLAG_RECV | NNS_EDGE_FLAG_SEND | NNS_EDGE_FLAG_SERVER, &edge_h);\r
+  EXPECT_EQ (ret, NNS_EDGE_ERROR_NONE);\r
+  nns_edge_set_info (edge_h, "DEST_HOST", "tcp://none");\r
+  nns_edge_set_info (edge_h, "DEST_PORT", "1883");\r
+\r
+  ret = nns_edge_mqtt_connect (edge_h);\r
+  EXPECT_NE (ret, NNS_EDGE_ERROR_NONE);\r
+\r
+  ret = nns_edge_release_handle (edge_h);\r
+  EXPECT_EQ (ret, NNS_EDGE_ERROR_NONE);\r
+}\r
+\r
+/**\r
+ * @brief Close the mqtt handle with invalid param.\r
+ */\r
+TEST(edgeMqtt, closeInvalidParam_n)\r
+{\r
+  int ret = -1;\r
+  if (0 != _check_mqtt_broker ())\r
+    return;\r
+\r
+  ret = nns_edge_mqtt_close (NULL);\r
+  EXPECT_NE (ret, NNS_EDGE_ERROR_NONE);\r
+}\r
+\r
+/**\r
+ * @brief Close the mqtt handle before the connection.\r
+ */\r
+TEST(edgeMqtt, closeInvalidParam2_n)\r
+{\r
+  int ret = -1;\r
+  nns_edge_h edge_h;\r
+\r
+  if (0 != _check_mqtt_broker ())\r
+    return;\r
+\r
+  ret = nns_edge_create_handle ("temp-server", NNS_EDGE_CONNECT_TYPE_HYBRID, NNS_EDGE_FLAG_RECV | NNS_EDGE_FLAG_SEND | NNS_EDGE_FLAG_SERVER, &edge_h);\r
+  EXPECT_EQ (ret, NNS_EDGE_ERROR_NONE);\r
+\r
+  ret = nns_edge_mqtt_close (edge_h);\r
+  EXPECT_NE (ret, NNS_EDGE_ERROR_NONE);\r
+\r
+  ret = nns_edge_release_handle (edge_h);\r
+  EXPECT_EQ (ret, NNS_EDGE_ERROR_NONE);\r
+}\r
+\r
+/**\r
+ * @brief Publish with invalid param.\r
+ */\r
+TEST(edgeMqtt, publishInvalidParam_n)\r
+{\r
+  int ret = -1;\r
+  const char* msg = "TEMP_MESSAGE";\r
+\r
+  if (0 != _check_mqtt_broker ())\r
+    return;\r
+\r
+  ret = nns_edge_mqtt_publish (NULL, msg, strlen (msg) + 1);\r
+  EXPECT_NE (ret, NNS_EDGE_ERROR_NONE);\r
+}\r
+\r
+/**\r
+ * @brief Publish with invalid param.\r
+ */\r
+TEST(edgeMqtt, publishInvalidParam2_n)\r
+{\r
+  int ret = -1;\r
+  nns_edge_h edge_h;\r
+  const char* msg = "TEMP_MESSAGE";\r
+\r
+  if (0 != _check_mqtt_broker ())\r
+    return;\r
+\r
+  ret = nns_edge_create_handle ("temp-server", NNS_EDGE_CONNECT_TYPE_HYBRID, NNS_EDGE_FLAG_RECV | NNS_EDGE_FLAG_SEND | NNS_EDGE_FLAG_SERVER, &edge_h);\r
+  EXPECT_EQ (ret, NNS_EDGE_ERROR_NONE);\r
+\r
+  ret = nns_edge_mqtt_publish (edge_h, NULL, strlen (msg) + 1);\r
+  EXPECT_NE (ret, NNS_EDGE_ERROR_NONE);\r
+\r
+  ret = nns_edge_release_handle (edge_h);\r
+  EXPECT_EQ (ret, NNS_EDGE_ERROR_NONE);\r
+}\r
+\r
+\r
+/**\r
+ * @brief Publish with invalid param.\r
+ */\r
+TEST(edgeMqtt, publishInvalidParam3_n)\r
+{\r
+  int ret = -1;\r
+  nns_edge_h edge_h;\r
+  const char* msg = "TEMP_MESSAGE";\r
+\r
+  if (0 != _check_mqtt_broker ())\r
+    return;\r
+\r
+  ret = nns_edge_create_handle ("temp-server", NNS_EDGE_CONNECT_TYPE_HYBRID, NNS_EDGE_FLAG_RECV | NNS_EDGE_FLAG_SEND | NNS_EDGE_FLAG_SERVER, &edge_h);\r
+  EXPECT_EQ (ret, NNS_EDGE_ERROR_NONE);\r
+\r
+  ret = nns_edge_mqtt_publish (edge_h, msg, 0);\r
+  EXPECT_NE (ret, NNS_EDGE_ERROR_NONE);\r
+\r
+  ret = nns_edge_release_handle (edge_h);\r
+  EXPECT_EQ (ret, NNS_EDGE_ERROR_NONE);\r
+}\r
+\r
+/**\r
+ * @brief Publish the message without the connection.\r
+ */\r
+TEST(edgeMqtt, publishInvalidParam4_n)\r
+{\r
+  int ret = -1;\r
+  nns_edge_h edge_h;\r
+  const char* msg = "TEMP_MESSAGE";\r
+\r
+  if (0 != _check_mqtt_broker ())\r
+    return;\r
+\r
+  ret = nns_edge_create_handle ("temp-server", NNS_EDGE_CONNECT_TYPE_HYBRID, NNS_EDGE_FLAG_RECV | NNS_EDGE_FLAG_SEND | NNS_EDGE_FLAG_SERVER, &edge_h);\r
+  EXPECT_EQ (ret, NNS_EDGE_ERROR_NONE);\r
+\r
+  ret = nns_edge_mqtt_publish (edge_h, msg, strlen (msg) + 1);\r
+  EXPECT_NE (ret, NNS_EDGE_ERROR_NONE);\r
+\r
+  ret = nns_edge_release_handle (edge_h);\r
+  EXPECT_EQ (ret, NNS_EDGE_ERROR_NONE);\r
+}\r
+\r
+/**\r
+ * @brief Subscribe the topic with invalid param.\r
+ */\r
+TEST(edgeMqtt, subscribeInvalidParam_n)\r
+{\r
+  int ret = -1;\r
+  if (0 != _check_mqtt_broker ())\r
+    return;\r
+\r
+  ret = nns_edge_mqtt_subscribe (NULL);\r
+  EXPECT_NE (ret, NNS_EDGE_ERROR_NONE);\r
+}\r
+\r
+/**\r
+ * @brief Subscribe the topic before the connection.\r
+ */\r
+TEST(edgeMqtt, subscribeInvalidParam2_n)\r
+{\r
+  int ret = -1;\r
+  nns_edge_h edge_h;\r
+\r
+  if (0 != _check_mqtt_broker ())\r
+    return;\r
+\r
+  ret = nns_edge_create_handle ("temp-server", NNS_EDGE_CONNECT_TYPE_HYBRID, NNS_EDGE_FLAG_RECV | NNS_EDGE_FLAG_SEND | NNS_EDGE_FLAG_SERVER, &edge_h);\r
+  EXPECT_EQ (ret, NNS_EDGE_ERROR_NONE);\r
+\r
+  ret = nns_edge_mqtt_subscribe (edge_h);\r
+  EXPECT_NE (ret, NNS_EDGE_ERROR_NONE);\r
+\r
+  ret = nns_edge_release_handle (edge_h);\r
+  EXPECT_EQ (ret, NNS_EDGE_ERROR_NONE);\r
+}\r
+\r
+/**\r
+ * @brief Get message with invalid param.\r
+ */\r
+TEST(edgeMqtt, getMessageInvalidParam_n)\r
+{\r
+  int ret = -1;\r
+  char *msg = NULL;\r
+\r
+  if (0 != _check_mqtt_broker ())\r
+    return;\r
+\r
+  ret = nns_edge_mqtt_get_message (NULL, &msg);\r
+  EXPECT_NE (ret, NNS_EDGE_ERROR_NONE);\r
+}\r
+\r
+/**\r
+ * @brief Get message with invalid param.\r
+ */\r
+TEST(edgeMqtt, getMessageInvalidParam2_n)\r
+{\r
+  int ret = -1;\r
+  nns_edge_h edge_h;\r
+\r
+  if (0 != _check_mqtt_broker ())\r
+    return;\r
+\r
+  ret = nns_edge_create_handle ("temp-server", NNS_EDGE_CONNECT_TYPE_HYBRID, NNS_EDGE_FLAG_RECV | NNS_EDGE_FLAG_SEND | NNS_EDGE_FLAG_SERVER, &edge_h);\r
+  EXPECT_EQ (ret, NNS_EDGE_ERROR_NONE);\r
+\r
+  ret = nns_edge_mqtt_get_message (edge_h, NULL);\r
+  EXPECT_NE (ret, NNS_EDGE_ERROR_NONE);\r
+\r
+  ret = nns_edge_release_handle (edge_h);\r
+  EXPECT_EQ (ret, NNS_EDGE_ERROR_NONE);\r
+}\r
+\r
+/**\r
+ * @brief Get message from empty message queue.\r
+ */\r
+TEST(edgeMqtt, getMessageWithinTimeout_n)\r
+{\r
+  int ret = -1;\r
+  nns_edge_h edge_h;\r
+  char *msg = NULL;\r
+\r
+  if (0 != _check_mqtt_broker ())\r
+    return;\r
+\r
+  ret = nns_edge_create_handle ("temp-server", NNS_EDGE_CONNECT_TYPE_HYBRID, NNS_EDGE_FLAG_RECV | NNS_EDGE_FLAG_SEND | NNS_EDGE_FLAG_SERVER, &edge_h);\r
+  EXPECT_EQ (ret, NNS_EDGE_ERROR_NONE);\r
+  nns_edge_set_info (edge_h, "DEST_HOST", "tcp://localhost");\r
+  nns_edge_set_info (edge_h, "DEST_PORT", "1883");\r
+\r
+  ret = nns_edge_mqtt_connect (edge_h);\r
+  EXPECT_EQ (ret, NNS_EDGE_ERROR_NONE);\r
+\r
+  ret = nns_edge_mqtt_get_message (edge_h, &msg);\r
+  EXPECT_NE (ret, NNS_EDGE_ERROR_NONE);\r
+\r
+  ret = nns_edge_mqtt_close (edge_h);\r
+  EXPECT_EQ (ret, NNS_EDGE_ERROR_NONE);\r
+\r
+  ret = nns_edge_release_handle (edge_h);\r
+  EXPECT_EQ (ret, NNS_EDGE_ERROR_NONE);\r
+}\r
+\r
 /**\r
  * @brief Main gtest\r
  */\r