test_stasis_channels.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414
  1. /*
  2. * Asterisk -- An open source telephony toolkit.
  3. *
  4. * Copyright (C) 2013, Digium, Inc.
  5. *
  6. * Matt Jordan <mjordan@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 Test Stasis Channel messages and objects
  21. *
  22. * \author\verbatim Matt Jordan <mjordan@digium.com> \endverbatim
  23. *
  24. * \ingroup tests
  25. */
  26. /*** MODULEINFO
  27. <depend>TEST_FRAMEWORK</depend>
  28. <support_level>core</support_level>
  29. ***/
  30. #include "asterisk.h"
  31. #include "asterisk/astobj2.h"
  32. #include "asterisk/module.h"
  33. #include "asterisk/stasis.h"
  34. #include "asterisk/stasis_message_router.h"
  35. #include "asterisk/test.h"
  36. #include "asterisk/stasis_channels.h"
  37. #include "asterisk/channel.h"
  38. static const char *test_category = "/stasis/channels/";
  39. static void safe_channel_release(struct ast_channel *chan)
  40. {
  41. if (!chan) {
  42. return;
  43. }
  44. ast_channel_release(chan);
  45. }
  46. AST_TEST_DEFINE(channel_blob_create)
  47. {
  48. struct ast_channel_blob *blob;
  49. RAII_VAR(struct stasis_message_type *, type, NULL, ao2_cleanup);
  50. RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
  51. RAII_VAR(struct ast_channel *, chan, NULL, safe_channel_release);
  52. RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
  53. RAII_VAR(struct ast_json *, bad_json, NULL, ast_json_unref);
  54. switch (cmd) {
  55. case TEST_INIT:
  56. info->name = __func__;
  57. info->category = test_category;
  58. info->summary = "Test creation of ast_channel_blob objects";
  59. info->description = "Test creation of ast_channel_blob objects";
  60. return AST_TEST_NOT_RUN;
  61. case TEST_EXECUTE:
  62. break;
  63. }
  64. ast_test_validate(test, stasis_message_type_create("test-type", NULL, &type) == STASIS_MESSAGE_TYPE_SUCCESS);
  65. chan = ast_channel_alloc(0, AST_STATE_DOWN, "100", "Alice", "100", "100", "default", NULL, NULL, 0, "TEST/Alice");
  66. ast_channel_unlock(chan);
  67. json = ast_json_pack("{s: s}",
  68. "foo", "bar");
  69. /* Off nominal creation */
  70. ast_channel_lock(chan);
  71. ast_test_validate(test, NULL == ast_channel_blob_create(chan, NULL, json));
  72. /* Test for single channel */
  73. msg = ast_channel_blob_create(chan, type, json);
  74. ast_channel_unlock(chan);
  75. ast_test_validate(test, NULL != msg);
  76. blob = stasis_message_data(msg);
  77. ast_test_validate(test, NULL != blob);
  78. ast_test_validate(test, NULL != blob->snapshot);
  79. ast_test_validate(test, NULL != blob->blob);
  80. ast_test_validate(test, type == stasis_message_type(msg));
  81. ast_test_validate(test, 1 == ao2_ref(msg, 0));
  82. ao2_cleanup(msg);
  83. /* Test for global channels */
  84. msg = ast_channel_blob_create(NULL, type, json);
  85. ast_test_validate(test, NULL != msg);
  86. blob = stasis_message_data(msg);
  87. ast_test_validate(test, NULL != blob);
  88. ast_test_validate(test, NULL == blob->snapshot);
  89. ast_test_validate(test, NULL != blob->blob);
  90. ast_test_validate(test, type == stasis_message_type(msg));
  91. return AST_TEST_PASS;
  92. }
  93. AST_TEST_DEFINE(null_blob)
  94. {
  95. struct ast_channel_blob *blob;
  96. RAII_VAR(struct stasis_message_type *, type, NULL, ao2_cleanup);
  97. RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
  98. RAII_VAR(struct ast_channel *, chan, NULL, safe_channel_release);
  99. RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
  100. RAII_VAR(struct ast_json *, bad_json, NULL, ast_json_unref);
  101. switch (cmd) {
  102. case TEST_INIT:
  103. info->name = __func__;
  104. info->category = test_category;
  105. info->summary = "Test creation of ast_channel_blob objects";
  106. info->description = "Test creation of ast_channel_blob objects";
  107. return AST_TEST_NOT_RUN;
  108. case TEST_EXECUTE:
  109. break;
  110. }
  111. ast_test_validate(test, stasis_message_type_create("test-type", NULL, &type) == STASIS_MESSAGE_TYPE_SUCCESS);
  112. chan = ast_channel_alloc(0, AST_STATE_DOWN, "100", "Alice", "100", "100", "default", NULL, NULL, 0, "TEST/Alice");
  113. ast_channel_unlock(chan);
  114. json = ast_json_pack("{s: s}",
  115. "foo", "bar");
  116. /* Test for single channel */
  117. ast_channel_lock(chan);
  118. msg = ast_channel_blob_create(chan, type, NULL);
  119. ast_channel_unlock(chan);
  120. ast_test_validate(test, NULL != msg);
  121. blob = stasis_message_data(msg);
  122. ast_test_validate(test, NULL != blob);
  123. ast_test_validate(test, NULL != blob->snapshot);
  124. ast_test_validate(test, ast_json_null() == blob->blob);
  125. ast_test_validate(test, type == stasis_message_type(msg));
  126. return AST_TEST_PASS;
  127. }
  128. AST_TEST_DEFINE(multi_channel_blob_create)
  129. {
  130. RAII_VAR(struct ast_multi_channel_blob *, blob, NULL, ao2_cleanup);
  131. RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
  132. RAII_VAR(struct ast_json *, bad_json, NULL, ast_json_unref);
  133. switch (cmd) {
  134. case TEST_INIT:
  135. info->name = __func__;
  136. info->category = test_category;
  137. info->summary = "Test creation of ast_multi_channel_blob objects";
  138. info->description = "Test creation of ast_multi_channel_blob objects";
  139. return AST_TEST_NOT_RUN;
  140. case TEST_EXECUTE:
  141. break;
  142. }
  143. json = ast_json_pack("{s: s}",
  144. "foo", "bar");
  145. /* Test for single channel */
  146. blob = ast_multi_channel_blob_create(json);
  147. ast_test_validate(test, NULL != blob);
  148. ast_test_validate(test, NULL != ast_multi_channel_blob_get_json(blob));
  149. return AST_TEST_PASS;
  150. }
  151. AST_TEST_DEFINE(multi_channel_blob_snapshots)
  152. {
  153. RAII_VAR(struct ast_multi_channel_blob *, blob, NULL, ao2_cleanup);
  154. RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
  155. RAII_VAR(struct ast_channel *, chan_alice, NULL, safe_channel_release);
  156. RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release);
  157. RAII_VAR(struct ast_channel *, chan_charlie, NULL, safe_channel_release);
  158. struct ast_channel_snapshot *snapshot;
  159. struct ao2_container *matches;
  160. switch (cmd) {
  161. case TEST_INIT:
  162. info->name = __func__;
  163. info->category = test_category;
  164. info->summary = "Test creation of ast_multi_channel_blob objects";
  165. info->description = "Test creation of ast_multi_channel_blob objects";
  166. return AST_TEST_NOT_RUN;
  167. case TEST_EXECUTE:
  168. break;
  169. }
  170. json = ast_json_pack("{s: s}",
  171. "type", "test");
  172. chan_alice = ast_channel_alloc(0, AST_STATE_DOWN, "100", "Alice", "100", "100", "default", NULL, NULL, 0, "TEST/Alice");
  173. ast_channel_unlock(chan_alice);
  174. chan_bob = ast_channel_alloc(0, AST_STATE_DOWN, "200", "Bob", "200", "200", "default", NULL, NULL, 0, "TEST/Bob");
  175. ast_channel_unlock(chan_bob);
  176. chan_charlie = ast_channel_alloc(0, AST_STATE_DOWN, "300", "Bob", "300", "300", "default", NULL, NULL, 0, "TEST/Charlie");
  177. ast_channel_unlock(chan_charlie);
  178. blob = ast_multi_channel_blob_create(json);
  179. ast_channel_lock(chan_alice);
  180. ast_multi_channel_blob_add_channel(blob, "Caller", ast_channel_snapshot_create(chan_alice));
  181. ast_channel_unlock(chan_alice);
  182. ast_channel_lock(chan_bob);
  183. ast_multi_channel_blob_add_channel(blob, "Peer", ast_channel_snapshot_create(chan_bob));
  184. ast_channel_unlock(chan_bob);
  185. ast_channel_lock(chan_charlie);
  186. ast_multi_channel_blob_add_channel(blob, "Peer", ast_channel_snapshot_create(chan_charlie));
  187. ast_channel_unlock(chan_charlie);
  188. /* Test for unknown role */
  189. ast_test_validate(test, NULL == ast_multi_channel_blob_get_channel(blob, "Foobar"));
  190. /* Test for single match */
  191. snapshot = ast_multi_channel_blob_get_channel(blob, "Caller");
  192. ast_test_validate(test, NULL != snapshot);
  193. ast_test_validate(test, 0 == strcmp("TEST/Alice", snapshot->base->name));
  194. /* Test for single match, multiple possibilities */
  195. snapshot = ast_multi_channel_blob_get_channel(blob, "Peer");
  196. ast_test_validate(test, NULL != snapshot);
  197. ast_test_validate(test, 0 != strcmp("TEST/Alice", snapshot->base->name));
  198. /* Multi-match */
  199. matches = ast_multi_channel_blob_get_channels(blob, "Peer");
  200. ast_test_validate(test, NULL != matches);
  201. ast_test_validate(test, 2 == ao2_container_count(matches));
  202. snapshot = ao2_find(matches, "TEST/Bob", OBJ_KEY);
  203. ast_test_validate(test, NULL != snapshot);
  204. ao2_cleanup(snapshot);
  205. snapshot = ao2_find(matches, "TEST/Charlie", OBJ_KEY);
  206. ast_test_validate(test, NULL != snapshot);
  207. ao2_cleanup(snapshot);
  208. ast_test_validate(test, 1 == ao2_ref(matches, 0));
  209. ao2_cleanup(matches);
  210. return AST_TEST_PASS;
  211. }
  212. AST_TEST_DEFINE(channel_snapshot_json)
  213. {
  214. RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
  215. RAII_VAR(struct ast_channel *, chan, NULL, safe_channel_release);
  216. RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup);
  217. RAII_VAR(struct ast_json *, expected, NULL, ast_json_unref);
  218. RAII_VAR(struct ast_json *, actual, NULL, ast_json_unref);
  219. switch (cmd) {
  220. case TEST_INIT:
  221. info->name = __func__;
  222. info->category = test_category;
  223. info->summary = "Test creation of ast_channel_blob objects";
  224. info->description = "Test creation of ast_channel_blob objects";
  225. return AST_TEST_NOT_RUN;
  226. case TEST_EXECUTE:
  227. break;
  228. }
  229. ast_test_validate(test, NULL == ast_channel_snapshot_to_json(NULL, NULL));
  230. chan = ast_channel_alloc(0, AST_STATE_DOWN, "cid_num", "cid_name", "acctcode", "exten", "context", NULL, NULL, 0, "TEST/name");
  231. ast_channel_unlock(chan);
  232. ast_test_validate(test, NULL != chan);
  233. ast_channel_lock(chan);
  234. snapshot = ast_channel_snapshot_create(chan);
  235. ast_channel_unlock(chan);
  236. ast_test_validate(test, NULL != snapshot);
  237. actual = ast_channel_snapshot_to_json(snapshot, NULL);
  238. expected = ast_json_pack("{ s: s, s: s, s: s, s: s, s: s,"
  239. " s: { s: s, s: s, s: i, s: s, s: s },"
  240. " s: { s: s, s: s },"
  241. " s: { s: s, s: s },"
  242. " s: s"
  243. " s: o"
  244. "}",
  245. "name", "TEST/name",
  246. "state", "Down",
  247. "accountcode", "acctcode",
  248. "id", ast_channel_uniqueid(chan),
  249. "protocol_id", "",
  250. "dialplan",
  251. "context", "context",
  252. "exten", "exten",
  253. "priority", 1,
  254. "app_name", "",
  255. "app_data", "",
  256. "caller",
  257. "name", "cid_name",
  258. "number", "cid_num",
  259. "connected",
  260. "name", "",
  261. "number", "",
  262. "language", "en",
  263. "creationtime",
  264. ast_json_timeval(
  265. ast_channel_creationtime(chan), NULL));
  266. ast_test_validate(test, ast_json_equal(expected, actual));
  267. return AST_TEST_PASS;
  268. }
  269. AST_TEST_DEFINE(channel_redirect_snapshot_json)
  270. {
  271. RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
  272. RAII_VAR(struct ast_channel *, chan, NULL, safe_channel_release);
  273. RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup);
  274. RAII_VAR(struct ast_json *, expected, NULL, ast_json_unref);
  275. RAII_VAR(struct ast_json *, actual, NULL, ast_json_unref);
  276. struct ast_party_redirecting data;
  277. switch (cmd) {
  278. case TEST_INIT:
  279. info->name = __func__;
  280. info->category = test_category;
  281. info->summary = "Test creation of ast_channel_blob objects with rdnis";
  282. info->description = "Test creation of ast_channel_blob objects with rdnis";
  283. return AST_TEST_NOT_RUN;
  284. case TEST_EXECUTE:
  285. break;
  286. }
  287. ast_test_validate(test, NULL == ast_channel_snapshot_to_json(NULL, NULL));
  288. chan = ast_channel_alloc(0, AST_STATE_DOWN, "cid_num", "cid_name", "acctcode", "exten", "context", NULL, NULL, 0, "TEST/name");
  289. ast_channel_unlock(chan);
  290. ast_test_validate(test, NULL != chan);
  291. ast_channel_lock(chan);
  292. ast_party_redirecting_init(&data);
  293. data.from.number.valid = 1;
  294. data.from.number.str = ast_strdup("123456");
  295. ast_channel_set_redirecting(chan, &data, NULL);
  296. ast_party_redirecting_free(&data);
  297. ast_channel_unlock(chan);
  298. ast_channel_lock(chan);
  299. snapshot = ast_channel_snapshot_create(chan);
  300. ast_channel_unlock(chan);
  301. ast_test_validate(test, NULL != snapshot);
  302. actual = ast_channel_snapshot_to_json(snapshot, NULL);
  303. expected = ast_json_pack("{ s: s, s: s, s: s, s: s, s: s,"
  304. " s: { s: s, s: s, s: i, s: s, s: s },"
  305. " s: { s: s, s: s },"
  306. " s: { s: s, s: s },"
  307. " s: s"
  308. " s: s"
  309. " s: o"
  310. "}",
  311. "name", "TEST/name",
  312. "state", "Down",
  313. "accountcode", "acctcode",
  314. "id", ast_channel_uniqueid(chan),
  315. "protocol_id", "",
  316. "dialplan",
  317. "context", "context",
  318. "exten", "exten",
  319. "priority", 1,
  320. "app_name", "",
  321. "app_data", "",
  322. "caller",
  323. "name", "cid_name",
  324. "number", "cid_num",
  325. "connected",
  326. "name", "",
  327. "number", "",
  328. "language", "en",
  329. "caller_rdnis", "123456",
  330. "creationtime",
  331. ast_json_timeval(
  332. ast_channel_creationtime(chan), NULL));
  333. ast_test_validate(test, ast_json_equal(expected, actual));
  334. return AST_TEST_PASS;
  335. }
  336. static int unload_module(void)
  337. {
  338. AST_TEST_UNREGISTER(channel_blob_create);
  339. AST_TEST_UNREGISTER(null_blob);
  340. AST_TEST_UNREGISTER(multi_channel_blob_create);
  341. AST_TEST_UNREGISTER(multi_channel_blob_snapshots);
  342. AST_TEST_UNREGISTER(channel_snapshot_json);
  343. AST_TEST_UNREGISTER(channel_redirect_snapshot_json);
  344. return 0;
  345. }
  346. static int load_module(void)
  347. {
  348. AST_TEST_REGISTER(channel_blob_create);
  349. AST_TEST_REGISTER(null_blob);
  350. AST_TEST_REGISTER(multi_channel_blob_create);
  351. AST_TEST_REGISTER(multi_channel_blob_snapshots);
  352. AST_TEST_REGISTER(channel_snapshot_json);
  353. AST_TEST_REGISTER(channel_redirect_snapshot_json);
  354. return AST_MODULE_LOAD_SUCCESS;
  355. }
  356. AST_MODULE_INFO(ASTERISK_GPL_KEY, 0, "Stasis Channel Testing",
  357. .support_level = AST_MODULE_SUPPORT_CORE,
  358. .load = load_module,
  359. .unload = unload_module
  360. );