/tests/nnstreamer_filter_lua/unittest_filter_lua.cc

https://github.com/nnstreamer/nnstreamer · C++ · 1063 lines · 773 code · 181 blank · 109 comment · 12 complexity · af727b0077306a5d21280899c434f5b9 MD5 · raw file

  1. /* SPDX-License-Identifier: LGPL-2.1-only */
  2. /**
  3. * @file unittest_filter_lua.cc
  4. * @date 14 Jun 2021
  5. * @brief Unit test for Lua tensor filter sub-plugin
  6. * @author Yongjoo Ahn <yongjoo1.ahn@samsung.com>
  7. * @see http://github.com/nnstreamer/nnstreamer
  8. * @bug No known bugs
  9. *
  10. */
  11. #include <gtest/gtest.h>
  12. #include <glib.h>
  13. #include <gst/gst.h>
  14. #include <unittest_util.h>
  15. #include <tensor_common.h>
  16. #include <nnstreamer_plugin_api_filter.h>
  17. #include <nnstreamer_util.h>
  18. /**
  19. * @brief Set tensor filter properties
  20. */
  21. static void
  22. _SetFilterProp (GstTensorFilterProperties *prop, const gchar *name, const gchar **models)
  23. {
  24. memset (prop, 0, sizeof (GstTensorFilterProperties));
  25. prop->fwname = name;
  26. prop->fw_opened = 0;
  27. prop->model_files = models;
  28. prop->num_models = g_strv_length ((gchar **) models);
  29. }
  30. /**
  31. * @brief Simple lua model
  32. */
  33. static const char *simple_lua_script = R""""(
  34. inputTensorsInfo = {
  35. num = 2,
  36. dim = {{3, 100, 100, 1}, {3, 24, 24, 1},},
  37. type = {'uint8', 'uint8',}
  38. }
  39. outputTensorsInfo = {
  40. num = 2,
  41. dim = {{3, 100, 100, 1}, {2, 1, 1, 1},},
  42. type = {'uint8', 'float32',}
  43. }
  44. function nnstreamer_invoke()
  45. input = input_tensor(1) --[[ get the first input tensor --]]
  46. output = output_tensor(1) --[[ get the first output tensor --]]
  47. for i=1,3*100*100*1 do
  48. output[i] = input[i]
  49. end
  50. input = input_tensor(2) --[[ get the second input tensor --]]
  51. output = output_tensor(2) --[[ get the second output tensor --]]
  52. for i=1,2 do
  53. output[i] = i * 11
  54. end
  55. end
  56. )"""";
  57. /**
  58. * @brief Signal to validate new output data
  59. */
  60. static void
  61. check_output (GstElement *element, GstBuffer *buffer, gpointer user_data)
  62. {
  63. GstMemory *mem_res;
  64. GstMapInfo info_res;
  65. gboolean mapped;
  66. gfloat *output;
  67. UNUSED (element);
  68. UNUSED (user_data);
  69. mem_res = gst_buffer_get_memory (buffer, 0);
  70. mapped = gst_memory_map (mem_res, &info_res, GST_MAP_READ);
  71. ASSERT_TRUE (mapped);
  72. output = (gfloat *) info_res.data;
  73. for (guint i = 1; i <= 2; i++) {
  74. EXPECT_EQ (i * 11, output[i - 1]);
  75. }
  76. }
  77. /**
  78. * @brief Negative test case with invalid model file path
  79. */
  80. TEST (nnstreamerFilterLua, openClose00_n)
  81. {
  82. int ret;
  83. void *data = NULL;
  84. const gchar *model_files[] = {
  85. "some/invalid/model/path.lua",
  86. NULL,
  87. };
  88. GstTensorFilterProperties prop;
  89. const GstTensorFilterFramework *sp = nnstreamer_filter_find ("lua");
  90. EXPECT_NE (sp, nullptr);
  91. _SetFilterProp (&prop, "lua", model_files);
  92. ret = sp->open (&prop, &data);
  93. EXPECT_NE (ret, 0);
  94. }
  95. /**
  96. * @brief Negative test case with invalid script
  97. */
  98. TEST (nnstreamerFilterLua, openClose01_n)
  99. {
  100. int ret;
  101. void *data = NULL;
  102. const char *invalid_lua_script = R""""(
  103. invalid LUA script...
  104. )"""";
  105. const gchar *model_files[] = {
  106. invalid_lua_script,
  107. NULL,
  108. };
  109. GstTensorFilterProperties prop;
  110. const GstTensorFilterFramework *sp = nnstreamer_filter_find ("lua");
  111. EXPECT_NE (sp, nullptr);
  112. _SetFilterProp (&prop, "lua", model_files);
  113. ret = sp->open (&prop, &data);
  114. EXPECT_NE (ret, 0);
  115. }
  116. /**
  117. * @brief Negative test case with invalid script: invalid TensorsInfo
  118. */
  119. TEST (nnstreamerFilterLua, openClose02_n)
  120. {
  121. int ret;
  122. void *data = NULL;
  123. const char *invalid_lua_script = R""""(
  124. inputTensorsInfo = {
  125. num = 2,
  126. dim = {{3, 100, 100, 1}, }, --[[ Should provide 2-length dim --]]
  127. type = {'uint8', } --[[ Should provide 2-length type --]]
  128. }
  129. outputTensorsInfo = {
  130. num = 1,
  131. dim = {{3, 100, 100, 1}, },
  132. type = {'uint8', }
  133. }
  134. function nnstreamer_invoke()
  135. input = input_tensor(1)
  136. output = output_tensor(1)
  137. for i=1,3*100*100*1 do
  138. output[i] = input[i]
  139. end
  140. end
  141. )"""";
  142. const gchar *model_files[] = {
  143. invalid_lua_script,
  144. NULL,
  145. };
  146. GstTensorFilterProperties prop;
  147. const GstTensorFilterFramework *sp = nnstreamer_filter_find ("lua");
  148. EXPECT_NE (sp, nullptr);
  149. _SetFilterProp (&prop, "lua", model_files);
  150. ret = sp->open (&prop, &data);
  151. EXPECT_NE (ret, 0);
  152. }
  153. /**
  154. * @brief Negative test case with invalid script: double quotes in script
  155. */
  156. TEST (nnstreamerFilterLua, openClose03_n)
  157. {
  158. int ret;
  159. void *data = NULL;
  160. const char *invalid_lua_script = R""""(
  161. inputTensorsInfo = {
  162. num = 1,
  163. dim = {{3, 100, 100, 1}, },
  164. type = {\"uint8\", } --[[ In script mode, should not use double quotes --]]
  165. }
  166. outputTensorsInfo = {
  167. num = 1,
  168. dim = {{3, 100, 100, 1}, },
  169. type = {'uint8', }
  170. }
  171. function nnstreamer_invoke()
  172. input = input_tensor(1)
  173. output = output_tensor(1)
  174. for i=1,3*100*100*1 do
  175. output[i] = input[i]
  176. end
  177. end
  178. )"""";
  179. const gchar *model_files[] = {
  180. invalid_lua_script,
  181. NULL,
  182. };
  183. GstTensorFilterProperties prop;
  184. const GstTensorFilterFramework *sp = nnstreamer_filter_find ("lua");
  185. EXPECT_NE (sp, nullptr);
  186. _SetFilterProp (&prop, "lua", model_files);
  187. ret = sp->open (&prop, &data);
  188. EXPECT_NE (ret, 0);
  189. }
  190. /**
  191. * @brief Positive case with open/close (script mode)
  192. */
  193. TEST (nnstreamerFilterLua, openClose04)
  194. {
  195. int ret;
  196. void *data = NULL;
  197. const char *lua_script = R""""(
  198. inputTensorsInfo = {
  199. num = 1,
  200. dim = {{3, 100, 100, 1}, },
  201. type = {'uint8', }
  202. }
  203. outputTensorsInfo = {
  204. num = 1,
  205. dim = {{3, 100, 100, 1}, },
  206. type = {'uint8', }
  207. }
  208. function nnstreamer_invoke()
  209. input = input_tensor(1)
  210. output = output_tensor(1)
  211. for i=1,3*100*100*1 do
  212. output[i] = input[i]
  213. end
  214. end
  215. )"""";
  216. const gchar *model_files[] = {
  217. lua_script,
  218. NULL,
  219. };
  220. GstTensorFilterProperties prop;
  221. const GstTensorFilterFramework *sp = nnstreamer_filter_find ("lua");
  222. EXPECT_NE (sp, nullptr);
  223. _SetFilterProp (&prop, "lua", model_files);
  224. /* close before open */
  225. sp->close (&prop, &data);
  226. ret = sp->open (&prop, &data);
  227. EXPECT_EQ (ret, 0);
  228. sp->close (&prop, &data);
  229. /* double close */
  230. sp->close (&prop, &data);;
  231. }
  232. /**
  233. * @brief Positive case with open/close (file mode)
  234. */
  235. TEST (nnstreamerFilterLua, openClose05)
  236. {
  237. int ret;
  238. void *data = NULL;
  239. gchar *model_file;
  240. const gchar *root_path = g_getenv ("NNSTREAMER_SOURCE_ROOT_PATH");
  241. GstTensorFilterProperties prop;
  242. model_file = g_build_filename (
  243. root_path, "tests", "test_models", "models", "passthrough.lua", NULL);
  244. ASSERT_TRUE (g_file_test (model_file, G_FILE_TEST_EXISTS));
  245. const gchar *model_files[] = {
  246. model_file,
  247. NULL,
  248. };
  249. const GstTensorFilterFramework *sp = nnstreamer_filter_find ("lua");
  250. EXPECT_NE (sp, nullptr);
  251. _SetFilterProp (&prop, "lua", model_files);
  252. /* close before open */
  253. sp->close (&prop, &data);
  254. ret = sp->open (&prop, &data);
  255. EXPECT_EQ (ret, 0);
  256. sp->close (&prop, &data);
  257. /* double close */
  258. sp->close (&prop, &data);
  259. g_free (model_file);
  260. }
  261. /**
  262. * @brief Positive case with successful getModelInfo
  263. */
  264. TEST (nnstreamerFilterLua, getModelInfo00)
  265. {
  266. int ret;
  267. void *data = NULL;
  268. gchar *model_file;
  269. const gchar *root_path = g_getenv ("NNSTREAMER_SOURCE_ROOT_PATH");
  270. GstTensorFilterProperties prop;
  271. model_file = g_build_filename (
  272. root_path, "tests", "test_models", "models", "passthrough.lua", NULL);
  273. ASSERT_TRUE (g_file_test (model_file, G_FILE_TEST_EXISTS));
  274. const gchar *model_files[] = {
  275. model_file,
  276. NULL,
  277. };
  278. const GstTensorFilterFramework *sp = nnstreamer_filter_find ("lua");
  279. EXPECT_NE (sp, nullptr);
  280. _SetFilterProp (&prop, "lua", model_files);
  281. ret = sp->open (&prop, &data);
  282. EXPECT_EQ (ret, 0);
  283. GstTensorsInfo in_info, out_info;
  284. ret = sp->getModelInfo (NULL, NULL, data, GET_IN_OUT_INFO, &in_info, &out_info);
  285. EXPECT_EQ (ret, 0);
  286. EXPECT_EQ (in_info.num_tensors, 1U);
  287. EXPECT_EQ (in_info.info[0].dimension[0], 3U);
  288. EXPECT_EQ (in_info.info[0].dimension[1], 640U);
  289. EXPECT_EQ (in_info.info[0].dimension[2], 480U);
  290. EXPECT_EQ (in_info.info[0].dimension[3], 1U);
  291. EXPECT_EQ (in_info.info[0].type, _NNS_UINT8);
  292. EXPECT_EQ (out_info.num_tensors, 1U);
  293. EXPECT_EQ (out_info.info[0].dimension[0], 3U);
  294. EXPECT_EQ (out_info.info[0].dimension[1], 640U);
  295. EXPECT_EQ (out_info.info[0].dimension[2], 480U);
  296. EXPECT_EQ (out_info.info[0].dimension[3], 1U);
  297. EXPECT_EQ (out_info.info[0].type, _NNS_UINT8);
  298. sp->close (&prop, &data);
  299. g_free (model_file);
  300. }
  301. /**
  302. * @brief Negative case calling getModelInfo before open
  303. */
  304. TEST (nnstreamerFilterLua, getModelInfo01_n)
  305. {
  306. int ret;
  307. void *data = NULL;
  308. gchar *model_file;
  309. const gchar *root_path = g_getenv ("NNSTREAMER_SOURCE_ROOT_PATH");
  310. GstTensorFilterProperties prop;
  311. model_file = g_build_filename (
  312. root_path, "tests", "test_models", "models", "passthrough.lua", NULL);
  313. ASSERT_TRUE (g_file_test (model_file, G_FILE_TEST_EXISTS));
  314. const gchar *model_files[] = {
  315. model_file,
  316. NULL,
  317. };
  318. const GstTensorFilterFramework *sp = nnstreamer_filter_find ("lua");
  319. EXPECT_NE (sp, nullptr);
  320. GstTensorsInfo in_info, out_info;
  321. ret = sp->getModelInfo (NULL, NULL, data, SET_INPUT_INFO, &in_info, &out_info);
  322. EXPECT_NE (ret, 0);
  323. _SetFilterProp (&prop, "lua", model_files);
  324. sp->close (&prop, &data);
  325. g_free (model_file);
  326. }
  327. /**
  328. * @brief Negative case with invalid argument
  329. */
  330. TEST (nnstreamerFilterLua, getModelInfo02_n)
  331. {
  332. int ret;
  333. void *data = NULL;
  334. gchar *model_file;
  335. const gchar *root_path = g_getenv ("NNSTREAMER_SOURCE_ROOT_PATH");
  336. GstTensorFilterProperties prop;
  337. model_file = g_build_filename (
  338. root_path, "tests", "test_models", "models", "passthrough.lua", NULL);
  339. ASSERT_TRUE (g_file_test (model_file, G_FILE_TEST_EXISTS));
  340. const gchar *model_files[] = {
  341. model_file,
  342. NULL,
  343. };
  344. const GstTensorFilterFramework *sp = nnstreamer_filter_find ("lua");
  345. EXPECT_NE (sp, nullptr);
  346. _SetFilterProp (&prop, "lua", model_files);
  347. ret = sp->open (&prop, &data);
  348. EXPECT_EQ (ret, 0);
  349. sp->close (&prop, &data);
  350. GstTensorsInfo in_info, out_info;
  351. /* not supported */
  352. ret = sp->getModelInfo (NULL, NULL, data, SET_INPUT_INFO, &in_info, &out_info);
  353. EXPECT_NE (ret, 0);
  354. sp->close (&prop, &data);
  355. g_free (model_file);
  356. }
  357. /**
  358. * @brief Negative test case with invoke before open
  359. */
  360. TEST (nnstreamerFilterLua, invoke00_n)
  361. {
  362. int ret;
  363. void *data = NULL;
  364. GstTensorMemory input, output;
  365. const gchar *root_path = g_getenv ("NNSTREAMER_SOURCE_ROOT_PATH");
  366. GstTensorFilterProperties prop;
  367. gchar *model_file = g_build_filename (
  368. root_path, "tests", "test_models", "models", "passthrough.lua", NULL);
  369. const gchar *model_files[] = {
  370. model_file,
  371. NULL,
  372. };
  373. output.size = input.size = sizeof (float) * 1;
  374. input.data = g_malloc (input.size);
  375. output.data = g_malloc (output.size);
  376. const GstTensorFilterFramework *sp = nnstreamer_filter_find ("lua");
  377. EXPECT_NE (sp, nullptr);
  378. _SetFilterProp (&prop, "lua", model_files);
  379. ret = sp->invoke (NULL, NULL, data, &input, &output);
  380. EXPECT_NE (ret, 0);
  381. g_free (model_file);
  382. g_free (input.data);
  383. g_free (output.data);
  384. sp->close (&prop, &data);
  385. }
  386. /**
  387. * @brief Negative case with invalid input/output
  388. */
  389. TEST (nnstreamerFilterLua, invoke01_n)
  390. {
  391. int ret;
  392. void *data = NULL;
  393. GstTensorMemory input, output;
  394. GstTensorFilterProperties prop;
  395. const gchar *model_files[] = {
  396. simple_lua_script,
  397. NULL,
  398. };
  399. const GstTensorFilterFramework *sp = nnstreamer_filter_find ("lua");
  400. EXPECT_NE (sp, nullptr);
  401. _SetFilterProp (&prop, "lua", model_files);
  402. ret = sp->open (&prop, &data);
  403. EXPECT_EQ (ret, 0);
  404. EXPECT_NE (data, nullptr);
  405. output.size = input.size = sizeof (float) * 1;
  406. input.data = g_malloc (input.size);
  407. output.data = g_malloc (output.size);
  408. ((float *) input.data)[0] = 10.0;
  409. /* catching assertion error */
  410. EXPECT_DEATH (sp->invoke (NULL, NULL, data, NULL, &output), "");
  411. EXPECT_DEATH (sp->invoke (NULL, NULL, data, &input, NULL), "");
  412. g_free (input.data);
  413. g_free (output.data);
  414. sp->close (&prop, &data);
  415. }
  416. /**
  417. * @brief Negative test case with invalid private_data
  418. */
  419. TEST (nnstreamerFilterLua, invoke02_n)
  420. {
  421. int ret;
  422. void *data = NULL;
  423. GstTensorMemory input, output;
  424. const gchar *root_path = g_getenv ("NNSTREAMER_SOURCE_ROOT_PATH");
  425. GstTensorFilterProperties prop;
  426. gchar *model_file = g_build_filename (
  427. root_path, "tests", "test_models", "models", "passthrough.lua", NULL);
  428. const gchar *model_files[] = {
  429. model_file,
  430. NULL,
  431. };
  432. const GstTensorFilterFramework *sp = nnstreamer_filter_find ("lua");
  433. EXPECT_NE (sp, nullptr);
  434. _SetFilterProp (&prop, "lua", model_files);
  435. ret = sp->open (&prop, &data);
  436. EXPECT_EQ (ret, 0);
  437. EXPECT_NE (data, nullptr);
  438. output.size = input.size = sizeof (float) * 1;
  439. input.data = g_malloc (input.size);
  440. output.data = g_malloc (output.size);
  441. ((float *) input.data)[0] = 10.0;
  442. /* unsucessful invoke with NULL priv_data */
  443. ret = sp->invoke (NULL, NULL, NULL, &input, &output);
  444. EXPECT_NE (ret, 0);
  445. g_free (model_file);
  446. g_free (input.data);
  447. g_free (output.data);
  448. sp->close (&prop, &data);
  449. }
  450. /**
  451. * @brief Positive case with invoke for lua model
  452. */
  453. TEST (nnstreamerFilterLua, invoke03)
  454. {
  455. int ret;
  456. void *data = NULL;
  457. GstTensorMemory input, output;
  458. const gchar *root_path = g_getenv ("NNSTREAMER_SOURCE_ROOT_PATH");
  459. GstTensorFilterProperties prop;
  460. gchar *model_file = g_build_filename (
  461. root_path, "tests", "test_models", "models", "passthrough.lua", NULL);
  462. ASSERT_TRUE (g_file_test (model_file, G_FILE_TEST_EXISTS));
  463. const gchar *model_files[] = {
  464. model_file,
  465. NULL,
  466. };
  467. output.size = input.size = sizeof (uint8_t) * 3 * 640 * 480 * 1;
  468. /* alloc input data without alignment */
  469. input.data = g_malloc (input.size);
  470. output.data = g_malloc (output.size);
  471. memset (input.data, 0, input.size);
  472. const GstTensorFilterFramework *sp = nnstreamer_filter_find ("lua");
  473. EXPECT_NE (sp, nullptr);
  474. _SetFilterProp (&prop, "lua", model_files);
  475. ret = sp->open (&prop, &data);
  476. EXPECT_EQ (ret, 0);
  477. EXPECT_NE (data, (void *) NULL);
  478. ret = sp->invoke (NULL, NULL, data, &input, &output);
  479. EXPECT_EQ (ret, 0);
  480. EXPECT_EQ (static_cast<uint8_t *> (output.data)[0], 0U);
  481. g_free (model_file);
  482. g_free (input.data);
  483. g_free (output.data);
  484. sp->close (&prop, &data);
  485. }
  486. /**
  487. * @brief Positive case with invoke for lua model (script mode)
  488. */
  489. TEST (nnstreamerFilterLua, invoke04)
  490. {
  491. int ret;
  492. void *data = NULL;
  493. GstTensorMemory input, output;
  494. GstTensorFilterProperties prop;
  495. const char *lua_script = R""""(
  496. inputTensorsInfo = {
  497. num = 1,
  498. dim = {{3, 100, 100, 1}, },
  499. type = {'uint8', }
  500. }
  501. outputTensorsInfo = {
  502. num = 1,
  503. dim = {{3, 100, 100, 1}, },
  504. type = {'uint8', }
  505. }
  506. function nnstreamer_invoke()
  507. input = input_tensor(1)
  508. output = output_tensor(1)
  509. for i=1,3*100*100*1 do
  510. output[i] = input[i]
  511. end
  512. end
  513. )"""";
  514. const gchar *model_files[] = {
  515. lua_script,
  516. NULL,
  517. };
  518. output.size = input.size = sizeof (uint8_t) * 3 * 100 * 100 * 1;
  519. /* alloc input data without alignment */
  520. input.data = g_malloc (input.size);
  521. output.data = g_malloc (output.size);
  522. memset (input.data, 0, input.size);
  523. const GstTensorFilterFramework *sp = nnstreamer_filter_find ("lua");
  524. EXPECT_NE (sp, nullptr);
  525. _SetFilterProp (&prop, "lua", model_files);
  526. ret = sp->open (&prop, &data);
  527. EXPECT_EQ (ret, 0);
  528. EXPECT_NE (data, (void *) NULL);
  529. ret = sp->invoke (NULL, NULL, data, &input, &output);
  530. EXPECT_EQ (ret, 0);
  531. EXPECT_EQ (static_cast<uint8_t *> (output.data)[0], 0U);
  532. g_free (input.data);
  533. g_free (output.data);
  534. sp->close (&prop, &data);
  535. }
  536. /**
  537. * @brief Negative case with invoke for lua model: invalid index for tensor
  538. */
  539. TEST (nnstreamerFilterLua, invoke05_n)
  540. {
  541. int ret;
  542. void *data = NULL;
  543. GstTensorMemory input, output;
  544. GstTensorFilterProperties prop;
  545. const char *invalid_lua_script = R""""(
  546. inputTensorsInfo = {
  547. num = 1,
  548. dim = {{3, 100, 100, 1}, },
  549. type = {'uint8', }
  550. }
  551. outputTensorsInfo = {
  552. num = 1,
  553. dim = {{3, 100, 100, 1}, },
  554. type = {'uint8', }
  555. }
  556. function nnstreamer_invoke()
  557. input = input_tensor(1)
  558. output = output_tensor(1)
  559. for i=1,3*100*100*2 do --[[ invalid index for tensor here --]]
  560. output[i] = input[i]
  561. end
  562. end
  563. )"""";
  564. const gchar *model_files[] = {
  565. invalid_lua_script,
  566. NULL,
  567. };
  568. output.size = input.size = sizeof (uint8_t) * 3 * 100 * 100 * 1;
  569. /* alloc input data without alignment */
  570. input.data = g_malloc (input.size);
  571. output.data = g_malloc (output.size);
  572. memset (input.data, 0, input.size);
  573. const GstTensorFilterFramework *sp = nnstreamer_filter_find ("lua");
  574. EXPECT_NE (sp, nullptr);
  575. _SetFilterProp (&prop, "lua", model_files);
  576. ret = sp->open (&prop, &data);
  577. EXPECT_EQ (ret, 0);
  578. EXPECT_NE (data, (void *) NULL);
  579. ret = sp->invoke (NULL, NULL, data, &input, &output);
  580. EXPECT_NE (ret, 0);
  581. g_free (input.data);
  582. g_free (output.data);
  583. sp->close (&prop, &data);
  584. }
  585. /**
  586. * @brief Positive case with reload lua model file
  587. */
  588. TEST (nnstreamerFilterLua, reload00)
  589. {
  590. int ret;
  591. void *data = NULL;
  592. GstTensorMemory input, output;
  593. GstTensorsInfo in_info, out_info;
  594. const gchar *root_path = g_getenv ("NNSTREAMER_SOURCE_ROOT_PATH");
  595. GstTensorFilterProperties prop;
  596. gchar *model_file = g_build_filename (
  597. root_path, "tests", "test_models", "models", "passthrough.lua", NULL);
  598. ASSERT_TRUE (g_file_test (model_file, G_FILE_TEST_EXISTS));
  599. const gchar *model_files[] = {
  600. model_file,
  601. NULL,
  602. };
  603. gchar *model_file2 = g_build_filename (
  604. root_path, "tests", "test_models", "models", "scaler.lua", NULL);
  605. ASSERT_TRUE (g_file_test (model_file, G_FILE_TEST_EXISTS));
  606. const gchar *model_files2[] = {
  607. model_file2,
  608. NULL,
  609. };
  610. output.size = input.size = sizeof (uint8_t) * 3 * 640 * 480 * 1;
  611. /* alloc input data without alignment */
  612. input.data = g_malloc (input.size);
  613. output.data = g_malloc (output.size);
  614. memset (input.data, 0, input.size);
  615. const GstTensorFilterFramework *sp = nnstreamer_filter_find ("lua");
  616. EXPECT_NE (sp, nullptr);
  617. _SetFilterProp (&prop, "lua", model_files);
  618. ret = sp->open (&prop, &data);
  619. EXPECT_EQ (ret, 0);
  620. EXPECT_NE (data, (void *) NULL);
  621. ret = sp->invoke (NULL, NULL, data, &input, &output);
  622. EXPECT_EQ (ret, 0);
  623. EXPECT_EQ (static_cast<uint8_t *> (output.data)[0], 0U);
  624. ret = sp->getModelInfo (NULL, NULL, data, GET_IN_OUT_INFO, &in_info, &out_info);
  625. EXPECT_EQ (ret, 0);
  626. EXPECT_EQ (in_info.num_tensors, 1U);
  627. EXPECT_EQ (in_info.info[0].dimension[0], 3U);
  628. EXPECT_EQ (in_info.info[0].dimension[1], 640U);
  629. EXPECT_EQ (in_info.info[0].dimension[2], 480U);
  630. EXPECT_EQ (in_info.info[0].dimension[3], 1U);
  631. EXPECT_EQ (in_info.info[0].type, _NNS_UINT8);
  632. EXPECT_EQ (out_info.num_tensors, 1U);
  633. EXPECT_EQ (out_info.info[0].dimension[0], 3U);
  634. EXPECT_EQ (out_info.info[0].dimension[1], 640U);
  635. EXPECT_EQ (out_info.info[0].dimension[2], 480U);
  636. EXPECT_EQ (out_info.info[0].dimension[3], 1U);
  637. EXPECT_EQ (out_info.info[0].type, _NNS_UINT8);
  638. /** reload model */
  639. _SetFilterProp (&prop, "lua", model_files2);
  640. ret = sp->open (&prop, &data);
  641. EXPECT_EQ (ret, 0);
  642. EXPECT_NE (data, (void *) NULL);
  643. ret = sp->invoke (NULL, NULL, data, &input, &output);
  644. EXPECT_EQ (ret, 0);
  645. EXPECT_EQ (static_cast<uint8_t *> (output.data)[0], 0);
  646. ret = sp->getModelInfo (NULL, NULL, data, GET_IN_OUT_INFO, &in_info, &out_info);
  647. EXPECT_EQ (ret, 0);
  648. EXPECT_EQ (in_info.num_tensors, 1U);
  649. EXPECT_EQ (in_info.info[0].dimension[0], 3U);
  650. EXPECT_EQ (in_info.info[0].dimension[1], 640U);
  651. EXPECT_EQ (in_info.info[0].dimension[2], 480U);
  652. EXPECT_EQ (in_info.info[0].dimension[3], 1U);
  653. EXPECT_EQ (in_info.info[0].type, _NNS_UINT8);
  654. EXPECT_EQ (out_info.num_tensors, 1U);
  655. EXPECT_EQ (out_info.info[0].dimension[0], 3U);
  656. EXPECT_EQ (out_info.info[0].dimension[1], 320U);
  657. EXPECT_EQ (out_info.info[0].dimension[2], 240U);
  658. EXPECT_EQ (out_info.info[0].dimension[3], 1U);
  659. EXPECT_EQ (out_info.info[0].type, _NNS_UINT8);
  660. g_free (model_file);
  661. g_free (input.data);
  662. g_free (output.data);
  663. sp->close (&prop, &data);
  664. }
  665. /**
  666. * @brief Positive case with reload lua script
  667. */
  668. TEST (nnstreamerFilterLua, reload01)
  669. {
  670. int ret;
  671. void *data = NULL;
  672. GstTensorMemory input, output;
  673. GstTensorFilterProperties prop;
  674. const char *lua_script = R""""(
  675. inputTensorsInfo = {
  676. num = 1,
  677. dim = {{3, 100, 100, 1}, },
  678. type = {'uint8', }
  679. }
  680. outputTensorsInfo = {
  681. num = 1,
  682. dim = {{3, 100, 100, 1}, },
  683. type = {'uint8', }
  684. }
  685. function nnstreamer_invoke()
  686. input = input_tensor(1)
  687. output = output_tensor(1)
  688. for i=1,3*100*100*1 do
  689. output[i] = input[i]
  690. end
  691. end
  692. )"""";
  693. const gchar *model_files[] = {
  694. lua_script,
  695. NULL,
  696. };
  697. const char *lua_script2 = R""""(
  698. inputTensorsInfo = {
  699. num = 1,
  700. dim = {{3, 100, 100, 1}, },
  701. type = {'uint8', }
  702. }
  703. outputTensorsInfo = {
  704. num = 1,
  705. dim = {{3, 100, 100, 1}, },
  706. type = {'uint8', }
  707. }
  708. function nnstreamer_invoke()
  709. input = input_tensor(1)
  710. output = output_tensor(1)
  711. for i=1,3*100*100*1 do
  712. output[i] = 77
  713. end
  714. end
  715. )"""";
  716. const gchar *model_files2[] = {
  717. lua_script2,
  718. NULL,
  719. };
  720. output.size = input.size = sizeof (uint8_t) * 3 * 100 * 100 * 1;
  721. /* alloc input data without alignment */
  722. input.data = g_malloc (input.size);
  723. output.data = g_malloc (output.size);
  724. memset (input.data, 0, input.size);
  725. const GstTensorFilterFramework *sp = nnstreamer_filter_find ("lua");
  726. EXPECT_NE (sp, nullptr);
  727. _SetFilterProp (&prop, "lua", model_files);
  728. ret = sp->open (&prop, &data);
  729. EXPECT_EQ (ret, 0);
  730. EXPECT_NE (data, (void *) NULL);
  731. ret = sp->invoke (NULL, NULL, data, &input, &output);
  732. EXPECT_EQ (ret, 0);
  733. EXPECT_EQ (static_cast<uint8_t *> (output.data)[0], 0U);
  734. /** reload */
  735. _SetFilterProp (&prop, "lua", model_files2);
  736. ret = sp->open (&prop, &data);
  737. EXPECT_EQ (ret, 0);
  738. EXPECT_NE (data, (void *) NULL);
  739. ret = sp->invoke (NULL, NULL, data, &input, &output);
  740. EXPECT_EQ (ret, 0);
  741. EXPECT_EQ (static_cast<uint8_t *> (output.data)[0], 77U);
  742. g_free (input.data);
  743. g_free (output.data);
  744. sp->close (&prop, &data);
  745. }
  746. /**
  747. * @brief Negative case with lua script with invalid data type
  748. */
  749. TEST (nnstreamerFilterLua, dataType00_n)
  750. {
  751. /**
  752. * Invalid data type `uint128`. Type should be one of
  753. * { float32, float64, int64, uint64, int32, uint32, int16, uint16, int8, uint8 }
  754. */
  755. const char *invalid_data_type = "uint128";
  756. int ret;
  757. void *data = NULL;
  758. gchar *model;
  759. GstTensorFilterProperties prop;
  760. const GstTensorFilterFramework *sp = nnstreamer_filter_find ("lua");
  761. EXPECT_NE (sp, nullptr);
  762. model = g_strdup_printf ("\
  763. inputTensorsInfo={num=1,dim={{1,2,2,1},},type={'%s',}} \
  764. outputTensorsInfo={num=1,dim={{1,2,2,1},},type={'%s',}} \
  765. function nnstreamer_invoke() \
  766. for i=1,1*2*2*1 do output_tensor(1)[i] = input_tensor(1)[i] end \
  767. end", invalid_data_type, invalid_data_type);
  768. const gchar *model_files[] = {
  769. model,
  770. NULL,
  771. };
  772. _SetFilterProp (&prop, "lua", model_files);
  773. ret = sp->open (&prop, &data);
  774. EXPECT_NE (ret, 0);
  775. g_free (model);
  776. }
  777. /**
  778. * @brief Positive case with lua script for all data types
  779. */
  780. TEST (nnstreamerFilterLua, dataType01)
  781. {
  782. int ret;
  783. gchar *model;
  784. void *data = NULL;
  785. GstTensorMemory input, output;
  786. GstTensorFilterProperties prop;
  787. output.size = input.size = sizeof (int64_t) * 1 * 2 * 2 * 1;
  788. /* alloc input data without alignment */
  789. input.data = g_malloc0 (input.size);
  790. output.data = g_malloc0 (output.size);
  791. const GstTensorFilterFramework *sp = nnstreamer_filter_find ("lua");
  792. EXPECT_NE (sp, nullptr);
  793. for (int i = 0; i < _NNS_END; ++i) {
  794. tensor_type ttype = (tensor_type) i;
  795. model = g_strdup_printf ("\
  796. inputTensorsInfo={num=1,dim={{1,2,2,1},},type={'%s',}} \
  797. outputTensorsInfo={num=1,dim={{1,2,2,1},},type={'%s',}} \
  798. function nnstreamer_invoke() \
  799. for i=1,1*2*2*1 do output_tensor(1)[i] = input_tensor(1)[i] end \
  800. end", gst_tensor_get_type_string (ttype), gst_tensor_get_type_string (ttype));
  801. const gchar *model_files[] = {
  802. model,
  803. NULL,
  804. };
  805. _SetFilterProp (&prop, "lua", model_files);
  806. ret = sp->open (&prop, &data);
  807. EXPECT_EQ (ret, 0);
  808. EXPECT_NE (data, (void *) NULL);
  809. ret = sp->invoke (NULL, NULL, data, &input, &output);
  810. EXPECT_EQ (ret, 0);
  811. g_free (model);
  812. }
  813. g_free (input.data);
  814. g_free (output.data);
  815. sp->close (&prop, &data);
  816. }
  817. /**
  818. * @brief Negative case to launch gst pipeline: wrong dimension
  819. */
  820. TEST (nnstreamerFilterLua, launch00_n)
  821. {
  822. gchar *pipeline;
  823. GstElement *gstpipe;
  824. GError *err = NULL;
  825. /**
  826. * Create a invalid pipeline the input dimension should be 3 : 24 : 24 : 1
  827. * Given 3 : 11 : 11 : 1
  828. */
  829. pipeline = g_strdup_printf ("videotestsrc num-buffers=1 ! video/x-raw,width=100,height=100,format=RGB ! tensor_converter ! mux.sink_0 videotestsrc num-buffers=1 ! video/x-raw,width=11,height=11,format=RGB ! tensor_converter ! mux.sink_1 tensor_mux name=mux sync_mode=nosync ! tensor_filter framework=lua model=\"%s\" ! tensor_demux name=demux demux.src_0 ! tensor_decoder mode=direct_video ! video/x-raw,width=100,height=100,format=RGB ! videoconvert ! autovideosink demux.src_1 ! tensor_sink name=sinkx async=false sync=false",
  830. simple_lua_script);
  831. gstpipe = gst_parse_launch (pipeline, &err);
  832. EXPECT_NE (gstpipe, nullptr);
  833. GstElement *sink_handle = gst_bin_get_by_name (GST_BIN (gstpipe), "sinkx");
  834. EXPECT_NE (sink_handle, nullptr);
  835. g_signal_connect (sink_handle, "new-data", (GCallback) check_output, NULL);
  836. EXPECT_NE (setPipelineStateSync (gstpipe, GST_STATE_PLAYING, UNITTEST_STATECHANGE_TIMEOUT * 10), 0);
  837. gst_object_unref (sink_handle);
  838. gst_object_unref (gstpipe);
  839. g_free (pipeline);
  840. }
  841. /**
  842. * @brief Positive case to launch gst pipeline
  843. */
  844. TEST (nnstreamerFilterLua, launch01)
  845. {
  846. gchar *pipeline;
  847. GstElement *gstpipe;
  848. GError *err = NULL;
  849. /* create a nnstreamer pipeline */
  850. pipeline = g_strdup_printf ("videotestsrc num-buffers=1 ! video/x-raw,width=100,height=100,format=RGB ! tensor_converter ! mux.sink_0 videotestsrc num-buffers=1 ! video/x-raw,width=24,height=24,format=RGB ! tensor_converter ! mux.sink_1 tensor_mux name=mux sync_mode=nosync ! tensor_filter framework=lua model=\"%s\" ! tensor_demux name=demux demux.src_0 ! tensor_decoder mode=direct_video ! video/x-raw,width=100,height=100,format=RGB ! videoconvert ! autovideosink demux.src_1 ! tensor_sink name=sinkx async=false sync=false",
  851. simple_lua_script);
  852. gstpipe = gst_parse_launch (pipeline, &err);
  853. EXPECT_NE (gstpipe, nullptr);
  854. GstElement *sink_handle = gst_bin_get_by_name (GST_BIN (gstpipe), "sinkx");
  855. EXPECT_NE (sink_handle, nullptr);
  856. g_signal_connect (sink_handle, "new-data", (GCallback) check_output, NULL);
  857. EXPECT_EQ (setPipelineStateSync (gstpipe, GST_STATE_PLAYING, UNITTEST_STATECHANGE_TIMEOUT * 10), 0);
  858. EXPECT_EQ (setPipelineStateSync (gstpipe, GST_STATE_NULL, UNITTEST_STATECHANGE_TIMEOUT * 10), 0);
  859. gst_object_unref (sink_handle);
  860. gst_object_unref (gstpipe);
  861. g_free (pipeline);
  862. }
  863. /**
  864. * @brief Main gtest
  865. */
  866. int
  867. main (int argc, char **argv)
  868. {
  869. int result = -1;
  870. try {
  871. testing::InitGoogleTest (&argc, argv);
  872. } catch (...) {
  873. g_warning ("catch 'testing::internal::<unnamed>::ClassUniqueToAlwaysTrue'");
  874. }
  875. gst_init (&argc, &argv);
  876. try {
  877. result = RUN_ALL_TESTS ();
  878. } catch (...) {
  879. g_warning ("catch `testing::internal::GoogleTestFailureException`");
  880. }
  881. return result;
  882. }