#include <gst/gstbuffer.h>
#include <gst/app/app.h>
#include <string.h>
+#include <curl/curl.h>
#include "ml-api-internal.h"
#include "ml-api-service.h"
if (g_ascii_strcasecmp (service_str, "model_raw") == 0) {
service_type = ML_REMOTE_SERVICE_TYPE_MODEL_RAW;
- } else if (g_ascii_strcasecmp (service_str, "model_url") == 0) {
- service_type = ML_REMOTE_SERVICE_TYPE_MODEL_URL;
+ } else if (g_ascii_strcasecmp (service_str, "model_uri") == 0) {
+ service_type = ML_REMOTE_SERVICE_TYPE_MODEL_URI;
} else if (g_ascii_strcasecmp (service_str, "pipeline_raw") == 0) {
service_type = ML_REMOTE_SERVICE_TYPE_PIPELINE_RAW;
- } else if (g_ascii_strcasecmp (service_str, "pipeline_url") == 0) {
- service_type = ML_REMOTE_SERVICE_TYPE_PIPELINE_URL;
+ } else if (g_ascii_strcasecmp (service_str, "pipeline_uri") == 0) {
+ service_type = ML_REMOTE_SERVICE_TYPE_PIPELINE_URI;
} else {
_ml_error_report ("Invalid service type: %s, Please check service type.",
service_str);
}
/**
+ * @brief Get ml remote service activation type.
+ */
+static gboolean
+_mlrs_parse_activate (gchar * activate)
+{
+ gboolean ret = TRUE;
+
+ if (g_ascii_strcasecmp (activate, "false") == 0) {
+ ret = FALSE;
+ }
+
+ return ret;
+}
+
+/**
+ * @brief Callback function for receving data using curl.
+ */
+static size_t
+curl_mem_write_cb (void *data, size_t size, size_t nmemb, void *clientp)
+{
+ size_t recv_size = size * nmemb;
+ GByteArray *array = (GByteArray *) clientp;
+
+ if (!array || !data || recv_size == 0)
+ return 0;
+
+ g_byte_array_append (array, data, recv_size);
+
+ return recv_size;
+}
+
+/**
+ * @brief Register model file given by the remote sender.
+ */
+static gboolean
+_mlrs_model_register (gchar * service_key, nns_edge_data_h data_h,
+ void *data, nns_size_t data_len)
+{
+ guint version = -1;
+ gchar *description = NULL;
+ gchar *name = NULL;
+ gchar *current_dir = g_get_current_dir ();
+ gchar *dir_path = NULL;
+ gchar *model_path = NULL;
+ gchar *activate = NULL;
+ gboolean active_bool = TRUE;
+ GError *error = NULL;
+ gboolean ret = TRUE;
+
+ nns_edge_data_get_info (data_h, "description", &description);
+ nns_edge_data_get_info (data_h, "name", &name);
+ nns_edge_data_get_info (data_h, "activate", &activate);
+ active_bool = _mlrs_parse_activate (activate);
+
+ dir_path = g_build_path ("/", current_dir, service_key, NULL);
+ g_mkdir_with_parents (dir_path, 0755);
+ model_path = g_build_path ("/", dir_path, name, NULL);
+
+ if (!g_file_set_contents (model_path, (char *) data, data_len, &error)) {
+ _ml_loge ("Failed to write data to file: %s",
+ error ? error->message : "unknown error");
+ g_clear_error (&error);
+ ret = FALSE;
+ goto error;
+ }
+
+ /**
+ * @todo Hashing the path. Where is the default path to save the model file?
+ */
+ if (ML_ERROR_NONE != ml_service_model_register (service_key, model_path,
+ active_bool, description, &version)) {
+ _ml_loge ("Failed to register model, service ket:%s", service_key);
+ ret = FALSE;
+ }
+error:
+ g_free (current_dir);
+ g_free (dir_path);
+ g_free (activate);
+ g_free (model_path);
+ g_free (description);
+ g_free (name);
+
+ return ret;
+}
+
+/**
+ * @brief Get data from gievn uri
+ */
+static gboolean
+_mlrs_get_data_from_uri (gchar * uri, GByteArray * array)
+{
+ CURL *curl;
+ CURLcode res;
+ gboolean ret = FALSE;
+
+ curl = curl_easy_init ();
+ if (curl) {
+ curl_easy_setopt (curl, CURLOPT_URL, (gchar *) uri);
+ curl_easy_setopt (curl, CURLOPT_FOLLOWLOCATION, 1L);
+ curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, curl_mem_write_cb);
+ curl_easy_setopt (curl, CURLOPT_WRITEDATA, (void *) array);
+
+ res = curl_easy_perform (curl);
+
+ if (res != CURLE_OK) {
+ _ml_loge ("curl_easy_perform failed: %s\n", curl_easy_strerror (res));
+ return FALSE;
+ }
+
+ curl_easy_cleanup (curl);
+ ret = TRUE;
+ }
+
+ return ret;
+}
+
+/**
* @brief Process ml remote service
*/
static int
}
switch (service_type) {
- case ML_REMOTE_SERVICE_TYPE_MODEL_URL:
- /** @todo Download the model file from given URL */
+ case ML_REMOTE_SERVICE_TYPE_MODEL_URI:
+ {
+ GByteArray *array = g_byte_array_new ();
+
+ if (!_mlrs_get_data_from_uri ((gchar *) data, array)) {
+ _ml_error_report_return (NNS_EDGE_ERROR_IO,
+ "Failed to get data from uri: %s.", (gchar *) data);
+ }
+ if (!_mlrs_model_register (service_key, data_h, array->data, array->len)) {
+ _ml_error_report ("Failed to register model downloaded from: %s.",
+ (gchar *) data);
+ ret = NNS_EDGE_ERROR_UNKNOWN;
+ }
+ g_byte_array_free (array, TRUE);
+ break;
+ }
case ML_REMOTE_SERVICE_TYPE_MODEL_RAW:
- /** @todo Save model file to given path and register the model */
+ {
+ if (!_mlrs_model_register (service_key, data_h, data, data_len)) {
+ _ml_error_report ("Failed to register model downloaded from: %s.",
+ (gchar *) data);
+ ret = NNS_EDGE_ERROR_UNKNOWN;
+ }
+ break;
+ }
+ case ML_REMOTE_SERVICE_TYPE_PIPELINE_URI:
+ {
+ GByteArray *array = g_byte_array_new ();
+
+ ret = _mlrs_get_data_from_uri ((gchar *) data, array);
+ if (!ret) {
+ _ml_error_report_return (ret,
+ "Failed to get data from uri: %s.", (gchar *) data);
+ }
+ ret = ml_service_set_pipeline (service_key, (gchar *) array->data);
+ g_byte_array_free (array, TRUE);
break;
- case ML_REMOTE_SERVICE_TYPE_PIPELINE_URL:
- /** @todo Download the pipeline description from given URL */
+ }
case ML_REMOTE_SERVICE_TYPE_PIPELINE_RAW:
- ml_service_set_pipeline (service_key, (gchar *) data);
+ ret = ml_service_set_pipeline (service_key, (gchar *) data);
break;
default:
- _ml_error_report
- ("Unknown service type or not supported yet. Service num: %d",
- service_type);
+ _ml_error_report ("Unknown service type or not supported yet. "
+ "Service num: %d", service_type);
break;
}
return ret;
nns_edge_data_h data_h = NULL;
int ret = NNS_EDGE_ERROR_NONE;
gchar *service_str = NULL;
+ gchar *description = NULL;
+ gchar *name = NULL;
+ gchar *activate = NULL;
check_feature_state (ML_FEATURE_SERVICE);
check_feature_state (ML_FEATURE_INFERENCE);
nns_edge_data_set_info (data_h, "service-type", service_str);
nns_edge_data_set_info (data_h, "service-key", service_key);
+ ml_option_get (option, "description", (void **) &description);
+ nns_edge_data_set_info (data_h, "description", description);
+ ml_option_get (option, "name", (void **) &name);
+ nns_edge_data_set_info (data_h, "name", name);
+ ml_option_get (option, "activate", (void **) &activate);
+ nns_edge_data_set_info (data_h, "activate", activate);
ret = nns_edge_data_add (data_h, data, data_len, NULL);
if (NNS_EDGE_ERROR_NONE != ret) {
_ml_error_report ("Failed to add camera data to the edge data.\n");
nns_edge_data_destroy (data_h);
+ return ret;
}
ret = nns_edge_send (remote_s->edge_h, data_h);
#include <gtest/gtest.h>
#include <gdbus-util.h>
#include <gio/gio.h>
+#include <glib/gstdio.h>
#include <ml-api-inference-pipeline-internal.h>
#include <ml-api-internal.h>
#include <ml-api-service-private.h>
status = ml_option_set (client_option_h, "node-type", client_node_type, g_free);
EXPECT_EQ (ML_ERROR_NONE, status);
- gchar *client_dest_host = g_strdup ("127.0.0.1");
- status = ml_option_set (client_option_h, "host", client_dest_host, g_free);
+ gchar *client_host = g_strdup ("127.0.0.1");
+ status = ml_option_set (client_option_h, "host", client_host, g_free);
EXPECT_EQ (ML_ERROR_NONE, status);
- guint dest_port = 3000;
- status = ml_option_set (client_option_h, "port", &dest_port, NULL);
+ guint port = _get_available_port ();
+ status = ml_option_set (client_option_h, "port", &port, NULL);
EXPECT_EQ (ML_ERROR_NONE, status);
gchar *client_connect_type = g_strdup ("TCP");
status = ml_option_set (server_option_h, "topic", topic, g_free);
EXPECT_EQ (ML_ERROR_NONE, status);
- status = ml_option_set (server_option_h, "dest-port", &dest_port, NULL);
+ status = ml_option_set (server_option_h, "dest-port", &port, NULL);
EXPECT_EQ (ML_ERROR_NONE, status);
gchar *server_connect_type = g_strdup ("TCP");
EXPECT_EQ (ML_ERROR_NONE, status);
}
+
+/**
+ * @brief use case of pipeline registration using ml remote service.
+ */
+TEST_F (MLRemoteService, registerPipelineURI)
+{
+ int status;
+
+ /**============= Prepare client ============= **/
+ ml_service_h client_h;
+ ml_option_h client_option_h = NULL;
+
+ status = ml_option_create (&client_option_h);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+
+ gchar *client_node_type = g_strdup ("remote_sender");
+ status = ml_option_set (client_option_h, "node-type", client_node_type, g_free);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+
+ gchar *client_host = g_strdup ("127.0.0.1");
+ status = ml_option_set (client_option_h, "host", client_host, g_free);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+
+ guint port = _get_available_port ();
+ status = ml_option_set (client_option_h, "port", &port, NULL);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+
+ gchar *client_connect_type = g_strdup ("TCP");
+ status = ml_option_set (client_option_h, "connect-type", client_connect_type, g_free);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+
+ gchar *topic = g_strdup ("remote_service_test_topic");
+ status = ml_option_set (client_option_h, "topic", topic, NULL);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+
+ status = ml_remote_service_create (client_option_h, &client_h);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+
+ /**============= Prepare server ============= **/
+ ml_service_h server_h;
+ ml_option_h server_option_h = NULL;
+ status = ml_option_create (&server_option_h);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+
+ gchar *server_node_type = g_strdup ("remote_receiver");
+ status = ml_option_set (server_option_h, "node-type", server_node_type, g_free);
+
+ gchar *dest_host = g_strdup ("127.0.0.1");
+ status = ml_option_set (server_option_h, "dest-host", dest_host, g_free);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+
+ status = ml_option_set (server_option_h, "topic", topic, g_free);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+
+ status = ml_option_set (server_option_h, "dest-port", &port, NULL);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+
+ gchar *server_connect_type = g_strdup ("TCP");
+ status = ml_option_set (server_option_h, "connect-type", server_connect_type, g_free);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+
+ status = ml_remote_service_create (server_option_h, &server_h);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+
+ ml_option_h remote_service_option_h = NULL;
+ status = ml_option_create (&remote_service_option_h);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+
+ gchar *service_type = g_strdup ("pipeline_uri");
+ ml_option_set (remote_service_option_h, "service-type", service_type, g_free);
+
+ gchar *service_key = g_strdup ("pipeline_test_key");
+ ml_option_set (remote_service_option_h, "service-key", service_key, g_free);
+
+ gchar *current_dir = g_get_current_dir ();
+ gchar *test_file_path = g_build_path ("/", current_dir, "test.pipeline", NULL);
+ const gchar *pipeline_desc = "fakesrc ! fakesink";
+
+ EXPECT_TRUE (g_file_set_contents (
+ test_file_path, pipeline_desc, strlen (pipeline_desc) + 1, NULL));
+
+ gchar *pipeline_uri = g_strdup_printf ("file://%s", test_file_path);
+ g_free (test_file_path);
+
+ status = ml_remote_service_register (client_h, remote_service_option_h,
+ pipeline_uri, strlen (pipeline_uri) + 1);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+
+ /** Wait for the server to register the pipeline. */
+ g_usleep (1000000);
+
+ gchar *ret_pipeline = NULL;
+ status = ml_service_get_pipeline (service_key, &ret_pipeline);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+ EXPECT_STREQ (pipeline_desc, ret_pipeline);
+
+ status = ml_service_delete_pipeline (service_key);
+ EXPECT_TRUE (status == ML_ERROR_NONE);
+
+ g_free (ret_pipeline);
+ g_free (pipeline_uri);
+ status = ml_service_destroy (server_h);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+ status = ml_service_destroy (client_h);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+ status = ml_option_destroy (server_option_h);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+ status = ml_option_destroy (remote_service_option_h);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+ status = ml_option_destroy (client_option_h);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+}
+
/**
* @brief Test ml_remote_service_create with invalid param.
*/
status = ml_option_set (option_h, "node-type", client_node_type, g_free);
EXPECT_EQ (ML_ERROR_NONE, status);
- gchar *client_dest_host = g_strdup ("127.0.0.1");
- status = ml_option_set (option_h, "dest-host", client_dest_host, g_free);
+ gchar *client_host = g_strdup ("127.0.0.1");
+ status = ml_option_set (option_h, "host", client_host, g_free);
EXPECT_EQ (ML_ERROR_NONE, status);
- guint dest_port = 1883;
- status = ml_option_set (option_h, "dest-port", &dest_port, NULL);
+ guint port = _get_available_port ();
+ status = ml_option_set (option_h, "port", &port, NULL);
EXPECT_EQ (ML_ERROR_NONE, status);
- gchar *client_connect_type = g_strdup ("HYBRID");
+ gchar *client_connect_type = g_strdup ("TCP");
status = ml_option_set (option_h, "connect-type", client_connect_type, g_free);
EXPECT_EQ (ML_ERROR_NONE, status);
- gchar *topic = g_strdup ("temp_test_topic");
- status = ml_option_set (option_h, "topic", topic, NULL);
+ status = ml_remote_service_create (option_h, &service_h);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+
+ status = ml_option_destroy (option_h);
EXPECT_EQ (ML_ERROR_NONE, status);
- status = ml_remote_service_create (option_h, &service_h);
+ ml_option_h remote_service_option_h = NULL;
+ status = ml_option_create (&remote_service_option_h);
EXPECT_EQ (ML_ERROR_NONE, status);
- status = ml_remote_service_register (NULL, option_h, str, len);
+ gchar *service_type = g_strdup ("pipeline_raw");
+ ml_option_set (remote_service_option_h, "service-type", service_type, g_free);
+
+ gchar *service_key = g_strdup ("pipeline_test_key");
+ ml_option_set (remote_service_option_h, "service-key", service_key, g_free);
+
+ g_autofree gchar *pipeline_desc = g_strdup ("fakesrc ! fakesink");
+ status = ml_remote_service_register (NULL, remote_service_option_h, str, len);
EXPECT_EQ (ML_ERROR_INVALID_PARAMETER, status);
status = ml_remote_service_register (service_h, NULL, str, len);
EXPECT_EQ (ML_ERROR_INVALID_PARAMETER, status);
- status = ml_remote_service_register (service_h, option_h, NULL, len);
+ status = ml_remote_service_register (service_h, remote_service_option_h, NULL, len);
EXPECT_EQ (ML_ERROR_INVALID_PARAMETER, status);
- status = ml_remote_service_register (service_h, option_h, str, 0);
+ status = ml_remote_service_register (service_h, remote_service_option_h, str, 0);
EXPECT_EQ (ML_ERROR_INVALID_PARAMETER, status);
- status = ml_option_destroy (option_h);
+ status = ml_option_destroy (remote_service_option_h);
EXPECT_EQ (ML_ERROR_NONE, status);
-
status = ml_service_destroy (service_h);
EXPECT_EQ (ML_ERROR_NONE, status);
}
+
+/**
+ * @brief use case of model registration using ml remote service.
+ */
+TEST_F (MLRemoteService, registerModel)
+{
+ int status;
+
+ /**============= Prepare client ============= **/
+ ml_service_h client_h;
+ ml_option_h client_option_h = NULL;
+
+ status = ml_option_create (&client_option_h);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+
+ gchar *client_node_type = g_strdup ("remote_sender");
+ status = ml_option_set (client_option_h, "node-type", client_node_type, g_free);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+
+ gchar *client_host = g_strdup ("127.0.0.1");
+ status = ml_option_set (client_option_h, "host", client_host, g_free);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+
+ guint port = _get_available_port ();
+ status = ml_option_set (client_option_h, "port", &port, NULL);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+
+ gchar *client_connect_type = g_strdup ("TCP");
+ status = ml_option_set (client_option_h, "connect-type", client_connect_type, g_free);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+
+ gchar *topic = g_strdup ("remote_service_test_topic");
+ status = ml_option_set (client_option_h, "topic", topic, NULL);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+
+ status = ml_remote_service_create (client_option_h, &client_h);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+
+ /**============= Prepare server ============= **/
+ ml_service_h server_h;
+ ml_option_h server_option_h = NULL;
+ status = ml_option_create (&server_option_h);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+
+ gchar *server_node_type = g_strdup ("remote_receiver");
+ status = ml_option_set (server_option_h, "node-type", server_node_type, g_free);
+
+ gchar *dest_host = g_strdup ("127.0.0.1");
+ status = ml_option_set (server_option_h, "dest-host", dest_host, g_free);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+
+ status = ml_option_set (server_option_h, "topic", topic, g_free);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+
+ status = ml_option_set (server_option_h, "dest-port", &port, NULL);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+
+ gchar *server_connect_type = g_strdup ("TCP");
+ status = ml_option_set (server_option_h, "connect-type", server_connect_type, g_free);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+
+ status = ml_remote_service_create (server_option_h, &server_h);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+
+ /** Set service option */
+ const gchar *root_path = g_getenv ("MLAPI_SOURCE_ROOT_PATH");
+ /* ml_remote_service_register () requires absolute path to model, ignore this case. */
+ if (root_path == NULL)
+ return;
+
+ gchar *test_model = g_build_filename (root_path, "tests", "test_models",
+ "models", "mobilenet_v1_1.0_224_quant.tflite", NULL);
+ EXPECT_TRUE (g_file_test (test_model, G_FILE_TEST_EXISTS));
+
+ gchar *contents = NULL;
+ gsize len = 0;
+ EXPECT_TRUE (g_file_get_contents (test_model, &contents, &len, NULL));
+
+ ml_option_h remote_service_option_h = NULL;
+ status = ml_option_create (&remote_service_option_h);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+
+ gchar *service_key = g_strdup ("model_registration_test_key");
+ ml_option_set (remote_service_option_h, "service-key", service_key, g_free);
+
+ gchar *service_type = g_strdup ("model_raw");
+ ml_option_set (remote_service_option_h, "service-type", service_type, g_free);
+
+ gchar *activate = g_strdup ("true");
+ ml_option_set (remote_service_option_h, "activate", activate, g_free);
+
+ gchar *description = g_strdup ("temp description for remote model registeration test");
+ ml_option_set (remote_service_option_h, "description", description, g_free);
+
+ gchar *name = g_strdup ("mobilenet_v1_1.0_224_quant.tflite");
+ ml_option_set (remote_service_option_h, "name", name, g_free);
+
+ status = ml_remote_service_register (client_h, remote_service_option_h, contents, len);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+
+ /** Wait for the server to register the pipeline. */
+ g_usleep (1000000);
+
+ // Get model file
+ ml_information_h activated_model_info;
+ status = ml_service_model_get_activated (service_key, &activated_model_info);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+ EXPECT_NE (activated_model_info, nullptr);
+
+ gchar *activated_model_path;
+ status = ml_information_get (activated_model_info, "path", (void **) &activated_model_path);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+
+ gchar *activated_model_contents = NULL;
+ gsize activated_model_len = 0;
+ EXPECT_TRUE (g_file_get_contents (activated_model_path,
+ &activated_model_contents, &activated_model_len, NULL));
+ EXPECT_EQ (len, activated_model_len);
+ EXPECT_EQ (memcmp (contents, activated_model_contents, len), 0);
+
+ status = ml_service_model_delete (service_key, 0U);
+ EXPECT_TRUE (status == ML_ERROR_NONE);
+
+ g_remove (activated_model_path);
+
+ g_free (contents);
+ g_free (test_model);
+ g_free (activated_model_contents);
+ status = ml_service_destroy (server_h);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+ status = ml_service_destroy (client_h);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+ status = ml_option_destroy (server_option_h);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+ status = ml_option_destroy (remote_service_option_h);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+ status = ml_option_destroy (client_option_h);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+ status = ml_information_destroy (activated_model_info);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+}
+
+/**
+ * @brief use case of model registration from URI using ml remote service.
+ */
+TEST_F (MLRemoteService, registerModelURI)
+{
+ int status;
+
+ /**============= Prepare client ============= **/
+ ml_service_h client_h;
+ ml_option_h client_option_h = NULL;
+
+ status = ml_option_create (&client_option_h);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+
+ gchar *client_node_type = g_strdup ("remote_sender");
+ status = ml_option_set (client_option_h, "node-type", client_node_type, g_free);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+
+ gchar *client_host = g_strdup ("127.0.0.1");
+ status = ml_option_set (client_option_h, "host", client_host, g_free);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+
+ guint port = _get_available_port ();
+ status = ml_option_set (client_option_h, "port", &port, NULL);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+
+ gchar *client_connect_type = g_strdup ("TCP");
+ status = ml_option_set (client_option_h, "connect-type", client_connect_type, g_free);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+
+ gchar *topic = g_strdup ("remote_service_test_topic");
+ status = ml_option_set (client_option_h, "topic", topic, NULL);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+
+ status = ml_remote_service_create (client_option_h, &client_h);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+
+ /**============= Prepare server ============= **/
+ ml_service_h server_h;
+ ml_option_h server_option_h = NULL;
+ status = ml_option_create (&server_option_h);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+
+ gchar *server_node_type = g_strdup ("remote_receiver");
+ status = ml_option_set (server_option_h, "node-type", server_node_type, g_free);
+
+ gchar *dest_host = g_strdup ("127.0.0.1");
+ status = ml_option_set (server_option_h, "dest-host", dest_host, g_free);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+
+ status = ml_option_set (server_option_h, "topic", topic, g_free);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+
+ status = ml_option_set (server_option_h, "dest-port", &port, NULL);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+
+ gchar *server_connect_type = g_strdup ("TCP");
+ status = ml_option_set (server_option_h, "connect-type", server_connect_type, g_free);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+
+ status = ml_remote_service_create (server_option_h, &server_h);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+
+ /** Prepare model register service */
+ const gchar *root_path = g_getenv ("MLAPI_SOURCE_ROOT_PATH");
+ /* ml_remote_service_register () requires absolute path to model, ignore this case. */
+ if (root_path == NULL)
+ return;
+
+ gchar *test_model_path = g_build_filename (root_path, "tests", "test_models",
+ "models", "mobilenet_v1_1.0_224_quant.tflite", NULL);
+ EXPECT_TRUE (g_file_test (test_model_path, G_FILE_TEST_EXISTS));
+
+ ml_option_h remote_service_option_h = NULL;
+ status = ml_option_create (&remote_service_option_h);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+
+ gchar *service_type = g_strdup ("model_uri");
+ ml_option_set (remote_service_option_h, "service-type", service_type, g_free);
+
+ gchar *service_key = g_strdup ("pipeline_test_key");
+ ml_option_set (remote_service_option_h, "service-key", service_key, g_free);
+
+ gchar *model_uri = g_strdup_printf ("file://%s", test_model_path);
+
+ gchar *activate = g_strdup ("true");
+ ml_option_set (remote_service_option_h, "activate", activate, g_free);
+
+ gchar *description = g_strdup ("temp descriptio for remote model register test");
+ ml_option_set (remote_service_option_h, "description", description, g_free);
+
+ gchar *name = g_strdup ("mobilenet_v1_1.0_224_quant.tflite");
+ ml_option_set (remote_service_option_h, "name", name, g_free);
+
+ status = ml_remote_service_register (
+ client_h, remote_service_option_h, model_uri, strlen (model_uri) + 1);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+ g_free (model_uri);
+
+ /** Wait for the server to register the pipeline. */
+ g_usleep (1000000);
+
+ gchar *contents = NULL;
+ gsize len = 0;
+ EXPECT_TRUE (g_file_get_contents (test_model_path, &contents, &len, NULL));
+
+ ml_information_h activated_model_info;
+ status = ml_service_model_get_activated (service_key, &activated_model_info);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+ EXPECT_NE (activated_model_info, nullptr);
+
+ gchar *activated_model_path;
+ status = ml_information_get (activated_model_info, "path", (void **) &activated_model_path);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+
+ gchar *activated_model_contents = NULL;
+ gsize activated_model_len = 0;
+ EXPECT_TRUE (g_file_get_contents (activated_model_path,
+ &activated_model_contents, &activated_model_len, NULL));
+ EXPECT_EQ (len, activated_model_len);
+ EXPECT_EQ (memcmp (contents, activated_model_contents, len), 0);
+
+ status = ml_service_model_delete (service_key, 0U);
+ EXPECT_TRUE (status == ML_ERROR_NONE);
+
+ status = g_remove (activated_model_path);
+ EXPECT_TRUE (status == 0);
+
+ g_free (contents);
+ g_free (activated_model_contents);
+ g_free (test_model_path);
+ status = ml_service_destroy (server_h);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+ status = ml_service_destroy (client_h);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+ status = ml_option_destroy (server_option_h);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+ status = ml_option_destroy (remote_service_option_h);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+ status = ml_option_destroy (client_option_h);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+ status = ml_information_destroy (activated_model_info);
+ EXPECT_EQ (ML_ERROR_NONE, status);
+}
+
/**
* @brief Main gtest
*/