[edge] Deprecate port and host property of edgesrc and update description for port...
[platform/upstream/nnstreamer.git] / tests / nnstreamer_edge / edge / unittest_edge.cc
1 /* SPDX-License-Identifier: LGPL-2.1-only */
2 /**
3  * @file        unittest_edge.cc
4  * @date        21 Jul 2022
5  * @brief       Unit test for NNStreamer edge element
6  * @see         https://github.com/nnstreamer/nnstreamer
7  * @author      Yechan Choi <yechan9.choi@samsung.com>
8  * @bug         No known bugs
9  */
10
11 #include <gtest/gtest.h>
12 #include <glib.h>
13 #include <gst/app/gstappsrc.h>
14 #include <gst/gst.h>
15 #include "nnstreamer_log.h"
16 #include "unittest_util.h"
17
18 static int data_received;
19
20 /**
21  * @brief Test for edgesink get and set properties.
22  */
23 TEST (edgeSink, properties0)
24 {
25   gchar *pipeline;
26   GstElement *gstpipe;
27   GstElement *edge_handle;
28   gint int_val;
29   guint uint_val;
30   gchar *str_val;
31
32   /* Create a nnstreamer pipeline */
33   pipeline = g_strdup_printf ("gst-launch-1.0 videotestsrc ! videoconvert ! videoscale ! "
34                               "video/x-raw,width=320,height=240,format=RGB,framerate=10/1 ! "
35                               "tensor_converter ! edgesink name=sinkx port=0");
36   gstpipe = gst_parse_launch (pipeline, NULL);
37   EXPECT_NE (gstpipe, nullptr);
38
39   edge_handle = gst_bin_get_by_name (GST_BIN (gstpipe), "sinkx");
40   EXPECT_NE (edge_handle, nullptr);
41
42   /* Set/Get properties of edgesink */
43   g_object_set (edge_handle, "host", "127.0.0.2", NULL);
44   g_object_get (edge_handle, "host", &str_val, NULL);
45   EXPECT_STREQ ("127.0.0.2", str_val);
46   g_free (str_val);
47
48   g_object_set (edge_handle, "port", 5001U, NULL);
49   g_object_get (edge_handle, "port", &uint_val, NULL);
50   EXPECT_EQ (5001U, uint_val);
51
52   g_object_set (edge_handle, "dest-host", "127.0.0.2", NULL);
53   g_object_get (edge_handle, "dest-host", &str_val, NULL);
54   EXPECT_STREQ ("127.0.0.2", str_val);
55   g_free (str_val);
56
57   g_object_set (edge_handle, "dest-port", 5001U, NULL);
58   g_object_get (edge_handle, "dest-port", &uint_val, NULL);
59   EXPECT_EQ (5001U, uint_val);
60
61   g_object_set (edge_handle, "connect-type", 0, NULL);
62   g_object_get (edge_handle, "connect-type", &int_val, NULL);
63   EXPECT_EQ (0, int_val);
64
65   g_object_set (edge_handle, "topic", "TEMP_TEST_TOPIC", NULL);
66   g_object_get (edge_handle, "topic", &str_val, NULL);
67   EXPECT_STREQ ("TEMP_TEST_TOPIC", str_val);
68   g_free (str_val);
69
70   gst_object_unref (edge_handle);
71   gst_object_unref (gstpipe);
72   g_free (pipeline);
73 }
74
75 /**
76  * @brief Test for edgesink with invalid host name.
77  */
78 TEST (edgeSink, properties2_n)
79 {
80   gchar *pipeline;
81   GstElement *gstpipe;
82
83   /* Create a nnstreamer pipeline */
84   pipeline = g_strdup_printf (
85       "gst-launch-1.0 videotestsrc ! videoconvert ! videoscale ! "
86       "video/x-raw,width=320,height=240,format=RGB,framerate=10/1 ! "
87       "tensor_converter ! edgesink host=f.a.i.l name=sinkx port=0");
88   gstpipe = gst_parse_launch (pipeline, NULL);
89   EXPECT_NE (gstpipe, nullptr);
90
91   EXPECT_NE (setPipelineStateSync (gstpipe, GST_STATE_PLAYING, UNITTEST_STATECHANGE_TIMEOUT), 0);
92
93   gst_object_unref (gstpipe);
94   g_free (pipeline);
95 }
96
97 /**
98  * @brief Test for edgesrc get and set properties.
99  */
100 TEST (edgeSrc, properties0)
101 {
102   gchar *pipeline;
103   GstElement *gstpipe;
104   GstElement *edge_handle;
105   gint int_val;
106   guint uint_val;
107   gchar *str_val;
108
109   /* Create a nnstreamer pipeline */
110   pipeline = g_strdup_printf ("gst-launch-1.0 edgesrc name=srcx ! "
111                               "other/tensors,num_tensors=1,dimensions=3:320:240:1,types=uint8,format=static,framerate=30/1 ! "
112                               "tensor_sink");
113   gstpipe = gst_parse_launch (pipeline, NULL);
114   EXPECT_NE (gstpipe, nullptr);
115
116   edge_handle = gst_bin_get_by_name (GST_BIN (gstpipe), "srcx");
117   EXPECT_NE (edge_handle, nullptr);
118
119   /* Set/Get properties of edgesrc */
120   g_object_set (edge_handle, "dest-host", "127.0.0.2", NULL);
121   g_object_get (edge_handle, "dest-host", &str_val, NULL);
122   EXPECT_STREQ ("127.0.0.2", str_val);
123   g_free (str_val);
124
125   g_object_set (edge_handle, "dest-port", 5001U, NULL);
126   g_object_get (edge_handle, "dest-port", &uint_val, NULL);
127   EXPECT_EQ (5001U, uint_val);
128
129   g_object_set (edge_handle, "connect-type", 0, NULL);
130   g_object_get (edge_handle, "connect-type", &int_val, NULL);
131   EXPECT_EQ (0, int_val);
132
133   g_object_set (edge_handle, "topic", "TEMP_TEST_TOPIC", NULL);
134   g_object_get (edge_handle, "topic", &str_val, NULL);
135   EXPECT_STREQ ("TEMP_TEST_TOPIC", str_val);
136   g_free (str_val);
137
138   gst_object_unref (edge_handle);
139   gst_object_unref (gstpipe);
140   g_free (pipeline);
141 }
142
143 /**
144  * @brief Test for edgesrc with invalid host name.
145  */
146 TEST (edgeSrc, properties2_n)
147 {
148   gchar *pipeline;
149   GstElement *gstpipe;
150
151   /* Create a nnstreamer pipeline */
152   pipeline = g_strdup_printf ("gst-launch-1.0 edgesrc host=f.a.i.l port=0 name=srcx ! "
153                               "other/tensors,num_tensors=1,dimensions=3:320:240:1,types=uint8,format=static,framerate=30/1 ! "
154                               "tensor_sink");
155   gstpipe = gst_parse_launch (pipeline, NULL);
156   EXPECT_NE (gstpipe, nullptr);
157
158   EXPECT_NE (setPipelineStateSync (gstpipe, GST_STATE_PLAYING, UNITTEST_STATECHANGE_TIMEOUT), 0);
159
160   gst_object_unref (gstpipe);
161   g_free (pipeline);
162 }
163
164 /**
165  * @brief Test data for edgesink/src (dimension 3:4:2)
166  */
167 const gint test_frames[48] = { 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109,
168   1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122,
169   1123, 1124, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211,
170   1212, 1213, 1214, 1215, 1216, 1217, 1218, 1219, 1220, 1221, 1222, 1223, 1224 };
171
172 /**
173  * @brief Callback for tensor sink signal.
174  */
175 static void
176 new_data_cb (GstElement *element, GstBuffer *buffer, gpointer user_data)
177 {
178   GstMemory *mem_res;
179   GstMapInfo info_res;
180   gint *output, i;
181   gboolean ret;
182
183   g_critical ("[DEBUG] NEW DATA RECEIVED!");
184   data_received++;
185   mem_res = gst_buffer_get_memory (buffer, 0);
186   ret = gst_memory_map (mem_res, &info_res, GST_MAP_READ);
187   ASSERT_TRUE (ret);
188   output = (gint *) info_res.data;
189
190   for (i = 0; i < 48; i++) {
191     EXPECT_EQ (test_frames[i], output[i]);
192   }
193   gst_memory_unmap (mem_res, &info_res);
194   gst_memory_unref (mem_res);
195 }
196
197 /**
198  * @brief Test for edgesink and edgesrc.
199  */
200 TEST (edgeSinkSrc, runNormal)
201 {
202   gchar *sink_pipeline, *src_pipeline;
203   GstElement *sink_gstpipe, *src_gstpipe;
204   GstElement *appsrc_handle, *sink_handle, *edge_handle;
205   guint port;
206   GstBuffer *buf;
207   GstMemory *mem;
208   GstMapInfo info;
209   int ret;
210
211   /* Create a nnstreamer pipeline */
212   port = get_available_port ();
213   sink_pipeline = g_strdup_printf (
214       "appsrc name=appsrc ! other/tensor,dimension=(string)3:4:2:2,type=(string)int32,framerate=(fraction)0/1 ! edgesink name=sinkx port=%u async=false",
215       port);
216   sink_gstpipe = gst_parse_launch (sink_pipeline, NULL);
217   EXPECT_NE (sink_gstpipe, nullptr);
218
219   edge_handle = gst_bin_get_by_name (GST_BIN (sink_gstpipe), "sinkx");
220   EXPECT_NE (edge_handle, nullptr);
221   g_object_get (edge_handle, "port", &port, NULL);
222
223   appsrc_handle = gst_bin_get_by_name (GST_BIN (sink_gstpipe), "appsrc");
224   EXPECT_NE (appsrc_handle, nullptr);
225
226   src_pipeline = g_strdup_printf ("gst-launch-1.0 edgesrc dest-port=%u name=srcx ! "
227                                   "other/tensor,dimension=(string)3:4:2:2,type=(string)int32,framerate=(fraction)0/1 ! "
228                                   "tensor_sink name=sinkx async=false",
229       port);
230   src_gstpipe = gst_parse_launch (src_pipeline, NULL);
231   EXPECT_NE (src_gstpipe, nullptr);
232
233   sink_handle = gst_bin_get_by_name (GST_BIN (src_gstpipe), "sinkx");
234   EXPECT_NE (sink_handle, nullptr);
235
236   g_signal_connect (sink_handle, "new-data", (GCallback) new_data_cb, NULL);
237
238   buf = gst_buffer_new ();
239   mem = gst_allocator_alloc (NULL, 192, NULL);
240   ret = gst_memory_map (mem, &info, GST_MAP_WRITE);
241   ASSERT_TRUE (ret);
242   memcpy (info.data, test_frames, 192);
243   gst_memory_unmap (mem, &info);
244   gst_buffer_append_memory (buf, mem);
245   data_received = 0;
246
247   EXPECT_EQ (setPipelineStateSync (sink_gstpipe, GST_STATE_PLAYING, UNITTEST_STATECHANGE_TIMEOUT),
248       0);
249   g_usleep (1000000);
250
251   buf = gst_buffer_ref (buf);
252   EXPECT_EQ (gst_app_src_push_buffer (GST_APP_SRC (appsrc_handle), buf), GST_FLOW_OK);
253   g_usleep (100000);
254
255   EXPECT_EQ (setPipelineStateSync (src_gstpipe, GST_STATE_PLAYING, UNITTEST_STATECHANGE_TIMEOUT),
256       0);
257   g_usleep (100000);
258
259   EXPECT_EQ (gst_app_src_push_buffer (GST_APP_SRC (appsrc_handle), buf), GST_FLOW_OK);
260   g_usleep (100000);
261
262   gst_object_unref (src_gstpipe);
263   g_free (src_pipeline);
264
265   gst_object_unref (appsrc_handle);
266   gst_object_unref (edge_handle);
267   gst_object_unref (sink_handle);
268   gst_object_unref (sink_gstpipe);
269   g_free (sink_pipeline);
270 }
271
272 #ifdef ENABLE_AITT
273 /**
274  * @brief Check whether MQTT broker is running or not.
275  */
276 static bool
277 _check_mqtt_broker ()
278 {
279   int ret = 0;
280
281   ret = system ("ps aux | grep mosquitto | grep -v grep");
282   if (0 != ret) {
283     nns_logw ("MQTT broker is not running. Skip query hybrid test.");
284     return false;
285   }
286
287   return true;
288 }
289
290 /**
291  * @brief Test for edgesink and edgesrc using AITT.
292  */
293 TEST (edgeSinkSrc, runNormalAitt)
294 {
295   gchar *sink_pipeline, *src_pipeline;
296   GstElement *sink_gstpipe, *src_gstpipe;
297   GstElement *appsrc_handle, *sink_handle;
298   GstBuffer *buf;
299   GstMemory *mem;
300   GstMapInfo info;
301   int ret;
302
303   if (!_check_mqtt_broker ())
304     return;
305
306   /* Create a nnstreamer pipeline */
307   sink_pipeline = g_strdup_printf (
308       "appsrc name=appsrc ! other/tensor,dimension=(string)3:4:2:2,type=(string)int32,framerate=(fraction)0/1 ! edgesink name=sinkx port=0 connect-type=AITT dest-host=127.0.0.1 dest-port=1883 topic=tempTestTopic async=false");
309   sink_gstpipe = gst_parse_launch (sink_pipeline, NULL);
310   EXPECT_NE (sink_gstpipe, nullptr);
311
312   appsrc_handle = gst_bin_get_by_name (GST_BIN (sink_gstpipe), "appsrc");
313   EXPECT_NE (appsrc_handle, nullptr);
314
315   src_pipeline = g_strdup_printf (
316       "gst-launch-1.0 edgesrc connect-type=AITT dest-host=127.0.0.1 dest-port=1883 topic=tempTestTopic name=srcx ! "
317       "other/tensor,dimension=(string)3:4:2:2,type=(string)int32,framerate=(fraction)0/1 ! "
318       "tensor_sink name=sinkx async=false");
319   src_gstpipe = gst_parse_launch (src_pipeline, NULL);
320   EXPECT_NE (src_gstpipe, nullptr);
321
322   sink_handle = gst_bin_get_by_name (GST_BIN (src_gstpipe), "sinkx");
323   EXPECT_NE (sink_handle, nullptr);
324
325   g_signal_connect (sink_handle, "new-data", (GCallback) new_data_cb, NULL);
326
327   buf = gst_buffer_new ();
328   mem = gst_allocator_alloc (NULL, 192, NULL);
329   ret = gst_memory_map (mem, &info, GST_MAP_WRITE);
330   ASSERT_TRUE (ret);
331   memcpy (info.data, test_frames, 192);
332   gst_memory_unmap (mem, &info);
333   gst_buffer_append_memory (buf, mem);
334   data_received = 0;
335
336   EXPECT_EQ (setPipelineStateSync (sink_gstpipe, GST_STATE_PLAYING, UNITTEST_STATECHANGE_TIMEOUT),
337       0);
338   g_usleep (1000000);
339
340   buf = gst_buffer_ref (buf);
341   EXPECT_EQ (gst_app_src_push_buffer (GST_APP_SRC (appsrc_handle), buf), GST_FLOW_OK);
342   g_usleep (100000);
343
344   EXPECT_EQ (setPipelineStateSync (src_gstpipe, GST_STATE_PLAYING, UNITTEST_STATECHANGE_TIMEOUT),
345       0);
346   g_usleep (100000);
347
348   EXPECT_EQ (gst_app_src_push_buffer (GST_APP_SRC (appsrc_handle), buf), GST_FLOW_OK);
349   g_usleep (100000);
350
351   gst_object_unref (src_gstpipe);
352   g_free (src_pipeline);
353
354   gst_object_unref (appsrc_handle);
355   gst_object_unref (sink_handle);
356   gst_object_unref (sink_gstpipe);
357   g_free (sink_pipeline);
358 }
359 #endif
360 /**
361  * @brief Main GTest
362  */
363 int
364 main (int argc, char **argv)
365 {
366   int result = -1;
367
368   try {
369     testing::InitGoogleTest (&argc, argv);
370   } catch (...) {
371     g_warning ("catch 'testing::internal::<unnamed>::ClassUniqueToAlwaysTrue'");
372   }
373
374   gst_init (&argc, &argv);
375
376   try {
377     result = RUN_ALL_TESTS ();
378   } catch (...) {
379     g_warning ("catch `testing::internal::GoogleTestFailureException`");
380   }
381
382   return result;
383 }