test_stasis_channels.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  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 \brief Test Stasis Channel messages and objects
  20. *
  21. * \author\verbatim Matt Jordan <mjordan@digium.com> \endverbatim
  22. *
  23. * \ingroup tests
  24. */
  25. /*** MODULEINFO
  26. <depend>TEST_FRAMEWORK</depend>
  27. <support_level>core</support_level>
  28. ***/
  29. #include "asterisk.h"
  30. ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
  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->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->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,"
  239. " s: { s: s, s: s, s: i },"
  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. "dialplan",
  250. "context", "context",
  251. "exten", "exten",
  252. "priority", 1,
  253. "caller",
  254. "name", "cid_name",
  255. "number", "cid_num",
  256. "connected",
  257. "name", "",
  258. "number", "",
  259. "language", "en",
  260. "creationtime",
  261. ast_json_timeval(
  262. ast_channel_creationtime(chan), NULL));
  263. ast_test_validate(test, ast_json_equal(expected, actual));
  264. return AST_TEST_PASS;
  265. }
  266. static int unload_module(void)
  267. {
  268. AST_TEST_UNREGISTER(channel_blob_create);
  269. AST_TEST_UNREGISTER(null_blob);
  270. AST_TEST_UNREGISTER(multi_channel_blob_create);
  271. AST_TEST_UNREGISTER(multi_channel_blob_snapshots);
  272. AST_TEST_UNREGISTER(channel_snapshot_json);
  273. return 0;
  274. }
  275. static int load_module(void)
  276. {
  277. AST_TEST_REGISTER(channel_blob_create);
  278. AST_TEST_REGISTER(null_blob);
  279. AST_TEST_REGISTER(multi_channel_blob_create);
  280. AST_TEST_REGISTER(multi_channel_blob_snapshots);
  281. AST_TEST_REGISTER(channel_snapshot_json);
  282. return AST_MODULE_LOAD_SUCCESS;
  283. }
  284. AST_MODULE_INFO(ASTERISK_GPL_KEY, 0, "Stasis Channel Testing",
  285. .support_level = AST_MODULE_SUPPORT_CORE,
  286. .load = load_module,
  287. .unload = unload_module
  288. );