test('unittest_filter_shared_model', unittest_filter_shared_model, timeout: 30, env: testenv)
endif
+
+ # Run unittest_datareposink
+ unittest_datareposink = executable('unittest_datareposink',
+ join_paths('nnstreamer_datarepo', 'unittest_datareposink.cc'),
+ dependencies: [nnstreamer_unittest_deps],
+ install: get_option('install-test'),
+ install_dir: unittest_install_dir
+ )
+
+ test('unittest_datareposink', unittest_datareposink, env: testenv)
+
+ # Run unittest_datareposrc
+ unittest_datareposrc = executable('unittest_datareposrc',
+ join_paths('nnstreamer_datarepo', 'unittest_datareposrc.cc'),
+ dependencies: [nnstreamer_unittest_deps],
+ install: get_option('install-test'),
+ install_dir: unittest_install_dir
+ )
+
+ test('unittest_datareposrc', unittest_datareposrc, env: testenv)
+
+ # Run unittest_trainer
+ unittest_trainer = executable('unittest_trainer',
+ join_paths('nnstreamer_trainer', 'unittest_trainer.cc'),
+ dependencies: [nnstreamer_unittest_deps],
+ install: get_option('install-test'),
+ install_dir: unittest_install_dir
+ )
+
+ test('unittest_trainer', unittest_trainer, env: testenv)
+
endif # gtest_dep.found()
tensor_filter_ext_enabled = tflite_support_is_available or \
--- /dev/null
+ /**
+ * @file unittest_datareposink.cc
+ * @date 21 Apr 2023
+ * @brief Unit test for datareposink
+ * @see https://github.com/nnstreamer/nnstreamer
+ * @author Hyunil Park <hyunil46.park@samsung.com>
+ * @bug No known bugs
+ */
+
+#include <gtest/gtest.h>
+#include <glib.h>
+#include <glib/gstdio.h>
+#include <gst/gst.h>
+#include <unittest_util.h>
+
+static const gchar filename[] = "mnist.data";
+static const gchar json[] = "mnist.json";
+
+/**
+ * @brief Get file path
+ */
+static gchar *
+get_file_path (const gchar * filename)
+{
+ const gchar *root_path = NULL;
+ gchar *file_path = NULL;
+
+ root_path = g_getenv ("NNSTREAMER_SOURCE_ROOT_PATH");
+
+ /** supposed to run test in build directory */
+ if (root_path == NULL)
+ root_path = "..";
+
+ file_path =
+ g_build_filename (root_path, "tests", "test_models", "data", "datarepo",
+ filename, NULL);
+
+ return file_path;
+}
+
+
+/**
+ * @brief Bus callback function
+ */
+static gboolean
+bus_callback (GstBus * bus, GstMessage * message, gpointer data)
+{
+ switch (GST_MESSAGE_TYPE (message)) {
+ case GST_MESSAGE_EOS:
+ g_main_loop_quit ((GMainLoop *) data);
+ break;
+ default:
+ break;
+ }
+
+ return TRUE;
+}
+
+/**
+ * @brief Test for writing image files
+ */
+TEST (datareposink, writeImageFiles)
+{
+ GError *error = NULL;
+ GFile *file = NULL;
+ gchar *contents = NULL;
+ gchar *filename = NULL;
+ GstBus *bus;
+ GMainLoop *loop;
+ gint i = 0;
+
+ loop = g_main_loop_new (NULL, FALSE);
+
+ gchar *str_pipeline =
+ g_strdup ("gst-launch-1.0 videotestsrc num-buffers=5 ! pngenc ! "
+ "datareposink location=image_%02d.png json=image.json");
+
+ GstElement *pipeline = gst_parse_launch (str_pipeline, NULL);
+ g_free (str_pipeline);
+
+ bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
+ ASSERT_NE (bus, nullptr);
+ gst_bus_add_watch (bus, bus_callback, loop);
+ gst_object_unref (bus);
+
+ setPipelineStateSync (pipeline, GST_STATE_PLAYING,
+ UNITTEST_STATECHANGE_TIMEOUT);
+ g_main_loop_run (loop);
+
+ setPipelineStateSync (pipeline, GST_STATE_NULL, UNITTEST_STATECHANGE_TIMEOUT);
+ gst_object_unref (pipeline);
+ g_main_loop_unref (loop);
+
+ /* Confirm file creation */
+ for (i = 0; i < 5; i++) {
+ filename = g_strdup_printf ("image_%02d.png", i);
+ file = g_file_new_for_path (filename);
+ g_file_load_contents (file, NULL, &contents, NULL, NULL, &error);
+ ASSERT_FALSE (error != NULL);
+ }
+
+ g_object_unref (file);
+ g_free (contents);
+ file = NULL;
+ g_free (filename);
+
+ /* Confirm file creation */
+ file = g_file_new_for_path ("image.json");
+ g_file_load_contents (file, NULL, &contents, NULL, NULL, &error);
+ ASSERT_FALSE (error != NULL);
+
+ g_object_unref (file);
+ g_free (contents);
+}
+
+/**
+ * @brief Test for writing an audio raw file
+ */
+TEST (datareposink, writeAudioRaw)
+{
+ GError *error = NULL;
+ GFile *file = NULL;
+ gchar *contents = NULL;
+ GstBus *bus;
+ GMainLoop *loop;
+
+ loop = g_main_loop_new (NULL, FALSE);
+
+ gchar *str_pipeline =
+ g_strdup
+ ("gst-launch-1.0 audiotestsrc samplesperbuffer=44100 num-buffers=1 ! "
+ "audio/x-raw, format=S16LE, layout=interleaved, rate=44100, channels=1 ! "
+ "datareposink location=audio.raw json=audio.json");
+
+ GstElement *pipeline = gst_parse_launch (str_pipeline, NULL);
+ g_free (str_pipeline);
+ ASSERT_NE (pipeline, nullptr);
+
+ bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
+ ASSERT_NE (bus, nullptr);
+ gst_bus_add_watch (bus, bus_callback, loop);
+ gst_object_unref (bus);
+
+ setPipelineStateSync (pipeline, GST_STATE_PLAYING,
+ UNITTEST_STATECHANGE_TIMEOUT);
+ g_main_loop_run (loop);
+
+ setPipelineStateSync (pipeline, GST_STATE_NULL, UNITTEST_STATECHANGE_TIMEOUT);
+ gst_object_unref (pipeline);
+ g_main_loop_unref (loop);
+
+ /* Confirm file creation */
+ file = g_file_new_for_path ("audio.raw");
+ g_file_load_contents (file, NULL, &contents, NULL, NULL, &error);
+ ASSERT_FALSE (error != NULL);
+
+ g_object_unref (file);
+ g_free (contents);
+ file = NULL;
+
+ /* Confirm file creation */
+ file = g_file_new_for_path ("audio.json");
+ g_file_load_contents (file, NULL, &contents, NULL, NULL, &error);
+ ASSERT_FALSE (error != NULL);
+
+ g_object_unref (file);
+ g_free (contents);
+}
+
+/**
+ * @brief Test for writing a video raw file
+ */
+TEST (datareposink, writeVideoRaw)
+{
+ GError *error = NULL;
+ GFile *file = NULL;
+ gchar *contents = NULL;
+ GstBus *bus;
+ GMainLoop *loop;
+
+ loop = g_main_loop_new (NULL, FALSE);
+
+ gchar *str_pipeline =
+ g_strdup ("gst-launch-1.0 videotestsrc num-buffers=10 ! "
+ "datareposink location=video.raw json=video.json");
+
+ GstElement *pipeline = gst_parse_launch (str_pipeline, NULL);
+ g_free (str_pipeline);
+ ASSERT_NE (pipeline, nullptr);
+
+ bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
+ ASSERT_NE (bus, nullptr);
+ gst_bus_add_watch (bus, bus_callback, loop);
+ gst_object_unref (bus);
+
+ setPipelineStateSync (pipeline, GST_STATE_PLAYING,
+ UNITTEST_STATECHANGE_TIMEOUT);
+ g_main_loop_run (loop);
+
+ setPipelineStateSync (pipeline, GST_STATE_NULL, UNITTEST_STATECHANGE_TIMEOUT);
+ gst_object_unref (pipeline);
+ g_main_loop_unref (loop);
+
+ /* Confirm file creation */
+ file = g_file_new_for_path ("video.raw");
+ g_file_load_contents (file, NULL, &contents, NULL, NULL, &error);
+ ASSERT_FALSE (error != NULL);
+
+ g_object_unref (file);
+ g_free (contents);
+ file = NULL;
+
+ /* Confirm file creation */
+ file = g_file_new_for_path ("video.json");
+ g_file_load_contents (file, NULL, &contents, NULL, NULL, &error);
+ ASSERT_FALSE (error != NULL);
+
+ g_object_unref (file);
+ g_free (contents);
+}
+
+/**
+ * @brief Test for writing a Tensors file
+ */
+TEST (datareposink, writeTensors)
+{
+ GError *error = NULL;
+ GFile *file = NULL;
+ gchar *contents = NULL;
+ GstBus *bus;
+ GMainLoop *loop;
+ gchar *file_path = NULL;
+ gchar *json_path = NULL;
+ GstElement *datareposink = NULL;
+ gchar *get_str = NULL;
+
+ loop = g_main_loop_new (NULL, FALSE);
+
+ file_path = get_file_path (filename);
+ json_path = get_file_path (json);
+
+ gchar *str_pipeline =
+ g_strdup_printf
+ ("gst-launch-1.0 datareposrc location=%s json=%s "
+ "start-sample-index=0 stop-sample-index=9 ! "
+ "other/tensors, format=static, num_tensors=2, framerate=0/1, "
+ "dimensions=1:1:784:1.1:1:10:1, types=float32.float32 ! "
+ "datareposink name=datareposink location=mnist.data json=mnist.json",
+ file_path, json_path);
+
+ GstElement *pipeline = gst_parse_launch (str_pipeline, NULL);
+ g_free (str_pipeline);
+ ASSERT_NE (pipeline, nullptr);
+
+ datareposink = gst_bin_get_by_name (GST_BIN (pipeline), "datareposink");
+ EXPECT_NE (datareposink, nullptr);
+
+ g_object_get (datareposink, "location", &get_str, NULL);
+ EXPECT_STREQ (get_str, "mnist.data");
+
+ g_object_get (datareposink, "json", &get_str, NULL);
+ EXPECT_STREQ (get_str, "mnist.json");
+
+ bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
+ ASSERT_NE (bus, nullptr);
+ gst_bus_add_watch (bus, bus_callback, loop);
+ gst_object_unref (bus);
+
+ setPipelineStateSync (pipeline, GST_STATE_PLAYING,
+ UNITTEST_STATECHANGE_TIMEOUT);
+ g_main_loop_run (loop);
+
+ setPipelineStateSync (pipeline, GST_STATE_NULL, UNITTEST_STATECHANGE_TIMEOUT);
+ gst_object_unref (pipeline);
+ g_main_loop_unref (loop);
+
+ /* Confirm file creation */
+ file = g_file_new_for_path ("mnist.data");
+ g_file_load_contents (file, NULL, &contents, NULL, NULL, &error);
+ ASSERT_FALSE (error != NULL);
+
+ g_object_unref (file);
+ g_free (contents);
+ file = NULL;
+
+ /* Confirm file creation */
+ file = g_file_new_for_path ("mnist.json");
+ g_file_load_contents (file, NULL, &contents, NULL, NULL, &error);
+ ASSERT_FALSE (error != NULL);
+
+ g_free (contents);
+ g_object_unref (file);
+ g_free (file_path);
+ g_free (json_path);
+
+}
+
+/**
+ * @brief Test for writing a file with invalid param (JSON path)
+ */
+TEST (datareposink, invalidJsonPath0_n)
+{
+ GstElement *datareposink = NULL;
+
+ gchar *str_pipeline =
+ g_strdup ("gst-launch-1.0 videotestsrc num-buffers=10 ! pngenc ! "
+ "datareposink name=datareposink");
+
+ GstElement *pipeline = gst_parse_launch (str_pipeline, NULL);
+ g_free (str_pipeline);
+
+ datareposink = gst_bin_get_by_name (GST_BIN (pipeline), "datareposink");
+ EXPECT_NE (datareposink, nullptr);
+
+ g_object_set (GST_OBJECT (datareposink), "location", "video.raw", NULL);
+ /* set invalid param */
+ g_object_set (GST_OBJECT (datareposink), "json", NULL, NULL);
+
+ /* state chagne failure is expected */
+ EXPECT_NE (setPipelineStateSync (pipeline, GST_STATE_PLAYING,
+ UNITTEST_STATECHANGE_TIMEOUT), 0);
+
+ gst_object_unref (pipeline);
+}
+
+/**
+ * @brief Test for writing a file with invalid param (file path)
+ */
+TEST (datareposink, invalidFilePath0_n)
+{
+ GstElement *datareposink = NULL;
+
+ gchar *str_pipeline =
+ g_strdup ("gst-launch-1.0 videotestsrc num-buffers=10 ! pngenc ! "
+ "datareposink name=datareposink");
+
+ GstElement *pipeline = gst_parse_launch (str_pipeline, NULL);
+ g_free (str_pipeline);
+ ASSERT_NE (pipeline, nullptr);
+
+ datareposink = gst_bin_get_by_name (GST_BIN (pipeline), "datareposink");
+ EXPECT_NE (datareposink, nullptr);
+
+ g_object_set (GST_OBJECT (datareposink), "json", "image.json", NULL);
+ /* set invalid param */
+ g_object_set (GST_OBJECT (datareposink), "location", NULL, NULL);
+
+ /* state chagne failure is expected */
+ EXPECT_NE (setPipelineStateSync (pipeline, GST_STATE_PLAYING,
+ UNITTEST_STATECHANGE_TIMEOUT), 0);
+
+ gst_object_unref (pipeline);
+}
+
+/**
+ * @brief Test for writing a file with video compression format
+ */
+TEST (datareposink, unsupportedVideoCaps0_n)
+{
+ gchar *str_pipeline =
+ g_strdup ("gst-launch-1.0 videotestsrc ! vp8enc ! "
+ "datareposink location=video.raw json=video.json");
+
+ GstElement *pipeline = gst_parse_launch (str_pipeline, NULL);
+ g_free (str_pipeline);
+ ASSERT_NE (pipeline, nullptr);
+
+ /* Could not to to GST_STATE_PLAYING state due to caps negotiation failure */
+ EXPECT_NE (setPipelineStateSync (pipeline, GST_STATE_PLAYING,
+ UNITTEST_STATECHANGE_TIMEOUT), 0);
+
+ gst_object_unref (pipeline);
+}
+
+/**
+ * @brief Test for writing a file with audio compression format
+ */
+TEST (datareposink, unsupportedAudioCaps0_n)
+{
+ gchar *str_pipeline =
+ g_strdup
+ ("gst-launch-1.0 audiotestsrc ! audio/x-raw,rate=44100,channels=2 ! wavenc ! "
+ "datareposink location=audio.raw json=audio.json");
+
+ GstElement *pipeline = gst_parse_launch (str_pipeline, NULL);
+ g_free (str_pipeline);
+ ASSERT_NE (pipeline, nullptr);
+
+ /* Could not to to GST_STATE_PLAYING state due to caps negotiation failure */
+ EXPECT_NE (setPipelineStateSync (pipeline, GST_STATE_PLAYING,
+ UNITTEST_STATECHANGE_TIMEOUT), 0);
+
+ gst_object_unref (pipeline);
+}
+
+/**
+ * @brief remove test file
+ */
+static void
+remove_test_file (void)
+{
+ gchar *filename = NULL;
+ int i;
+
+ g_remove ("audio.json");
+ g_remove ("audio.raw");
+ g_remove ("video.json");
+ g_remove ("video.raw");
+ g_remove ("mnist.json");
+ g_remove ("mnist.data");
+
+ for (i = 0; i < 5; i++) {
+ filename = g_strdup_printf ("image_%02d.png", i);
+ g_remove (filename);
+ }
+ g_free (filename);
+}
+
+/**
+ * @brief Main GTest
+ */
+int
+main (int argc, char **argv)
+{
+ int result = -1;
+
+ try {
+ testing::InitGoogleTest (&argc, argv);
+ } catch ( ...) {
+ g_warning ("catch 'testing::internal::<unnamed>::ClassUniqueToAlwaysTrue'");
+ }
+
+ gst_init (&argc, &argv);
+
+ try {
+ result = RUN_ALL_TESTS ();
+ } catch ( ...) {
+ g_warning ("catch `testing::internal::GoogleTestFailureException`");
+ }
+
+ remove_test_file ();
+
+ return result;
+}
--- /dev/null
+ /**
+ * @file unittest_datareposrc.cc
+ * @date 21 Apr 2023
+ * @brief Unit test for datareposrc
+ * @see https://github.com/nnstreamer/nnstreamer
+ * @author Hyunil Park <hyunil46.park@samsung.com>
+ * @bug No known bugs
+ */
+
+#include <gtest/gtest.h>
+#include <glib.h>
+#include <glib/gstdio.h>
+#include <gst/gst.h>
+#include <unittest_util.h>
+
+static const gchar filename[] = "mnist.data";
+static const gchar json[] = "mnist.json";
+
+/**
+ * @brief Get file path
+ */
+static gchar *
+get_file_path (const gchar * filename)
+{
+ const gchar *root_path = NULL;
+ gchar *file_path = NULL;
+
+ root_path = g_getenv ("NNSTREAMER_SOURCE_ROOT_PATH");
+
+ /** supposed to run test in build directory */
+ if (root_path == NULL)
+ root_path = "..";
+
+ file_path =
+ g_build_filename (root_path, "tests", "test_models", "data", "datarepo",
+ filename, NULL);
+
+ return file_path;
+}
+
+/**
+ * @brief Bus callback function
+ */
+static gboolean
+bus_callback (GstBus * bus, GstMessage * message, gpointer data)
+{
+ switch (GST_MESSAGE_TYPE (message)) {
+ case GST_MESSAGE_EOS:
+ g_main_loop_quit ((GMainLoop *) data);
+ break;
+ default:
+ break;
+ }
+
+ return TRUE;
+}
+
+/**
+ * @brief create video test file
+ */
+static void
+create_video_test_file ()
+{
+ GstBus *bus;
+ GMainLoop *loop;
+
+ loop = g_main_loop_new (NULL, FALSE);
+
+ gchar *str_pipeline =
+ g_strdup ("gst-launch-1.0 videotestsrc num-buffers=10 ! "
+ "datareposink location=video1.raw json=video1.json");
+
+ GstElement *pipeline = gst_parse_launch (str_pipeline, NULL);
+ g_free (str_pipeline);
+ ASSERT_NE (pipeline, nullptr);
+
+ bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
+ ASSERT_NE (bus, nullptr);
+ gst_bus_add_watch (bus, bus_callback, loop);
+ gst_object_unref (bus);
+
+ setPipelineStateSync (pipeline, GST_STATE_PLAYING,
+ UNITTEST_STATECHANGE_TIMEOUT);
+ g_main_loop_run (loop);
+
+ setPipelineStateSync (pipeline, GST_STATE_NULL, UNITTEST_STATECHANGE_TIMEOUT);
+ gst_object_unref (pipeline);
+ g_main_loop_unref (loop);
+}
+
+/**
+ * @brief create audio test file
+ */
+static void
+create_audio_test_file ()
+{
+ GstBus *bus;
+ GMainLoop *loop;
+
+ loop = g_main_loop_new (NULL, FALSE);
+
+ gchar *str_pipeline =
+ g_strdup
+ ("gst-launch-1.0 audiotestsrc samplesperbuffer=44100 num-buffers=1 ! "
+ "audio/x-raw, format=S16LE, layout=interleaved, rate=44100, channels=1 ! "
+ "datareposink location=audio1.raw json=audio1.json");
+
+ GstElement *pipeline = gst_parse_launch (str_pipeline, NULL);
+ g_free (str_pipeline);
+ ASSERT_NE (pipeline, nullptr);
+
+ bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
+ ASSERT_NE (bus, nullptr);
+ gst_bus_add_watch (bus, bus_callback, loop);
+ gst_object_unref (bus);
+
+ setPipelineStateSync (pipeline, GST_STATE_PLAYING,
+ UNITTEST_STATECHANGE_TIMEOUT);
+ g_main_loop_run (loop);
+
+ setPipelineStateSync (pipeline, GST_STATE_NULL, UNITTEST_STATECHANGE_TIMEOUT);
+ gst_object_unref (pipeline);
+ g_main_loop_unref (loop);
+}
+
+/**
+ * @brief create image test file
+ */
+static void
+create_image_test_file ()
+{
+ GstBus *bus;
+ GMainLoop *loop;
+
+ loop = g_main_loop_new (NULL, FALSE);
+
+ gchar *str_pipeline =
+ g_strdup ("gst-launch-1.0 videotestsrc num-buffers=5 ! pngenc ! "
+ "datareposink location=img_%02d.png json=img.json");
+
+ GstElement *pipeline = gst_parse_launch (str_pipeline, NULL);
+ g_free (str_pipeline);
+ ASSERT_NE (pipeline, nullptr);
+
+ bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
+ ASSERT_NE (bus, nullptr);
+ gst_bus_add_watch (bus, bus_callback, loop);
+ gst_object_unref (bus);
+
+ setPipelineStateSync (pipeline, GST_STATE_PLAYING,
+ UNITTEST_STATECHANGE_TIMEOUT);
+ g_main_loop_run (loop);
+
+ setPipelineStateSync (pipeline, GST_STATE_NULL, UNITTEST_STATECHANGE_TIMEOUT);
+ gst_object_unref (pipeline);
+ g_main_loop_unref (loop);
+}
+
+/**
+ * @brief Test for reading image files
+ */
+TEST (datareposrc, readImageFiles)
+{
+ GstBus *bus;
+ GMainLoop *loop;
+
+ create_image_test_file ();
+
+ loop = g_main_loop_new (NULL, FALSE);
+
+ gchar *str_pipeline =
+ g_strdup ("gst-launch-1.0 datareposrc "
+ "location=img_%02d.png "
+ "json=img.json "
+ "start-sample-index=0 stop-sample-index=4 ! pngdec ! fakesink");
+ GstElement *pipeline = gst_parse_launch (str_pipeline, NULL);
+ g_free (str_pipeline);
+ ASSERT_NE (pipeline, nullptr);
+
+ bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
+ ASSERT_NE (bus, nullptr);
+ gst_bus_add_watch (bus, bus_callback, loop);
+ gst_object_unref (bus);
+
+ EXPECT_EQ (setPipelineStateSync (pipeline, GST_STATE_PLAYING,
+ UNITTEST_STATECHANGE_TIMEOUT), 0);
+
+ g_main_loop_run (loop);
+
+ setPipelineStateSync (pipeline, GST_STATE_NULL, UNITTEST_STATECHANGE_TIMEOUT);
+ gst_object_unref (pipeline);
+ g_main_loop_unref (loop);
+}
+
+/**
+ * @brief Test for reading a video raw file
+ */
+TEST (datareposrc, readVideoRaw)
+{
+ GstBus *bus;
+ GMainLoop *loop;
+
+ create_video_test_file ();
+
+ loop = g_main_loop_new (NULL, FALSE);
+
+ gchar *str_pipeline =
+ g_strdup ("gst-launch-1.0 datareposrc "
+ "location=video1.raw "
+ "json=video1.json ! "
+ "video/x-raw, format=RGBx, width=320, height=240, framerate=30/1 ! fakesink");
+ GstElement *pipeline = gst_parse_launch (str_pipeline, NULL);
+ g_free (str_pipeline);
+ ASSERT_NE (pipeline, nullptr);
+
+ bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
+ ASSERT_NE (bus, nullptr);
+ gst_bus_add_watch (bus, bus_callback, loop);
+ gst_object_unref (bus);
+
+ EXPECT_EQ (setPipelineStateSync (pipeline, GST_STATE_PLAYING,
+ UNITTEST_STATECHANGE_TIMEOUT), 0);
+
+ g_main_loop_run (loop);
+
+ setPipelineStateSync (pipeline, GST_STATE_NULL, UNITTEST_STATECHANGE_TIMEOUT);
+ gst_object_unref (pipeline);
+ g_main_loop_unref (loop);
+}
+
+/**
+ * @brief Test for reading a video raw file
+ */
+TEST (datareposrc, readAudioRaw)
+{
+ GstBus *bus;
+ GMainLoop *loop;
+
+ create_audio_test_file ();
+
+ loop = g_main_loop_new (NULL, FALSE);
+
+ gchar *str_pipeline =
+ g_strdup ("gst-launch-1.0 datareposrc "
+ "location=audio1.raw "
+ "json=audio1.json ! "
+ "audio/x-raw, format=S16LE, rate=44100, channels=1, layout=interleaved ! fakesink ");
+ GstElement *pipeline = gst_parse_launch (str_pipeline, NULL);
+ g_free (str_pipeline);
+ ASSERT_NE (pipeline, nullptr);
+
+ bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
+ ASSERT_NE (bus, nullptr);
+ gst_bus_add_watch (bus, bus_callback, loop);
+ gst_object_unref (bus);
+
+ EXPECT_EQ (setPipelineStateSync (pipeline, GST_STATE_PLAYING,
+ UNITTEST_STATECHANGE_TIMEOUT), 0);
+
+ g_main_loop_run (loop);
+
+ setPipelineStateSync (pipeline, GST_STATE_NULL, UNITTEST_STATECHANGE_TIMEOUT);
+ gst_object_unref (pipeline);
+ g_main_loop_unref (loop);
+}
+
+/**
+ * @brief Test for reading a file with invalid param (JSON path)
+ */
+TEST (datareposrc, invalidJsonPath0_n)
+{
+ GstElement *datareposrc = NULL;
+
+ gchar *str_pipeline =
+ g_strdup ("gst-launch-1.0 datareposrc name=datareposrc ! "
+ "video/x-raw, format=RGBx, width=320, height=240, framerate=30/1 ! fakesink");
+ GstElement *pipeline = gst_parse_launch (str_pipeline, NULL);
+ g_free (str_pipeline);
+ ASSERT_NE (pipeline, nullptr);
+
+ datareposrc = gst_bin_get_by_name (GST_BIN (pipeline), "datareposrc");
+ ASSERT_NE (datareposrc, nullptr);
+
+ g_object_set (GST_OBJECT (datareposrc), "location", "video1.raw", NULL);
+ /* set invalid param */
+ g_object_set (GST_OBJECT (datareposrc), "json", NULL, NULL);
+
+ /* state chagne failure is expected */
+ EXPECT_NE (setPipelineStateSync (pipeline, GST_STATE_PLAYING,
+ UNITTEST_STATECHANGE_TIMEOUT), 0);
+
+
+ gst_object_unref (pipeline);
+}
+
+/**
+ * @brief Test for reading a file with invalid param (JSON path)
+ */
+TEST (datareposrc, invalidJsonPath1_n)
+{
+ GstElement *datareposrc = NULL;
+
+ gchar *str_pipeline =
+ g_strdup ("gst-launch-1.0 datareposrc name=datareposrc ! "
+ "video/x-raw, format=RGBx, width=320, height=240, framerate=30/1 ! fakesink");
+ GstElement *pipeline = gst_parse_launch (str_pipeline, NULL);
+ g_free (str_pipeline);
+ ASSERT_NE (pipeline, nullptr);
+
+ datareposrc = gst_bin_get_by_name (GST_BIN (pipeline), "datareposrc");
+ ASSERT_NE (datareposrc, nullptr);
+
+ g_object_set (GST_OBJECT (datareposrc), "location", "video1.raw", NULL);
+ /* set invalid param */
+ g_object_set (GST_OBJECT (datareposrc), "json", "no_search_file", NULL);
+
+ /* state chagne failure is expected */
+ EXPECT_NE (setPipelineStateSync (pipeline, GST_STATE_PLAYING,
+ UNITTEST_STATECHANGE_TIMEOUT), 0);
+
+ setPipelineStateSync (pipeline, GST_STATE_NULL, UNITTEST_STATECHANGE_TIMEOUT);
+
+ gst_object_unref (pipeline);
+}
+
+/**
+ * @brief Test for reading a file with invalid param (File path)
+ */
+TEST (datareposrc, invalidFilePath0_n)
+{
+ GstElement *datareposrc = NULL;
+
+ gchar *str_pipeline =
+ g_strdup ("gst-launch-1.0 datareposrc name=datareposrc ! "
+ "video/x-raw, format=RGBx, width=320, height=240, framerate=30/1 ! fakesink");
+ GstElement *pipeline = gst_parse_launch (str_pipeline, NULL);
+ g_free (str_pipeline);
+ ASSERT_NE (pipeline, nullptr);
+
+ datareposrc = gst_bin_get_by_name (GST_BIN (pipeline), "datareposrc");
+ ASSERT_NE (datareposrc, nullptr);
+
+ g_object_set (GST_OBJECT (datareposrc), "json", "video1.json", NULL);
+ /* set invalid param */
+ g_object_set (GST_OBJECT (datareposrc), "location", NULL, NULL);
+
+ /* state chagne failure is expected */
+ EXPECT_NE (setPipelineStateSync (pipeline, GST_STATE_PLAYING,
+ UNITTEST_STATECHANGE_TIMEOUT), 0);
+
+ gst_object_unref (pipeline);
+}
+
+/**
+ * @brief Test for reading a file with invalid param (File path)
+ */
+TEST (datareposrc, invalidFilePath1_n)
+{
+ GstElement *datareposrc = NULL;
+
+ gchar *str_pipeline =
+ g_strdup ("gst-launch-1.0 datareposrc name=datareposrc ! "
+ "video/x-raw, format=RGBx, width=320, height=240, framerate=30/1 ! fakesink");
+ GstElement *pipeline = gst_parse_launch (str_pipeline, NULL);
+ g_free (str_pipeline);
+ ASSERT_NE (pipeline, nullptr);
+
+ datareposrc = gst_bin_get_by_name (GST_BIN (pipeline), "datareposrc");
+ ASSERT_NE (datareposrc, nullptr);
+
+ g_object_set (GST_OBJECT (datareposrc), "json", "video1.json", NULL);
+ /* set invalid param */
+ g_object_set (GST_OBJECT (datareposrc), "location", "no_search_file", NULL);
+
+ /* state chagne failure is expected */
+ EXPECT_NE (setPipelineStateSync (pipeline, GST_STATE_PLAYING,
+ UNITTEST_STATECHANGE_TIMEOUT), 0);
+
+ gst_object_unref (pipeline);
+}
+
+/**
+ * @brief Test for reading a tensors file
+ * the number of total sample(mnist.data) is 10 (0~9)
+ * the number tensors is 2 and indices (0,1), default is (0,1)
+ * the default epochs is 1,
+ * the default shuffle is TRUE.
+ * can remove start-sample-index, epochs, tensors-sequence, shuffle property.
+ */
+TEST (datareposrc, readTensors)
+{
+ GstBus *bus;
+ GMainLoop *loop;
+ gchar *file_path = NULL;
+ gchar *json_path = NULL;
+ GstElement *datareposrc = NULL;
+ gchar *get_str;
+ guint get_value;
+
+ loop = g_main_loop_new (NULL, FALSE);
+
+ file_path = get_file_path (filename);
+ json_path = get_file_path (json);
+
+ gchar *str_pipeline =
+ g_strdup_printf
+ ("gst-launch-1.0 datareposrc name=datareposrc location=%s json=%s "
+ "start-sample-index=0 stop-sample-index=9 epochs=2 tensors-sequence=0,1 !"
+ "other/tensors, format=static, num_tensors=2, framerate=0/1, "
+ "dimensions=1:1:784:1.1:1:10:1, types=float32.float32 ! fakesink",
+ file_path, json_path);
+ GstElement *pipeline = gst_parse_launch (str_pipeline, NULL);
+ g_free (str_pipeline);
+ ASSERT_NE (pipeline, nullptr);
+
+ datareposrc = gst_bin_get_by_name (GST_BIN (pipeline), "datareposrc");
+ EXPECT_NE (datareposrc, nullptr);
+
+ bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
+ ASSERT_NE (bus, nullptr);
+ gst_bus_add_watch (bus, bus_callback, loop);
+ gst_object_unref (bus);
+
+ g_object_get (datareposrc, "location", &get_str, NULL);
+ EXPECT_STREQ (get_str, file_path);
+
+ g_object_get (datareposrc, "json", &get_str, NULL);
+ EXPECT_STREQ (get_str, json_path);
+
+ g_object_get (datareposrc, "tensors-sequence", &get_str, NULL);
+ EXPECT_STREQ (get_str, "0,1");
+
+ g_object_get (datareposrc, "is-shuffle", &get_value, NULL);
+ ASSERT_EQ (get_value, 1U);
+
+ EXPECT_EQ (setPipelineStateSync (pipeline, GST_STATE_PLAYING,
+ UNITTEST_STATECHANGE_TIMEOUT), 0);
+
+ g_main_loop_run (loop);
+
+ setPipelineStateSync (pipeline, GST_STATE_NULL, UNITTEST_STATECHANGE_TIMEOUT);
+
+ gst_object_unref (pipeline);
+ g_main_loop_unref (loop);
+ g_free (file_path);
+ g_free (json_path);
+}
+
+/**
+ * @brief Test for reading a file with invalid param (start-sample-index)
+ * the number of total sample(mnist.data) is 1000 (0~999)
+ */
+TEST (datareposrc, invalidStartSampleIndex0_n)
+{
+ GstElement *datareposrc = NULL;
+ int idx_out_of_range = 1000;
+ gchar *file_path = NULL;
+ gchar *json_path = NULL;
+
+ file_path = get_file_path (filename);
+ json_path = get_file_path (json);
+
+ gchar *str_pipeline =
+ g_strdup_printf
+ ("gst-launch-1.0 datareposrc name=datareposrc location=%s json=%s "
+ "stop-sample-index=9 epochs=2 tensors-sequence=0,1 !"
+ "other/tensors, format=static, num_tensors=2, framerate=0/1, "
+ "dimensions=1:1:784:1.1:1:10:1, types=float32.float32 ! fakesink",
+ file_path, json_path);
+ GstElement *pipeline = gst_parse_launch (str_pipeline, NULL);
+ g_free (str_pipeline);
+ g_free (file_path);
+ g_free (json_path);
+ ASSERT_NE (pipeline, nullptr);
+
+ datareposrc = gst_bin_get_by_name (GST_BIN (pipeline), "datareposrc");
+ ASSERT_NE (datareposrc, nullptr);
+
+ /* set invalid param */
+ g_object_set (GST_OBJECT (datareposrc), "start-sample-index",
+ idx_out_of_range, NULL);
+
+ /* state chagne failure is expected */
+ EXPECT_NE (setPipelineStateSync (pipeline, GST_STATE_PLAYING,
+ UNITTEST_STATECHANGE_TIMEOUT), 0);
+
+ gst_object_unref (pipeline);
+}
+
+/**
+ * @brief Test for reading a file with invalid param (start-sample-index)
+ * the number of total sample(mnist.data) is 10 (0~9)
+ */
+TEST (datareposrc, invalidStartSampleIndex1_n)
+{
+ GstElement *datareposrc = NULL;
+ gint idx_out_of_range = -1;
+ guint get_value;
+ gchar *file_path = NULL;
+ gchar *json_path = NULL;
+
+ file_path = get_file_path (filename);
+ json_path = get_file_path (json);
+
+ gchar *str_pipeline =
+ g_strdup_printf
+ ("gst-launch-1.0 datareposrc name=datareposrc location=%s json=%s "
+ "stop-sample-index=9 epochs=2 tensors-sequence=0,1 !"
+ "other/tensors, format=static, num_tensors=2, framerate=0/1, "
+ "dimensions=1:1:784:1.1:1:10:1, types=float32.float32 ! fakesink",
+ file_path, json_path);
+ GstElement *pipeline = gst_parse_launch (str_pipeline, NULL);
+ g_free (str_pipeline);
+ g_free (file_path);
+ g_free (json_path);
+ ASSERT_NE (pipeline, nullptr);
+
+ datareposrc = gst_bin_get_by_name (GST_BIN (pipeline), "datareposrc");
+ ASSERT_NE (datareposrc, nullptr);
+
+ /* set invalid param */
+ g_object_set (GST_OBJECT (datareposrc), "start-sample-index",
+ idx_out_of_range, NULL);
+ /** value "-1" of type 'gint' is invalid or out of range for property 'start-sample-index' of type 'gint'
+ default value is set */
+ g_object_get (GST_OBJECT (datareposrc), "start-sample-index", &get_value,
+ NULL);
+ EXPECT_EQ (get_value, 0U);
+
+ gst_object_unref (pipeline);
+}
+
+/**
+ * @brief Test for reading a file with invalid param (stop-sample-index)
+ * the number of total sample(mnist.data) is 1000 (0~999)
+ */
+TEST (datareposrc, invalidStopSampleIndex0_n)
+{
+ GstElement *datareposrc = NULL;
+ guint idx_out_of_range = 1000;
+ gchar *file_path = NULL;
+ gchar *json_path = NULL;
+
+ file_path = get_file_path (filename);
+ json_path = get_file_path (json);
+
+ gchar *str_pipeline =
+ g_strdup_printf
+ ("gst-launch-1.0 datareposrc name=datareposrc location=%s json=%s "
+ "start-sample-index=0 epochs=2 tensors-sequence=0,1 !"
+ "other/tensors, format=static, num_tensors=2, framerate=0/1, "
+ "dimensions=1:1:784:1.1:1:10:1, types=float32.float32 ! fakesink",
+ file_path, json_path);
+ GstElement *pipeline = gst_parse_launch (str_pipeline, NULL);
+ g_free (str_pipeline);
+ g_free (file_path);
+ g_free (json_path);
+ ASSERT_NE (pipeline, nullptr);
+
+ datareposrc = gst_bin_get_by_name (GST_BIN (pipeline), "datareposrc");
+ ASSERT_NE (datareposrc, nullptr);
+
+ g_object_set (GST_OBJECT (datareposrc), "stop-sample-index", idx_out_of_range,
+ NULL);
+
+ /* state chagne failure is expected */
+ EXPECT_NE (setPipelineStateSync (pipeline, GST_STATE_PLAYING,
+ UNITTEST_STATECHANGE_TIMEOUT), 0);
+
+ gst_object_unref (pipeline);
+}
+
+/**
+ * @brief Test for reading a file with invalid param (start-sample-index)
+ * the number of total sample(mnist.data) is 10 (0~9)
+ */
+TEST (datareposrc, invalidStopSampleIndex1_n)
+{
+ GstElement *datareposrc = NULL;
+ gint idx_out_of_range = -1;
+ guint get_value;
+ gchar *file_path = NULL;
+ gchar *json_path = NULL;
+
+ file_path = get_file_path (filename);
+ json_path = get_file_path (json);
+
+ gchar *str_pipeline =
+ g_strdup_printf
+ ("gst-launch-1.0 datareposrc name=datareposrc location=%s json=%s "
+ "start-sample-index=0 epochs=2 tensors-sequence=0,1 !"
+ "other/tensors, format=static, num_tensors=2, framerate=0/1, "
+ "dimensions=1:1:784:1.1:1:10:1, types=float32.float32 ! fakesink",
+ file_path, json_path);
+ GstElement *pipeline = gst_parse_launch (str_pipeline, NULL);
+ g_free (str_pipeline);
+ g_free (file_path);
+ g_free (json_path);
+ ASSERT_NE (pipeline, nullptr);
+
+ datareposrc = gst_bin_get_by_name (GST_BIN (pipeline), "datareposrc");
+ ASSERT_NE (datareposrc, nullptr);
+
+ /* set invalid param */
+ g_object_set (GST_OBJECT (datareposrc), "stop-sample-index", idx_out_of_range,
+ NULL);
+ /** value "-1" of type 'gint' is invalid or out of range for property 'start-sample-index' of type 'gint'
+ default value is set */
+ g_object_get (GST_OBJECT (datareposrc), "stop-sample-index", &get_value,
+ NULL);
+ EXPECT_EQ (get_value, 0U);
+
+ gst_object_unref (pipeline);
+}
+
+/**
+ * @brief Test for reading a file with invalid param (epochs)
+ */
+TEST (datareposrc, invalidEpochs0_n)
+{
+ GstElement *datareposrc = NULL;
+ gint invalid_epochs = -1;
+ guint get_value;
+ gchar *file_path = NULL;
+ gchar *json_path = NULL;
+
+ file_path = get_file_path (filename);
+ json_path = get_file_path (json);
+
+ gchar *str_pipeline =
+ g_strdup_printf
+ ("gst-launch-1.0 datareposrc name=datareposrc location=%s json=%s "
+ "start-sample-index=0 stop-sample-index=9 tensors-sequence=0,1 ! "
+ "other/tensors, format=static, num_tensors=2, framerate=0/1, "
+ "dimensions=1:1:784:1.1:1:10:1, types=float32.float32 ! fakesink",
+ file_path, json_path);
+ GstElement *pipeline = gst_parse_launch (str_pipeline, NULL);
+ g_free (str_pipeline);
+ g_free (file_path);
+ g_free (json_path);
+ ASSERT_NE (pipeline, nullptr);
+
+ datareposrc = gst_bin_get_by_name (GST_BIN (pipeline), "datareposrc");
+ ASSERT_NE (datareposrc, nullptr);
+
+ /* set invalid param */
+ g_object_set (GST_OBJECT (datareposrc), "epochs", invalid_epochs, NULL);
+ /** value "-1" of type 'gint' is invalid or out of range for property 'start-sample-index' of type 'gint'
+ default value is set */
+ g_object_get (GST_OBJECT (datareposrc), "epochs", &get_value, NULL);
+ EXPECT_EQ (get_value, 1U);
+
+ gst_object_unref (pipeline);
+}
+
+/**
+ * @brief Test for reading a file with invalid param (epochs)
+ */
+TEST (datareposrc, invalidEpochs1_n)
+{
+ GstElement *datareposrc = NULL;
+ guint invalid_epochs = 0;
+ gchar *file_path = NULL;
+ gchar *json_path = NULL;
+
+ file_path = get_file_path (filename);
+ json_path = get_file_path (json);
+
+ gchar *str_pipeline =
+ g_strdup_printf
+ ("gst-launch-1.0 datareposrc name=datareposrc location=%s json=%s "
+ "start-sample-index=0 stop-sample-index=9 tensors-sequence=0,1 ! "
+ "other/tensors, format=static, num_tensors=2, framerate=0/1, "
+ "dimensions=1:1:784:1.1:1:10:1, types=float32.float32 ! fakesink",
+ file_path, json_path);
+ GstElement *pipeline = gst_parse_launch (str_pipeline, NULL);
+ g_free (str_pipeline);
+ g_free (file_path);
+ g_free (json_path);
+ ASSERT_NE (pipeline, nullptr);
+
+ datareposrc = gst_bin_get_by_name (GST_BIN (pipeline), "datareposrc");
+ ASSERT_NE (datareposrc, nullptr);
+
+ /* set invalid param */
+ g_object_set (GST_OBJECT (datareposrc), "epochs", invalid_epochs, NULL);
+
+ /* state chagne failure is expected */
+ EXPECT_NE (setPipelineStateSync (pipeline, GST_STATE_PLAYING,
+ UNITTEST_STATECHANGE_TIMEOUT), 0);
+
+ gst_object_unref (pipeline);
+}
+
+/**
+ * @brief Test for reading a file with invalid param (tensors-sequence)
+ * the number tensors is 2 and indices (0,1)
+ */
+TEST (datareposrc, invalidTensorsSequence0_n)
+{
+ GstElement *datareposrc = NULL;
+ gchar *file_path = NULL;
+ gchar *json_path = NULL;
+
+ file_path = get_file_path (filename);
+ json_path = get_file_path (json);
+
+ gchar *str_pipeline =
+ g_strdup_printf
+ ("gst-launch-1.0 datareposrc name=datareposrc location=%s json=%s "
+ "start-sample-index=0 stop-sample-index=9 ! "
+ "other/tensors, format=static, num_tensors=2, framerate=0/1, "
+ "dimensions=1:1:784:1.1:1:10:1, types=float32.float32 ! fakesink",
+ file_path, json_path);
+ GstElement *pipeline = gst_parse_launch (str_pipeline, NULL);
+ g_free (str_pipeline);
+ g_free (file_path);
+ g_free (json_path);
+ ASSERT_NE (pipeline, nullptr);
+
+ datareposrc = gst_bin_get_by_name (GST_BIN (pipeline), "datareposrc");
+ ASSERT_NE (datareposrc, nullptr);
+
+ /* set invalid param */
+ g_object_set (GST_OBJECT (datareposrc), "tensors-sequence", "1,0,2", NULL);
+
+ /* state chagne failure is expected */
+ EXPECT_NE (setPipelineStateSync (pipeline, GST_STATE_PLAYING,
+ UNITTEST_STATECHANGE_TIMEOUT), 0);
+
+ gst_object_unref (pipeline);
+}
+
+/**
+ * @brief remove test file
+ */
+static void
+remove_test_file (void)
+{
+ gchar *filename = NULL;
+ int i;
+
+ g_remove ("audio1.json");
+ g_remove ("audio1.raw");
+ g_remove ("video1.json");
+ g_remove ("video1.raw");
+ g_remove ("img.son");
+
+ for (i = 0; i < 5; i++) {
+ filename = g_strdup_printf ("img_%02d.png", i);
+ g_remove (filename);
+ }
+ g_free (filename);
+}
+
+/**
+ * @brief Main GTest
+ */
+int
+main (int argc, char **argv)
+{
+ int result = -1;
+
+ try {
+ testing::InitGoogleTest (&argc, argv);
+ } catch ( ...) {
+ g_warning ("catch 'testing::internal::<unnamed>::ClassUniqueToAlwaysTrue'");
+ }
+
+ gst_init (&argc, &argv);
+
+ try {
+ result = RUN_ALL_TESTS ();
+ } catch ( ...) {
+ g_warning ("catch `testing::internal::GoogleTestFailureException`");
+ }
+
+ remove_test_file ();
+
+ return result;
+}
--- /dev/null
+/**
+ * @file unittest_trainer.cc
+ * @date 21 Apr 2023
+ * @brief Unit test for tensor_trainer
+ * @see https://github.com/nnstreamer/nnstreamer
+ * @author Hyunil Park <hyunil46.park@samsung.com>
+ * @bug No known bugs
+ */
+
+#include <gtest/gtest.h>
+#include <glib.h>
+#include <glib/gstdio.h>
+#include <gst/gst.h>
+#include <unittest_util.h>
+
+static const gchar filename[] = "mnist.data";
+static const gchar json[] = "mnist.json";
+static const gchar model_config[] = "mnist.ini";
+
+/**
+ * @brief Get file path
+ */
+static gchar *
+get_file_path (const gchar * filename)
+{
+ const gchar *root_path = NULL;
+ gchar *file_path = NULL;
+
+ root_path = g_getenv ("NNSTREAMER_SOURCE_ROOT_PATH");
+
+ /** supposed to run test in build directory */
+ if (root_path == NULL)
+ root_path = "..";
+
+ file_path =
+ g_build_filename (root_path, "tests", "test_models", "data", "datarepo",
+ filename, NULL);
+
+ return file_path;
+}
+
+
+/**
+ * @brief Model training test using mnist.data (MNIST Test), model.bin is created.
+ *
+ * framework: framework to use for training the model
+ * model-config: model configuration file path. models are limited to creating with configuration files.
+ * model-save-path: model save path by query in MLOps
+ * input-dims:input dimensions, in case of MNIST, 1:1:784:1 is a input and 1:1:10:1 is a label.
+ * input_type: data type. Sample(mnist.data)'s data type is float32.
+ * num-inputs: sub-plugin supports multiple inputs, in case of MNIST, num-inputs is 1.
+ * num-labels: sub-plugin supports multiple labels, in case of MNIST, num-labels is 1.
+ * num-training-samples: Number of training samples, A sample can consist of multiple inputs and labels in tensors(in case of MNIST, all is 1),
+ * set how many samples are taken for training model.
+ * num-validation-samples: num-validation-samples, A sample can consist of multiple inputs and labels in tensors(in case of MNIST, all is 1),
+ * set how many samples are taken for validation model.
+ * epochs : epochs are repetitions of training samples and validation smaples.
+ * number of samples received for model training is (num-training-samples + num-validation-samples) * epochs
+ */
+
+TEST (tensor_trainer, SetParams)
+{
+ gchar *file_path = NULL;
+ gchar *json_path = NULL;
+ gchar *model_config_path = NULL;
+ guint get_value;
+ gchar *get_str;
+ GstElement *tensor_trainer = NULL;
+
+ file_path = get_file_path (filename);
+ json_path = get_file_path (json);
+ model_config_path = get_file_path (model_config);
+
+ gchar *str_pipeline =
+ g_strdup_printf
+ ("gst-launch-1.0 datareposrc location=%s json=%s "
+ "start-sample-index=3 stop-sample-index=202 tensors-sequence=0,1 epochs=1 ! "
+ "other/tensors, format=static, num_tensors=2, framerate=0/1, "
+ "dimensions=1:1:784:1.1:1:10:1, types=float32.float32 ! "
+ "tensor_trainer name=tensor_trainer framework=nntrainer model-config=%s "
+ "model-save-path=model.bin input-dim=1:1:784:1,1:1:10:1 "
+ "input-type=float32,float32 num-inputs=1 num-labels=1 "
+ "num-training-samples=100 num-validation-samples=100 epochs=1 ! "
+ "tensor_sink", file_path, json_path, model_config_path);
+
+ GstElement *pipeline = gst_parse_launch (str_pipeline, NULL);
+ g_free (str_pipeline);
+ ASSERT_NE (pipeline, nullptr);
+
+ tensor_trainer = gst_bin_get_by_name (GST_BIN (pipeline), "tensor_trainer");
+ EXPECT_NE (tensor_trainer, nullptr);
+
+ setPipelineStateSync (pipeline, GST_STATE_PAUSED,
+ UNITTEST_STATECHANGE_TIMEOUT);
+
+ g_object_get (tensor_trainer, "model-config", &get_str, NULL);
+ EXPECT_STREQ (get_str, model_config_path);
+
+ g_object_get (tensor_trainer, "model-save-path", &get_str, NULL);
+ EXPECT_STREQ (get_str, "model.bin");
+
+ g_object_get (tensor_trainer, "input-dim", &get_str, NULL);
+ EXPECT_STREQ (get_str, "1:1:784:1,1:1:10:1");
+
+
+ g_object_get (tensor_trainer, "input-dim", &get_str, NULL);
+ EXPECT_STREQ (get_str, "1:1:784:1,1:1:10:1");
+
+ g_object_get (tensor_trainer, "input-type", &get_str, NULL);
+ EXPECT_STREQ (get_str, "float32,float32");
+
+ g_object_get (tensor_trainer, "num-inputs", &get_value, NULL);
+ ASSERT_EQ (get_value, 1U);
+
+ g_object_get (tensor_trainer, "num-labels", &get_value, NULL);
+ ASSERT_EQ (get_value, 1U);
+
+ g_object_get (tensor_trainer, "num-training-samples", &get_value, NULL);
+ ASSERT_EQ (get_value, 100U);
+
+ g_object_get (tensor_trainer, "num-validation-samples", &get_value, NULL);
+ ASSERT_EQ (get_value, 100U);
+
+ g_object_get (tensor_trainer, "epochs", &get_value, NULL);
+ ASSERT_EQ (get_value, 1U);
+
+ setPipelineStateSync (pipeline, GST_STATE_NULL, UNITTEST_STATECHANGE_TIMEOUT);
+
+ gst_object_unref (pipeline);
+ g_free (file_path);
+ g_free (json_path);
+ g_free (model_config_path);
+}
+
+/**
+ * @brief Model training test with invalid param (framework)
+ */
+TEST (tensor_trainer, invalidFramework0_n)
+{
+ gchar *file_path = NULL;
+ gchar *json_path = NULL;
+ gchar *model_config_path = NULL;
+ GstElement *tensor_trainer = NULL;
+
+ file_path = get_file_path (filename);
+ json_path = get_file_path (json);
+ model_config_path = get_file_path (model_config);
+
+ gchar *str_pipeline =
+ g_strdup_printf
+ ("gst-launch-1.0 datareposrc location=%s json=%s "
+ "start-sample-index=3 stop-sample-index=202 tensors-sequence=0,1 epochs=5 ! "
+ "other/tensors, format=static, num_tensors=2, framerate=0/1, "
+ "dimensions=1:1:784:1.1:1:10:1, types=float32.float32 ! "
+ "tensor_trainer name=tensor_trainer model-config=%s "
+ "model-save-path=model.bin input-dim=1:1:784:1,1:1:10:1 "
+ "input-type=float32,float32 num-inputs=1 num-labels=1 "
+ "num-training-samples=100 num-validation-samples=100 epochs=5 ! tensor_sink",
+ file_path, json_path, model_config_path);
+
+ GstElement *pipeline = gst_parse_launch (str_pipeline, NULL);
+
+ g_free (str_pipeline);
+ g_free (file_path);
+ g_free (json_path);
+ g_free (model_config_path);
+ ASSERT_NE (pipeline, nullptr);
+
+ tensor_trainer = gst_bin_get_by_name (GST_BIN (pipeline), "tensor_trainer");
+ ASSERT_NE (tensor_trainer, nullptr);
+
+ /* set invalid param */
+ g_object_set (GST_OBJECT (tensor_trainer), "framework", NULL, NULL);
+
+ /* state chagne failure is expected */
+ EXPECT_NE (setPipelineStateSync (pipeline, GST_STATE_PLAYING,
+ UNITTEST_STATECHANGE_TIMEOUT), 0);
+
+ gst_object_unref (pipeline);
+}
+
+/**
+ * @brief Model training test with invalid param (framework)
+ */
+TEST (tensor_trainer, invalidFramework1_n)
+{
+ gchar *file_path = NULL;
+ gchar *json_path = NULL;
+ gchar *model_config_path = NULL;
+ GstElement *tensor_trainer = NULL;
+
+ file_path = get_file_path (filename);
+ json_path = get_file_path (json);
+ model_config_path = get_file_path (model_config);
+
+ gchar *str_pipeline =
+ g_strdup_printf
+ ("gst-launch-1.0 datareposrc location=%s json=%s "
+ "start-sample-index=3 stop-sample-index=202 tensors-sequence=0,1 epochs=5 ! "
+ "other/tensors, format=static, num_tensors=2, framerate=0/1, "
+ "dimensions=1:1:784:1.1:1:10:1, types=float32.float32 ! "
+ "tensor_trainer name=tensor_trainer model-config=%s "
+ "model-save-path=model.bin input-dim=1:1:784:1,1:1:10:1 "
+ "input-type=float32,float32 num-inputs=1 num-labels=1 "
+ "num-training-samples=100 num-validation-samples=100 epochs=5 ! tensor_sink",
+ file_path, json_path, model_config_path);
+
+ GstElement *pipeline = gst_parse_launch (str_pipeline, NULL);
+ g_free (str_pipeline);
+ ASSERT_NE (pipeline, nullptr);
+
+ g_free (file_path);
+ g_free (json_path);
+ g_free (model_config_path);
+
+ tensor_trainer = gst_bin_get_by_name (GST_BIN (pipeline), "tensor_trainer");
+ ASSERT_NE (tensor_trainer, nullptr);
+
+ /* set invalid param */
+ g_object_set (GST_OBJECT (tensor_trainer), "framework", "no_framework", NULL);
+
+ /* state chagne failure is expected */
+ EXPECT_NE (setPipelineStateSync (pipeline, GST_STATE_PLAYING,
+ UNITTEST_STATECHANGE_TIMEOUT), 0);
+
+ gst_object_unref (pipeline);
+}
+
+/**
+ * @brief Model training test with invalid param (model-config)
+ */
+TEST (tensor_trainer, invalidModelConfig0_n)
+{
+ gchar *file_path = NULL;
+ gchar *json_path = NULL;
+ GstElement *tensor_trainer = NULL;
+
+ file_path = get_file_path (filename);
+ json_path = get_file_path (json);
+
+ gchar *str_pipeline =
+ g_strdup_printf
+ ("gst-launch-1.0 datareposrc location=%s json=%s"
+ "start-sample-index=3 stop-sample-index=202 tensors-sequence=0,1 epochs=5 ! "
+ "other/tensors, format=static, num_tensors=2, framerate=0/1, "
+ "dimensions=1:1:784:1.1:1:10:1, types=float32.float32 ! "
+ "tensor_trainer name=tensor_trainer framework=nntrainer"
+ "model-save-path=model.bin input-dim=1:1:784:1,1:1:10:1 "
+ "input-type=float32,float32 num-inputs=1 num-labels=1 "
+ "num-training-samples=100 num-validation-samples=100 epochs=5 ! tensor_sink",
+ file_path, json_path);
+
+ GstElement *pipeline = gst_parse_launch (str_pipeline, NULL);
+ g_free (str_pipeline);
+ g_free (file_path);
+ g_free (json_path);
+ ASSERT_NE (pipeline, nullptr);
+
+ tensor_trainer = gst_bin_get_by_name (GST_BIN (pipeline), "tensor_trainer");
+ ASSERT_NE (tensor_trainer, nullptr);
+
+ /* set invalid param */
+ g_object_set (GST_OBJECT (tensor_trainer), "model-config", NULL, NULL);
+
+ /* state chagne failure is expected */
+ EXPECT_NE (setPipelineStateSync (pipeline, GST_STATE_PLAYING,
+ UNITTEST_STATECHANGE_TIMEOUT), 0);
+
+ gst_object_unref (pipeline);
+}
+
+/**
+ * @brief Model training test with invalid param (model-save-path)
+ */
+TEST (tensor_trainer, invalidModelSavePath0_n)
+{
+ gchar *file_path = NULL;
+ gchar *json_path = NULL;
+ gchar *model_config_path = NULL;
+ GstElement *tensor_trainer = NULL;
+
+ file_path = get_file_path (filename);
+ json_path = get_file_path (json);
+ model_config_path = get_file_path (model_config);
+
+ gchar *str_pipeline =
+ g_strdup_printf
+ ("gst-launch-1.0 datareposrc location=%s json=%s "
+ "start-sample-index=3 stop-sample-index=202 tensors-sequence=0,1 epochs=5 ! "
+ "other/tensors, format=static, num_tensors=2, framerate=0/1, "
+ "dimensions=1:1:784:1.1:1:10:1, types=float32.float32 ! "
+ "tensor_trainer name=tensor_trainer framework=nntrainer model-config=%s "
+ "input-dim=1:1:784:1,1:1:10:1 input-type=float32,float32 num-inputs=1 num-labels=1 "
+ "num-training-samples=100 num-validation-samples=100 epochs=5 ! tensor_sink",
+ file_path, json_path, model_config_path);
+
+ GstElement *pipeline = gst_parse_launch (str_pipeline, NULL);
+ g_free (str_pipeline);
+ g_free (file_path);
+ g_free (json_path);
+ g_free (model_config_path);
+ ASSERT_NE (pipeline, nullptr);
+
+ tensor_trainer = gst_bin_get_by_name (GST_BIN (pipeline), "tensor_trainer");
+ ASSERT_NE (tensor_trainer, nullptr);
+
+ /* set invalid param */
+ g_object_set (GST_OBJECT (tensor_trainer), "model-save-path", NULL, NULL);
+
+ /* state chagne failure is expected */
+ EXPECT_NE (setPipelineStateSync (pipeline, GST_STATE_PLAYING,
+ UNITTEST_STATECHANGE_TIMEOUT), 0);
+
+ gst_object_unref (pipeline);
+}
+
+/**
+ * @brief Model training test with invalid param (input-dim)
+ */
+TEST (tensor_trainer, invalidInputDimension0_n)
+{
+ gchar *file_path = NULL;
+ gchar *json_path = NULL;
+ gchar *model_config_path = NULL;
+ GstElement *tensor_trainer = NULL;
+
+ file_path = get_file_path (filename);
+ json_path = get_file_path (json);
+ model_config_path = get_file_path (model_config);
+
+ gchar *str_pipeline =
+ g_strdup_printf
+ ("gst-launch-1.0 datareposrc location=%s json=%s "
+ "start-sample-index=3 stop-sample-index=202 tensors-sequence=0,1 epochs=5 ! "
+ "other/tensors, format=static, num_tensors=2, framerate=0/1, "
+ "dimensions=1:1:784:1.1:1:10:1, types=float32.float32 ! "
+ "tensor_trainer name=tensor_trainer framework=nntrainer model-config=%s "
+ "model-save-path=model.bin input-type=float32,float32 num-labels=1 num-labels=1 "
+ "num-training-samples=100 num-validation-samples=100 epochs=5 ! tensor_sink",
+ file_path, json_path, model_config_path);
+
+ GstElement *pipeline = gst_parse_launch (str_pipeline, NULL);
+ g_free (str_pipeline);
+ g_free (file_path);
+ g_free (json_path);
+ g_free (model_config_path);
+ ASSERT_NE (pipeline, nullptr);
+
+ tensor_trainer = gst_bin_get_by_name (GST_BIN (pipeline), "tensor_trainer");
+ ASSERT_NE (tensor_trainer, nullptr);
+
+ /* set invalid param */
+ g_object_set (GST_OBJECT (tensor_trainer), "input-dim", NULL, NULL);
+
+ /* state chagne failure is expected */
+ EXPECT_NE (setPipelineStateSync (pipeline, GST_STATE_PLAYING,
+ UNITTEST_STATECHANGE_TIMEOUT), 0);
+
+ gst_object_unref (pipeline);
+}
+
+/**
+ * @brief Model training test with invalid param (input-type)
+ */
+TEST (tensor_trainer, invalidInputType0_n)
+{
+ gchar *file_path = NULL;
+ gchar *json_path = NULL;
+ gchar *model_config_path = NULL;
+ GstElement *tensor_trainer = NULL;
+
+ file_path = get_file_path (filename);
+ json_path = get_file_path (json);
+ model_config_path = get_file_path (model_config);
+
+ gchar *str_pipeline =
+ g_strdup_printf
+ ("gst-launch-1.0 datareposrc location=%s json=%s "
+ "start-sample-index=3 stop-sample-index=202 tensors-sequence=0,1 epochs=5 ! "
+ "other/tensors, format=static, num_tensors=2, framerate=0/1, "
+ "dimensions=1:1:784:1.1:1:10:1, types=float32.float32 ! "
+ "tensor_trainer name=tensor_trainer framework=nntrainer model-config=%s "
+ "model-save-path=model.bin input-dim=1:1:784:1,1:1:10:1 num-labels=1 num-labels=1 "
+ "num-training-samples=100 num-validation-samples=100 epochs=5 ! tensor_sink",
+ file_path, json_path, model_config_path);
+
+ GstElement *pipeline = gst_parse_launch (str_pipeline, NULL);
+ g_free (str_pipeline);
+ g_free (file_path);
+ g_free (json_path);
+ g_free (model_config_path);
+ ASSERT_NE (pipeline, nullptr);
+
+ tensor_trainer = gst_bin_get_by_name (GST_BIN (pipeline), "tensor_trainer");
+ ASSERT_NE (tensor_trainer, nullptr);
+
+ /* set invalid param */
+ g_object_set (GST_OBJECT (tensor_trainer), "input-type", NULL, NULL);
+
+ /* state chagne failure is expected */
+ EXPECT_NE (setPipelineStateSync (pipeline, GST_STATE_PLAYING,
+ UNITTEST_STATECHANGE_TIMEOUT), 0);
+
+ gst_object_unref (pipeline);
+}
+
+/**
+ * @brief Model training test with invalid param (num-training-samples)
+ */
+TEST (tensor_trainer, invalidModelNumTrainingSamples0_n)
+{
+ GstElement *tensor_trainer = NULL;
+ gint invalid_value = -1;
+ guint get_value;
+ gchar *file_path = NULL;
+ gchar *json_path = NULL;
+ gchar *model_config_path = NULL;
+
+ file_path = get_file_path (filename);
+ json_path = get_file_path (json);
+ model_config_path = get_file_path (model_config);
+
+ gchar *str_pipeline =
+ g_strdup_printf
+ ("gst-launch-1.0 datareposrc location=%s json=%s "
+ "start-sample-index=3 stop-sample-index=202 tensors-sequence=0,1 epochs=5 ! "
+ "other/tensors, format=static, num_tensors=2, framerate=0/1, "
+ "dimensions=1:1:784:1.1:1:10:1, types=float32.float32 ! "
+ "tensor_trainer name=tensor_trainer framework=nntrainer model-config=%s "
+ "model-save-path=model.bin input-dim=1:1:784:1,1:1:10:1 "
+ "input-type=float32,float32 num-inputs=1 num-labels=1 "
+ "num-validation-samples=100 epochs=5 ! tensor_sink", file_path, json_path,
+ model_config_path);
+
+ GstElement *pipeline = gst_parse_launch (str_pipeline, NULL);
+ g_free (str_pipeline);
+ g_free (file_path);
+ g_free (json_path);
+ g_free (model_config_path);
+ ASSERT_NE (pipeline, nullptr);
+
+ tensor_trainer = gst_bin_get_by_name (GST_BIN (pipeline), "tensor_trainer");
+ ASSERT_NE (tensor_trainer, nullptr);
+
+ /* set invalid param */
+ g_object_set (GST_OBJECT (tensor_trainer), "num-training-samples",
+ invalid_value, NULL);
+ /** value "-1" is out of range for property 'num-training-samples' of type 'guint'
+ default value is set */
+ g_object_get (GST_OBJECT (tensor_trainer), "num-training-samples", &get_value,
+ NULL);
+ /* state chagne failure is expected */
+ EXPECT_EQ (get_value, 0U);
+
+ gst_object_unref (pipeline);
+}
+
+/**
+ * @brief Model training test with invalid param (num-validation-samples)
+ */
+TEST (tensor_trainer, invalidModelNumValidationSamples0_n)
+{
+ GstElement *tensor_trainer = NULL;
+ gint invalid_value = -1;
+ guint get_value;
+ gchar *file_path = NULL;
+ gchar *json_path = NULL;
+ gchar *model_config_path = NULL;
+
+ file_path = get_file_path (filename);
+ json_path = get_file_path (json);
+ model_config_path = get_file_path (model_config);
+
+ gchar *str_pipeline =
+ g_strdup_printf
+ ("gst-launch-1.0 datareposrc location=%s json=%s "
+ "start-sample-index=3 stop-sample-index=202 tensors-sequence=0,1 epochs=5 ! "
+ "other/tensors, format=static, num_tensors=2, framerate=0/1, "
+ "dimensions=1:1:784:1.1:1:10:1, types=float32.float32 ! "
+ "tensor_trainer name=tensor_trainer framework=nntrainer model-config=%s "
+ "model-save-path=model.bin input-dim=1:1:784:1,1:1:10:1 "
+ "input-type=float32,float32 num-inputs=1 num-labels=1 "
+ "num-training-samples=100 epochs=5 ! tensor_sink", file_path, json_path,
+ model_config_path);
+
+ GstElement *pipeline = gst_parse_launch (str_pipeline, NULL);
+ g_free (str_pipeline);
+ g_free (file_path);
+ g_free (json_path);
+ g_free (model_config_path);
+ ASSERT_NE (pipeline, nullptr);
+
+ tensor_trainer = gst_bin_get_by_name (GST_BIN (pipeline), "tensor_trainer");
+ ASSERT_NE (tensor_trainer, nullptr);
+
+ /* set invalid param */
+ g_object_set (GST_OBJECT (tensor_trainer), "num-validation-samples",
+ invalid_value, NULL);
+ /** value "-1" is out of range for property 'num-validation-samples' of type 'guint'
+ default value is set */
+ g_object_get (GST_OBJECT (tensor_trainer), "num-validation-samples",
+ &get_value, NULL);
+ /* state chagne failure is expected */
+ EXPECT_EQ (get_value, 0U);
+
+ gst_object_unref (pipeline);
+}
+
+/**
+ * @brief Model training test with invalid param (epochs)
+ */
+TEST (tensor_trainer, invalidEpochs0_n)
+{
+ GstElement *tensor_trainer = NULL;
+ gint invalid_value = -1;
+ guint get_value;
+ gchar *file_path = NULL;
+ gchar *json_path = NULL;
+ gchar *model_config_path = NULL;
+
+ file_path = get_file_path (filename);
+ json_path = get_file_path (json);
+ model_config_path = get_file_path (model_config);
+
+ gchar *str_pipeline =
+ g_strdup_printf
+ ("gst-launch-1.0 datareposrc location=%s json=%s "
+ "start-sample-index=3 stop-sample-index=202 tensors-sequence=0,1 epochs=5 ! "
+ "other/tensors, format=static, num_tensors=2, framerate=0/1, "
+ "dimensions=1:1:784:1.1:1:10:1, types=float32.float32 ! "
+ "tensor_trainer name=tensor_trainer framework=nntrainer model-config=%s "
+ "model-save-path=model.bin input-dim=1:1:784:1,1:1:10:1 "
+ "input-type=float32,float32 num-inputs=1 num-labels=1 "
+ "num-training-samples=100 num-validation-samples=100 ! tensor_sink",
+ file_path, json_path, model_config_path);
+
+ GstElement *pipeline = gst_parse_launch (str_pipeline, NULL);
+ g_free (str_pipeline);
+ g_free (file_path);
+ g_free (json_path);
+ g_free (model_config_path);
+ ASSERT_NE (pipeline, nullptr);
+
+ tensor_trainer = gst_bin_get_by_name (GST_BIN (pipeline), "tensor_trainer");
+ ASSERT_NE (tensor_trainer, nullptr);
+
+ /* set invalid param */
+ g_object_set (GST_OBJECT (tensor_trainer), "epochs", invalid_value, NULL);
+ /** value "-1" is out of range for property 'epochs' of type 'guint'
+ default value is set */
+ g_object_get (GST_OBJECT (tensor_trainer), "epochs", &get_value, NULL);
+ /* state chagne failure is expected */
+ EXPECT_EQ (get_value, 1U);
+
+ gst_object_unref (pipeline);
+}
+
+/**
+ * @brief Model training test with invalid param (num-inputs)
+ */
+TEST (tensor_trainer, invalidNumInputs0_n)
+{
+ GstElement *tensor_trainer = NULL;
+ gint invalid_value = -1;
+ guint get_value;
+ gchar *file_path = NULL;
+ gchar *json_path = NULL;
+ gchar *model_config_path = NULL;
+
+ file_path = get_file_path (filename);
+ json_path = get_file_path (json);
+ model_config_path = get_file_path (model_config);
+
+ gchar *str_pipeline =
+ g_strdup_printf
+ ("gst-launch-1.0 datareposrc location=%s json=%s "
+ "start-sample-index=3 stop-sample-index=202 tensors-sequence=0,1 epochs=5 ! "
+ "other/tensors, format=static, num_tensors=2, framerate=0/1, "
+ "dimensions=1:1:784:1.1:1:10:1, types=float32.float32 ! "
+ "tensor_trainer name=tensor_trainer framework=nntrainer model-config=%s "
+ "model-save-path=model.bin input-dim=1:1:784:1,1:1:10:1 "
+ "input-type=float32,float32 num-labels=1 num-training-samples=100 "
+ "num-validation-samples=100 epochs=5 ! tensor_sink", file_path, json_path,
+ model_config_path);
+
+ GstElement *pipeline = gst_parse_launch (str_pipeline, NULL);
+ g_free (str_pipeline);
+ g_free (file_path);
+ g_free (json_path);
+ g_free (model_config_path);
+ ASSERT_NE (pipeline, nullptr);
+
+ tensor_trainer = gst_bin_get_by_name (GST_BIN (pipeline), "tensor_trainer");
+ ASSERT_NE (tensor_trainer, nullptr);
+
+ /* set invalid param */
+ g_object_set (GST_OBJECT (tensor_trainer), "num-inputs", invalid_value, NULL);
+ /** value "-1" is out of range for property 'num-inputs' of type 'guint'
+ default value is set */
+ g_object_get (GST_OBJECT (tensor_trainer), "num-inputs", &get_value, NULL);
+ /* state chagne failure is expected */
+ EXPECT_EQ (get_value, 1U);
+
+ gst_object_unref (pipeline);
+}
+
+/**
+ * @brief Model training test with invalid param (num-labels)
+ */
+TEST (tensor_trainer, invalidNumLabels0_n)
+{
+ GstElement *tensor_trainer = NULL;
+ gint invalid_value = -1;
+ guint get_value;
+ gchar *file_path = NULL;
+ gchar *json_path = NULL;
+ gchar *model_config_path = NULL;
+
+ file_path = get_file_path (filename);
+ json_path = get_file_path (json);
+ model_config_path = get_file_path (model_config);
+
+ gchar *str_pipeline =
+ g_strdup_printf
+ ("gst-launch-1.0 datareposrc location=%s json=%s "
+ "start-sample-index=3 stop-sample-index=202 tensors-sequence=0,1 epochs=5 ! "
+ "other/tensors, format=static, num_tensors=2, framerate=0/1, "
+ "dimensions=1:1:784:1.1:1:10:1, types=float32.float32 ! "
+ "tensor_trainer name=tensor_trainer framework=nntrainer model-config=%s"
+ "model-save-path=model.bin input-dim=1:1:784:1,1:1:10:1 "
+ "input-type=float32,float32 num-labels=1 num-labels=1 "
+ "num-training-samples=100 num-validation-samples=100 epochs=5 ! "
+ "tensor_sink", file_path, json_path, model_config_path);
+
+ GstElement *pipeline = gst_parse_launch (str_pipeline, NULL);
+ g_free (str_pipeline);
+ g_free (file_path);
+ g_free (json_path);
+ g_free (model_config_path);
+ ASSERT_NE (pipeline, nullptr);
+
+ tensor_trainer = gst_bin_get_by_name (GST_BIN (pipeline), "tensor_trainer");
+ ASSERT_NE (tensor_trainer, nullptr);
+
+ /* set invalid param */
+ g_object_set (GST_OBJECT (tensor_trainer), "num-labels", invalid_value, NULL);
+ /** value "-1" of type 'gint64' is invalid or out of range for property 'num-labels' of type 'guint'
+ default value is set */
+ g_object_get (GST_OBJECT (tensor_trainer), "num-labels", &get_value, NULL);
+ /* state chagne failure is expected */
+ EXPECT_EQ (get_value, 1U);
+
+ gst_object_unref (pipeline);
+}
+
+/**
+ * @brief Main GTest
+ */
+int
+main (int argc, char **argv)
+{
+ int result = -1;
+
+ try {
+ testing::InitGoogleTest (&argc, argv);
+ } catch ( ...) {
+ g_warning ("catch 'testing::internal::<unnamed>::ClassUniqueToAlwaysTrue'");
+ }
+
+ gst_init (&argc, &argv);
+
+ try {
+ result = RUN_ALL_TESTS ();
+ } catch ( ...) {
+ g_warning ("catch `testing::internal::GoogleTestFailureException`");
+ }
+
+ return result;
+}
--- /dev/null
+# Network Section : Network
+
+[Model]
+Type = NeuralNetwork # Network Type : Regression, KNN, NeuralNetwork
+Epochs = 10 # Epochs
+Loss = cross # Loss function : mse (mean squared error)
+ # cross ( for cross entropy )
+#Save_Path = "mnist_model.bin" # model path to save / read
+batch_size = 10 # batch size
+
+[Optimizer]
+Type = adam
+beta1 = 0.9 # beta 1 for adam
+beta2 = 0.999 # beta 2 for adam
+epsilon = 1e-7 # epsilon for adam
+
+[LearningRateScheduler]
+type=constant
+Learning_rate = 1e-4 # Learning Rate
+
+# Layer Section : Name
+[inputlayer]
+Type = input
+Input_Shape = 1:28:28
+
+# Layer Section : Name
+[conv2d_c1_layer]
+Type = conv2d
+input_layers = inputlayer
+kernel_size = 5,5
+bias_initializer=zeros
+Activation=sigmoid
+weight_initializer = xavier_uniform
+filters = 6
+stride = 1,1
+padding = 0,0
+
+[pooling2d_p1]
+Type=pooling2d
+input_layers = conv2d_c1_layer
+pool_size = 2,2
+stride =2,2
+padding = 0,0
+pooling = average
+
+[conv2d_c2_layer]
+Type = conv2d
+input_layers = pooling2d_p1
+kernel_size = 5,5
+bias_initializer=zeros
+Activation=sigmoid
+weight_initializer = xavier_uniform
+filters = 12
+stride = 1,1
+padding = 0,0
+
+[pooling2d_p2]
+Type=pooling2d
+input_layers = conv2d_c2_layer
+pool_size = 2,2
+stride =2,2
+padding = 0,0
+pooling = average
+
+[flatten]
+Type=flatten
+input_layers = pooling2d_p2
+
+[outputlayer]
+Type = fully_connected
+input_layers=flatten
+Unit = 10 # Output Layer Dimension ( = Weight Width )
+weight_initializer = xavier_uniform
+bias_initializer = zeros
+Activation = softmax # activation : sigmoid, softmax
+
--- /dev/null
+{
+ "gst_caps":"other/tensors, format=(string)static, framerate=(fraction)0/1, num_tensors=(int)2, dimensions=(string)1:1:784:1.1:1:10:1, types=(string)float32.float32",
+ "total_samples":1000,
+ "sample_size":3176
+}