[NNS/Test] Add nnstreamer plugin test
authorDongju Chae <dongju.chae@samsung.com>
Wed, 7 Jul 2021 12:32:03 +0000 (21:32 +0900)
committer채동주/On-Device Lab(SR)/Staff Engineer/삼성전자 <dongju.chae@samsung.com>
Fri, 9 Jul 2021 01:05:16 +0000 (10:05 +0900)
This patch adds nnstreamer plugin test.

Signed-off-by: Dongju Chae <dongju.chae@samsung.com>
meson.build
tests/meson.build
tests/plugins/meson.build [new file with mode: 0644]
tests/plugins/nnstreamer_test.cc [new file with mode: 0644]

index 59c709a..ba50318 100644 (file)
@@ -136,9 +136,9 @@ if get_option('enable_buffering')
 endif
 
 subdir('src')
-subdir('tests')
 subdir('utils')
 subdir('plugins')
+subdir('tests')
 
 # Set configuration to install .ini
 ne_install_conf = configuration_data()
index 8619eb3..9fab197 100644 (file)
@@ -1,3 +1,4 @@
 subdir('utils')
 subdir('unittests')
 subdir('apptests')
+subdir('plugins')
diff --git a/tests/plugins/meson.build b/tests/plugins/meson.build
new file mode 100644 (file)
index 0000000..d02580f
--- /dev/null
@@ -0,0 +1,15 @@
+if ne_test_utils_gtest_dep.found()
+  testenv = environment()
+  testenv.set('LD_LIBRARY_PATH', ne_libdir)
+
+  if get_option('enable_plugin_nns')
+    plugintest_nnstreamer = executable('plugintest_nnstreamer',
+      ['nnstreamer_test.cc'],
+      dependencies: [ne_test_utils_gtest_dep, glib_dep, gst_dep],
+      install : true,
+      install_rpath : ne_libdir,
+      install_dir : join_paths(ne_bindir, 'plugins')
+    )
+    test('plugintest_nnstreamer', plugintest_nnstreamer, env: testenv)
+  endif
+endif
diff --git a/tests/plugins/nnstreamer_test.cc b/tests/plugins/nnstreamer_test.cc
new file mode 100644 (file)
index 0000000..dbc41a9
--- /dev/null
@@ -0,0 +1,134 @@
+/**
+ * Proprietary
+ * Copyright (C) 2021 Samsung Electronics
+ * Copyright (C) 2021 Dongju Chae <dongju.chae@samsung.com>
+ */
+/**
+ * @file nnstreamer_test.cc
+ * @date 07 July 2021
+ * @brief Test NNStreamer filter sub-plugin for TRIV2
+ * @author Dongju Chae <dongju.chae@samsung.com>
+ * @bug No known bugs except for NYI items
+ */
+
+#include <ne_test_utils_gtest.h>
+
+#include <glib.h>
+#include <gst/gst.h>
+
+#define STATECHANGE_TIMEOUT 100000 /* 100s */
+
+typedef enum {
+  MODEL_CONV_2D_000 = 0,
+  MODEL_MOBILENET_V1,
+  MODEL_END
+} srnpu_model;
+
+static const gchar *model_names[MODEL_END] = {
+    [MODEL_CONV_2D_000] = "CONV_2D_000",
+    [MODEL_MOBILENET_V1] = "MOBILENET_V1",
+};
+
+static const gchar *input_dims[MODEL_END] = {
+    [MODEL_CONV_2D_000] = "64:1:1:1",
+    [MODEL_MOBILENET_V1] = "3:224:224:1",
+};
+
+static const gchar *output_dims[MODEL_END] = {
+    [MODEL_CONV_2D_000] = "64:1:1:1",
+    [MODEL_MOBILENET_V1] = "1000:1:1:1",
+};
+
+static int
+set_pipeline_state_sync (GstElement *pipeline, GstState state,
+                         uint32_t timeout_ms) {
+  GstState cur_state = GST_STATE_VOID_PENDING;
+  GstStateChangeReturn ret;
+  gint counter = 0;
+
+  ret = gst_element_set_state (pipeline, state);
+  if (ret == GST_STATE_CHANGE_FAILURE)
+    return -EPIPE;
+
+  do {
+    ret = gst_element_get_state (pipeline, &cur_state, NULL, 10 * GST_MSECOND);
+    if (ret == GST_STATE_CHANGE_FAILURE)
+      return -EPIPE;
+    if (cur_state == state)
+      return 0;
+    g_usleep (10000); /* 10 ms */
+  } while ((timeout_ms / 20) > counter++);
+
+  return -ETIME;
+}
+
+static gchar *
+make_pipeline_srnpu (srnpu_model model) {
+  if (model < 0 || model >= MODEL_END)
+    return nullptr;
+
+  const gchar *input_dim = input_dims[model];
+  const gchar *output_dim = output_dims[model];
+  gchar *model_path = g_strdup_printf ("%s/testdata/TRIV235_2TOPS/%s",
+                                       NE_DATADIR, model_names[model]);
+  gchar *pipeline = g_strdup_printf (
+      "filesrc location=%s/input_fmap_0.bin blocksize=-1 ! "
+      "application/octet-stream "
+      "! tensor_converter input-dim=%s input-type=uint8 "
+      "! tensor_filter framework=srnpu accelerator=true:npu.sr "
+      "model=%s/model.tvn "
+      "  input=%s inputtype=uint8 inputlayout=NHWC "
+      "  output=%s outputtype=uint8 outputlayout=NHWC "
+      "! fakesink",
+      model_path, input_dim, model_path, input_dim, output_dim);
+
+  g_free (model_path);
+  return pipeline;
+}
+
+TEST (nnstreamer_test, launch_conv_2d) {
+  gchar *pipeline;
+  GstElement *gstpipe;
+  GError *err = NULL;
+
+  pipeline = make_pipeline_srnpu (MODEL_CONV_2D_000);
+  gstpipe = gst_parse_launch (pipeline, &err);
+  EXPECT_NE (gstpipe, nullptr);
+
+  EXPECT_EQ (
+      set_pipeline_state_sync (gstpipe, GST_STATE_PLAYING, STATECHANGE_TIMEOUT),
+      0);
+  EXPECT_EQ (
+      set_pipeline_state_sync (gstpipe, GST_STATE_NULL, STATECHANGE_TIMEOUT),
+      0);
+
+  gst_object_unref (gstpipe);
+  g_free (pipeline);
+}
+
+TEST (nnstreamer_test, launch_mobilenet_v1) {
+  gchar *pipeline;
+  GstElement *gstpipe;
+  GError *err = NULL;
+
+  pipeline = make_pipeline_srnpu (MODEL_MOBILENET_V1);
+  gstpipe = gst_parse_launch (pipeline, &err);
+  EXPECT_NE (gstpipe, nullptr);
+
+  EXPECT_EQ (
+      set_pipeline_state_sync (gstpipe, GST_STATE_PLAYING, STATECHANGE_TIMEOUT),
+      0);
+  EXPECT_EQ (
+      set_pipeline_state_sync (gstpipe, GST_STATE_NULL, STATECHANGE_TIMEOUT),
+      0);
+
+  gst_object_unref (gstpipe);
+  g_free (pipeline);
+}
+
+/** @brief plugintest main */
+int
+main (int argc, char **argv) {
+  gst_init (&argc, &argv);
+  return start_gtest (argc, argv);
+}