test_core_format.c 34 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081
  1. /*
  2. * Asterisk -- An open source telephony toolkit.
  3. *
  4. * Copyright (C) 2014, Digium, Inc.
  5. *
  6. * Joshua Colp <jcolp@digium.com>
  7. *
  8. * See http://www.asterisk.org for more information about
  9. * the Asterisk project. Please do not directly contact
  10. * any of the maintainers of this project for assistance;
  11. * the project provides a web site, mailing lists and IRC
  12. * channels for your use.
  13. *
  14. * This program is free software, distributed under the terms of
  15. * the GNU General Public License Version 2. See the LICENSE file
  16. * at the top of the source tree.
  17. */
  18. /*!
  19. * \file
  20. * \brief Core Format API Unit Tests
  21. *
  22. * \author Joshua Colp <jcolp@digium.com>
  23. *
  24. */
  25. /*** MODULEINFO
  26. <depend>TEST_FRAMEWORK</depend>
  27. <support_level>core</support_level>
  28. ***/
  29. #include "asterisk.h"
  30. #include "asterisk/test.h"
  31. #include "asterisk/module.h"
  32. #include "asterisk/codec.h"
  33. #include "asterisk/format.h"
  34. #define TEST_CATEGORY "/main/core_format/"
  35. static void test_core_format_destroy(struct ast_format *format);
  36. static int test_core_format_clone(const struct ast_format *src, struct ast_format *dst);
  37. static enum ast_format_cmp_res test_core_format_cmp(const struct ast_format *format1, const struct ast_format *format2);
  38. static struct ast_format *test_core_format_get_joint(const struct ast_format *format1, const struct ast_format *format2);
  39. static struct ast_format *test_core_format_attribute_set(const struct ast_format *format, const char *name, const char *value);
  40. static const void *test_core_format_attribute_get(const struct ast_format *format, const char *name);
  41. static struct ast_format *test_core_format_parse_sdp_fmtp(const struct ast_format *format, const char *attributes);
  42. static void test_core_format_generate_sdp_fmtp(const struct ast_format *format, unsigned int payload, struct ast_str **str);
  43. /*! \brief A format attribute 'module' used by the unit tests */
  44. static struct ast_format_interface test_core_format_attr = {
  45. .format_destroy = &test_core_format_destroy,
  46. .format_clone = &test_core_format_clone,
  47. .format_cmp = &test_core_format_cmp,
  48. .format_get_joint = &test_core_format_get_joint,
  49. .format_attribute_set = &test_core_format_attribute_set,
  50. .format_attribute_get = &test_core_format_attribute_get,
  51. .format_parse_sdp_fmtp = &test_core_format_parse_sdp_fmtp,
  52. .format_generate_sdp_fmtp = &test_core_format_generate_sdp_fmtp,
  53. };
  54. /*! \brief A test piece of data to associate with \ref test_core_format_attr */
  55. struct test_core_format_pvt {
  56. /*! Some data field */
  57. int field_one;
  58. /*! Another arbitrary data field */
  59. int field_two;
  60. };
  61. /*! \brief A test codec for these unit tests. Should be used with \c test_core_format */
  62. static struct ast_codec test_core_format_codec = {
  63. .name = "test_core_format_codec",
  64. .description = "Unit test codec used by test_core_format",
  65. .type = AST_MEDIA_TYPE_AUDIO,
  66. .sample_rate = 8000,
  67. .minimum_ms = 10,
  68. .maximum_ms = 150,
  69. .default_ms = 20,
  70. };
  71. /*! \brief Tracking object used to verify format attribute callbacks */
  72. struct callbacks_called {
  73. /*! Number of times \ref test_core_format_destroy was called */
  74. int format_destroy;
  75. /*! Number of times \ref test_core_format_clone was called */
  76. int format_clone;
  77. /*! Number of times \ref test_core_format_cmp was called */
  78. int format_cmp;
  79. /*! Number of times \ref test_core_format_get_joint was called */
  80. int format_get_joint;
  81. /*! Number of times \ref test_core_format_attribute_set was called */
  82. int format_attribute_set;
  83. /*! Number of times \ref test_core_format_parse_sdp_fmtp was called */
  84. int format_parse_sdp_fmtp;
  85. /*! Number of times \ref test_core_format_generate_sdp_fmtp was called */
  86. int format_generate_sdp_fmtp;
  87. };
  88. /*! \brief A global tracking object. Cleared out by the test init cb */
  89. static struct callbacks_called test_callbacks_called;
  90. /*! \brief Format attribute callback for when format attributes are to be destroyed */
  91. static void test_core_format_destroy(struct ast_format *format)
  92. {
  93. struct test_core_format_pvt *pvt = ast_format_get_attribute_data(format);
  94. ast_free(pvt);
  95. ++test_callbacks_called.format_destroy;
  96. }
  97. /*! \brief Format attribute callback called during format cloning */
  98. static int test_core_format_clone(const struct ast_format *src, struct ast_format *dst)
  99. {
  100. struct test_core_format_pvt *pvt = ast_format_get_attribute_data(src);
  101. struct test_core_format_pvt *new_pvt;
  102. new_pvt = ast_calloc(1, sizeof(*new_pvt));
  103. if (!new_pvt) {
  104. return -1;
  105. }
  106. if (pvt) {
  107. *new_pvt = *pvt;
  108. }
  109. ast_format_set_attribute_data(dst, new_pvt);
  110. ++test_callbacks_called.format_clone;
  111. return 0;
  112. }
  113. /*! \brief Format attribute callback called during format comparison */
  114. static enum ast_format_cmp_res test_core_format_cmp(const struct ast_format *format1, const struct ast_format *format2)
  115. {
  116. struct test_core_format_pvt *pvt1 = ast_format_get_attribute_data(format1);
  117. struct test_core_format_pvt *pvt2 = ast_format_get_attribute_data(format2);
  118. ++test_callbacks_called.format_cmp;
  119. if (pvt1 == pvt2) {
  120. return AST_FORMAT_CMP_EQUAL;
  121. }
  122. if ((!pvt1 && pvt2 && (pvt2->field_one != 0 || pvt2->field_two != 0))
  123. || (pvt1 && !pvt2 && (pvt1->field_one != 0 || pvt1->field_two != 0))) {
  124. return AST_FORMAT_CMP_NOT_EQUAL;
  125. }
  126. if (pvt1 && pvt2) {
  127. if (!memcmp(pvt1, pvt2, sizeof(*pvt1))) {
  128. return AST_FORMAT_CMP_EQUAL;
  129. } else {
  130. return AST_FORMAT_CMP_NOT_EQUAL;
  131. }
  132. }
  133. return AST_FORMAT_CMP_EQUAL;
  134. }
  135. /*!
  136. * \brief Format attribute callback called during joint format capability
  137. * \note Our test will assume the max of attributes \c field_one and \c field_two
  138. */
  139. static struct ast_format *test_core_format_get_joint(const struct ast_format *format1, const struct ast_format *format2)
  140. {
  141. struct test_core_format_pvt *pvt1 = ast_format_get_attribute_data(format1);
  142. struct test_core_format_pvt *pvt2 = ast_format_get_attribute_data(format2);
  143. struct ast_format *joint;
  144. struct test_core_format_pvt *joint_pvt;
  145. joint = ast_format_clone(format1);
  146. if (!joint) {
  147. return NULL;
  148. }
  149. joint_pvt = ast_format_get_attribute_data(joint);
  150. joint_pvt->field_one = MAX(pvt1 ? pvt1->field_one : 0, pvt2 ? pvt2->field_one : 0);
  151. joint_pvt->field_two = MAX(pvt2 ? pvt2->field_two : 0, pvt2 ? pvt2->field_two : 0);
  152. ++test_callbacks_called.format_get_joint;
  153. return joint;
  154. }
  155. /*! \brief Format attribute callback for setting an attribute on a format */
  156. static struct ast_format *test_core_format_attribute_set(const struct ast_format *format, const char *name, const char *value)
  157. {
  158. struct ast_format *clone = ast_format_clone(format);
  159. struct test_core_format_pvt *clone_pvt;
  160. if (!clone) {
  161. return NULL;
  162. }
  163. clone_pvt = ast_format_get_attribute_data(clone);
  164. if (!strcmp(name, "one")) {
  165. clone_pvt->field_one = atoi(value);
  166. } else if (!strcmp(name, "two")) {
  167. clone_pvt->field_two = atoi(value);
  168. }
  169. ++test_callbacks_called.format_attribute_set;
  170. return clone;
  171. }
  172. /*! \brief Format attribute callback for retrieving an attribute */
  173. static const void *test_core_format_attribute_get(const struct ast_format *format, const char *name)
  174. {
  175. struct test_core_format_pvt *pvt = ast_format_get_attribute_data(format);
  176. if (!strcmp(name, "one")) {
  177. return &pvt->field_one;
  178. } else if (!strcmp(name, "two")) {
  179. return &pvt->field_two;
  180. }
  181. return NULL;
  182. }
  183. /*! \brief Format attribute callback to construct a format from an SDP fmtp line */
  184. static struct ast_format *test_core_format_parse_sdp_fmtp(const struct ast_format *format, const char *attributes)
  185. {
  186. struct ast_format *clone = ast_format_clone(format);
  187. struct test_core_format_pvt *pvt;
  188. if (!clone) {
  189. return NULL;
  190. }
  191. pvt = ast_format_get_attribute_data(clone);
  192. if (sscanf(attributes, "one=%d;two=%d", &pvt->field_one, &pvt->field_two) != 2) {
  193. ao2_ref(clone, -1);
  194. return NULL;
  195. }
  196. ++test_callbacks_called.format_parse_sdp_fmtp;
  197. return clone;
  198. }
  199. /*! \brief Format attribute callback to generate an SDP fmtp line from a format */
  200. static void test_core_format_generate_sdp_fmtp(const struct ast_format *format, unsigned int payload, struct ast_str **str)
  201. {
  202. struct test_core_format_pvt *pvt = ast_format_get_attribute_data(format);
  203. if (!pvt) {
  204. return;
  205. }
  206. ast_str_append(str, 0, "a=fmtp:%u one=%d;two=%d\r\n", payload, pvt->field_one, pvt->field_two);
  207. ++test_callbacks_called.format_generate_sdp_fmtp;
  208. }
  209. AST_TEST_DEFINE(format_create)
  210. {
  211. RAII_VAR(struct ast_codec *, codec, NULL, ao2_cleanup);
  212. RAII_VAR(struct ast_format *, format, NULL, ao2_cleanup);
  213. switch (cmd) {
  214. case TEST_INIT:
  215. info->name = __PRETTY_FUNCTION__;
  216. info->category = TEST_CATEGORY;
  217. info->summary = "Format creation unit test";
  218. info->description =
  219. "Test creation of a format";
  220. return AST_TEST_NOT_RUN;
  221. case TEST_EXECUTE:
  222. break;
  223. }
  224. codec = ast_codec_get("ulaw", AST_MEDIA_TYPE_AUDIO, 8000);
  225. if (!codec) {
  226. ast_test_status_update(test, "Could not retrieve built-in ulaw codec\n");
  227. return AST_TEST_FAIL;
  228. }
  229. format = ast_format_create(codec);
  230. if (!format) {
  231. ast_test_status_update(test, "Could not create format using built-in codec\n");
  232. return AST_TEST_FAIL;
  233. } else if (ast_format_get_codec_id(format) != codec->id) {
  234. ast_test_status_update(test, "Created format does not contain provided codec\n");
  235. return AST_TEST_FAIL;
  236. }
  237. ao2_ref(format, -1);
  238. format = ast_format_create_named("super_ulaw", codec);
  239. if (!format) {
  240. ast_test_status_update(test, "Could not create format using built-in codec\n");
  241. return AST_TEST_FAIL;
  242. } else if (ast_format_get_codec_id(format) != codec->id) {
  243. ast_test_status_update(test, "Created format does not contain provided codec\n");
  244. return AST_TEST_FAIL;
  245. }
  246. return AST_TEST_PASS;
  247. }
  248. AST_TEST_DEFINE(format_create_attr)
  249. {
  250. RAII_VAR(struct ast_codec *, codec, NULL, ao2_cleanup);
  251. RAII_VAR(struct ast_format *, format, NULL, ao2_cleanup);
  252. RAII_VAR(struct ast_format *, format_w_attr, NULL, ao2_cleanup);
  253. switch (cmd) {
  254. case TEST_INIT:
  255. info->name = __PRETTY_FUNCTION__;
  256. info->category = TEST_CATEGORY;
  257. info->summary = "Format creation w/ attributes unit test";
  258. info->description =
  259. "Test creation of a format with attributes";
  260. return AST_TEST_NOT_RUN;
  261. case TEST_EXECUTE:
  262. break;
  263. }
  264. codec = ast_codec_get("test_core_format_codec", AST_MEDIA_TYPE_AUDIO, 8000);
  265. if (!codec) {
  266. ast_test_status_update(test, "Could not retrieve test_core_format_codec codec\n");
  267. return AST_TEST_FAIL;
  268. }
  269. format = ast_format_create(codec);
  270. if (!format) {
  271. ast_test_status_update(test, "Could not create format using test_core_format_codec codec\n");
  272. return AST_TEST_FAIL;
  273. } else if (ast_format_get_codec_id(format) != codec->id) {
  274. ast_test_status_update(test, "Created format does not contain provided codec\n");
  275. return AST_TEST_FAIL;
  276. }
  277. format_w_attr = ast_format_attribute_set(format, "one", "1");
  278. if (!format_w_attr) {
  279. ast_test_status_update(test, "Could not create format with attributes using test_core_format_codec codec\n");
  280. return AST_TEST_FAIL;
  281. } else if (ast_format_get_codec_id(format_w_attr) != codec->id) {
  282. ast_test_status_update(test, "Created format does not contain provided codec\n");
  283. return AST_TEST_FAIL;
  284. } else if (ast_format_cmp(format, format_w_attr) == AST_FORMAT_CMP_EQUAL) {
  285. ast_test_status_update(test, "Format with attributes should not be equal to format without attributes\n");
  286. return AST_TEST_FAIL;
  287. }
  288. ast_test_validate(test, test_callbacks_called.format_attribute_set == 1);
  289. ast_test_validate(test, test_callbacks_called.format_cmp == 1);
  290. return AST_TEST_PASS;
  291. }
  292. AST_TEST_DEFINE(format_retrieve_attr)
  293. {
  294. RAII_VAR(struct ast_codec *, codec, NULL, ao2_cleanup);
  295. RAII_VAR(struct ast_format *, format, NULL, ao2_cleanup);
  296. RAII_VAR(struct ast_format *, format_w_attr, NULL, ao2_cleanup);
  297. switch (cmd) {
  298. case TEST_INIT:
  299. info->name = __PRETTY_FUNCTION__;
  300. info->category = TEST_CATEGORY;
  301. info->summary = "Format attribute retrieval unit test";
  302. info->description =
  303. "Test retrieval of format attributes";
  304. return AST_TEST_NOT_RUN;
  305. case TEST_EXECUTE:
  306. break;
  307. }
  308. codec = ast_codec_get("test_core_format_codec", AST_MEDIA_TYPE_AUDIO, 8000);
  309. if (!codec) {
  310. ast_test_status_update(test, "Could not retrieve test_core_format_codec codec\n");
  311. return AST_TEST_FAIL;
  312. }
  313. format = ast_format_create(codec);
  314. if (!format) {
  315. ast_test_status_update(test, "Could not create format using test_core_format_codec codec\n");
  316. return AST_TEST_FAIL;
  317. }
  318. format_w_attr = ast_format_attribute_set(format, "one", "1");
  319. if (!format_w_attr) {
  320. ast_test_status_update(test, "Could not create format with attributes using test_core_format_codec codec\n");
  321. return AST_TEST_FAIL;
  322. }
  323. if (*((int *)ast_format_attribute_get(format_w_attr, "one")) != 1) {
  324. ast_test_status_update(test, "Could not retrieve valid format attribute\n");
  325. return AST_TEST_FAIL;
  326. }
  327. if (ast_format_attribute_get(format_w_attr, "foo") != NULL) {
  328. ast_test_status_update(test, "Retrieved invalid format attribute\n");
  329. return AST_TEST_FAIL;
  330. }
  331. return AST_TEST_PASS;
  332. }
  333. AST_TEST_DEFINE(format_clone)
  334. {
  335. RAII_VAR(struct ast_codec *, codec, NULL, ao2_cleanup);
  336. RAII_VAR(struct ast_format *, format, NULL, ao2_cleanup);
  337. RAII_VAR(struct ast_format *, format_w_attr, NULL, ao2_cleanup);
  338. RAII_VAR(struct ast_format *, clone, NULL, ao2_cleanup);
  339. switch (cmd) {
  340. case TEST_INIT:
  341. info->name = __PRETTY_FUNCTION__;
  342. info->category = TEST_CATEGORY;
  343. info->summary = "Format cloning unit test";
  344. info->description =
  345. "Test cloning of a format";
  346. return AST_TEST_NOT_RUN;
  347. case TEST_EXECUTE:
  348. break;
  349. }
  350. codec = ast_codec_get("test_core_format_codec", AST_MEDIA_TYPE_AUDIO, 8000);
  351. if (!codec) {
  352. ast_test_status_update(test, "Could not retrieve test_core_format_codec codec\n");
  353. return AST_TEST_FAIL;
  354. }
  355. format = ast_format_create(codec);
  356. if (!format) {
  357. ast_test_status_update(test, "Could not create format using test_core_format_codec codec\n");
  358. return AST_TEST_FAIL;
  359. } else if (ast_format_get_codec_id(format) != codec->id) {
  360. ast_test_status_update(test, "Created format does not contain provided codec\n");
  361. return AST_TEST_FAIL;
  362. }
  363. format_w_attr = ast_format_attribute_set(format, "one", "1");
  364. if (!format_w_attr) {
  365. ast_test_status_update(test, "Could not create format with attributes using test_core_format_codec codec\n");
  366. return AST_TEST_FAIL;
  367. } else if (ast_format_get_codec_id(format_w_attr) != codec->id) {
  368. ast_test_status_update(test, "Created format does not contain provided codec\n");
  369. return AST_TEST_FAIL;
  370. }
  371. /* Test cloning a format without attributes */
  372. clone = ast_format_clone(format);
  373. if (!clone) {
  374. ast_test_status_update(test, "Could not create cloned format\n");
  375. return AST_TEST_FAIL;
  376. } else if (ast_format_get_codec_id(clone) != codec->id) {
  377. ast_test_status_update(test, "Cloned format does not contain provided codec\n");
  378. return AST_TEST_FAIL;
  379. } else if (clone == format) {
  380. ast_test_status_update(test, "Cloned format pointer is the same as original format pointer\n");
  381. return AST_TEST_FAIL;
  382. } else if (ast_format_cmp(clone, format) != AST_FORMAT_CMP_EQUAL) {
  383. ast_test_status_update(test, "Cloned format is not the same as its original format\n");
  384. return AST_TEST_FAIL;
  385. }
  386. ao2_ref(clone, -1);
  387. /* Test cloning a format with attributes */
  388. clone = ast_format_clone(format_w_attr);
  389. if (!clone) {
  390. ast_test_status_update(test, "Could not create cloned format\n");
  391. return AST_TEST_FAIL;
  392. } else if (ast_format_get_codec_id(clone) != codec->id) {
  393. ast_test_status_update(test, "Cloned format does not contain provided codec\n");
  394. return AST_TEST_FAIL;
  395. } else if (clone == format_w_attr) {
  396. ast_test_status_update(test, "Cloned format pointer is the same as original format pointer\n");
  397. return AST_TEST_FAIL;
  398. } else if (ast_format_cmp(clone, format_w_attr) != AST_FORMAT_CMP_EQUAL) {
  399. ast_test_status_update(test, "Cloned format is not the same as its original format\n");
  400. return AST_TEST_FAIL;
  401. }
  402. ast_test_validate(test, test_callbacks_called.format_attribute_set == 1);
  403. ast_test_validate(test, test_callbacks_called.format_clone == 3);
  404. ast_test_validate(test, test_callbacks_called.format_cmp == 2);
  405. return AST_TEST_PASS;
  406. }
  407. AST_TEST_DEFINE(format_cmp_same_codec)
  408. {
  409. RAII_VAR(struct ast_codec *, codec, NULL, ao2_cleanup);
  410. RAII_VAR(struct ast_format *, first, NULL, ao2_cleanup);
  411. RAII_VAR(struct ast_format *, second, NULL, ao2_cleanup);
  412. RAII_VAR(struct ast_format *, named, NULL, ao2_cleanup);
  413. switch (cmd) {
  414. case TEST_INIT:
  415. info->name = __PRETTY_FUNCTION__;
  416. info->category = TEST_CATEGORY;
  417. info->summary = "Format comparison unit test";
  418. info->description =
  419. "Test comparison of two different formats with same codec";
  420. return AST_TEST_NOT_RUN;
  421. case TEST_EXECUTE:
  422. break;
  423. }
  424. codec = ast_codec_get("ulaw", AST_MEDIA_TYPE_AUDIO, 8000);
  425. if (!codec) {
  426. ast_test_status_update(test, "Could not retrieve built-in ulaw codec\n");
  427. return AST_TEST_FAIL;
  428. }
  429. first = ast_format_create(codec);
  430. if (!first) {
  431. ast_test_status_update(test, "Could not create first format using built-in codec\n");
  432. return AST_TEST_FAIL;
  433. }
  434. second = ast_format_create(codec);
  435. if (!second) {
  436. ast_test_status_update(test, "Could not create second format using built-in codec\n");
  437. return AST_TEST_FAIL;
  438. }
  439. named = ast_format_create_named("super_ulaw", codec);
  440. if (!named) {
  441. ast_test_status_update(test, "Could not create named format using built-in codec\n");
  442. return AST_TEST_FAIL;
  443. }
  444. if (ast_format_cmp(first, second) != AST_FORMAT_CMP_EQUAL) {
  445. ast_test_status_update(test, "Two formats that are the same compared as not being equal\n");
  446. return AST_TEST_FAIL;
  447. }
  448. if (ast_format_cmp(first, named) != AST_FORMAT_CMP_EQUAL) {
  449. ast_test_status_update(test, "Two formats that are the same compared as not being equal\n");
  450. return AST_TEST_FAIL;
  451. }
  452. return AST_TEST_PASS;
  453. }
  454. AST_TEST_DEFINE(format_cmp_different_codec)
  455. {
  456. RAII_VAR(struct ast_codec *, first_codec, NULL, ao2_cleanup);
  457. RAII_VAR(struct ast_codec *, second_codec, NULL, ao2_cleanup);
  458. RAII_VAR(struct ast_format *, first, NULL, ao2_cleanup);
  459. RAII_VAR(struct ast_format *, second, NULL, ao2_cleanup);
  460. switch (cmd) {
  461. case TEST_INIT:
  462. info->name = __PRETTY_FUNCTION__;
  463. info->category = TEST_CATEGORY;
  464. info->summary = "Format comparison unit test";
  465. info->description =
  466. "Test comparison of two different formats with different codec";
  467. return AST_TEST_NOT_RUN;
  468. case TEST_EXECUTE:
  469. break;
  470. }
  471. first_codec = ast_codec_get("ulaw", AST_MEDIA_TYPE_AUDIO, 8000);
  472. if (!first_codec) {
  473. ast_test_status_update(test, "Could not retrieve built-in ulaw codec\n");
  474. return AST_TEST_FAIL;
  475. }
  476. first = ast_format_create(first_codec);
  477. if (!first) {
  478. ast_test_status_update(test, "Could not create first format using built-in codec\n");
  479. return AST_TEST_FAIL;
  480. }
  481. second_codec = ast_codec_get("alaw", AST_MEDIA_TYPE_AUDIO, 8000);
  482. if (!second_codec) {
  483. ast_test_status_update(test, "Could not retrieve built-in alaw codec\n");
  484. return AST_TEST_FAIL;
  485. }
  486. second = ast_format_create(second_codec);
  487. if (!second) {
  488. ast_test_status_update(test, "Could not create second format using built-in codec\n");
  489. return AST_TEST_FAIL;
  490. }
  491. if (ast_format_cmp(first, second) != AST_FORMAT_CMP_NOT_EQUAL) {
  492. ast_test_status_update(test, "Two formats that have different codecs did not compare as being not equal\n");
  493. return AST_TEST_FAIL;
  494. }
  495. return AST_TEST_PASS;
  496. }
  497. AST_TEST_DEFINE(format_attr_cmp_same_codec)
  498. {
  499. RAII_VAR(struct ast_codec *, codec, NULL, ao2_cleanup);
  500. RAII_VAR(struct ast_format *, first, NULL, ao2_cleanup);
  501. RAII_VAR(struct ast_format *, second, NULL, ao2_cleanup);
  502. RAII_VAR(struct ast_format *, original, NULL, ao2_cleanup);
  503. switch (cmd) {
  504. case TEST_INIT:
  505. info->name = __PRETTY_FUNCTION__;
  506. info->category = TEST_CATEGORY;
  507. info->summary = "Format with attributes comparison unit test";
  508. info->description =
  509. "Test comparison of two different formats with attributes with same codec";
  510. return AST_TEST_NOT_RUN;
  511. case TEST_EXECUTE:
  512. break;
  513. }
  514. codec = ast_codec_get("test_core_format_codec", AST_MEDIA_TYPE_AUDIO, 8000);
  515. if (!codec) {
  516. ast_test_status_update(test, "Could not retrieve test_core_format_codec codec\n");
  517. return AST_TEST_FAIL;
  518. }
  519. original = ast_format_create(codec);
  520. if (!original) {
  521. ast_test_status_update(test, "Could not create format using test_core_format_codec codec\n");
  522. return AST_TEST_FAIL;
  523. }
  524. first = ast_format_attribute_set(original, "one", "1");
  525. if (!first) {
  526. ast_test_status_update(test, "Could not create first format with attributes\n");
  527. return AST_TEST_FAIL;
  528. }
  529. second = ast_format_attribute_set(original, "two", "1");
  530. if (!second) {
  531. ast_test_status_update(test, "Could not create second format with attributes\n");
  532. return AST_TEST_FAIL;
  533. }
  534. if (ast_format_cmp(first, second) == AST_FORMAT_CMP_EQUAL) {
  535. ast_test_status_update(test, "Formats with different attributes were compared to be equal when they should not\n");
  536. return AST_TEST_FAIL;
  537. }
  538. ao2_ref(second, -1);
  539. second = ast_format_attribute_set(original, "one", "1");
  540. if (ast_format_cmp(first, second) != AST_FORMAT_CMP_EQUAL) {
  541. ast_test_status_update(test, "Formats with the same attributes should be equal\n");
  542. return AST_TEST_FAIL;
  543. }
  544. ast_test_validate(test, test_callbacks_called.format_attribute_set == 3);
  545. ast_test_validate(test, test_callbacks_called.format_cmp == 2);
  546. return AST_TEST_PASS;
  547. }
  548. AST_TEST_DEFINE(format_joint_same_codec)
  549. {
  550. RAII_VAR(struct ast_codec *, codec, NULL, ao2_cleanup);
  551. RAII_VAR(struct ast_format *, first, NULL, ao2_cleanup);
  552. RAII_VAR(struct ast_format *, second, NULL, ao2_cleanup);
  553. RAII_VAR(struct ast_format *, joint, NULL, ao2_cleanup);
  554. switch (cmd) {
  555. case TEST_INIT:
  556. info->name = __PRETTY_FUNCTION__;
  557. info->category = TEST_CATEGORY;
  558. info->summary = "Joint format unit test";
  559. info->description =
  560. "Test joint format creation using two different formats with same codec";
  561. return AST_TEST_NOT_RUN;
  562. case TEST_EXECUTE:
  563. break;
  564. }
  565. codec = ast_codec_get("ulaw", AST_MEDIA_TYPE_AUDIO, 8000);
  566. if (!codec) {
  567. ast_test_status_update(test, "Could not retrieve built-in ulaw codec\n");
  568. return AST_TEST_FAIL;
  569. }
  570. first = ast_format_create(codec);
  571. if (!first) {
  572. ast_test_status_update(test, "Could not create first format using built-in codec\n");
  573. return AST_TEST_FAIL;
  574. }
  575. second = ast_format_create(codec);
  576. if (!second) {
  577. ast_test_status_update(test, "Could not create second format using built-in codec\n");
  578. return AST_TEST_FAIL;
  579. }
  580. joint = ast_format_joint(first, second);
  581. if (!joint) {
  582. ast_test_status_update(test, "Failed to create a joint format using two formats of same codec\n");
  583. return AST_TEST_FAIL;
  584. } else if (ast_format_get_codec_id(joint) != codec->id) {
  585. ast_test_status_update(test, "Returned joint format does not contain expected codec\n");
  586. return AST_TEST_FAIL;
  587. }
  588. return AST_TEST_PASS;
  589. }
  590. AST_TEST_DEFINE(format_attr_joint_same_codec)
  591. {
  592. RAII_VAR(struct ast_codec *, codec, NULL, ao2_cleanup);
  593. RAII_VAR(struct ast_format *, original, NULL, ao2_cleanup);
  594. RAII_VAR(struct ast_format *, first, NULL, ao2_cleanup);
  595. RAII_VAR(struct ast_format *, second, NULL, ao2_cleanup);
  596. RAII_VAR(struct ast_format *, joint, NULL, ao2_cleanup);
  597. struct ast_str *fmtp = ast_str_alloca(64);
  598. switch (cmd) {
  599. case TEST_INIT:
  600. info->name = __PRETTY_FUNCTION__;
  601. info->category = TEST_CATEGORY;
  602. info->summary = "Joint format attribute unit test";
  603. info->description =
  604. "Test joint format creation using two different formats with attributes and with same codec";
  605. return AST_TEST_NOT_RUN;
  606. case TEST_EXECUTE:
  607. break;
  608. }
  609. codec = ast_codec_get("test_core_format_codec", AST_MEDIA_TYPE_AUDIO, 8000);
  610. if (!codec) {
  611. ast_test_status_update(test, "Could not retrieve test_core_format_codec codec\n");
  612. return AST_TEST_FAIL;
  613. }
  614. original = ast_format_create(codec);
  615. if (!original) {
  616. ast_test_status_update(test, "Could not create format from test_core_format_codec codec\n");
  617. return AST_TEST_FAIL;
  618. }
  619. first = ast_format_attribute_set(original, "one", "2");
  620. if (!first) {
  621. ast_test_status_update(test, "Could not create first format using test_core_format_codec codec\n");
  622. return AST_TEST_FAIL;
  623. }
  624. second = ast_format_attribute_set(original, "one", "5");
  625. if (!second) {
  626. ast_test_status_update(test, "Could not create second format using test_core_format_codec codec\n");
  627. return AST_TEST_FAIL;
  628. }
  629. joint = ast_format_joint(first, second);
  630. if (!joint) {
  631. ast_test_status_update(test, "Failed to create a joint format using two formats of same codec\n");
  632. return AST_TEST_FAIL;
  633. } else if (ast_format_get_codec_id(joint) != codec->id) {
  634. ast_test_status_update(test, "Returned joint format does not contain expected codec\n");
  635. return AST_TEST_FAIL;
  636. }
  637. ast_format_generate_sdp_fmtp(joint, 100, &fmtp);
  638. ast_test_validate(test, strcmp("a=fmtp:100 one=5;two=0\r\n", ast_str_buffer(fmtp)) == 0);
  639. ast_test_validate(test, test_callbacks_called.format_attribute_set == 2);
  640. ast_test_validate(test, test_callbacks_called.format_get_joint == 1);
  641. ast_test_validate(test, test_callbacks_called.format_generate_sdp_fmtp == 1);
  642. return AST_TEST_PASS;
  643. }
  644. AST_TEST_DEFINE(format_joint_different_codec)
  645. {
  646. RAII_VAR(struct ast_codec *, first_codec, NULL, ao2_cleanup);
  647. RAII_VAR(struct ast_codec *, second_codec, NULL, ao2_cleanup);
  648. RAII_VAR(struct ast_format *, first, NULL, ao2_cleanup);
  649. RAII_VAR(struct ast_format *, second, NULL, ao2_cleanup);
  650. RAII_VAR(struct ast_format *, joint, NULL, ao2_cleanup);
  651. switch (cmd) {
  652. case TEST_INIT:
  653. info->name = __PRETTY_FUNCTION__;
  654. info->category = TEST_CATEGORY;
  655. info->summary = "Joint format unit test";
  656. info->description =
  657. "Test that there is no joint format between two different formats with different codec";
  658. return AST_TEST_NOT_RUN;
  659. case TEST_EXECUTE:
  660. break;
  661. }
  662. first_codec = ast_codec_get("ulaw", AST_MEDIA_TYPE_AUDIO, 8000);
  663. if (!first_codec) {
  664. ast_test_status_update(test, "Could not retrieve built-in ulaw codec\n");
  665. return AST_TEST_FAIL;
  666. }
  667. first = ast_format_create(first_codec);
  668. if (!first) {
  669. ast_test_status_update(test, "Could not create first format using built-in codec\n");
  670. return AST_TEST_FAIL;
  671. }
  672. second_codec = ast_codec_get("alaw", AST_MEDIA_TYPE_AUDIO, 8000);
  673. if (!second_codec) {
  674. ast_test_status_update(test, "Could not retrieve built-in alaw codec\n");
  675. return AST_TEST_FAIL;
  676. }
  677. second = ast_format_create(second_codec);
  678. if (!second) {
  679. ast_test_status_update(test, "Could not create second format using built-in codec\n");
  680. return AST_TEST_FAIL;
  681. }
  682. joint = ast_format_joint(first, second);
  683. if (joint) {
  684. ast_test_status_update(test, "Got a joint format between two formats with different codecs\n");
  685. return AST_TEST_FAIL;
  686. }
  687. return AST_TEST_PASS;
  688. }
  689. AST_TEST_DEFINE(format_copy)
  690. {
  691. RAII_VAR(struct ast_codec *, codec, NULL, ao2_cleanup);
  692. RAII_VAR(struct ast_format *, format, NULL, ao2_cleanup);
  693. RAII_VAR(struct ast_format *, copy, NULL, ao2_cleanup);
  694. switch (cmd) {
  695. case TEST_INIT:
  696. info->name = __PRETTY_FUNCTION__;
  697. info->category = TEST_CATEGORY;
  698. info->summary = "Format copying unit test";
  699. info->description =
  700. "Test copying of a format";
  701. return AST_TEST_NOT_RUN;
  702. case TEST_EXECUTE:
  703. break;
  704. }
  705. codec = ast_codec_get("ulaw", AST_MEDIA_TYPE_AUDIO, 8000);
  706. if (!codec) {
  707. ast_test_status_update(test, "Could not retrieve built-in ulaw codec\n");
  708. return AST_TEST_FAIL;
  709. }
  710. format = ast_format_create(codec);
  711. if (!format) {
  712. ast_test_status_update(test, "Could not create format using built-in codec\n");
  713. return AST_TEST_FAIL;
  714. }
  715. copy = ao2_bump(format);
  716. if (!copy) {
  717. ast_test_status_update(test, "Copying of a just created format failed\n");
  718. return AST_TEST_FAIL;
  719. } else if (copy != format) {
  720. ast_test_status_update(test, "Copying of a format returned a new format instead of the same one\n");
  721. return AST_TEST_FAIL;
  722. }
  723. return AST_TEST_PASS;
  724. }
  725. AST_TEST_DEFINE(format_attribute_set_without_interface)
  726. {
  727. RAII_VAR(struct ast_codec *, codec, NULL, ao2_cleanup);
  728. RAII_VAR(struct ast_format *, format, NULL, ao2_cleanup);
  729. struct ast_format *attr_set;
  730. switch (cmd) {
  731. case TEST_INIT:
  732. info->name = __PRETTY_FUNCTION__;
  733. info->category = TEST_CATEGORY;
  734. info->summary = "Format attribute setting unit test";
  735. info->description =
  736. "Test that attribute setting on a format without an interface fails";
  737. return AST_TEST_NOT_RUN;
  738. case TEST_EXECUTE:
  739. break;
  740. }
  741. codec = ast_codec_get("ulaw", AST_MEDIA_TYPE_AUDIO, 8000);
  742. if (!codec) {
  743. ast_test_status_update(test, "Could not retrieve built-in ulaw codec\n");
  744. return AST_TEST_FAIL;
  745. }
  746. format = ast_format_create(codec);
  747. if (!format) {
  748. ast_test_status_update(test, "Could not create format using built-in codec\n");
  749. return AST_TEST_FAIL;
  750. }
  751. attr_set = ast_format_attribute_set(format, "bees", "cool");
  752. if (!attr_set) {
  753. ast_test_status_update(test, "Successfully set an attribute on a format without an interface\n");
  754. return AST_TEST_FAIL;
  755. }
  756. ao2_cleanup(attr_set);
  757. return AST_TEST_PASS;
  758. }
  759. AST_TEST_DEFINE(format_attribute_get_without_interface)
  760. {
  761. RAII_VAR(struct ast_codec *, codec, NULL, ao2_cleanup);
  762. RAII_VAR(struct ast_format *, format, NULL, ao2_cleanup);
  763. switch (cmd) {
  764. case TEST_INIT:
  765. info->name = __PRETTY_FUNCTION__;
  766. info->category = TEST_CATEGORY;
  767. info->summary = "Format attribute retrieval unit test";
  768. info->description =
  769. "Test that attribute retrieval on a format without an interface fails";
  770. return AST_TEST_NOT_RUN;
  771. case TEST_EXECUTE:
  772. break;
  773. }
  774. codec = ast_codec_get("ulaw", AST_MEDIA_TYPE_AUDIO, 8000);
  775. if (!codec) {
  776. ast_test_status_update(test, "Could not retrieve built-in ulaw codec\n");
  777. return AST_TEST_FAIL;
  778. }
  779. format = ast_format_create(codec);
  780. if (!format) {
  781. ast_test_status_update(test, "Could not create format using built-in codec\n");
  782. return AST_TEST_FAIL;
  783. }
  784. if (ast_format_attribute_get(format, "bees") != NULL) {
  785. ast_test_status_update(test, "Successfully retrieved an attribute on a format without an interface\n");
  786. return AST_TEST_FAIL;
  787. }
  788. return AST_TEST_PASS;
  789. }
  790. AST_TEST_DEFINE(format_parse_sdp_fmtp_without_interface)
  791. {
  792. RAII_VAR(struct ast_codec *, codec, NULL, ao2_cleanup);
  793. RAII_VAR(struct ast_format *, format, NULL, ao2_cleanup);
  794. RAII_VAR(struct ast_format *, generated, NULL, ao2_cleanup);
  795. switch (cmd) {
  796. case TEST_INIT:
  797. info->name = __PRETTY_FUNCTION__;
  798. info->category = TEST_CATEGORY;
  799. info->summary = "Format sdp parse unit test";
  800. info->description =
  801. "Test that sdp parsing on a format without an interface fails";
  802. return AST_TEST_NOT_RUN;
  803. case TEST_EXECUTE:
  804. break;
  805. }
  806. codec = ast_codec_get("ulaw", AST_MEDIA_TYPE_AUDIO, 8000);
  807. if (!codec) {
  808. ast_test_status_update(test, "Could not retrieve built-in ulaw codec\n");
  809. return AST_TEST_FAIL;
  810. }
  811. format = ast_format_create(codec);
  812. if (!format) {
  813. ast_test_status_update(test, "Could not create format using built-in codec\n");
  814. return AST_TEST_FAIL;
  815. }
  816. generated = ast_format_parse_sdp_fmtp(format, "tacos");
  817. if (generated != format) {
  818. ast_test_status_update(test, "Successfully parsed SDP on a format without an interface\n");
  819. return AST_TEST_FAIL;
  820. }
  821. return AST_TEST_PASS;
  822. }
  823. AST_TEST_DEFINE(format_parse_and_generate_sdp_fmtp)
  824. {
  825. RAII_VAR(struct ast_codec *, codec, NULL, ao2_cleanup);
  826. RAII_VAR(struct ast_format *, format, NULL, ao2_cleanup);
  827. RAII_VAR(struct ast_format *, generated, NULL, ao2_cleanup);
  828. struct ast_str *fmtp = ast_str_alloca(64);
  829. switch (cmd) {
  830. case TEST_INIT:
  831. info->name = __PRETTY_FUNCTION__;
  832. info->category = TEST_CATEGORY;
  833. info->summary = "Format sdp parse/generate unit test";
  834. info->description =
  835. "Test that sdp parsing and generation on a format with an interface succeeds";
  836. return AST_TEST_NOT_RUN;
  837. case TEST_EXECUTE:
  838. break;
  839. }
  840. codec = ast_codec_get("test_core_format_codec", AST_MEDIA_TYPE_AUDIO, 8000);
  841. if (!codec) {
  842. ast_test_status_update(test, "Could not retrieve test_core_format_codec codec\n");
  843. return AST_TEST_FAIL;
  844. }
  845. format = ast_format_create(codec);
  846. if (!format) {
  847. ast_test_status_update(test, "Could not create format using test_core_format_codec codec\n");
  848. return AST_TEST_FAIL;
  849. }
  850. generated = ast_format_parse_sdp_fmtp(format, "one=1000;two=256");
  851. if (format == generated) {
  852. ast_test_status_update(test, "Failed to parse SDP on a format without an interface\n");
  853. return AST_TEST_FAIL;
  854. }
  855. ast_format_generate_sdp_fmtp(generated, 8, &fmtp);
  856. ast_test_validate(test, strcmp("a=fmtp:8 one=1000;two=256\r\n", ast_str_buffer(fmtp)) == 0);
  857. ast_test_validate(test, test_callbacks_called.format_parse_sdp_fmtp == 1);
  858. ast_test_validate(test, test_callbacks_called.format_generate_sdp_fmtp == 1);
  859. return AST_TEST_PASS;
  860. }
  861. static int test_core_format_init(struct ast_test_info *info, struct ast_test *test)
  862. {
  863. memset(&test_callbacks_called, 0, sizeof(test_callbacks_called));
  864. return 0;
  865. }
  866. static int unload_module(void)
  867. {
  868. AST_TEST_UNREGISTER(format_create);
  869. AST_TEST_UNREGISTER(format_create_attr);
  870. AST_TEST_UNREGISTER(format_retrieve_attr);
  871. AST_TEST_UNREGISTER(format_clone);
  872. AST_TEST_UNREGISTER(format_cmp_same_codec);
  873. AST_TEST_UNREGISTER(format_attr_cmp_same_codec);
  874. AST_TEST_UNREGISTER(format_cmp_different_codec);
  875. AST_TEST_UNREGISTER(format_joint_same_codec);
  876. AST_TEST_UNREGISTER(format_attr_joint_same_codec);
  877. AST_TEST_UNREGISTER(format_joint_different_codec);
  878. AST_TEST_UNREGISTER(format_copy);
  879. AST_TEST_UNREGISTER(format_attribute_set_without_interface);
  880. AST_TEST_UNREGISTER(format_attribute_get_without_interface);
  881. AST_TEST_UNREGISTER(format_parse_sdp_fmtp_without_interface);
  882. AST_TEST_UNREGISTER(format_parse_and_generate_sdp_fmtp);
  883. return 0;
  884. }
  885. static int load_module(void)
  886. {
  887. /* Test codec/format interface used by this module */
  888. if (ast_codec_register(&test_core_format_codec)) {
  889. ast_log(AST_LOG_ERROR, "Failed to register test_core_format_codec\n");
  890. return AST_MODULE_LOAD_DECLINE;
  891. }
  892. if (ast_format_interface_register("test_core_format_codec", &test_core_format_attr)) {
  893. ast_log(AST_LOG_ERROR, "Failed to register format interface for test_core_format_codec\n");
  894. return AST_MODULE_LOAD_DECLINE;
  895. }
  896. AST_TEST_REGISTER(format_create);
  897. AST_TEST_REGISTER(format_create_attr);
  898. AST_TEST_REGISTER(format_retrieve_attr);
  899. AST_TEST_REGISTER(format_clone);
  900. AST_TEST_REGISTER(format_cmp_same_codec);
  901. AST_TEST_REGISTER(format_attr_cmp_same_codec);
  902. AST_TEST_REGISTER(format_cmp_different_codec);
  903. AST_TEST_REGISTER(format_joint_same_codec);
  904. AST_TEST_REGISTER(format_attr_joint_same_codec);
  905. AST_TEST_REGISTER(format_joint_different_codec);
  906. AST_TEST_REGISTER(format_copy);
  907. AST_TEST_REGISTER(format_attribute_set_without_interface);
  908. AST_TEST_REGISTER(format_attribute_get_without_interface);
  909. AST_TEST_REGISTER(format_parse_sdp_fmtp_without_interface);
  910. AST_TEST_REGISTER(format_parse_and_generate_sdp_fmtp);
  911. ast_test_register_init(TEST_CATEGORY, &test_core_format_init);
  912. return AST_MODULE_LOAD_SUCCESS;
  913. }
  914. AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Core format API test module");