#include <unittest_util.h>\r
#include <tensor_converter_custom.h>\r
#include <flatbuffers/flexbuffers.h>\r
+#include <gst/app/gstappsrc.h>\r
#include <nnstreamer_plugin_api_converter.h>\r
\r
#define TEST_TIMEOUT_MS (1000U)\r
}\r
\r
/**\r
+ * @brief Test data for tensor_conveter::flexbuf (dimension 24:1:1:1)\r
+ */\r
+const gint _test_frames1[24]\r
+ = { 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112,\r
+ 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124};\r
+\r
+/**\r
+ * @brief Test data for tensor_conveter::flexbuf (dimension 48:1:1:1)\r
+ */\r
+const gint _test_frames2[48]\r
+ = { 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112,\r
+ 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124,\r
+ 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212,\r
+ 1213, 1214, 1215, 1216, 1217, 1218, 1219, 1220, 1221, 1222, 1223, 1224 };\r
+\r
+/**\r
+ * @brief Callback for tensor sink signal.\r
+ */\r
+static void\r
+new_data_cb (GstElement *element, GstBuffer *buffer, gpointer user_data)\r
+{\r
+ (*(guint *)user_data)++;\r
+}\r
+\r
+/**\r
+ * @brief Test for dynamic dimension of the custom converter\r
+ */\r
+TEST (tensorConverterPython, dynamicDimension)\r
+{\r
+ GstBuffer *buf_0, *buf_1, *buf_2;\r
+ GstElement *appsrc_handle, *sink_handle;\r
+ const gchar *root_path = g_getenv ("NNSTREAMER_SOURCE_ROOT_PATH");\r
+ gchar *test_model;\r
+ GstPad *sink_pad;\r
+ GstCaps *caps;\r
+ GstStructure *structure;\r
+ GstTensorConfig config;\r
+ guint *data_received = NULL;\r
+\r
+ /** supposed to run test in build directory */\r
+ if (root_path == NULL)\r
+ root_path = "..";\r
+\r
+ test_model = g_build_filename (root_path, "tests", "test_models", "models",\r
+ "custom_converter_test.py", NULL);\r
+\r
+ gchar *str_pipeline = g_strdup_printf ("appsrc name=srcx ! application/octet-stream ! tensor_converter silent=false mode=custom-script:%s ! tensor_sink name=sinkx async=false", test_model);\r
+\r
+ GstElement *pipeline = gst_parse_launch (str_pipeline, NULL);\r
+ g_free (test_model);\r
+ g_free (str_pipeline);\r
+ ASSERT_NE (pipeline, nullptr);\r
+\r
+ appsrc_handle = gst_bin_get_by_name (GST_BIN (pipeline), "srcx");\r
+ EXPECT_NE (appsrc_handle, nullptr);\r
+\r
+ sink_handle = gst_bin_get_by_name (GST_BIN (pipeline), "sinkx");\r
+ EXPECT_NE (sink_handle, nullptr);\r
+\r
+ data_received = (guint *) g_malloc0 (sizeof (guint));\r
+ g_signal_connect (sink_handle, "new-data", (GCallback)new_data_cb, data_received);\r
+\r
+ buf_0 = gst_buffer_new_wrapped (g_memdup (_test_frames1, 24), 24);\r
+ buf_1 = gst_buffer_new_wrapped (g_memdup (_test_frames2, 48), 48);\r
+ buf_2 = gst_buffer_copy (buf_0);\r
+\r
+ EXPECT_EQ (setPipelineStateSync (pipeline, GST_STATE_PLAYING, UNITTEST_STATECHANGE_TIMEOUT), 0);\r
+ EXPECT_EQ (gst_app_src_push_buffer (GST_APP_SRC (appsrc_handle), buf_0), GST_FLOW_OK);\r
+ EXPECT_TRUE (wait_pipeline_process_buffers (data_received, 1, TEST_TIMEOUT_MS));\r
+\r
+ sink_pad = gst_element_get_static_pad (sink_handle, "sink");\r
+ EXPECT_NE (sink_pad, nullptr);\r
+ caps = gst_pad_get_current_caps (sink_pad);\r
+ EXPECT_NE (caps, nullptr);\r
+ structure = gst_caps_get_structure (caps, 0);\r
+ EXPECT_NE (structure, nullptr);\r
+ gst_tensor_config_from_structure (&config, structure);\r
+\r
+ EXPECT_EQ (24, config.info.dimension[0]);\r
+ EXPECT_EQ (1, config.info.dimension[1]);\r
+ EXPECT_EQ (1, config.info.dimension[2]);\r
+ EXPECT_EQ (1, config.info.dimension[3]);\r
+\r
+ gst_caps_unref (caps);\r
+\r
+ EXPECT_EQ (gst_app_src_push_buffer (GST_APP_SRC (appsrc_handle), buf_1), GST_FLOW_OK);\r
+ EXPECT_TRUE (wait_pipeline_process_buffers (data_received, 2, TEST_TIMEOUT_MS));\r
+\r
+ caps = gst_pad_get_current_caps (sink_pad);\r
+ EXPECT_NE (caps, nullptr);\r
+ structure = gst_caps_get_structure (caps, 0);\r
+ EXPECT_NE (structure, nullptr);\r
+ gst_tensor_config_from_structure (&config, structure);\r
+\r
+ EXPECT_EQ (48, config.info.dimension[0]);\r
+ EXPECT_EQ (1, config.info.dimension[1]);\r
+ EXPECT_EQ (1, config.info.dimension[2]);\r
+ EXPECT_EQ (1, config.info.dimension[3]);\r
+ gst_caps_unref (caps);\r
+\r
+ EXPECT_EQ (gst_app_src_push_buffer (GST_APP_SRC (appsrc_handle), buf_2), GST_FLOW_OK);\r
+ EXPECT_TRUE (wait_pipeline_process_buffers (data_received, 3, TEST_TIMEOUT_MS));\r
+\r
+ sink_pad = gst_element_get_static_pad (sink_handle, "sink");\r
+ EXPECT_NE (sink_pad, nullptr);\r
+ caps = gst_pad_get_current_caps (sink_pad);\r
+ EXPECT_NE (caps, nullptr);\r
+ structure = gst_caps_get_structure (caps, 0);\r
+ EXPECT_NE (structure, nullptr);\r
+ gst_tensor_config_from_structure (&config, structure);\r
+\r
+ EXPECT_EQ (24, config.info.dimension[0]);\r
+ EXPECT_EQ (1, config.info.dimension[1]);\r
+ EXPECT_EQ (1, config.info.dimension[2]);\r
+ EXPECT_EQ (1, config.info.dimension[3]);\r
+ gst_caps_unref (caps);\r
+\r
+ EXPECT_EQ (setPipelineStateSync (pipeline, GST_STATE_NULL, UNITTEST_STATECHANGE_TIMEOUT), 0);\r
+ g_usleep (100000);\r
+\r
+ EXPECT_EQ (3, *data_received);\r
+ g_free (data_received);\r
+ gst_object_unref (sink_handle);\r
+ gst_object_unref (appsrc_handle);\r
+ gst_object_unref (pipeline);\r
+}\r
+\r
+/**\r
+ * @brief Callback for tensor sink signal.\r
+ */\r
+static void\r
+new_data_cb_json (GstElement *element, GstBuffer *buffer, gpointer user_data)\r
+{\r
+ guint num_tensors;\r
+ GstMapInfo info_res;\r
+ gboolean mapped;\r
+ GstMemory *mem_res;\r
+ gchar * output;\r
+ (*(guint *)user_data)++;\r
+\r
+ num_tensors = gst_buffer_n_memory (buffer);\r
+ EXPECT_EQ (2U, num_tensors);\r
+\r
+ mem_res = gst_buffer_get_memory (buffer, 0);\r
+ mapped = gst_memory_map (mem_res, &info_res, GST_MAP_READ);\r
+ ASSERT_TRUE (mapped);\r
+ output = (gchar *)info_res.data;\r
+ EXPECT_STREQ ("string_example", output);\r
+ gst_memory_unmap (mem_res, &info_res);\r
+ gst_memory_unref (mem_res);\r
+}\r
+\r
+/**\r
+ * @brief Test for python json parser of the custom converter\r
+ */\r
+TEST (tensorConverterPython, jsonParser)\r
+{\r
+ GstElement *sink_handle;\r
+ const gchar *root_path = g_getenv ("NNSTREAMER_SOURCE_ROOT_PATH");\r
+ gchar *test_model, *data_file;\r
+ guint *data_received = NULL;\r
+ /** supposed to run test in build directory */\r
+ if (root_path == NULL)\r
+ root_path = "..";\r
+\r
+ test_model = g_build_filename (root_path, "tests", "test_models", "models",\r
+ "custom_converter_json.py", NULL);\r
+ data_file = g_build_filename (root_path, "tests", "test_models", "data",\r
+ "example.json", NULL);\r
+\r
+ gchar *str_pipeline = g_strdup_printf ("filesrc location=%s ! application/octet-stream ! tensor_converter silent=false mode=custom-script:%s ! tensor_sink name=sinkx", data_file, test_model);\r
+\r
+ GstElement *pipeline = gst_parse_launch (str_pipeline, NULL);\r
+ g_free (data_file);\r
+ g_free (test_model);\r
+ g_free (str_pipeline);\r
+ ASSERT_NE (pipeline, nullptr);\r
+\r
+ sink_handle = gst_bin_get_by_name (GST_BIN (pipeline), "sinkx");\r
+ EXPECT_NE (sink_handle, nullptr);\r
+\r
+ data_received = (guint *) g_malloc0 (sizeof (guint));\r
+ g_signal_connect (sink_handle, "new-data", (GCallback)new_data_cb_json, data_received);\r
+\r
+ EXPECT_EQ (setPipelineStateSync (pipeline, GST_STATE_PLAYING, UNITTEST_STATECHANGE_TIMEOUT), 0);\r
+ g_usleep (100000);\r
+\r
+ EXPECT_EQ (setPipelineStateSync (pipeline, GST_STATE_NULL, UNITTEST_STATECHANGE_TIMEOUT), 0);\r
+ g_usleep (100000);\r
+\r
+ EXPECT_EQ (1U, *data_received);\r
+\r
+ g_free (data_received);\r
+ gst_object_unref (sink_handle);\r
+ gst_object_unref (pipeline);\r
+}\r
+\r
+/**\r
+ * @brief Test for python custom converter with invalid param\r
+ */\r
+TEST (tensorConverterPython, openTwice)\r
+{\r
+ const gchar *root_path = g_getenv ("NNSTREAMER_SOURCE_ROOT_PATH");\r
+ const NNStreamerExternalConverter *ex;\r
+ void *py_core = NULL;\r
+ gchar *test_model1, *test_model2;\r
+\r
+ /** supposed to run test in build directory */\r
+ if (root_path == NULL)\r
+ root_path = "..";\r
+\r
+ ex = nnstreamer_converter_find ("python3");\r
+ ASSERT_NE (nullptr, ex);\r
+\r
+ test_model1 = g_build_filename (root_path, "tests", "test_models", "models",\r
+ "custom_converter_test.py", NULL);\r
+ test_model2 = g_build_filename (root_path, "tests", "test_models", "models",\r
+ "custom_converter_json.py", NULL);\r
+\r
+ EXPECT_EQ (0, ex->open (test_model1, &py_core));\r
+ /** Open with same python script */\r
+ EXPECT_EQ (1, ex->open (test_model1, &py_core));\r
+ /** Open with different python script */\r
+ EXPECT_EQ (0, ex->open (test_model2, &py_core));\r
+\r
+ ex->close (&py_core);\r
+ g_free (test_model1);\r
+ g_free (test_model2);\r
+}\r
+\r
+/**\r
+ * @brief Test for python custom converter with invalid param\r
+ */\r
+TEST (tensorConverterPython, invalidParam_n)\r
+{\r
+ const gchar *root_path = g_getenv ("NNSTREAMER_SOURCE_ROOT_PATH");\r
+ gchar *test_model, *data_file;\r
+ GstStateChangeReturn ret;\r
+\r
+ /** supposed to run test in build directory */\r
+ if (root_path == NULL)\r
+ root_path = "..";\r
+\r
+ test_model = g_build_filename (root_path, "tests", "test_models", "models",\r
+ "NOT_EXIST.py", NULL);\r
+ data_file = g_build_filename (root_path, "tests", "test_models", "data",\r
+ "example.json", NULL);\r
+\r
+ gchar *str_pipeline = g_strdup_printf ("filesrc location=%s blocksize=-1 ! application/octet-stream ! tensor_converter silent=false mode=custom-script:%s ! tensor_sink name=sinkx", data_file, test_model);\r
+\r
+ GstElement *pipeline = gst_parse_launch (str_pipeline, NULL);\r
+ g_free (test_model);\r
+ g_free (data_file);\r
+ g_free (str_pipeline);\r
+ ASSERT_NE (pipeline, nullptr);\r
+\r
+ gst_element_set_state (pipeline, GST_STATE_PLAYING);\r
+ g_usleep (100000);\r
+ ret = gst_element_get_state (pipeline, NULL, NULL, GST_CLOCK_TIME_NONE);\r
+ EXPECT_TRUE (ret == GST_STATE_CHANGE_FAILURE);\r
+\r
+ gst_object_unref (pipeline);\r
+}\r
+\r
+/**\r
+ * @brief Test for python custom converter with invalid param\r
+ */\r
+TEST (tensorConverterPython, invalidParam2_n)\r
+{\r
+ const NNStreamerExternalConverter *ex;\r
+ GstTensorsConfig config;\r
+\r
+ gst_tensors_config_init (&config);\r
+ ex = nnstreamer_converter_find ("python3");\r
+ ASSERT_NE (nullptr, ex);\r
+\r
+ EXPECT_EQ (FALSE, ex->get_out_config (NULL, &config));\r
+}\r
+\r
+/**\r
+ * @brief Test for python custom converter with invalid param\r
+ */\r
+TEST (tensorConverterPython, invalidParam3_n)\r
+{\r
+ const NNStreamerExternalConverter *ex;\r
+ GstCaps *caps;\r
+\r
+ caps = gst_caps_from_string ("application/octet-stream");\r
+ ex = nnstreamer_converter_find ("python3");\r
+ ASSERT_NE (nullptr, ex);\r
+\r
+ EXPECT_EQ (FALSE, ex->get_out_config (caps, NULL));\r
+ g_usleep (100000);\r
+ gst_caps_unref (caps);\r
+}\r
+\r
+/**\r
+ * @brief Test for python custom converter with invalid param\r
+ */\r
+TEST (tensorConverterPython, invalidParam4_n)\r
+{\r
+ const gchar *root_path = g_getenv ("NNSTREAMER_SOURCE_ROOT_PATH");\r
+ const NNStreamerExternalConverter *ex;\r
+ void *py_core = NULL;\r
+ GstTensorsConfig config;\r
+ gchar *test_model;\r
+\r
+ gst_tensors_config_init (&config);\r
+ /** supposed to run test in build directory */\r
+ if (root_path == NULL)\r
+ root_path = "..";\r
+\r
+ ex = nnstreamer_converter_find ("python3");\r
+ ASSERT_NE (nullptr, ex);\r
+\r
+ test_model = g_build_filename (root_path, "tests", "test_models", "models",\r
+ "custom_converter_test.py", NULL);\r
+\r
+ EXPECT_EQ (0, ex->open (test_model, &py_core));\r
+ EXPECT_FALSE (ex->convert (NULL, &config, py_core));\r
+\r
+ ex->close (&py_core);\r
+ g_free (test_model);\r
+}\r
+\r
+/**\r
+ * @brief Test for python custom converter with invalid param\r
+ */\r
+TEST (tensorConverterPython, invalidParam5_n)\r
+{\r
+ const gchar *root_path = g_getenv ("NNSTREAMER_SOURCE_ROOT_PATH");\r
+ const NNStreamerExternalConverter *ex;\r
+ void *py_core = NULL;\r
+ gchar *test_model;\r
+ GstBuffer *buf;\r
+\r
+ /** supposed to run test in build directory */\r
+ if (root_path == NULL)\r
+ root_path = "..";\r
+\r
+ ex = nnstreamer_converter_find ("python3");\r
+ ASSERT_NE (nullptr, ex);\r
+\r
+ test_model = g_build_filename (root_path, "tests", "test_models", "models",\r
+ "custom_converter_test.py", NULL);\r
+ buf = gst_buffer_new ();\r
+ EXPECT_EQ (0, ex->open (test_model, &py_core));\r
+ EXPECT_FALSE (ex->convert (buf, NULL, py_core));\r
+\r
+ ex->close (&py_core);\r
+ g_free (test_model);\r
+ gst_buffer_unref (buf);\r
+}\r
+\r
+/**\r
+ * @brief Test for python custom converter with invalid param\r
+ */\r
+TEST (tensorConverterPython, invalidParam6_n)\r
+{\r
+ const gchar *root_path = g_getenv ("NNSTREAMER_SOURCE_ROOT_PATH");\r
+ const NNStreamerExternalConverter *ex;\r
+ void *py_core = NULL;\r
+ gchar *test_model;\r
+\r
+ /** supposed to run test in build directory */\r
+ if (root_path == NULL)\r
+ root_path = "..";\r
+\r
+ ex = nnstreamer_converter_find ("python3");\r
+ ASSERT_NE (nullptr, ex);\r
+\r
+ test_model = g_build_filename (root_path, "tests", "test_models", "models",\r
+ "invalid_class_custom_converter.py", NULL);\r
+ EXPECT_NE (0, ex->open (test_model, &py_core));\r
+\r
+ g_free (test_model);\r
+}\r
+\r
+/**\r
* @brief Main GTest\r
*/\r
int\r