From 1774099dc2e739c847929b1c890fb711e5b7dbdb Mon Sep 17 00:00:00 2001 From: Jaeyun Date: Thu, 8 Nov 2018 21:25:52 +0900 Subject: [PATCH] [Test] add testcase using gst-harness Added new testcases using gst-harness. If needs to test simple data conversion in nnstreamer plugins, add tc in unittest_plugins. Signed-off-by: Jaeyun Jung --- packaging/nnstreamer.spec | 1 + tests/CMakeLists.txt | 4 + tests/nnstreamer_plugins/unittest_plugins.cpp | 323 ++++++++++++++++++++++++++ 3 files changed, 328 insertions(+) create mode 100644 tests/nnstreamer_plugins/unittest_plugins.cpp diff --git a/packaging/nnstreamer.spec b/packaging/nnstreamer.spec index 383a037..829f0e4 100644 --- a/packaging/nnstreamer.spec +++ b/packaging/nnstreamer.spec @@ -95,6 +95,7 @@ export LD_LIBRARY_PATH=$(pwd):$(pwd)/gst/tensor_filter make %{?_smp_mflags} ./tests/unittest_common ./tests/unittest_sink --gst-plugin-path=. +./tests/unittest_plugins --gst-plugin-path=. popd pushd tests # The ssat requires 6~7min to run armv7l binary files in the current CI server. diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index a6fbd3a..6ce303b 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -40,6 +40,10 @@ TARGET_LINK_LIBRARIES(unittest_sink ${pkgs_LIBRARIES} ${testpkgs_LIBRARIES} ${gt ADD_LIBRARY(nnscustom_framecounter SHARED nnstreamer_sink/nnscustom_framecounter.c) TARGET_LINK_LIBRARIES(nnscustom_framecounter ${CUSTOMFILTERDEP}) +# Unit test for nnstreamer plugins +ADD_EXECUTABLE(unittest_plugins nnstreamer_plugins/unittest_plugins.cpp ${gtestSrc}) +TARGET_INCLUDE_DIRECTORIES(unittest_plugins PUBLIC ${pkgs_INCLUDE_DIRS} ${testpkgs_INCLUDE_DIRS} ${gtestInc}) +TARGET_LINK_LIBRARIES(unittest_plugins ${pkgs_LIBRARIES} ${testpkgs_LIBRARIES} ${gtestLink}) ADD_TEST(NAME unit_test COMMAND sh -c "GST_PLUGIN_PATH=${PROJECT_SOURCE_DIR}/build ssat ${CMAKE_CURRENT_SOURCE_DIR}") diff --git a/tests/nnstreamer_plugins/unittest_plugins.cpp b/tests/nnstreamer_plugins/unittest_plugins.cpp new file mode 100644 index 0000000..e2e3ad7 --- /dev/null +++ b/tests/nnstreamer_plugins/unittest_plugins.cpp @@ -0,0 +1,323 @@ +/** + * @file unittest_plugins.cpp + * @date 7 November 2018 + * @brief Unit test for nnstreamer plugins. (testcases to check data conversion or buffer transfer) + * @see https://github.com/nnsuite/nnstreamer + * @author Jaeyun Jung + * @bug No known bugs. + */ + +#include +#include +#include +#include +#include +#include +#include + +/** + * @brief Macro for debug mode. + */ +#ifndef DBG +#define DBG FALSE +#endif + +/** + * @brief Macro for debug message. + */ +#define _print_log(...) if (DBG) g_message (__VA_ARGS__) + +/** + * @brief Test for tensor_transform typecast (uint8 > uint32) + */ +TEST (test_tensor_transform, typecast_1) +{ + const guint num_buffers = 3; + const guint array_size = 5; + + GstHarness *h; + GstBuffer *in_buf, *out_buf; + GstTensorConfig config; + GstMemory *mem; + GstMapInfo info; + guint i, b; + gsize data_in_size, data_out_size; + + h = gst_harness_new ("tensor_transform"); + + g_object_set (h->element, "mode", "typecast", "option", "uint32", NULL); + + /* input tensor info */ + config.info.type = _NNS_UINT8; + get_tensor_dimension ("5", config.info.dimension); + config.rate_n = 0; + config.rate_d = 1; + + gst_harness_set_src_caps (h, gst_tensor_caps_from_config (&config)); + data_in_size = gst_tensor_info_get_size (&config.info); + + config.info.type = _NNS_UINT32; + data_out_size = gst_tensor_info_get_size (&config.info); + + /* push buffers */ + for (b = 0; b < num_buffers; b++) { + /* set input buffer */ + in_buf = gst_harness_create_buffer (h, data_in_size); + + mem = gst_buffer_peek_memory (in_buf, 0); + ASSERT_TRUE (gst_memory_map (mem, &info, GST_MAP_WRITE)); + + for (i = 0; i < array_size; i++) { + uint8_t value = (i + 1) * (b + 1); + ((uint8_t *) info.data)[i] = value; + } + + gst_memory_unmap (mem, &info); + + EXPECT_EQ (gst_harness_push (h, in_buf), GST_FLOW_OK); + + /* get output buffer */ + out_buf = gst_harness_pull (h); + + ASSERT_TRUE (out_buf != NULL); + ASSERT_EQ (gst_buffer_n_memory (out_buf), 1); + ASSERT_EQ (gst_buffer_get_size (out_buf), data_out_size); + + mem = gst_buffer_peek_memory (out_buf, 0); + ASSERT_TRUE (gst_memory_map (mem, &info, GST_MAP_READ)); + + for (i = 0; i < array_size; i++) { + uint32_t expected = (i + 1) * (b + 1); + EXPECT_EQ (((uint32_t *) info.data)[i], expected); + } + + gst_memory_unmap (mem, &info); + gst_buffer_unref (out_buf); + } + + EXPECT_EQ (gst_harness_buffers_received (h), num_buffers); + gst_harness_teardown (h); +} + +/** + * @brief Test for tensor_transform typecast (uint32 > float64) + */ +TEST (test_tensor_transform, typecast_2) +{ + const guint num_buffers = 3; + const guint array_size = 5; + + GstHarness *h; + GstBuffer *in_buf, *out_buf; + GstTensorConfig config; + GstMemory *mem; + GstMapInfo info; + guint i, b; + gsize data_in_size, data_out_size; + + h = gst_harness_new ("tensor_transform"); + + g_object_set (h->element, "mode", "typecast", "option", "float64", NULL); + + /* input tensor info */ + config.info.type = _NNS_UINT32; + get_tensor_dimension ("5", config.info.dimension); + config.rate_n = 0; + config.rate_d = 1; + + gst_harness_set_src_caps (h, gst_tensor_caps_from_config (&config)); + data_in_size = gst_tensor_info_get_size (&config.info); + + config.info.type = _NNS_FLOAT64; + data_out_size = gst_tensor_info_get_size (&config.info); + + /* push buffers */ + for (b = 0; b < num_buffers; b++) { + /* set input buffer */ + in_buf = gst_harness_create_buffer (h, data_in_size); + + mem = gst_buffer_peek_memory (in_buf, 0); + ASSERT_TRUE (gst_memory_map (mem, &info, GST_MAP_WRITE)); + + for (i = 0; i < array_size; i++) { + uint32_t value = (i + 1) * (b + 1); + ((uint32_t *) info.data)[i] = value; + } + + gst_memory_unmap (mem, &info); + + EXPECT_EQ (gst_harness_push (h, in_buf), GST_FLOW_OK); + + /* get output buffer */ + out_buf = gst_harness_pull (h); + + ASSERT_TRUE (out_buf != NULL); + ASSERT_EQ (gst_buffer_n_memory (out_buf), 1); + ASSERT_EQ (gst_buffer_get_size (out_buf), data_out_size); + + mem = gst_buffer_peek_memory (out_buf, 0); + ASSERT_TRUE (gst_memory_map (mem, &info, GST_MAP_READ)); + + for (i = 0; i < array_size; i++) { + double expected = (i + 1) * (b + 1); + EXPECT_EQ (((double *) info.data)[i], expected); + } + + gst_memory_unmap (mem, &info); + gst_buffer_unref (out_buf); + } + + EXPECT_EQ (gst_harness_buffers_received (h), num_buffers); + gst_harness_teardown (h); +} + +/** + * @brief Test for tensor_transform arithmetic (float32, add .5) + */ +TEST (test_tensor_transform, arithmetic_1) +{ + const guint num_buffers = 3; + const guint array_size = 5; + + GstHarness *h; + GstBuffer *in_buf, *out_buf; + GstTensorConfig config; + GstMemory *mem; + GstMapInfo info; + guint i, b; + gsize data_size; + + h = gst_harness_new ("tensor_transform"); + + g_object_set (h->element, "mode", "arithmetic", "option", "add:.5", NULL); + + /* input tensor info */ + config.info.type = _NNS_FLOAT32; + get_tensor_dimension ("5", config.info.dimension); + config.rate_n = 0; + config.rate_d = 1; + + gst_harness_set_src_caps (h, gst_tensor_caps_from_config (&config)); + data_size = gst_tensor_info_get_size (&config.info); + + /* push buffers */ + for (b = 0; b < num_buffers; b++) { + /* set input buffer */ + in_buf = gst_harness_create_buffer (h, data_size); + + mem = gst_buffer_peek_memory (in_buf, 0); + ASSERT_TRUE (gst_memory_map (mem, &info, GST_MAP_WRITE)); + + for (i = 0; i < array_size; i++) { + float value = (i + 1) * (b + 1) + .2; + ((float *) info.data)[i] = value; + } + + gst_memory_unmap (mem, &info); + + EXPECT_EQ (gst_harness_push (h, in_buf), GST_FLOW_OK); + + /* get output buffer */ + out_buf = gst_harness_pull (h); + + ASSERT_TRUE (out_buf != NULL); + ASSERT_EQ (gst_buffer_n_memory (out_buf), 1); + ASSERT_EQ (gst_buffer_get_size (out_buf), data_size); + + mem = gst_buffer_peek_memory (out_buf, 0); + ASSERT_TRUE (gst_memory_map (mem, &info, GST_MAP_READ)); + + for (i = 0; i < array_size; i++) { + float expected = (i + 1) * (b + 1) + .2 + .5; + EXPECT_EQ (((float *) info.data)[i], expected); + } + + gst_memory_unmap (mem, &info); + gst_buffer_unref (out_buf); + } + + EXPECT_EQ (gst_harness_buffers_received (h), num_buffers); + gst_harness_teardown (h); +} + +/** + * @brief Test for tensor_transform arithmetic (float64, mul .5) + */ +TEST (test_tensor_transform, arithmetic_2) +{ + const guint num_buffers = 3; + const guint array_size = 5; + + GstHarness *h; + GstBuffer *in_buf, *out_buf; + GstTensorConfig config; + GstMemory *mem; + GstMapInfo info; + guint i, b; + gsize data_size; + + h = gst_harness_new ("tensor_transform"); + + g_object_set (h->element, "mode", "arithmetic", "option", "mul:.5", NULL); + + /* input tensor info */ + config.info.type = _NNS_FLOAT64; + get_tensor_dimension ("5", config.info.dimension); + config.rate_n = 0; + config.rate_d = 1; + + gst_harness_set_src_caps (h, gst_tensor_caps_from_config (&config)); + data_size = gst_tensor_info_get_size (&config.info); + + /* push buffers */ + for (b = 0; b < num_buffers; b++) { + /* set input buffer */ + in_buf = gst_harness_create_buffer (h, data_size); + + mem = gst_buffer_peek_memory (in_buf, 0); + ASSERT_TRUE (gst_memory_map (mem, &info, GST_MAP_WRITE)); + + for (i = 0; i < array_size; i++) { + double value = (i + 1) * (b + 1) + .2; + ((double *) info.data)[i] = value; + } + + gst_memory_unmap (mem, &info); + + EXPECT_EQ (gst_harness_push (h, in_buf), GST_FLOW_OK); + + /* get output buffer */ + out_buf = gst_harness_pull (h); + + ASSERT_TRUE (out_buf != NULL); + ASSERT_EQ (gst_buffer_n_memory (out_buf), 1); + ASSERT_EQ (gst_buffer_get_size (out_buf), data_size); + + mem = gst_buffer_peek_memory (out_buf, 0); + ASSERT_TRUE (gst_memory_map (mem, &info, GST_MAP_READ)); + + for (i = 0; i < array_size; i++) { + double expected = ((i + 1) * (b + 1) + .2) * .5; + EXPECT_EQ (((double *) info.data)[i], expected); + } + + gst_memory_unmap (mem, &info); + gst_buffer_unref (out_buf); + } + + EXPECT_EQ (gst_harness_buffers_received (h), num_buffers); + gst_harness_teardown (h); +} + +/** + * @brief Main function for unit test. + */ +int +main (int argc, char **argv) +{ + testing::InitGoogleTest (&argc, argv); + + gst_init (&argc, &argv); + + return RUN_ALL_TESTS (); +} -- 2.7.4