diff --git a/include/nnstreamer-edge-custom.h b/include/nnstreamer-edge-custom.h index 5c9959f..5fee205 100644 --- a/include/nnstreamer-edge-custom.h +++ b/include/nnstreamer-edge-custom.h @@ -13,15 +13,18 @@ #ifndef __NNSTREAMER_EDGE_CUSTOM_H__ #define __NNSTREAMER_EDGE_CUSTOM_H__ -#include -#include -#include -#include #include "nnstreamer-edge.h" +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * @brief NNStreamer Edge custom connection definition. This is used to define a custom connsction. The user should implement the functions and provide them using nns_edge_custom_get_instance(). Refer to the example in nnstreamer-edge-custom.c for more details. + */ typedef struct _NnsEdgeCustomDef { - char *(*nns_edge_get_connection_type) (); + const char *(*nns_edge_custom_get_description) (); int (*nns_edge_custom_create) (void **priv); int (*nns_edge_custom_close) (void *priv); int (*nns_edge_custom_start) (void *priv); @@ -33,8 +36,15 @@ typedef struct _NnsEdgeCustomDef int (*nns_edge_custom_send_data) (void *priv, nns_edge_data_h data_h); int (*nns_edge_custom_set_option) (void *priv, const char *key, const char *value); char *(*nns_edge_custom_get_option) (void *priv, const char *key); -} NnsEdgeCustomDef; +} nns_edge_custom_s; + +/** + * @brief Get nns edge custom connection instance. + */ +void* nns_edge_custom_get_instance (); -void* nns_edge_custom_get_handle (); +#ifdef __cplusplus +} +#endif /* __cplusplus */ #endif /* __NNSTREAMER_EDGE_CUSTOM_H__ */ diff --git a/packaging/nnstreamer-edge.spec b/packaging/nnstreamer-edge.spec index a733543..58e00fd 100644 --- a/packaging/nnstreamer-edge.spec +++ b/packaging/nnstreamer-edge.spec @@ -126,6 +126,7 @@ popd %if 0%{?unit_test} LD_LIBRARY_PATH=./src bash %{test_script} ./tests/unittest_nnstreamer-edge +LD_LIBRARY_PATH=./src:./tests bash %{test_script} ./tests/unittest_nnstreamer-edge-custom %if 0%{?mqtt_support} LD_LIBRARY_PATH=./src bash %{test_script} ./tests/unittest_nnstreamer-edge-mqtt @@ -181,6 +182,8 @@ rm -rf %{buildroot} %manifest nnstreamer-edge.manifest %defattr(-,root,root,-) %{_bindir}/unittest_nnstreamer-edge +%{_bindir}/unittest_nnstreamer-edge-custom +%{_libdir}/libnnstreamer-edge-custom-test.so* %if 0%{?mqtt_support} %{_bindir}/unittest_nnstreamer-edge-mqtt diff --git a/src/libnnstreamer-edge/nnstreamer-edge-internal.c b/src/libnnstreamer-edge/nnstreamer-edge-internal.c index f9fdfb0..705b84d 100644 --- a/src/libnnstreamer-edge/nnstreamer-edge-internal.c +++ b/src/libnnstreamer-edge/nnstreamer-edge-internal.c @@ -33,6 +33,16 @@ */ #define N_BACKLOG 10 +/** + * @brief Data structure for edge custom connection. + */ +typedef struct +{ + void *dl_handle; + void *instance; + void *priv; +} custom_connection_s; + /** * @brief Data structure for edge handle. */ @@ -74,7 +84,9 @@ typedef struct /* MQTT or AITT handle */ void *broker_h; - void *custom_h; + + /* Data for custom connection */ + custom_connection_s custom; } nns_edge_handle_s; /** @@ -924,10 +936,10 @@ _nns_edge_send_thread (void *thread_data) break; case NNS_EDGE_CONNECT_TYPE_CUSTOM: { - NnsEdgeCustomDef *custom_h = (NnsEdgeCustomDef *) eh->custom_h; - ret = custom_h->nns_edge_custom_send_data (eh->broker_h, data_h); + nns_edge_custom_s *custom_h = (nns_edge_custom_s *) eh->custom.instance; + ret = custom_h->nns_edge_custom_send_data (eh->custom.priv, data_h); if (NNS_EDGE_ERROR_NONE != ret) - nns_edge_loge ("Failed to send data via MCF connection."); + nns_edge_loge ("Failed to send data via nns edge custom connection."); break; } default: @@ -1297,7 +1309,9 @@ _nns_edge_create_handle (const char *id, nns_edge_node_type_e node_type, eh->sending = false; eh->listener_fd = -1; eh->caps_str = nns_edge_strdup (""); - eh->custom_h = NULL; + eh->custom.dl_handle = NULL; + eh->custom.instance = NULL; + eh->custom.priv = NULL; ret = nns_edge_metadata_create (&eh->metadata); if (ret != NNS_EDGE_ERROR_NONE) { @@ -1319,6 +1333,34 @@ _nns_edge_create_handle (const char *id, nns_edge_node_type_e node_type, return ret; } +/** + * @brief Load custom lib and get edge custom instance. + */ +static int +_nns_edge_load_custom_library (nns_edge_h edge_h, const char *lib_path) +{ + nns_edge_handle_s *eh = (nns_edge_handle_s *) edge_h; + + eh->custom.dl_handle = dlopen (lib_path, RTLD_LAZY); + if (NULL == eh->custom.dl_handle) { + nns_edge_loge ("Failed to open custom lib: %s", dlerror ()); + return NNS_EDGE_ERROR_UNKNOWN; + } + + void *(*getCustomHandle) () = + (void *(*)()) dlsym (eh->custom.dl_handle, "nns_edge_custom_get_instance"); + if (!getCustomHandle) { + nns_edge_loge ("Failed to find nns_edge_custom_get_instance: %s", + dlerror ()); + dlclose (eh->custom.dl_handle); + eh->custom.dl_handle = NULL; + return NNS_EDGE_ERROR_UNKNOWN; + } + + eh->custom.instance = (nns_edge_custom_s *) getCustomHandle (); + return 0; +} + /** * @brief Create edge custom handle. */ @@ -1328,8 +1370,7 @@ nns_edge_custom_create_handle (const char *id, const char *lib_path, { int ret = NNS_EDGE_ERROR_NONE; nns_edge_handle_s *eh; - void *custom_handle; - NnsEdgeCustomDef *custom_h; + nns_edge_custom_s *custom_h; if (node_type < 0 || node_type >= NNS_EDGE_NODE_TYPE_UNKNOWN) { nns_edge_loge ("Invalid param, set exact node type."); @@ -1354,23 +1395,15 @@ nns_edge_custom_create_handle (const char *id, const char *lib_path, eh = (nns_edge_handle_s *) * edge_h; eh->connect_type = NNS_EDGE_CONNECT_TYPE_CUSTOM; - custom_handle = dlopen (lib_path, RTLD_LAZY); - if (custom_handle) { - void *(*getCustomHandle) () = - (void *(*)()) dlsym (custom_handle, "nns_edge_custom_get_handle"); - if (!getCustomHandle) { - nns_edge_loge ("Failed to find nns_edge_custom_get_handle: %s", - dlerror ()); - return NNS_EDGE_ERROR_UNKNOWN; - } - eh->custom_h = getCustomHandle (); - } else { - nns_edge_loge ("Failed to open custom handle: %s]\n", dlerror ()); - return NNS_EDGE_ERROR_INVALID_PARAMETER;; + ret = _nns_edge_load_custom_library (*edge_h, lib_path); + if (NNS_EDGE_ERROR_NONE != ret) { + nns_edge_loge + ("Failed to load custom lib. Please check the custom lib path or permission."); + return ret; } - custom_h = (NnsEdgeCustomDef *) eh->custom_h; - ret = custom_h->nns_edge_custom_create (&eh->broker_h); + custom_h = (nns_edge_custom_s *) eh->custom.instance; + ret = custom_h->nns_edge_custom_create (&eh->custom.priv); if (NNS_EDGE_ERROR_NONE != ret) { nns_edge_loge ("Failed to create custom connection handle."); } @@ -1431,6 +1464,33 @@ nns_edge_create_handle (const char *id, nns_edge_connect_type_e connect_type, return ret; } +/** + * @brief Start the nnstreamer edge custom. + */ +static int +_nns_edge_custom_start (nns_edge_handle_s * eh) +{ + int ret = NNS_EDGE_ERROR_NONE; + nns_edge_custom_s *custom_h = (nns_edge_custom_s *) eh->custom.instance; + + ret = custom_h->nns_edge_custom_start (eh->custom.priv); + if (NNS_EDGE_ERROR_NONE != ret) { + nns_edge_loge ("Failed to start edge custom connection"); + return ret; + } + + ret = custom_h->nns_edge_custom_set_event_cb (eh->custom.priv, eh->event_cb, + eh->user_data); + if (NNS_EDGE_ERROR_NONE != ret) { + nns_edge_loge ("Failed to set event callback to custom connection."); + return ret; + } + + ret = _nns_edge_create_send_thread (eh); + + return ret; +} + /** * @brief Start the nnstreamer edge. */ @@ -1454,18 +1514,10 @@ nns_edge_start (nns_edge_h edge_h) nns_edge_lock (eh); if (NNS_EDGE_CONNECT_TYPE_CUSTOM == eh->connect_type) { - NnsEdgeCustomDef *custom_h = (NnsEdgeCustomDef *) eh->custom_h; - ret = custom_h->nns_edge_custom_start (eh->broker_h); + ret = _nns_edge_custom_start (edge_h); if (NNS_EDGE_ERROR_NONE != ret) { nns_edge_loge ("Failed to start edge custom connection"); } - ret = custom_h->nns_edge_custom_set_event_cb (eh->broker_h, eh->event_cb, - eh->user_data); - if (NNS_EDGE_ERROR_NONE != ret) { - nns_edge_loge ("Failed to set event callback to custom connection."); - goto done; - } - ret = _nns_edge_create_send_thread (eh); goto done; } @@ -1556,6 +1608,22 @@ nns_edge_start (nns_edge_h edge_h) return ret; } +/** + * @brief Stop the nnstreamer edge custom connection. + */ +static int +_nns_edge_custom_stop (nns_edge_handle_s * eh) +{ + int ret = NNS_EDGE_ERROR_NONE; + nns_edge_custom_s *custom_h = (nns_edge_custom_s *) eh->custom.instance; + ret = custom_h->nns_edge_custom_stop (eh->custom.priv); + if (NNS_EDGE_ERROR_NONE != ret) { + nns_edge_loge ("Failed to stop nns edge custom connection"); + } + + return ret; +} + /** * @brief Stop the nnstreamer edge. */ @@ -1577,20 +1645,35 @@ nns_edge_stop (nns_edge_h edge_h) } nns_edge_lock (eh); + if (!eh->is_started) { + nns_edge_logi ("Edge is not started yet. Nothing to stop."); + goto done; + } if (NNS_EDGE_CONNECT_TYPE_CUSTOM == eh->connect_type) { - NnsEdgeCustomDef *custom_h = (NnsEdgeCustomDef *) eh->custom_h; - ret = custom_h->nns_edge_custom_stop (eh->broker_h); - if (NNS_EDGE_ERROR_NONE != ret) { - nns_edge_loge ("Failed to stop MCF"); - } + ret = _nns_edge_custom_stop (eh); } eh->is_started = FALSE; + +done: nns_edge_unlock (eh); return ret; } +static void +_nns_edge_custom_release (nns_edge_handle_s * eh) +{ + nns_edge_custom_s *custom_h = (nns_edge_custom_s *) eh->custom.instance; + int ret = custom_h->nns_edge_custom_close (eh->custom.priv); + if (NNS_EDGE_ERROR_NONE != ret) { + nns_edge_loge ("Failed to stop nns edge custom connection"); + } + dlclose (eh->custom.dl_handle); + eh->custom.instance = NULL; + eh->custom.dl_handle = NULL; +} + /** * @brief Release the given handle. */ @@ -1610,8 +1693,7 @@ nns_edge_release_handle (nns_edge_h edge_h) return NNS_EDGE_ERROR_INVALID_PARAMETER; } - if (eh->is_started) - nns_edge_stop (eh); + nns_edge_stop (eh); nns_edge_lock (eh); @@ -1629,12 +1711,7 @@ nns_edge_release_handle (nns_edge_h edge_h) break; case NNS_EDGE_CONNECT_TYPE_CUSTOM: { - NnsEdgeCustomDef *custom_h = (NnsEdgeCustomDef *) eh->custom_h; - int ret = custom_h->nns_edge_custom_close (eh->broker_h); - if (NNS_EDGE_ERROR_NONE != ret) { - nns_edge_loge ("Failed to stop MCF"); - } - dlclose (eh->custom_h); + _nns_edge_custom_release (eh); break; } default: @@ -1879,8 +1956,8 @@ nns_edge_connect (nns_edge_h edge_h, const char *dest_host, int dest_port) goto done; } } else if (NNS_EDGE_CONNECT_TYPE_CUSTOM == eh->connect_type) { - NnsEdgeCustomDef *custom_h = (NnsEdgeCustomDef *) eh->custom_h; - ret = custom_h->nns_edge_custom_connect (eh->broker_h); + nns_edge_custom_s *custom_h = (nns_edge_custom_s *) eh->custom.instance; + ret = custom_h->nns_edge_custom_connect (eh->custom.priv); if (ret != NNS_EDGE_ERROR_NONE) { nns_edge_loge ("Failed to connect to custom connection."); goto done; @@ -1952,8 +2029,8 @@ nns_edge_is_connected (nns_edge_h edge_h) return NNS_EDGE_ERROR_NONE; if (NNS_EDGE_CONNECT_TYPE_CUSTOM == eh->connect_type) { - NnsEdgeCustomDef *custom_h = (NnsEdgeCustomDef *) eh->custom_h; - return custom_h->nns_edge_custom_is_connected (eh->broker_h); + nns_edge_custom_s *custom_h = (nns_edge_custom_s *) eh->custom.instance; + return custom_h->nns_edge_custom_is_connected (eh->custom.priv); } conn_data = (nns_edge_conn_data_s *) eh->connections; @@ -2127,8 +2204,8 @@ nns_edge_set_info (nns_edge_h edge_h, const char *key, const char *value) } if (NNS_EDGE_CONNECT_TYPE_CUSTOM == eh->connect_type) { - NnsEdgeCustomDef *custom_h = (NnsEdgeCustomDef *) eh->custom_h; - ret = custom_h->nns_edge_custom_set_option (eh->broker_h, key, value); + nns_edge_custom_s *custom_h = (nns_edge_custom_s *) eh->custom.instance; + ret = custom_h->nns_edge_custom_set_option (eh->custom.priv, key, value); } nns_edge_unlock (eh); @@ -2195,8 +2272,8 @@ nns_edge_get_info (nns_edge_h edge_h, const char *key, char **value) } if (NNS_EDGE_CONNECT_TYPE_CUSTOM == eh->connect_type) { - NnsEdgeCustomDef *custom_h = (NnsEdgeCustomDef *) eh->custom_h; - *value = custom_h->nns_edge_custom_get_option (eh->broker_h, key); + nns_edge_custom_s *custom_h = (nns_edge_custom_s *) eh->custom.instance; + *value = custom_h->nns_edge_custom_get_option (eh->custom.priv, key); } nns_edge_unlock (eh); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 8b50342..0d84476 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -4,6 +4,20 @@ TARGET_INCLUDE_DIRECTORIES(unittest_nnstreamer-edge PRIVATE ${EDGE_REQUIRE_PKGS_ TARGET_LINK_LIBRARIES(unittest_nnstreamer-edge ${TEST_REQUIRE_PKGS_LDFLAGS} ${NNS_EDGE_LIB_NAME}) INSTALL (TARGETS unittest_nnstreamer-edge DESTINATION ${BIN_INSTALL_DIR}) +# Custom connection lib for unit test +SET(NNS_EDGE_CUSTOM_LIB_NAME nnstreamer-edge-custom-test) +SET(NNS_EDGE_CUSTOM_SRCS ${NNS_EDGE_SRCS} nnstreamer-edge-custom.c) +ADD_LIBRARY(${NNS_EDGE_CUSTOM_LIB_NAME} SHARED ${NNS_EDGE_CUSTOM_SRCS}) +SET_TARGET_PROPERTIES(${NNS_EDGE_CUSTOM_LIB_NAME} PROPERTIES VERSION ${SO_VERSION}) +TARGET_INCLUDE_DIRECTORIES(${NNS_EDGE_CUSTOM_LIB_NAME} PRIVATE ${EDGE_REQUIRE_PKGS_INCLUDE_DIRS} ${INCLUDE_DIR} ${NNS_EDGE_SRC_DIR}) +TARGET_LINK_LIBRARIES(${NNS_EDGE_CUSTOM_LIB_NAME} ${TEST_REQUIRE_PKGS_LDFLAGS} ${NNS_EDGE_LIB_NAME}) +INSTALL (TARGETS ${NNS_EDGE_CUSTOM_LIB_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR}) + +ADD_EXECUTABLE(unittest_nnstreamer-edge-custom unittest_nnstreamer-edge-custom.cc) +TARGET_INCLUDE_DIRECTORIES(unittest_nnstreamer-edge-custom PRIVATE ${EDGE_REQUIRE_PKGS_INCLUDE_DIRS} ${INCLUDE_DIR} ${NNS_EDGE_SRC_DIR}) +TARGET_LINK_LIBRARIES(unittest_nnstreamer-edge-custom ${TEST_REQUIRE_PKGS_LDFLAGS} ${NNS_EDGE_LIB_NAME} ${NNS_EDGE_CUSTOM_LIB_NAME}) +INSTALL (TARGETS unittest_nnstreamer-edge-custom DESTINATION ${BIN_INSTALL_DIR}) + # AITT test IF(AITT_SUPPORT) ADD_EXECUTABLE(unittest_nnstreamer-edge-aitt unittest_nnstreamer-edge-aitt.cc) diff --git a/tests/nnstreamer-edge-custom.c b/tests/nnstreamer-edge-custom.c new file mode 100644 index 0000000..7dc6586 --- /dev/null +++ b/tests/nnstreamer-edge-custom.c @@ -0,0 +1,201 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/** + * Copyright (C) 2024 Gichan Jang + * + * @file nnstreamer-edge-custom.c + * @date 16 Aug 2024 + * @brief NNStreamer-edge custom connection for test. + * @see https://github.com/nnstreamer/nnstreamer-edge + * @author Gichan Jang + * @bug No known bugs except for NYI items + */ + +#include "nnstreamer-edge-custom.h" +#include "nnstreamer-edge-log.h" +#include "nnstreamer-edge-util.h" +#include "nnstreamer-edge.h" + +typedef struct +{ + int is_connected; + char *peer_address; + nns_edge_event_cb event_cb; + void *user_data; +} nns_edge_custom_test_s; + +static int +nns_edge_custom_close (void *priv) +{ + if (!priv) { + nns_edge_loge ("Invalid param, priv should not be null."); + return NNS_EDGE_ERROR_INVALID_PARAMETER; + } + nns_edge_custom_test_s *custom_h = (nns_edge_custom_test_s *) priv; + + SAFE_FREE (custom_h->peer_address); + SAFE_FREE (custom_h); + + return NNS_EDGE_ERROR_NONE; +} + +static const char * +nns_edge_custom_get_description () +{ + return "custom"; +} + +static int +nns_edge_custom_create (void **priv) +{ + if (!priv) { + nns_edge_loge ("Invalid param, handle should not be null."); + return NNS_EDGE_ERROR_INVALID_PARAMETER; + } + + nns_edge_custom_test_s *custom_h = (nns_edge_custom_test_s *) calloc (1, sizeof (nns_edge_custom_test_s)); + if (!custom_h) { + nns_edge_loge ("Failed to allocate memory for edge custom handle."); + return NNS_EDGE_ERROR_OUT_OF_MEMORY; + } + + *priv = custom_h; + + return NNS_EDGE_ERROR_NONE; +} + +static int +nns_edge_custom_start (void *priv) +{ + if (!priv) { + nns_edge_loge ("Invalid param, priv should not be null."); + return NNS_EDGE_ERROR_INVALID_PARAMETER; + } + nns_edge_custom_test_s *custom_h = (nns_edge_custom_test_s *) priv; + custom_h->is_connected = 0; + + return NNS_EDGE_ERROR_NONE; +} + +static int +nns_edge_custom_stop (void *priv) +{ + if (!priv) { + nns_edge_loge ("Invalid param, priv should not be null."); + return NNS_EDGE_ERROR_INVALID_PARAMETER; + } + nns_edge_custom_test_s *custom_h = (nns_edge_custom_test_s *) priv; + custom_h->is_connected = 0; + + return NNS_EDGE_ERROR_NONE; +} + +static int +nns_edge_custom_connect (void *priv) +{ + if (!priv) { + nns_edge_loge ("Invalid param, priv is NULL"); + return NNS_EDGE_ERROR_INVALID_PARAMETER; + } + nns_edge_custom_test_s *custom_h = (nns_edge_custom_test_s *) priv; + custom_h->is_connected = 1; + + return NNS_EDGE_ERROR_NONE; +} + +static int +nns_edge_custom_subscribe (void *priv) +{ + return NNS_EDGE_ERROR_NOT_SUPPORTED; +} + +static int +nns_edge_custom_is_connected (void *priv) +{ + if (!priv) { + nns_edge_loge ("Invalid param, handle should not be null."); + return NNS_EDGE_ERROR_INVALID_PARAMETER; + } + nns_edge_custom_test_s *custom_h = (nns_edge_custom_test_s *) priv; + + if (custom_h->is_connected == 1) + return NNS_EDGE_ERROR_NONE; + + return NNS_EDGE_ERROR_CONNECTION_FAILURE; +} + +static int +nns_edge_custom_set_event_cb (void *priv, nns_edge_event_cb cb, void *user_data) +{ + if (!priv || !cb) { + nns_edge_loge ("Invalid param, cb(%p)", cb); + return NNS_EDGE_ERROR_INVALID_PARAMETER; + } + + return NNS_EDGE_ERROR_NONE; +} + +static int +nns_edge_custom_send_data (void *priv, nns_edge_data_h data_h) +{ + if (!priv || !data_h) { + nns_edge_loge ("Invalid param, data_h(%p)", data_h); + return NNS_EDGE_ERROR_INVALID_PARAMETER; + } + + return NNS_EDGE_ERROR_NONE; +} + +static int +nns_edge_custom_set_option (void *priv, const char *key, const char *value) +{ + if (!priv || !key || !value) { + nns_edge_loge ("Invalid param, key(%s), value(%s)", key, value); + return NNS_EDGE_ERROR_INVALID_PARAMETER; + } + nns_edge_custom_test_s *custom_h = (nns_edge_custom_test_s *) priv; + + if (strcasecmp (key, "PEER_ADDRESS") == 0) { + SAFE_FREE (custom_h->peer_address); + custom_h->peer_address = nns_edge_strdup (value); + } else { + nns_edge_loge ("key(%s) does not supported.", key); + return NNS_EDGE_ERROR_INVALID_PARAMETER; + } + + return NNS_EDGE_ERROR_NONE; +} + +static char * +nns_edge_custom_get_option (void *priv, const char *key) +{ + if (!priv || !key) { + nns_edge_loge ("Invalid param, key(%s)", key); + return NULL; + } + nns_edge_custom_test_s *custom_h = (nns_edge_custom_test_s *) priv; + if (strcasecmp (key, "PEER_ADDRESS") == 0) + return nns_edge_strdup (custom_h->peer_address); + + return NULL; +} + +nns_edge_custom_s edge_custom_h = { + .nns_edge_custom_get_description = nns_edge_custom_get_description, + .nns_edge_custom_create = nns_edge_custom_create, + .nns_edge_custom_close = nns_edge_custom_close, + .nns_edge_custom_start = nns_edge_custom_start, + .nns_edge_custom_stop = nns_edge_custom_stop, + .nns_edge_custom_connect = nns_edge_custom_connect, + .nns_edge_custom_subscribe = nns_edge_custom_subscribe, + .nns_edge_custom_is_connected = nns_edge_custom_is_connected, + .nns_edge_custom_set_event_cb = nns_edge_custom_set_event_cb, + .nns_edge_custom_send_data = nns_edge_custom_send_data, + .nns_edge_custom_set_option = nns_edge_custom_set_option, + .nns_edge_custom_get_option = nns_edge_custom_get_option +}; + +void * +nns_edge_custom_get_instance () +{ + return &edge_custom_h; +} diff --git a/tests/unittest_nnstreamer-edge-custom.cc b/tests/unittest_nnstreamer-edge-custom.cc new file mode 100644 index 0000000..49c1b74 --- /dev/null +++ b/tests/unittest_nnstreamer-edge-custom.cc @@ -0,0 +1,148 @@ +/** + * @file unittest_nnstreamer-edge-custom.cc + * @date 20 Aug 2024 + * @brief Unittest for nnstreamer-edge custom connection. + * @see https://github.com/nnstreamer/nnstreamer-edge + * @author Gichan Jang + * @bug No known bugs + */ + +#include +#include "nnstreamer-edge.h" +#include "nnstreamer-edge-data.h" +#include "nnstreamer-edge-event.h" +#include "nnstreamer-edge-log.h" +#include "nnstreamer-edge-custom.h" + +/** + * @brief Create edge custom handle. + */ +TEST (edgeCustom, createHandle) +{ + int ret; + nns_edge_h edge_h = NULL; + ret = nns_edge_custom_create_handle ("temp_id", "libnnstreamer-edge-custom-test.so", + NNS_EDGE_NODE_TYPE_QUERY_SERVER, &edge_h); + ASSERT_EQ (NNS_EDGE_ERROR_NONE, ret); + ret = nns_edge_release_handle (edge_h); + EXPECT_EQ (NNS_EDGE_ERROR_NONE, ret); +} + +/** + * @brief Create edge custom handle - invalid param. + */ +TEST(edgeCustom, createHandleInvalidParam01_n) +{ + nns_edge_h edge_h; + int ret; + + ret = nns_edge_custom_create_handle ("temp-id", "libnnstreamer-edge-custom-test.so", + NNS_EDGE_NODE_TYPE_UNKNOWN, &edge_h); + EXPECT_NE (NNS_EDGE_ERROR_NONE, ret); +} + +/** + * @brief Create edge custom handle - invalid param. + */ +TEST(edgeCustom, createHandleInvalidParam02_n) +{ + int ret; + + ret = nns_edge_custom_create_handle ("temp-id", "libnnstreamer-edge-custom-test.so", + NNS_EDGE_NODE_TYPE_QUERY_SERVER, NULL); + EXPECT_NE (NNS_EDGE_ERROR_NONE, ret); +} + +/** + * @brief Create edge custom handle - invalid param. + */ +TEST(edgeCustom, createHandleInvalidParam03_n) +{ + nns_edge_h edge_h; + int ret; + + ret = nns_edge_custom_create_handle ("temp-id", NULL, + NNS_EDGE_NODE_TYPE_QUERY_SERVER, &edge_h); + EXPECT_NE (NNS_EDGE_ERROR_NONE, ret); +} + +/** + * @brief Edge event callback for test. + */ +static int +_test_edge_event_cb (nns_edge_event_h event_h, void *user_data) +{ + return NNS_EDGE_ERROR_NONE; +} + +/** + * @brief Check the return value of custom connection. + */ +TEST(edgeCustom, expectedReturn) +{ + int ret; + nns_edge_h edge_h = NULL; + nns_edge_data_h data_h = NULL; + char *ret_str = NULL; + + ret = nns_edge_custom_create_handle ("temp_id", "libnnstreamer-edge-custom-test.so", + NNS_EDGE_NODE_TYPE_QUERY_SERVER, &edge_h); + ASSERT_EQ (NNS_EDGE_ERROR_NONE, ret); + + ret = nns_edge_set_event_callback (edge_h, _test_edge_event_cb, NULL); + EXPECT_EQ (NNS_EDGE_ERROR_NONE, ret); + ret = nns_edge_set_info (edge_h, "PEER_ADDRESS", "TE:MP:AD:DR:ES:SS"); + EXPECT_EQ (NNS_EDGE_ERROR_NONE, ret); + ret = nns_edge_get_info (edge_h, "PEER_ADDRESS", &ret_str); + EXPECT_EQ (NNS_EDGE_ERROR_NONE, ret); + EXPECT_STREQ ("TE:MP:AD:DR:ES:SS", ret_str); + + ret = nns_edge_start (edge_h); + EXPECT_EQ (NNS_EDGE_ERROR_NONE, ret); + + ret = nns_edge_is_connected (edge_h); + EXPECT_EQ (NNS_EDGE_ERROR_CONNECTION_FAILURE, ret); + + ret = nns_edge_connect (edge_h, "temp", 3000); + EXPECT_EQ (NNS_EDGE_ERROR_NONE, ret); + ret = nns_edge_is_connected (edge_h); + EXPECT_EQ (NNS_EDGE_ERROR_NONE, ret); + + ret = nns_edge_data_create (&data_h); + EXPECT_EQ (NNS_EDGE_ERROR_NONE, ret); + ret = nns_edge_send (edge_h, data_h); + EXPECT_EQ (NNS_EDGE_ERROR_NONE, ret); + + ret = nns_edge_data_destroy (data_h); + EXPECT_EQ (NNS_EDGE_ERROR_NONE, ret); + ret = nns_edge_stop (edge_h); + EXPECT_EQ (NNS_EDGE_ERROR_NONE, ret); + ret = nns_edge_is_connected (edge_h); + EXPECT_EQ (NNS_EDGE_ERROR_CONNECTION_FAILURE, ret); + + ret = nns_edge_release_handle (edge_h); + EXPECT_EQ (NNS_EDGE_ERROR_NONE, ret); +} + +/** + * @brief Main gtest + */ +int +main (int argc, char **argv) +{ + int result = -1; + + try { + testing::InitGoogleTest (&argc, argv); + } catch (...) { + nns_edge_loge ("Catch exception, failed to init google test."); + } + + try { + result = RUN_ALL_TESTS (); + } catch (...) { + nns_edge_loge ("Catch exception, failed to run the unittest."); + } + + return result; +}