test_cdr.c 88 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599
  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 CDR unit tests
  21. *
  22. * \author Matt Jordan <mjordan@digium.com>
  23. *
  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 <math.h>
  32. #include "asterisk/module.h"
  33. #include "asterisk/test.h"
  34. #include "asterisk/cdr.h"
  35. #include "asterisk/linkedlists.h"
  36. #include "asterisk/chanvars.h"
  37. #include "asterisk/utils.h"
  38. #include "asterisk/causes.h"
  39. #include "asterisk/time.h"
  40. #include "asterisk/bridge.h"
  41. #include "asterisk/bridge_basic.h"
  42. #include "asterisk/stasis_channels.h"
  43. #include "asterisk/stasis_bridges.h"
  44. #define EPSILON 0.001
  45. #define TEST_CATEGORY "/main/cdr/"
  46. #define MOCK_CDR_BACKEND "mock_cdr_backend"
  47. #define CHANNEL_TECH_NAME "CDRTestChannel"
  48. /*! \brief A placeholder for Asterisk's 'real' CDR configuration */
  49. static struct ast_cdr_config *saved_config;
  50. /*! \brief A configuration suitable for 'normal' CDRs */
  51. static struct ast_cdr_config debug_cdr_config = {
  52. .settings.flags = CDR_ENABLED | CDR_DEBUG,
  53. };
  54. /*! \brief A configuration suitable for CDRs with unanswered records */
  55. static struct ast_cdr_config unanswered_cdr_config = {
  56. .settings.flags = CDR_ENABLED | CDR_UNANSWERED | CDR_DEBUG,
  57. };
  58. /*! \brief A configuration suitable for CDRs with congestion enabled */
  59. static struct ast_cdr_config congestion_cdr_config = {
  60. .settings.flags = CDR_ENABLED | CDR_UNANSWERED | CDR_DEBUG | CDR_CONGESTION,
  61. };
  62. /*! \brief Macro to swap a configuration out from the CDR engine. This should be
  63. * used at the beginning of each test to set the needed configuration for that
  64. * test.
  65. */
  66. #define SWAP_CONFIG(ao2_config, template) do { \
  67. *(ao2_config) = (template); \
  68. ast_cdr_set_config((ao2_config)); \
  69. } while (0)
  70. /*! \brief A linked list of received CDR entries from the engine */
  71. static AST_LIST_HEAD(, test_cdr_entry) actual_cdr_entries = AST_LIST_HEAD_INIT_VALUE;
  72. /*! \brief The Mock CDR backend condition wait */
  73. static ast_cond_t mock_cdr_cond;
  74. /*! \brief A channel technology used for the unit tests */
  75. static struct ast_channel_tech test_cdr_chan_tech = {
  76. .type = CHANNEL_TECH_NAME,
  77. .description = "Mock channel technology for CDR tests",
  78. };
  79. struct test_cdr_entry {
  80. struct ast_cdr *cdr;
  81. AST_LIST_ENTRY(test_cdr_entry) list;
  82. };
  83. /*! \brief The number of CDRs the mock backend has received */
  84. static int global_mock_cdr_count;
  85. /*! \internal
  86. * \brief Callback function for the mock CDR backend
  87. *
  88. * This function 'processes' a dispatched CDR record by adding it to the
  89. * \ref actual_cdr_entries list. When a test completes, it can verify the
  90. * expected records against this list of actual CDRs created by the engine.
  91. *
  92. * \param cdr The public CDR object created by the engine
  93. *
  94. * \retval -1 on error
  95. * \retval 0 on success
  96. */
  97. static int mock_cdr_backend_cb(struct ast_cdr *cdr)
  98. {
  99. struct ast_cdr *cdr_copy, *cdr_prev = NULL;
  100. struct ast_cdr *mock_cdr = NULL;
  101. struct test_cdr_entry *cdr_wrapper;
  102. cdr_wrapper = ast_calloc(1, sizeof(*cdr_wrapper));
  103. if (!cdr_wrapper) {
  104. return -1;
  105. }
  106. for (; cdr; cdr = cdr->next) {
  107. struct ast_var_t *var_entry, *var_copy;
  108. cdr_copy = ast_calloc(1, sizeof(*cdr_copy));
  109. if (!cdr_copy) {
  110. return -1;
  111. }
  112. *cdr_copy = *cdr;
  113. cdr_copy->varshead.first = NULL;
  114. cdr_copy->varshead.last = NULL;
  115. cdr_copy->next = NULL;
  116. AST_LIST_TRAVERSE(&cdr->varshead, var_entry, entries) {
  117. var_copy = ast_var_assign(var_entry->name, var_entry->value);
  118. if (!var_copy) {
  119. return -1;
  120. }
  121. AST_LIST_INSERT_TAIL(&cdr_copy->varshead, var_copy, entries);
  122. }
  123. if (!mock_cdr) {
  124. mock_cdr = cdr_copy;
  125. }
  126. if (cdr_prev) {
  127. cdr_prev->next = cdr_copy;
  128. }
  129. cdr_prev = cdr_copy;
  130. }
  131. cdr_wrapper->cdr = mock_cdr;
  132. AST_LIST_LOCK(&actual_cdr_entries);
  133. AST_LIST_INSERT_TAIL(&actual_cdr_entries, cdr_wrapper, list);
  134. global_mock_cdr_count++;
  135. ast_cond_signal(&mock_cdr_cond);
  136. AST_LIST_UNLOCK(&actual_cdr_entries);
  137. return 0;
  138. }
  139. /*! \internal
  140. * \brief Remove all entries from \ref actual_cdr_entries
  141. */
  142. static void clear_mock_cdr_backend(void)
  143. {
  144. struct test_cdr_entry *cdr_wrapper;
  145. AST_LIST_LOCK(&actual_cdr_entries);
  146. while ((cdr_wrapper = AST_LIST_REMOVE_HEAD(&actual_cdr_entries, list))) {
  147. ast_cdr_free(cdr_wrapper->cdr);
  148. ast_free(cdr_wrapper);
  149. }
  150. global_mock_cdr_count = 0;
  151. AST_LIST_UNLOCK(&actual_cdr_entries);
  152. }
  153. /*! \brief Verify a string field. This will set the test status result to fail;
  154. * as such, it assumes that (a) test is the test object variable, and (b) that
  155. * a return variable res exists.
  156. */
  157. #define VERIFY_STRING_FIELD(field, actual, expected) do { \
  158. if (strcmp((actual)->field, (expected)->field)) { \
  159. ast_test_status_update(test, "Field %s failed: actual %s, expected %s\n", #field, (actual)->field, (expected)->field); \
  160. ast_test_set_result(test, AST_TEST_FAIL); \
  161. res = AST_TEST_FAIL; \
  162. } } while (0)
  163. /*! \brief Verify a numeric field. This will set the test status result to fail;
  164. * as such, it assumes that (a) test is the test object variable, and (b) that
  165. * a return variable res exists.
  166. */
  167. #define VERIFY_NUMERIC_FIELD(field, actual, expected) do { \
  168. if ((actual)->field != (expected)->field) { \
  169. ast_test_status_update(test, "Field %s failed: actual %ld, expected %ld\n", #field, (long)(actual)->field, (long)(expected)->field); \
  170. ast_test_set_result(test, AST_TEST_FAIL); \
  171. res = AST_TEST_FAIL; \
  172. } } while (0)
  173. /*! \brief Verify a time field. This will set the test status result to fail;
  174. * as such, it assumes that (a) test is the test object variable, and (b) that
  175. * a return variable res exists.
  176. */
  177. #define VERIFY_TIME_VALUE(field, actual) do { \
  178. if (ast_tvzero((actual)->field)) { \
  179. ast_test_status_update(test, "Field %s failed: should not be 0\n", #field); \
  180. ast_test_set_result(test, AST_TEST_FAIL); \
  181. res = AST_TEST_FAIL; \
  182. } } while (0)
  183. /*! \brief Alice's Caller ID */
  184. #define ALICE_CALLERID { .id.name.str = "Alice", .id.name.valid = 1, .id.number.str = "100", .id.number.valid = 1, }
  185. /*! \brief Bob's Caller ID */
  186. #define BOB_CALLERID { .id.name.str = "Bob", .id.name.valid = 1, .id.number.str = "200", .id.number.valid = 1, }
  187. /*! \brief Charlie's Caller ID */
  188. #define CHARLIE_CALLERID { .id.name.str = "Charlie", .id.name.valid = 1, .id.number.str = "300", .id.number.valid = 1, }
  189. /*! \brief David's Caller ID */
  190. #define DAVID_CALLERID { .id.name.str = "David", .id.name.valid = 1, .id.number.str = "400", .id.number.valid = 1, }
  191. /*! \brief Copy the linkedid and uniqueid from a channel to an expected CDR */
  192. #define COPY_IDS(channel_var, expected_record) do { \
  193. ast_copy_string((expected_record)->uniqueid, ast_channel_uniqueid((channel_var)), sizeof((expected_record)->uniqueid)); \
  194. ast_copy_string((expected_record)->linkedid, ast_channel_linkedid((channel_var)), sizeof((expected_record)->linkedid)); \
  195. } while (0)
  196. /*! \brief Create a \ref test_cdr_chan_tech for Alice, and set the expected
  197. * CDR records' linkedid and uniqueid. */
  198. #define CREATE_ALICE_CHANNEL(channel_var, caller_id, expected_record) do { \
  199. (channel_var) = ast_channel_alloc(0, AST_STATE_DOWN, "100", "Alice", "100", "100", "default", NULL, NULL, 0, CHANNEL_TECH_NAME "/Alice"); \
  200. ast_channel_set_caller((channel_var), (caller_id), NULL); \
  201. ast_copy_string((expected_record)->uniqueid, ast_channel_uniqueid((channel_var)), sizeof((expected_record)->uniqueid)); \
  202. ast_copy_string((expected_record)->linkedid, ast_channel_linkedid((channel_var)), sizeof((expected_record)->linkedid)); \
  203. ast_channel_unlock((channel_var)); \
  204. } while (0)
  205. /*! \brief Create a \ref test_cdr_chan_tech for Bob, and set the expected
  206. * CDR records' linkedid and uniqueid. */
  207. #define CREATE_BOB_CHANNEL(channel_var, caller_id, expected_record) do { \
  208. (channel_var) = ast_channel_alloc(0, AST_STATE_DOWN, "200", "Bob", "200", "200", "default", NULL, NULL, 0, CHANNEL_TECH_NAME "/Bob"); \
  209. ast_channel_set_caller((channel_var), (caller_id), NULL); \
  210. ast_copy_string((expected_record)->uniqueid, ast_channel_uniqueid((channel_var)), sizeof((expected_record)->uniqueid)); \
  211. ast_copy_string((expected_record)->linkedid, ast_channel_linkedid((channel_var)), sizeof((expected_record)->linkedid)); \
  212. ast_channel_unlock((channel_var)); \
  213. } while (0)
  214. /*! \brief Create a \ref test_cdr_chan_tech for Charlie, and set the expected
  215. * CDR records' linkedid and uniqueid. */
  216. #define CREATE_CHARLIE_CHANNEL(channel_var, caller_id, expected_record) do { \
  217. (channel_var) = ast_channel_alloc(0, AST_STATE_DOWN, "300", "Charlie", "300", "300", "default", NULL, NULL, 0, CHANNEL_TECH_NAME "/Charlie"); \
  218. ast_channel_set_caller((channel_var), (caller_id), NULL); \
  219. ast_copy_string((expected_record)->uniqueid, ast_channel_uniqueid((channel_var)), sizeof((expected_record)->uniqueid)); \
  220. ast_copy_string((expected_record)->linkedid, ast_channel_linkedid((channel_var)), sizeof((expected_record)->linkedid)); \
  221. ast_channel_unlock((channel_var)); \
  222. } while (0)
  223. /*! \brief Create a \ref test_cdr_chan_tech for Charlie, and set the expected
  224. * CDR records' linkedid and uniqueid. */
  225. #define CREATE_DAVID_CHANNEL(channel_var, caller_id, expected_record) do { \
  226. (channel_var) = ast_channel_alloc(0, AST_STATE_DOWN, "400", "David", "400", "400", "default", NULL, NULL, 0, CHANNEL_TECH_NAME "/David"); \
  227. ast_channel_set_caller((channel_var), (caller_id), NULL); \
  228. ast_copy_string((expected_record)->uniqueid, ast_channel_uniqueid((channel_var)), sizeof((expected_record)->uniqueid)); \
  229. ast_copy_string((expected_record)->linkedid, ast_channel_linkedid((channel_var)), sizeof((expected_record)->linkedid)); \
  230. ast_channel_unlock((channel_var)); \
  231. } while (0)
  232. /*! \brief Emulate a channel entering into an application */
  233. #define EMULATE_APP_DATA(channel, priority, application, data) do { \
  234. if ((priority) > 0) { \
  235. ast_channel_priority_set((channel), (priority)); \
  236. } \
  237. ast_channel_lock((channel)); \
  238. ast_channel_appl_set((channel), (application)); \
  239. ast_channel_data_set((channel), (data)); \
  240. ast_channel_publish_snapshot((channel)); \
  241. ast_channel_unlock((channel)); \
  242. } while (0)
  243. /*! \brief Hang up a test channel safely */
  244. #define HANGUP_CHANNEL(channel, cause) \
  245. do { \
  246. ast_channel_hangupcause_set((channel), (cause)); \
  247. ast_hangup(channel); \
  248. channel = NULL; \
  249. } while (0)
  250. static enum ast_test_result_state verify_mock_cdr_record(struct ast_test *test, struct ast_cdr *expected, int record)
  251. {
  252. struct ast_cdr *actual = NULL;
  253. struct test_cdr_entry *cdr_wrapper;
  254. int count = 0;
  255. struct timeval wait_now = ast_tvnow();
  256. struct timespec wait_time = { .tv_sec = wait_now.tv_sec + 5, .tv_nsec = wait_now.tv_usec * 1000 };
  257. enum ast_test_result_state res = AST_TEST_PASS;
  258. while (count < record) {
  259. AST_LIST_LOCK(&actual_cdr_entries);
  260. if (global_mock_cdr_count < record) {
  261. ast_cond_timedwait(&mock_cdr_cond, &actual_cdr_entries.lock, &wait_time);
  262. }
  263. cdr_wrapper = AST_LIST_REMOVE_HEAD(&actual_cdr_entries, list);
  264. AST_LIST_UNLOCK(&actual_cdr_entries);
  265. if (!cdr_wrapper) {
  266. ast_test_status_update(test, "Unable to find actual CDR record at %d\n", count);
  267. return AST_TEST_FAIL;
  268. }
  269. actual = cdr_wrapper->cdr;
  270. if (!expected && actual) {
  271. ast_test_status_update(test, "CDRs recorded where no record expected\n");
  272. return AST_TEST_FAIL;
  273. }
  274. ast_test_debug(test, "Verifying expected record %s, %s\n",
  275. expected->channel, S_OR(expected->dstchannel, "<none>"));
  276. VERIFY_STRING_FIELD(accountcode, actual, expected);
  277. VERIFY_NUMERIC_FIELD(amaflags, actual, expected);
  278. VERIFY_STRING_FIELD(channel, actual, expected);
  279. VERIFY_STRING_FIELD(clid, actual, expected);
  280. VERIFY_STRING_FIELD(dcontext, actual, expected);
  281. VERIFY_NUMERIC_FIELD(disposition, actual, expected);
  282. VERIFY_STRING_FIELD(dst, actual, expected);
  283. VERIFY_STRING_FIELD(dstchannel, actual, expected);
  284. VERIFY_STRING_FIELD(lastapp, actual, expected);
  285. VERIFY_STRING_FIELD(lastdata, actual, expected);
  286. VERIFY_STRING_FIELD(linkedid, actual, expected);
  287. VERIFY_STRING_FIELD(peeraccount, actual, expected);
  288. VERIFY_STRING_FIELD(src, actual, expected);
  289. VERIFY_STRING_FIELD(uniqueid, actual, expected);
  290. VERIFY_STRING_FIELD(userfield, actual, expected);
  291. VERIFY_TIME_VALUE(start, actual);
  292. VERIFY_TIME_VALUE(end, actual);
  293. /* Note: there's no way we can really calculate a duration or
  294. * billsec - the unit tests are too short. However, if billsec is
  295. * non-zero in the expected, then make sure we have an answer time
  296. */
  297. if (expected->billsec) {
  298. VERIFY_TIME_VALUE(answer, actual);
  299. }
  300. ast_test_debug(test, "Finished expected record %s, %s\n",
  301. expected->channel, S_OR(expected->dstchannel, "<none>"));
  302. expected = expected->next;
  303. ++count;
  304. }
  305. return res;
  306. }
  307. static void safe_channel_release(struct ast_channel *chan)
  308. {
  309. if (!chan) {
  310. return;
  311. }
  312. ast_channel_release(chan);
  313. }
  314. static void safe_bridge_destroy(struct ast_bridge *bridge)
  315. {
  316. if (!bridge) {
  317. return;
  318. }
  319. ast_bridge_destroy(bridge, 0);
  320. }
  321. static void do_sleep(struct timespec *to_sleep)
  322. {
  323. while ((nanosleep(to_sleep, to_sleep) == -1) && (errno == EINTR)) {
  324. }
  325. }
  326. AST_TEST_DEFINE(test_cdr_channel_creation)
  327. {
  328. RAII_VAR(struct ast_channel *, chan, NULL, safe_channel_release);
  329. RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
  330. ao2_cleanup);
  331. struct ast_party_caller caller = ALICE_CALLERID;
  332. struct ast_cdr expected = {
  333. .clid = "\"Alice\" <100>",
  334. .src = "100",
  335. .dst = "100",
  336. .dcontext = "default",
  337. .channel = CHANNEL_TECH_NAME "/Alice",
  338. .amaflags = AST_AMA_DOCUMENTATION,
  339. .disposition = AST_CDR_NOANSWER,
  340. .accountcode = "100",
  341. };
  342. enum ast_test_result_state result = AST_TEST_NOT_RUN;
  343. switch (cmd) {
  344. case TEST_INIT:
  345. info->name = __func__;
  346. info->category = TEST_CATEGORY;
  347. info->summary = "Test that a CDR is created when a channel is created";
  348. info->description =
  349. "Test that a CDR is created when a channel is created";
  350. return AST_TEST_NOT_RUN;
  351. case TEST_EXECUTE:
  352. break;
  353. }
  354. SWAP_CONFIG(config, unanswered_cdr_config);
  355. CREATE_ALICE_CHANNEL(chan, (&caller), &expected);
  356. HANGUP_CHANNEL(chan, AST_CAUSE_NORMAL);
  357. result = verify_mock_cdr_record(test, &expected, 1);
  358. return result;
  359. }
  360. AST_TEST_DEFINE(test_cdr_unanswered_inbound_call)
  361. {
  362. RAII_VAR(struct ast_channel *, chan, NULL, safe_channel_release);
  363. RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
  364. ao2_cleanup);
  365. struct ast_party_caller caller = ALICE_CALLERID;
  366. struct ast_cdr expected = {
  367. .clid = "\"Alice\" <100>",
  368. .src = "100",
  369. .dst = "100",
  370. .dcontext = "default",
  371. .channel = CHANNEL_TECH_NAME "/Alice",
  372. .lastapp = "Wait",
  373. .lastdata = "1",
  374. .amaflags = AST_AMA_DOCUMENTATION,
  375. .disposition = AST_CDR_NOANSWER,
  376. .accountcode = "100",
  377. };
  378. enum ast_test_result_state result = AST_TEST_NOT_RUN;
  379. switch (cmd) {
  380. case TEST_INIT:
  381. info->name = __func__;
  382. info->category = TEST_CATEGORY;
  383. info->summary = "Test inbound unanswered calls";
  384. info->description =
  385. "Test the properties of a CDR for a call that is\n"
  386. "inbound to Asterisk, executes some dialplan, but\n"
  387. "is never answered.\n";
  388. return AST_TEST_NOT_RUN;
  389. case TEST_EXECUTE:
  390. break;
  391. }
  392. SWAP_CONFIG(config, unanswered_cdr_config);
  393. CREATE_ALICE_CHANNEL(chan, &caller, &expected);
  394. EMULATE_APP_DATA(chan, 1, "Wait", "1");
  395. HANGUP_CHANNEL(chan, AST_CAUSE_NORMAL);
  396. result = verify_mock_cdr_record(test, &expected, 1);
  397. return result;
  398. }
  399. AST_TEST_DEFINE(test_cdr_unanswered_outbound_call)
  400. {
  401. RAII_VAR(struct ast_channel *, chan, NULL, safe_channel_release);
  402. RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
  403. ao2_cleanup);
  404. struct ast_party_caller caller = {
  405. .id.name.str = "",
  406. .id.name.valid = 1,
  407. .id.number.str = "",
  408. .id.number.valid = 1, };
  409. struct ast_cdr expected = {
  410. .clid = "\"\" <>",
  411. .dst = "s",
  412. .dcontext = "default",
  413. .channel = CHANNEL_TECH_NAME "/Alice",
  414. .lastapp = "AppDial",
  415. .lastdata = "(Outgoing Line)",
  416. .amaflags = AST_AMA_DOCUMENTATION,
  417. .disposition = AST_CDR_NOANSWER,
  418. .accountcode = "100",
  419. };
  420. enum ast_test_result_state result = AST_TEST_NOT_RUN;
  421. switch (cmd) {
  422. case TEST_INIT:
  423. info->name = __func__;
  424. info->category = TEST_CATEGORY;
  425. info->summary = "Test outbound unanswered calls";
  426. info->description =
  427. "Test the properties of a CDR for a call that is\n"
  428. "outbound to Asterisk but is never answered.\n";
  429. return AST_TEST_NOT_RUN;
  430. case TEST_EXECUTE:
  431. break;
  432. }
  433. SWAP_CONFIG(config, unanswered_cdr_config);
  434. CREATE_ALICE_CHANNEL(chan, &caller, &expected);
  435. ast_channel_exten_set(chan, "s");
  436. ast_channel_context_set(chan, "default");
  437. ast_set_flag(ast_channel_flags(chan), AST_FLAG_ORIGINATED);
  438. EMULATE_APP_DATA(chan, 0, "AppDial", "(Outgoing Line)");
  439. HANGUP_CHANNEL(chan, AST_CAUSE_NORMAL);
  440. result = verify_mock_cdr_record(test, &expected, 1);
  441. return result;
  442. }
  443. AST_TEST_DEFINE(test_cdr_outbound_bridged_call)
  444. {
  445. RAII_VAR(struct ast_channel *, chan_alice, NULL, safe_channel_release);
  446. RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release);
  447. RAII_VAR(struct ast_bridge *, bridge, NULL, safe_bridge_destroy);
  448. RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
  449. ao2_cleanup);
  450. struct timespec to_sleep = {1, 0};
  451. enum ast_test_result_state result = AST_TEST_NOT_RUN;
  452. struct ast_party_caller caller = ALICE_CALLERID;
  453. struct ast_cdr alice_expected = {
  454. .clid = "\"Alice\" <100>",
  455. .src = "100",
  456. .dst = "100",
  457. .dcontext = "default",
  458. .channel = CHANNEL_TECH_NAME "/Alice",
  459. .dstchannel = CHANNEL_TECH_NAME "/Bob",
  460. .lastapp = "",
  461. .lastdata = "",
  462. .amaflags = AST_AMA_DOCUMENTATION,
  463. .billsec = 1,
  464. .disposition = AST_CDR_ANSWERED,
  465. .accountcode = "100",
  466. .peeraccount = "200",
  467. };
  468. struct ast_cdr bob_expected = {
  469. .clid = "\"\" <>",
  470. .src = "",
  471. .dst = "s",
  472. .dcontext = "default",
  473. .channel = CHANNEL_TECH_NAME "/Bob",
  474. .dstchannel = "",
  475. .lastapp = "AppDial",
  476. .lastdata = "(Outgoing Line)",
  477. .amaflags = AST_AMA_DOCUMENTATION,
  478. .billsec = 1,
  479. .disposition = AST_CDR_ANSWERED,
  480. .accountcode = "200",
  481. .peeraccount = "",
  482. .next = &alice_expected,
  483. };
  484. switch (cmd) {
  485. case TEST_INIT:
  486. info->name = __func__;
  487. info->category = TEST_CATEGORY;
  488. info->summary = "Test dialing, answering, and going into a 2-party bridge";
  489. info->description =
  490. "The most 'basic' of scenarios\n";
  491. return AST_TEST_NOT_RUN;
  492. case TEST_EXECUTE:
  493. break;
  494. }
  495. SWAP_CONFIG(config, debug_cdr_config);
  496. CREATE_ALICE_CHANNEL(chan_alice, &caller, &alice_expected);
  497. ast_channel_state_set(chan_alice, AST_STATE_UP);
  498. bridge = ast_bridge_basic_new();
  499. ast_test_validate(test, bridge != NULL);
  500. do_sleep(&to_sleep);
  501. ast_test_validate(test, !ast_bridge_impart(bridge, chan_alice, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
  502. chan_bob = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, NULL, chan_alice, 0, CHANNEL_TECH_NAME "/Bob");
  503. ast_channel_unlock(chan_bob);
  504. ast_copy_string(bob_expected.linkedid, ast_channel_linkedid(chan_bob), sizeof(bob_expected.linkedid));
  505. ast_copy_string(bob_expected.uniqueid, ast_channel_uniqueid(chan_bob), sizeof(bob_expected.uniqueid));
  506. ast_set_flag(ast_channel_flags(chan_bob), AST_FLAG_OUTGOING);
  507. ast_set_flag(ast_channel_flags(chan_bob), AST_FLAG_ORIGINATED);
  508. EMULATE_APP_DATA(chan_bob, 0, "AppDial", "(Outgoing Line)");
  509. ast_channel_publish_dial(NULL, chan_bob, "Bob", NULL);
  510. ast_channel_state_set(chan_bob, AST_STATE_RINGING);
  511. ast_channel_publish_dial(NULL, chan_bob, NULL, "ANSWER");
  512. ast_channel_state_set(chan_bob, AST_STATE_UP);
  513. do_sleep(&to_sleep);
  514. ast_test_validate(test, !ast_bridge_impart(bridge, chan_bob, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
  515. do_sleep(&to_sleep);
  516. ast_bridge_depart(chan_bob);
  517. ast_bridge_depart(chan_alice);
  518. HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL);
  519. HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL);
  520. result = verify_mock_cdr_record(test, &bob_expected, 2);
  521. return result;
  522. }
  523. AST_TEST_DEFINE(test_cdr_single_party)
  524. {
  525. RAII_VAR(struct ast_channel *, chan, NULL, safe_channel_release);
  526. RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
  527. ao2_cleanup);
  528. struct ast_party_caller caller = ALICE_CALLERID;
  529. struct ast_cdr expected = {
  530. .clid = "\"Alice\" <100>",
  531. .src = "100",
  532. .dst = "100",
  533. .dcontext = "default",
  534. .channel = CHANNEL_TECH_NAME "/Alice",
  535. .dstchannel = "",
  536. .lastapp = "VoiceMailMain",
  537. .lastdata = "1",
  538. .billsec = 1,
  539. .amaflags = AST_AMA_DOCUMENTATION,
  540. .disposition = AST_CDR_ANSWERED,
  541. .accountcode = "100",
  542. };
  543. enum ast_test_result_state result = AST_TEST_NOT_RUN;
  544. switch (cmd) {
  545. case TEST_INIT:
  546. info->name = __func__;
  547. info->category = TEST_CATEGORY;
  548. info->summary = "Test cdrs for a single party";
  549. info->description =
  550. "Test the properties of a CDR for a call that is\n"
  551. "answered, but only involves a single channel\n";
  552. return AST_TEST_NOT_RUN;
  553. case TEST_EXECUTE:
  554. break;
  555. }
  556. SWAP_CONFIG(config, debug_cdr_config);
  557. CREATE_ALICE_CHANNEL(chan, &caller, &expected);
  558. ast_channel_lock(chan);
  559. EMULATE_APP_DATA(chan, 1, "Answer", "");
  560. ast_setstate(chan, AST_STATE_UP);
  561. EMULATE_APP_DATA(chan, 2, "VoiceMailMain", "1");
  562. ast_channel_unlock(chan);
  563. HANGUP_CHANNEL(chan, AST_CAUSE_NORMAL);
  564. result = verify_mock_cdr_record(test, &expected, 1);
  565. return result;
  566. }
  567. AST_TEST_DEFINE(test_cdr_single_bridge)
  568. {
  569. RAII_VAR(struct ast_channel *, chan, NULL, safe_channel_release);
  570. RAII_VAR(struct ast_bridge *, bridge, NULL, safe_bridge_destroy);
  571. RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
  572. ao2_cleanup);
  573. struct timespec to_sleep = {1, 0};
  574. struct ast_party_caller caller = ALICE_CALLERID;
  575. struct ast_cdr expected = {
  576. .clid = "\"Alice\" <100>",
  577. .src = "100",
  578. .dst = "100",
  579. .dcontext = "default",
  580. .channel = CHANNEL_TECH_NAME "/Alice",
  581. .lastapp = "Bridge",
  582. .billsec = 1,
  583. .amaflags = AST_AMA_DOCUMENTATION,
  584. .disposition = AST_CDR_ANSWERED,
  585. .accountcode = "100",
  586. };
  587. enum ast_test_result_state result = AST_TEST_NOT_RUN;
  588. switch (cmd) {
  589. case TEST_INIT:
  590. info->name = __func__;
  591. info->category = TEST_CATEGORY;
  592. info->summary = "Test cdrs for a single party entering/leaving a bridge";
  593. info->description =
  594. "Test the properties of a CDR for a call that is\n"
  595. "answered, enters a bridge, and leaves it.\n";
  596. return AST_TEST_NOT_RUN;
  597. case TEST_EXECUTE:
  598. break;
  599. }
  600. SWAP_CONFIG(config, debug_cdr_config);
  601. CREATE_ALICE_CHANNEL(chan, &caller, &expected);
  602. ast_channel_lock(chan);
  603. EMULATE_APP_DATA(chan, 1, "Answer", "");
  604. ast_setstate(chan, AST_STATE_UP);
  605. EMULATE_APP_DATA(chan, 2, "Bridge", "");
  606. ast_channel_unlock(chan);
  607. bridge = ast_bridge_basic_new();
  608. ast_test_validate(test, bridge != NULL);
  609. do_sleep(&to_sleep);
  610. ast_test_validate(test, !ast_bridge_impart(bridge, chan, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
  611. do_sleep(&to_sleep);
  612. ast_bridge_depart(chan);
  613. HANGUP_CHANNEL(chan, AST_CAUSE_NORMAL);
  614. result = verify_mock_cdr_record(test, &expected, 1);
  615. return result;
  616. }
  617. AST_TEST_DEFINE(test_cdr_single_bridge_continue)
  618. {
  619. RAII_VAR(struct ast_channel *, chan, NULL, safe_channel_release);
  620. RAII_VAR(struct ast_bridge *, bridge, NULL, safe_bridge_destroy);
  621. RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
  622. ao2_cleanup);
  623. struct timespec to_sleep = {1, 0};
  624. struct ast_party_caller caller = ALICE_CALLERID;
  625. struct ast_cdr expected_two = {
  626. .clid = "\"Alice\" <100>",
  627. .src = "100",
  628. .dst = "100",
  629. .dcontext = "default",
  630. .channel = CHANNEL_TECH_NAME "/Alice",
  631. .lastapp = "Wait",
  632. .billsec = 1,
  633. .amaflags = AST_AMA_DOCUMENTATION,
  634. .disposition = AST_CDR_ANSWERED,
  635. .accountcode = "100",
  636. };
  637. struct ast_cdr expected_one = {
  638. .clid = "\"Alice\" <100>",
  639. .src = "100",
  640. .dst = "100",
  641. .dcontext = "default",
  642. .channel = CHANNEL_TECH_NAME "/Alice",
  643. .lastapp = "Bridge",
  644. .billsec = 1,
  645. .amaflags = AST_AMA_DOCUMENTATION,
  646. .disposition = AST_CDR_ANSWERED,
  647. .accountcode = "100",
  648. .next = &expected_two,
  649. };
  650. enum ast_test_result_state result = AST_TEST_NOT_RUN;
  651. switch (cmd) {
  652. case TEST_INIT:
  653. info->name = __func__;
  654. info->category = TEST_CATEGORY;
  655. info->summary = "Test cdrs for a single party entering/leaving a bridge";
  656. info->description =
  657. "Test the properties of a CDR for a call that is\n"
  658. "answered, enters a bridge, and leaves it.\n";
  659. return AST_TEST_NOT_RUN;
  660. case TEST_EXECUTE:
  661. break;
  662. }
  663. SWAP_CONFIG(config, debug_cdr_config);
  664. CREATE_ALICE_CHANNEL(chan, &caller, &expected_one);
  665. COPY_IDS(chan, &expected_two);
  666. ast_channel_lock(chan);
  667. EMULATE_APP_DATA(chan, 1, "Answer", "");
  668. ast_setstate(chan, AST_STATE_UP);
  669. EMULATE_APP_DATA(chan, 2, "Bridge", "");
  670. ast_channel_unlock(chan);
  671. bridge = ast_bridge_basic_new();
  672. ast_test_validate(test, bridge != NULL);
  673. do_sleep(&to_sleep);
  674. ast_test_validate(test, !ast_bridge_impart(bridge, chan, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
  675. do_sleep(&to_sleep);
  676. ast_bridge_depart(chan);
  677. EMULATE_APP_DATA(chan, 3, "Wait", "");
  678. /* And then it hangs up */
  679. HANGUP_CHANNEL(chan, AST_CAUSE_NORMAL);
  680. result = verify_mock_cdr_record(test, &expected_one, 2);
  681. return result;
  682. }
  683. AST_TEST_DEFINE(test_cdr_single_twoparty_bridge_a)
  684. {
  685. RAII_VAR(struct ast_channel *, chan_alice, NULL, safe_channel_release);
  686. RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release);
  687. RAII_VAR(struct ast_bridge *, bridge, NULL, safe_bridge_destroy);
  688. RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
  689. ao2_cleanup);
  690. struct timespec to_sleep = {1, 0};
  691. struct ast_party_caller caller_alice = ALICE_CALLERID;
  692. struct ast_party_caller caller_bob = BOB_CALLERID;
  693. struct ast_cdr bob_expected = {
  694. .clid = "\"Bob\" <200>",
  695. .src = "200",
  696. .dst = "200",
  697. .dcontext = "default",
  698. .channel = CHANNEL_TECH_NAME "/Bob",
  699. .lastapp = "Bridge",
  700. .billsec = 1,
  701. .amaflags = AST_AMA_DOCUMENTATION,
  702. .disposition = AST_CDR_ANSWERED,
  703. .accountcode = "200",
  704. };
  705. struct ast_cdr alice_expected = {
  706. .clid = "\"Alice\" <100>",
  707. .src = "100",
  708. .dst = "100",
  709. .dcontext = "default",
  710. .channel = CHANNEL_TECH_NAME "/Alice",
  711. .dstchannel = CHANNEL_TECH_NAME "/Bob",
  712. .lastapp = "Bridge",
  713. .billsec = 1,
  714. .amaflags = AST_AMA_DOCUMENTATION,
  715. .disposition = AST_CDR_ANSWERED,
  716. .accountcode = "100",
  717. .peeraccount = "200",
  718. .next = &bob_expected,
  719. };
  720. enum ast_test_result_state result = AST_TEST_NOT_RUN;
  721. switch (cmd) {
  722. case TEST_INIT:
  723. info->name = __func__;
  724. info->category = TEST_CATEGORY;
  725. info->summary = "Test cdrs for a single party entering/leaving a bridge";
  726. info->description =
  727. "Test the properties of a CDR for a call that is\n"
  728. "answered, enters a bridge, and leaves it. In this scenario, the\n"
  729. "Party A should answer the bridge first.\n";
  730. return AST_TEST_NOT_RUN;
  731. case TEST_EXECUTE:
  732. break;
  733. }
  734. SWAP_CONFIG(config, debug_cdr_config);
  735. CREATE_ALICE_CHANNEL(chan_alice, &caller_alice, &alice_expected);
  736. CREATE_BOB_CHANNEL(chan_bob, &caller_bob, &bob_expected);
  737. ast_copy_string(bob_expected.linkedid, ast_channel_linkedid(chan_alice), sizeof(bob_expected.linkedid));
  738. ast_channel_lock(chan_alice);
  739. EMULATE_APP_DATA(chan_alice, 1, "Answer", "");
  740. ast_setstate(chan_alice, AST_STATE_UP);
  741. EMULATE_APP_DATA(chan_alice, 2, "Bridge", "");
  742. ast_channel_unlock(chan_alice);
  743. bridge = ast_bridge_basic_new();
  744. ast_test_validate(test, bridge != NULL);
  745. ast_test_validate(test, !ast_bridge_impart(bridge, chan_alice, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
  746. do_sleep(&to_sleep);
  747. ast_channel_lock(chan_bob);
  748. EMULATE_APP_DATA(chan_bob, 1, "Answer", "");
  749. ast_setstate(chan_bob, AST_STATE_UP);
  750. EMULATE_APP_DATA(chan_bob, 2, "Bridge", "");
  751. ast_channel_unlock(chan_bob);
  752. ast_test_validate(test, !ast_bridge_impart(bridge, chan_bob, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
  753. do_sleep(&to_sleep);
  754. ast_bridge_depart(chan_alice);
  755. ast_bridge_depart(chan_bob);
  756. HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL);
  757. HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL);
  758. result = verify_mock_cdr_record(test, &alice_expected, 2);
  759. return result;
  760. }
  761. AST_TEST_DEFINE(test_cdr_single_twoparty_bridge_b)
  762. {
  763. RAII_VAR(struct ast_channel *, chan_alice, NULL, safe_channel_release);
  764. RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release);
  765. RAII_VAR(struct ast_bridge *, bridge, NULL, safe_bridge_destroy);
  766. RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
  767. ao2_cleanup);
  768. struct timespec to_sleep = {1, 0};
  769. struct ast_party_caller caller_alice = ALICE_CALLERID;
  770. struct ast_party_caller caller_bob = BOB_CALLERID;
  771. struct ast_cdr bob_expected = {
  772. .clid = "\"Bob\" <200>",
  773. .src = "200",
  774. .dst = "200",
  775. .dcontext = "default",
  776. .channel = CHANNEL_TECH_NAME "/Bob",
  777. .lastapp = "Bridge",
  778. .billsec = 1,
  779. .amaflags = AST_AMA_DOCUMENTATION,
  780. .disposition = AST_CDR_ANSWERED,
  781. .accountcode = "200",
  782. };
  783. struct ast_cdr alice_expected = {
  784. .clid = "\"Alice\" <100>",
  785. .src = "100",
  786. .dst = "100",
  787. .dcontext = "default",
  788. .channel = CHANNEL_TECH_NAME "/Alice",
  789. .dstchannel = CHANNEL_TECH_NAME "/Bob",
  790. .lastapp = "Bridge",
  791. .billsec = 1,
  792. .amaflags = AST_AMA_DOCUMENTATION,
  793. .disposition = AST_CDR_ANSWERED,
  794. .accountcode = "100",
  795. .peeraccount = "200",
  796. .next = &bob_expected,
  797. };
  798. enum ast_test_result_state result = AST_TEST_NOT_RUN;
  799. switch (cmd) {
  800. case TEST_INIT:
  801. info->name = __func__;
  802. info->category = TEST_CATEGORY;
  803. info->summary = "Test cdrs for a single party entering/leaving a bridge";
  804. info->description =
  805. "Test the properties of a CDR for a call that is\n"
  806. "answered, enters a bridge, and leaves it. In this scenario, the\n"
  807. "Party B should answer the bridge first.\n";
  808. return AST_TEST_NOT_RUN;
  809. case TEST_EXECUTE:
  810. break;
  811. }
  812. SWAP_CONFIG(config, debug_cdr_config);
  813. CREATE_ALICE_CHANNEL(chan_alice, &caller_alice, &alice_expected);
  814. CREATE_BOB_CHANNEL(chan_bob, &caller_bob, &bob_expected);
  815. ast_copy_string(bob_expected.linkedid, ast_channel_linkedid(chan_alice), sizeof(bob_expected.linkedid));
  816. ast_channel_unlock(chan_alice);
  817. EMULATE_APP_DATA(chan_alice, 1, "Answer", "");
  818. ast_setstate(chan_alice, AST_STATE_UP);
  819. EMULATE_APP_DATA(chan_alice, 2, "Bridge", "");
  820. ast_channel_unlock(chan_alice);
  821. bridge = ast_bridge_basic_new();
  822. ast_test_validate(test, bridge != NULL);
  823. ast_channel_lock(chan_bob);
  824. EMULATE_APP_DATA(chan_bob, 1, "Answer", "");
  825. ast_setstate(chan_bob, AST_STATE_UP);
  826. EMULATE_APP_DATA(chan_bob, 2, "Bridge", "");
  827. ast_channel_unlock(chan_bob);
  828. do_sleep(&to_sleep);
  829. ast_test_validate(test, !ast_bridge_impart(bridge, chan_bob, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
  830. do_sleep(&to_sleep);
  831. ast_test_validate(test, !ast_bridge_impart(bridge, chan_alice, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
  832. do_sleep(&to_sleep);
  833. ast_bridge_depart(chan_alice);
  834. ast_bridge_depart(chan_bob);
  835. HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL);
  836. HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL);
  837. result = verify_mock_cdr_record(test, &alice_expected, 2);
  838. return result;
  839. }
  840. AST_TEST_DEFINE(test_cdr_single_multiparty_bridge)
  841. {
  842. RAII_VAR(struct ast_channel *, chan_alice, NULL, safe_channel_release);
  843. RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release);
  844. RAII_VAR(struct ast_channel *, chan_charlie, NULL, safe_channel_release);
  845. RAII_VAR(struct ast_bridge *, bridge, NULL, safe_bridge_destroy);
  846. RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
  847. ao2_cleanup);
  848. struct timespec to_sleep = {1, 0};
  849. struct ast_party_caller caller_alice = ALICE_CALLERID;
  850. struct ast_party_caller caller_bob = BOB_CALLERID;
  851. struct ast_party_caller caller_charlie = CHARLIE_CALLERID;
  852. struct ast_cdr charlie_expected = {
  853. .clid = "\"Charlie\" <300>",
  854. .src = "300",
  855. .dst = "300",
  856. .dcontext = "default",
  857. .channel = CHANNEL_TECH_NAME "/Charlie",
  858. .lastapp = "Bridge",
  859. .billsec = 1,
  860. .amaflags = AST_AMA_DOCUMENTATION,
  861. .disposition = AST_CDR_ANSWERED,
  862. .accountcode = "300",
  863. };
  864. struct ast_cdr bob_expected = {
  865. .clid = "\"Bob\" <200>",
  866. .src = "200",
  867. .dst = "200",
  868. .dcontext = "default",
  869. .channel = CHANNEL_TECH_NAME "/Bob",
  870. .dstchannel = CHANNEL_TECH_NAME "/Charlie",
  871. .lastapp = "Bridge",
  872. .billsec = 1,
  873. .amaflags = AST_AMA_DOCUMENTATION,
  874. .disposition = AST_CDR_ANSWERED,
  875. .accountcode = "200",
  876. .peeraccount = "300",
  877. .next = &charlie_expected,
  878. };
  879. struct ast_cdr alice_expected_two = {
  880. .clid = "\"Alice\" <100>",
  881. .src = "100",
  882. .dst = "100",
  883. .dcontext = "default",
  884. .channel = CHANNEL_TECH_NAME "/Alice",
  885. .dstchannel = CHANNEL_TECH_NAME "/Charlie",
  886. .lastapp = "Bridge",
  887. .billsec = 1,
  888. .amaflags = AST_AMA_DOCUMENTATION,
  889. .disposition = AST_CDR_ANSWERED,
  890. .accountcode = "100",
  891. .peeraccount = "300",
  892. .next = &bob_expected,
  893. };
  894. struct ast_cdr alice_expected_one = {
  895. .clid = "\"Alice\" <100>",
  896. .src = "100",
  897. .dst = "100",
  898. .dcontext = "default",
  899. .channel = CHANNEL_TECH_NAME "/Alice",
  900. .dstchannel = CHANNEL_TECH_NAME "/Bob",
  901. .lastapp = "Bridge",
  902. .billsec = 1,
  903. .amaflags = AST_AMA_DOCUMENTATION,
  904. .disposition = AST_CDR_ANSWERED,
  905. .accountcode = "100",
  906. .peeraccount = "200",
  907. .next = &alice_expected_two,
  908. };
  909. enum ast_test_result_state result = AST_TEST_NOT_RUN;
  910. switch (cmd) {
  911. case TEST_INIT:
  912. info->name = __func__;
  913. info->category = TEST_CATEGORY;
  914. info->summary = "Test cdrs for a single party entering/leaving a multi-party bridge";
  915. info->description =
  916. "Test the properties of a CDR for a call that is\n"
  917. "answered, enters a bridge, and leaves it. A total of three\n"
  918. "parties perform this action.\n";
  919. return AST_TEST_NOT_RUN;
  920. case TEST_EXECUTE:
  921. break;
  922. }
  923. SWAP_CONFIG(config, debug_cdr_config);
  924. CREATE_ALICE_CHANNEL(chan_alice, &caller_alice, &alice_expected_one);
  925. COPY_IDS(chan_alice, &alice_expected_two);
  926. CREATE_BOB_CHANNEL(chan_bob, &caller_bob, &bob_expected);
  927. ast_copy_string(bob_expected.linkedid, ast_channel_linkedid(chan_alice), sizeof(bob_expected.linkedid));
  928. CREATE_CHARLIE_CHANNEL(chan_charlie, &caller_charlie, &charlie_expected);
  929. ast_copy_string(charlie_expected.linkedid, ast_channel_linkedid(chan_alice), sizeof(charlie_expected.linkedid));
  930. ast_channel_lock(chan_alice);
  931. EMULATE_APP_DATA(chan_alice, 1, "Answer", "");
  932. ast_setstate(chan_alice, AST_STATE_UP);
  933. EMULATE_APP_DATA(chan_alice, 2, "Bridge", "");
  934. ast_channel_unlock(chan_alice);
  935. bridge = ast_bridge_basic_new();
  936. ast_test_validate(test, bridge != NULL);
  937. do_sleep(&to_sleep);
  938. ast_test_validate(test, !ast_bridge_impart(bridge, chan_alice, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
  939. ast_channel_lock(chan_bob);
  940. EMULATE_APP_DATA(chan_bob, 1, "Answer", "");
  941. ast_setstate(chan_bob, AST_STATE_UP);
  942. EMULATE_APP_DATA(chan_bob, 2, "Bridge", "");
  943. ast_channel_unlock(chan_bob);
  944. do_sleep(&to_sleep);
  945. ast_test_validate(test, !ast_bridge_impart(bridge, chan_bob, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
  946. do_sleep(&to_sleep);
  947. ast_channel_lock(chan_charlie);
  948. EMULATE_APP_DATA(chan_charlie, 1, "Answer", "");
  949. ast_setstate(chan_charlie, AST_STATE_UP);
  950. EMULATE_APP_DATA(chan_charlie, 2, "Bridge", "");
  951. ast_channel_unlock(chan_charlie);
  952. ast_test_validate(test, !ast_bridge_impart(bridge, chan_charlie, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
  953. do_sleep(&to_sleep);
  954. ast_bridge_depart(chan_alice);
  955. ast_bridge_depart(chan_bob);
  956. ast_bridge_depart(chan_charlie);
  957. HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL);
  958. HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL);
  959. HANGUP_CHANNEL(chan_charlie, AST_CAUSE_NORMAL);
  960. result = verify_mock_cdr_record(test, &alice_expected_one, 4);
  961. return result;
  962. }
  963. AST_TEST_DEFINE(test_cdr_dial_unanswered)
  964. {
  965. RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
  966. RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
  967. RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
  968. ao2_cleanup);
  969. struct ast_party_caller caller = ALICE_CALLERID;
  970. struct ast_cdr expected = {
  971. .clid = "\"Alice\" <100>",
  972. .src = "100",
  973. .dst = "100",
  974. .dcontext = "default",
  975. .channel = CHANNEL_TECH_NAME "/Alice",
  976. .dstchannel = CHANNEL_TECH_NAME "/Bob",
  977. .lastapp = "Dial",
  978. .lastdata = CHANNEL_TECH_NAME "/Bob",
  979. .billsec = 0,
  980. .amaflags = AST_AMA_DOCUMENTATION,
  981. .disposition = AST_CDR_NOANSWER,
  982. .accountcode = "100",
  983. .peeraccount = "200",
  984. };
  985. enum ast_test_result_state result = AST_TEST_NOT_RUN;
  986. switch (cmd) {
  987. case TEST_INIT:
  988. info->name = __func__;
  989. info->category = TEST_CATEGORY;
  990. info->summary = "Test CDRs for a dial that isn't answered";
  991. info->description =
  992. "Test the properties of a CDR for a channel that\n"
  993. "performs a dial operation that isn't answered\n";
  994. return AST_TEST_NOT_RUN;
  995. case TEST_EXECUTE:
  996. break;
  997. }
  998. SWAP_CONFIG(config, unanswered_cdr_config);
  999. CREATE_ALICE_CHANNEL(chan_caller, &caller, &expected);
  1000. EMULATE_APP_DATA(chan_caller, 1, "Dial", "CDRTestChannel/Bob");
  1001. chan_callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, NULL, chan_caller, 0, CHANNEL_TECH_NAME "/Bob");
  1002. ast_channel_unlock(chan_callee);
  1003. ast_set_flag(ast_channel_flags(chan_callee), AST_FLAG_OUTGOING);
  1004. EMULATE_APP_DATA(chan_callee, 0, "AppDial", "(Outgoing Line)");
  1005. ast_channel_publish_dial(chan_caller, chan_callee, "Bob", NULL);
  1006. ast_channel_state_set(chan_caller, AST_STATE_RINGING);
  1007. ast_channel_publish_dial(chan_caller, chan_callee, NULL, "NOANSWER");
  1008. HANGUP_CHANNEL(chan_caller, AST_CAUSE_NO_ANSWER);
  1009. HANGUP_CHANNEL(chan_callee, AST_CAUSE_NO_ANSWER);
  1010. result = verify_mock_cdr_record(test, &expected, 1);
  1011. return result;
  1012. }
  1013. AST_TEST_DEFINE(test_cdr_dial_busy)
  1014. {
  1015. RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
  1016. RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
  1017. RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
  1018. ao2_cleanup);
  1019. struct ast_party_caller caller = ALICE_CALLERID;
  1020. struct ast_cdr expected = {
  1021. .clid = "\"Alice\" <100>",
  1022. .src = "100",
  1023. .dst = "100",
  1024. .dcontext = "default",
  1025. .channel = CHANNEL_TECH_NAME "/Alice",
  1026. .dstchannel = CHANNEL_TECH_NAME "/Bob",
  1027. .lastapp = "Dial",
  1028. .lastdata = CHANNEL_TECH_NAME "/Bob",
  1029. .billsec = 0,
  1030. .amaflags = AST_AMA_DOCUMENTATION,
  1031. .disposition = AST_CDR_BUSY,
  1032. .accountcode = "100",
  1033. .peeraccount = "200",
  1034. };
  1035. enum ast_test_result_state result = AST_TEST_NOT_RUN;
  1036. switch (cmd) {
  1037. case TEST_INIT:
  1038. info->name = __func__;
  1039. info->category = TEST_CATEGORY;
  1040. info->summary = "Test CDRs for a dial that results in a busy";
  1041. info->description =
  1042. "Test the properties of a CDR for a channel that\n"
  1043. "performs a dial operation to an endpoint that's busy\n";
  1044. return AST_TEST_NOT_RUN;
  1045. case TEST_EXECUTE:
  1046. break;
  1047. }
  1048. SWAP_CONFIG(config, unanswered_cdr_config);
  1049. CREATE_ALICE_CHANNEL(chan_caller, &caller, &expected);
  1050. EMULATE_APP_DATA(chan_caller, 1, "Dial", CHANNEL_TECH_NAME "/Bob");
  1051. chan_callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, NULL, chan_caller, 0, CHANNEL_TECH_NAME "/Bob");
  1052. ast_channel_unlock(chan_callee);
  1053. ast_set_flag(ast_channel_flags(chan_callee), AST_FLAG_OUTGOING);
  1054. EMULATE_APP_DATA(chan_callee, 0, "AppDial", "(Outgoing Line)");
  1055. ast_channel_publish_dial(chan_caller, chan_callee, "Bob", NULL);
  1056. ast_channel_state_set(chan_caller, AST_STATE_RINGING);
  1057. ast_channel_publish_dial(chan_caller, chan_callee, NULL, "BUSY");
  1058. HANGUP_CHANNEL(chan_caller, AST_CAUSE_BUSY);
  1059. HANGUP_CHANNEL(chan_callee, AST_CAUSE_BUSY);
  1060. result = verify_mock_cdr_record(test, &expected, 1);
  1061. return result;
  1062. }
  1063. AST_TEST_DEFINE(test_cdr_dial_congestion)
  1064. {
  1065. RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
  1066. RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
  1067. RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
  1068. ao2_cleanup);
  1069. struct ast_party_caller caller = ALICE_CALLERID;
  1070. struct ast_cdr expected = {
  1071. .clid = "\"Alice\" <100>",
  1072. .src = "100",
  1073. .dst = "100",
  1074. .dcontext = "default",
  1075. .channel = CHANNEL_TECH_NAME "/Alice",
  1076. .dstchannel = CHANNEL_TECH_NAME "/Bob",
  1077. .lastapp = "Dial",
  1078. .lastdata = CHANNEL_TECH_NAME "/Bob",
  1079. .billsec = 0,
  1080. .amaflags = AST_AMA_DOCUMENTATION,
  1081. .disposition = AST_CDR_CONGESTION,
  1082. .accountcode = "100",
  1083. .peeraccount = "200",
  1084. };
  1085. enum ast_test_result_state result = AST_TEST_NOT_RUN;
  1086. switch (cmd) {
  1087. case TEST_INIT:
  1088. info->name = __func__;
  1089. info->category = TEST_CATEGORY;
  1090. info->summary = "Test CDRs for a dial that results in congestion";
  1091. info->description =
  1092. "Test the properties of a CDR for a channel that\n"
  1093. "performs a dial operation to an endpoint that's congested\n";
  1094. return AST_TEST_NOT_RUN;
  1095. case TEST_EXECUTE:
  1096. break;
  1097. }
  1098. SWAP_CONFIG(config, congestion_cdr_config);
  1099. CREATE_ALICE_CHANNEL(chan_caller, &caller, &expected);
  1100. EMULATE_APP_DATA(chan_caller, 1, "Dial", CHANNEL_TECH_NAME "/Bob");
  1101. chan_callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, NULL, chan_caller, 0, CHANNEL_TECH_NAME "/Bob");
  1102. ast_channel_unlock(chan_callee);
  1103. ast_set_flag(ast_channel_flags(chan_callee), AST_FLAG_OUTGOING);
  1104. EMULATE_APP_DATA(chan_callee, 0, "AppDial", "(Outgoing Line)");
  1105. ast_channel_publish_dial(chan_caller, chan_callee, "Bob", NULL);
  1106. ast_channel_state_set(chan_caller, AST_STATE_RINGING);
  1107. ast_channel_publish_dial(chan_caller, chan_callee, NULL, "CONGESTION");
  1108. HANGUP_CHANNEL(chan_caller, AST_CAUSE_CONGESTION);
  1109. HANGUP_CHANNEL(chan_callee, AST_CAUSE_CONGESTION);
  1110. result = verify_mock_cdr_record(test, &expected, 1);
  1111. return result;
  1112. }
  1113. AST_TEST_DEFINE(test_cdr_dial_unavailable)
  1114. {
  1115. RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
  1116. RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
  1117. RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
  1118. ao2_cleanup);
  1119. struct ast_party_caller caller = ALICE_CALLERID;
  1120. struct ast_cdr expected = {
  1121. .clid = "\"Alice\" <100>",
  1122. .src = "100",
  1123. .dst = "100",
  1124. .dcontext = "default",
  1125. .channel = CHANNEL_TECH_NAME "/Alice",
  1126. .dstchannel = CHANNEL_TECH_NAME "/Bob",
  1127. .lastapp = "Dial",
  1128. .lastdata = CHANNEL_TECH_NAME "/Bob",
  1129. .billsec = 0,
  1130. .amaflags = AST_AMA_DOCUMENTATION,
  1131. .disposition = AST_CDR_FAILED,
  1132. .accountcode = "100",
  1133. .peeraccount = "200",
  1134. };
  1135. enum ast_test_result_state result = AST_TEST_NOT_RUN;
  1136. switch (cmd) {
  1137. case TEST_INIT:
  1138. info->name = __func__;
  1139. info->category = TEST_CATEGORY;
  1140. info->summary = "Test CDRs for a dial that results in unavailable";
  1141. info->description =
  1142. "Test the properties of a CDR for a channel that\n"
  1143. "performs a dial operation to an endpoint that's unavailable\n";
  1144. return AST_TEST_NOT_RUN;
  1145. case TEST_EXECUTE:
  1146. break;
  1147. }
  1148. SWAP_CONFIG(config, unanswered_cdr_config);
  1149. CREATE_ALICE_CHANNEL(chan_caller, &caller, &expected);
  1150. EMULATE_APP_DATA(chan_caller, 1, "Dial", CHANNEL_TECH_NAME "/Bob");
  1151. chan_callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, NULL, chan_caller, 0, CHANNEL_TECH_NAME "/Bob");
  1152. ast_channel_unlock(chan_callee);
  1153. ast_set_flag(ast_channel_flags(chan_callee), AST_FLAG_OUTGOING);
  1154. EMULATE_APP_DATA(chan_callee, 0, "AppDial", "(Outgoing Line)");
  1155. ast_channel_publish_dial(chan_caller, chan_callee, "Bob", NULL);
  1156. ast_channel_state_set(chan_caller, AST_STATE_RINGING);
  1157. ast_channel_publish_dial(chan_caller, chan_callee, NULL, "CHANUNAVAIL");
  1158. HANGUP_CHANNEL(chan_caller, AST_CAUSE_NO_ROUTE_DESTINATION);
  1159. HANGUP_CHANNEL(chan_callee, AST_CAUSE_NO_ROUTE_DESTINATION);
  1160. result = verify_mock_cdr_record(test, &expected, 1);
  1161. return result;
  1162. }
  1163. AST_TEST_DEFINE(test_cdr_dial_caller_cancel)
  1164. {
  1165. RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
  1166. RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
  1167. RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
  1168. ao2_cleanup);
  1169. struct ast_party_caller caller = ALICE_CALLERID;
  1170. struct ast_cdr expected = {
  1171. .clid = "\"Alice\" <100>",
  1172. .src = "100",
  1173. .dst = "100",
  1174. .dcontext = "default",
  1175. .channel = CHANNEL_TECH_NAME "/Alice",
  1176. .dstchannel = CHANNEL_TECH_NAME "/Bob",
  1177. .lastapp = "Dial",
  1178. .lastdata = CHANNEL_TECH_NAME "/Bob",
  1179. .billsec = 0,
  1180. .amaflags = AST_AMA_DOCUMENTATION,
  1181. .disposition = AST_CDR_NOANSWER,
  1182. .accountcode = "100",
  1183. .peeraccount = "200",
  1184. };
  1185. enum ast_test_result_state result = AST_TEST_NOT_RUN;
  1186. switch (cmd) {
  1187. case TEST_INIT:
  1188. info->name = __func__;
  1189. info->category = TEST_CATEGORY;
  1190. info->summary = "Test CDRs for a dial where the caller cancels";
  1191. info->description =
  1192. "Test the properties of a CDR for a channel that\n"
  1193. "performs a dial operation to an endpoint but then decides\n"
  1194. "to hang up, cancelling the dial\n";
  1195. return AST_TEST_NOT_RUN;
  1196. case TEST_EXECUTE:
  1197. break;
  1198. }
  1199. SWAP_CONFIG(config, unanswered_cdr_config);
  1200. CREATE_ALICE_CHANNEL(chan_caller, &caller, &expected);
  1201. EMULATE_APP_DATA(chan_caller, 1, "Dial", CHANNEL_TECH_NAME "/Bob");
  1202. chan_callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, NULL, chan_caller, 0, CHANNEL_TECH_NAME "/Bob");
  1203. ast_channel_unlock(chan_callee);
  1204. ast_set_flag(ast_channel_flags(chan_callee), AST_FLAG_OUTGOING);
  1205. EMULATE_APP_DATA(chan_callee, 0, "AppDial", "(Outgoing Line)");
  1206. ast_channel_publish_dial(chan_caller, chan_callee, "Bob", NULL);
  1207. ast_channel_state_set(chan_caller, AST_STATE_RINGING);
  1208. ast_channel_publish_dial(chan_caller, chan_callee, NULL, "CANCEL");
  1209. HANGUP_CHANNEL(chan_callee, AST_CAUSE_NORMAL);
  1210. HANGUP_CHANNEL(chan_caller, AST_CAUSE_NORMAL);
  1211. result = verify_mock_cdr_record(test, &expected, 1);
  1212. return result;
  1213. }
  1214. AST_TEST_DEFINE(test_cdr_dial_parallel_failed)
  1215. {
  1216. RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
  1217. RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release);
  1218. RAII_VAR(struct ast_channel *, chan_charlie, NULL, safe_channel_release);
  1219. RAII_VAR(struct ast_channel *, chan_david, NULL, safe_channel_release);
  1220. RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
  1221. ao2_cleanup);
  1222. struct ast_party_caller caller = ALICE_CALLERID;
  1223. struct ast_cdr bob_expected = {
  1224. .clid = "\"Alice\" <100>",
  1225. .src = "100",
  1226. .dst = "100",
  1227. .dcontext = "default",
  1228. .channel = CHANNEL_TECH_NAME "/Alice",
  1229. .dstchannel = CHANNEL_TECH_NAME "/Bob",
  1230. .lastapp = "Dial",
  1231. .lastdata = CHANNEL_TECH_NAME "/Bob&" CHANNEL_TECH_NAME "/Charlie&" CHANNEL_TECH_NAME "/David",
  1232. .billsec = 0,
  1233. .amaflags = AST_AMA_DOCUMENTATION,
  1234. .disposition = AST_CDR_NOANSWER,
  1235. .accountcode = "100",
  1236. .peeraccount = "200",
  1237. };
  1238. struct ast_cdr charlie_expected = {
  1239. .clid = "\"Alice\" <100>",
  1240. .src = "100",
  1241. .dst = "100",
  1242. .dcontext = "default",
  1243. .channel = CHANNEL_TECH_NAME "/Alice",
  1244. .dstchannel = CHANNEL_TECH_NAME "/Charlie",
  1245. .lastapp = "Dial",
  1246. .lastdata = CHANNEL_TECH_NAME "/Bob&" CHANNEL_TECH_NAME "/Charlie&" CHANNEL_TECH_NAME "/David",
  1247. .billsec = 0,
  1248. .amaflags = AST_AMA_DOCUMENTATION,
  1249. .disposition = AST_CDR_BUSY,
  1250. .accountcode = "100",
  1251. .peeraccount = "300",
  1252. };
  1253. struct ast_cdr david_expected = {
  1254. .clid = "\"Alice\" <100>",
  1255. .src = "100",
  1256. .dst = "100",
  1257. .dcontext = "default",
  1258. .channel = CHANNEL_TECH_NAME "/Alice",
  1259. .dstchannel = CHANNEL_TECH_NAME "/David",
  1260. .lastapp = "Dial",
  1261. .lastdata = CHANNEL_TECH_NAME "/Bob&" CHANNEL_TECH_NAME "/Charlie&" CHANNEL_TECH_NAME "/David",
  1262. .billsec = 0,
  1263. .amaflags = AST_AMA_DOCUMENTATION,
  1264. .disposition = AST_CDR_CONGESTION,
  1265. .accountcode = "100",
  1266. .peeraccount = "400",
  1267. };
  1268. enum ast_test_result_state result = AST_TEST_NOT_RUN;
  1269. struct ast_cdr *expected = &bob_expected;
  1270. bob_expected.next = &charlie_expected;
  1271. charlie_expected.next = &david_expected;
  1272. switch (cmd) {
  1273. case TEST_INIT:
  1274. info->name = __func__;
  1275. info->category = TEST_CATEGORY;
  1276. info->summary = "Test a parallel dial where all channels fail to answer";
  1277. info->description =
  1278. "This tests dialing three parties: Bob, Charlie, David. Charlie\n"
  1279. "returns BUSY; David returns CONGESTION; Bob fails to answer and\n"
  1280. "Alice hangs up. Three records are created for Alice as a result.\n";
  1281. return AST_TEST_NOT_RUN;
  1282. case TEST_EXECUTE:
  1283. break;
  1284. }
  1285. SWAP_CONFIG(config, congestion_cdr_config);
  1286. CREATE_ALICE_CHANNEL(chan_caller, &caller, &bob_expected);
  1287. COPY_IDS(chan_caller, &charlie_expected);
  1288. COPY_IDS(chan_caller, &david_expected);
  1289. /* Channel enters Dial app */
  1290. EMULATE_APP_DATA(chan_caller, 1, "Dial", CHANNEL_TECH_NAME "/Bob&" CHANNEL_TECH_NAME "/Charlie&" CHANNEL_TECH_NAME "/David");
  1291. /* Outbound channels are created */
  1292. chan_bob = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, NULL, chan_caller, 0, CHANNEL_TECH_NAME "/Bob");
  1293. ast_channel_unlock(chan_bob);
  1294. ast_set_flag(ast_channel_flags(chan_bob), AST_FLAG_OUTGOING);
  1295. EMULATE_APP_DATA(chan_bob, 0, "AppDial", "(Outgoing Line)");
  1296. chan_charlie = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "300", NULL, NULL, NULL, chan_caller, 0, CHANNEL_TECH_NAME "/Charlie");
  1297. ast_channel_unlock(chan_charlie);
  1298. ast_set_flag(ast_channel_flags(chan_charlie), AST_FLAG_OUTGOING);
  1299. EMULATE_APP_DATA(chan_charlie, 0, "AppDial", "(Outgoing Line)");
  1300. chan_david = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "400", NULL, NULL, NULL, chan_caller, 0, CHANNEL_TECH_NAME "/David");
  1301. ast_channel_unlock(chan_david);
  1302. ast_set_flag(ast_channel_flags(chan_david), AST_FLAG_OUTGOING);
  1303. EMULATE_APP_DATA(chan_david, 0, "AppDial", "(Outgoing Line)");
  1304. /* Dial starts */
  1305. ast_channel_publish_dial(chan_caller, chan_bob, "Bob", NULL);
  1306. ast_channel_publish_dial(chan_caller, chan_charlie, "Charlie", NULL);
  1307. ast_channel_publish_dial(chan_caller, chan_david, "David", NULL);
  1308. ast_channel_state_set(chan_caller, AST_STATE_RINGING);
  1309. /* Charlie is busy */
  1310. ast_channel_publish_dial(chan_caller, chan_charlie, NULL, "BUSY");
  1311. HANGUP_CHANNEL(chan_charlie, AST_CAUSE_BUSY);
  1312. /* David is congested */
  1313. ast_channel_publish_dial(chan_caller, chan_david, NULL, "CONGESTION");
  1314. HANGUP_CHANNEL(chan_david, AST_CAUSE_CONGESTION);
  1315. /* Bob is canceled */
  1316. ast_channel_publish_dial(chan_caller, chan_bob, NULL, "CANCEL");
  1317. HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL);
  1318. /* Alice hangs up */
  1319. HANGUP_CHANNEL(chan_caller, AST_CAUSE_NORMAL);
  1320. result = verify_mock_cdr_record(test, expected, 3);
  1321. return result;
  1322. }
  1323. AST_TEST_DEFINE(test_cdr_dial_answer_no_bridge)
  1324. {
  1325. RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
  1326. RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
  1327. RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
  1328. ao2_cleanup);
  1329. struct ast_party_caller caller = ALICE_CALLERID;
  1330. struct ast_cdr bob_expected_one = {
  1331. .clid = "\"\" <>",
  1332. .src = "",
  1333. .dst = "s",
  1334. .dcontext = "default",
  1335. .channel = CHANNEL_TECH_NAME "/Bob",
  1336. .lastapp = "Wait",
  1337. .lastdata = "1",
  1338. .amaflags = AST_AMA_DOCUMENTATION,
  1339. .disposition = AST_CDR_ANSWERED,
  1340. .accountcode = "200",
  1341. };
  1342. struct ast_cdr alice_expected_two = {
  1343. .clid = "\"Alice\" <100>",
  1344. .src = "100",
  1345. .dst = "100",
  1346. .dcontext = "default",
  1347. .channel = CHANNEL_TECH_NAME "/Alice",
  1348. .lastapp = "Wait",
  1349. .lastdata = "1",
  1350. .amaflags = AST_AMA_DOCUMENTATION,
  1351. .disposition = AST_CDR_ANSWERED,
  1352. .accountcode = "100",
  1353. .next = &bob_expected_one,
  1354. };
  1355. struct ast_cdr alice_expected_one = {
  1356. .clid = "\"Alice\" <100>",
  1357. .src = "100",
  1358. .dst = "100",
  1359. .dcontext = "default",
  1360. .channel = CHANNEL_TECH_NAME "/Alice",
  1361. .dstchannel = CHANNEL_TECH_NAME "/Bob",
  1362. .lastapp = "Dial",
  1363. .lastdata = CHANNEL_TECH_NAME "/Bob",
  1364. .amaflags = AST_AMA_DOCUMENTATION,
  1365. .disposition = AST_CDR_ANSWERED,
  1366. .accountcode = "100",
  1367. .peeraccount = "200",
  1368. .next = &alice_expected_two,
  1369. };
  1370. enum ast_test_result_state result = AST_TEST_NOT_RUN;
  1371. switch (cmd) {
  1372. case TEST_INIT:
  1373. info->name = __func__;
  1374. info->category = TEST_CATEGORY;
  1375. info->summary = "Test dialing, answering, and not going into a bridge.";
  1376. info->description =
  1377. "This is a weird one, but theoretically possible. You can perform\n"
  1378. "a dial, then bounce both channels to different priorities and\n"
  1379. "never have them enter a bridge together. Ew. This makes sure that\n"
  1380. "when we answer, we get a CDR, it gets ended at that point, and\n"
  1381. "that it gets finalized appropriately. We should get three CDRs in\n"
  1382. "the end - one for the dial, and one for each CDR as they continued\n"
  1383. "on.\n";
  1384. return AST_TEST_NOT_RUN;
  1385. case TEST_EXECUTE:
  1386. break;
  1387. }
  1388. SWAP_CONFIG(config, debug_cdr_config);
  1389. CREATE_ALICE_CHANNEL(chan_caller, &caller, &alice_expected_one);
  1390. COPY_IDS(chan_caller, &alice_expected_two);
  1391. EMULATE_APP_DATA(chan_caller, 1, "Dial", CHANNEL_TECH_NAME "/Bob");
  1392. chan_callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, NULL, chan_caller, 0, CHANNEL_TECH_NAME "/Bob");
  1393. ast_channel_unlock(chan_callee);
  1394. ast_set_flag(ast_channel_flags(chan_callee), AST_FLAG_OUTGOING);
  1395. COPY_IDS(chan_callee, &bob_expected_one);
  1396. ast_channel_publish_dial(chan_caller, chan_callee, "Bob", NULL);
  1397. ast_channel_state_set(chan_caller, AST_STATE_RINGING);
  1398. ast_channel_publish_dial(chan_caller, chan_callee, NULL, "ANSWER");
  1399. ast_channel_state_set(chan_caller, AST_STATE_UP);
  1400. ast_clear_flag(ast_channel_flags(chan_callee), AST_FLAG_OUTGOING);
  1401. ast_channel_state_set(chan_callee, AST_STATE_UP);
  1402. EMULATE_APP_DATA(chan_caller, 2, "Wait", "1");
  1403. EMULATE_APP_DATA(chan_callee, 1, "Wait", "1");
  1404. HANGUP_CHANNEL(chan_caller, AST_CAUSE_NORMAL);
  1405. HANGUP_CHANNEL(chan_callee, AST_CAUSE_NORMAL);
  1406. result = verify_mock_cdr_record(test, &alice_expected_one, 3);
  1407. return result;
  1408. }
  1409. AST_TEST_DEFINE(test_cdr_dial_answer_twoparty_bridge_a)
  1410. {
  1411. RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
  1412. RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
  1413. RAII_VAR(struct ast_bridge *, bridge, NULL, safe_bridge_destroy);
  1414. RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
  1415. ao2_cleanup);
  1416. struct timespec to_sleep = {1, 0};
  1417. enum ast_test_result_state result = AST_TEST_NOT_RUN;
  1418. struct ast_party_caller caller = ALICE_CALLERID;
  1419. struct ast_cdr expected = {
  1420. .clid = "\"Alice\" <100>",
  1421. .src = "100",
  1422. .dst = "100",
  1423. .dcontext = "default",
  1424. .channel = CHANNEL_TECH_NAME "/Alice",
  1425. .dstchannel = CHANNEL_TECH_NAME "/Bob",
  1426. .lastapp = "Dial",
  1427. .lastdata = CHANNEL_TECH_NAME "/Bob",
  1428. .amaflags = AST_AMA_DOCUMENTATION,
  1429. .billsec = 1,
  1430. .disposition = AST_CDR_ANSWERED,
  1431. .accountcode = "100",
  1432. .peeraccount = "200",
  1433. };
  1434. switch (cmd) {
  1435. case TEST_INIT:
  1436. info->name = __func__;
  1437. info->category = TEST_CATEGORY;
  1438. info->summary = "Test dialing, answering, and going into a 2-party bridge";
  1439. info->description =
  1440. "The most 'basic' of scenarios\n";
  1441. return AST_TEST_NOT_RUN;
  1442. case TEST_EXECUTE:
  1443. break;
  1444. }
  1445. SWAP_CONFIG(config, debug_cdr_config);
  1446. CREATE_ALICE_CHANNEL(chan_caller, &caller, &expected);
  1447. EMULATE_APP_DATA(chan_caller, 1, "Dial", CHANNEL_TECH_NAME "/Bob");
  1448. chan_callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, NULL, chan_caller, 0, CHANNEL_TECH_NAME "/Bob");
  1449. ast_channel_unlock(chan_callee);
  1450. ast_set_flag(ast_channel_flags(chan_callee), AST_FLAG_OUTGOING);
  1451. EMULATE_APP_DATA(chan_callee, 0, "AppDial", "(Outgoing Line)");
  1452. ast_channel_publish_dial(chan_caller, chan_callee, "Bob", NULL);
  1453. ast_channel_state_set(chan_caller, AST_STATE_RINGING);
  1454. ast_channel_publish_dial(chan_caller, chan_callee, NULL, "ANSWER");
  1455. ast_channel_state_set(chan_caller, AST_STATE_UP);
  1456. ast_channel_state_set(chan_callee, AST_STATE_UP);
  1457. bridge = ast_bridge_basic_new();
  1458. ast_test_validate(test, bridge != NULL);
  1459. do_sleep(&to_sleep);
  1460. ast_test_validate(test, !ast_bridge_impart(bridge, chan_caller, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
  1461. ast_test_validate(test, !ast_bridge_impart(bridge, chan_callee, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
  1462. do_sleep(&to_sleep);
  1463. ast_bridge_depart(chan_caller);
  1464. ast_bridge_depart(chan_callee);
  1465. HANGUP_CHANNEL(chan_caller, AST_CAUSE_NORMAL);
  1466. HANGUP_CHANNEL(chan_callee, AST_CAUSE_NORMAL);
  1467. result = verify_mock_cdr_record(test, &expected, 1);
  1468. return result;
  1469. }
  1470. AST_TEST_DEFINE(test_cdr_dial_answer_twoparty_bridge_b)
  1471. {
  1472. RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
  1473. RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
  1474. RAII_VAR(struct ast_bridge *, bridge, NULL, safe_bridge_destroy);
  1475. RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
  1476. ao2_cleanup);
  1477. struct timespec to_sleep = {1, 0};
  1478. enum ast_test_result_state result = AST_TEST_NOT_RUN;
  1479. struct ast_party_caller caller = ALICE_CALLERID;
  1480. struct ast_cdr expected = {
  1481. .clid = "\"Alice\" <100>",
  1482. .src = "100",
  1483. .dst = "100",
  1484. .dcontext = "default",
  1485. .channel = CHANNEL_TECH_NAME "/Alice",
  1486. .dstchannel = CHANNEL_TECH_NAME "/Bob",
  1487. .lastapp = "Dial",
  1488. .lastdata = CHANNEL_TECH_NAME "/Bob",
  1489. .amaflags = AST_AMA_DOCUMENTATION,
  1490. .billsec = 1,
  1491. .disposition = AST_CDR_ANSWERED,
  1492. .accountcode = "100",
  1493. .peeraccount = "200",
  1494. };
  1495. switch (cmd) {
  1496. case TEST_INIT:
  1497. info->name = __func__;
  1498. info->category = TEST_CATEGORY;
  1499. info->summary = "Test dialing, answering, and going into a 2-party bridge";
  1500. info->description =
  1501. "The most 'basic' of scenarios\n";
  1502. return AST_TEST_NOT_RUN;
  1503. case TEST_EXECUTE:
  1504. break;
  1505. }
  1506. SWAP_CONFIG(config, debug_cdr_config);
  1507. CREATE_ALICE_CHANNEL(chan_caller, &caller, &expected);
  1508. EMULATE_APP_DATA(chan_caller, 1, "Dial", CHANNEL_TECH_NAME "/Bob");
  1509. chan_callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, NULL, chan_caller, 0, CHANNEL_TECH_NAME "/Bob");
  1510. ast_channel_unlock(chan_callee);
  1511. ast_set_flag(ast_channel_flags(chan_callee), AST_FLAG_OUTGOING);
  1512. EMULATE_APP_DATA(chan_callee, 0, "AppDial", "(Outgoing Line)");
  1513. ast_channel_publish_dial(chan_caller, chan_callee, "Bob", NULL);
  1514. ast_channel_state_set(chan_caller, AST_STATE_RINGING);
  1515. ast_channel_publish_dial(chan_caller, chan_callee, NULL, "ANSWER");
  1516. ast_channel_state_set(chan_caller, AST_STATE_UP);
  1517. ast_channel_state_set(chan_callee, AST_STATE_UP);
  1518. bridge = ast_bridge_basic_new();
  1519. ast_test_validate(test, bridge != NULL);
  1520. do_sleep(&to_sleep);
  1521. ast_test_validate(test, !ast_bridge_impart(bridge, chan_callee, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
  1522. do_sleep(&to_sleep);
  1523. ast_test_validate(test, !ast_bridge_impart(bridge, chan_caller, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
  1524. do_sleep(&to_sleep);
  1525. ast_bridge_depart(chan_caller);
  1526. ast_bridge_depart(chan_callee);
  1527. HANGUP_CHANNEL(chan_caller, AST_CAUSE_NORMAL);
  1528. HANGUP_CHANNEL(chan_callee, AST_CAUSE_NORMAL);
  1529. result = verify_mock_cdr_record(test, &expected, 1);
  1530. return result;
  1531. }
  1532. AST_TEST_DEFINE(test_cdr_dial_answer_multiparty)
  1533. {
  1534. RAII_VAR(struct ast_channel *, chan_alice, NULL, safe_channel_release);
  1535. RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release);
  1536. RAII_VAR(struct ast_channel *, chan_charlie, NULL, safe_channel_release);
  1537. RAII_VAR(struct ast_channel *, chan_david, NULL, safe_channel_release);
  1538. RAII_VAR(struct ast_bridge *, bridge, NULL, safe_bridge_destroy);
  1539. RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
  1540. ao2_cleanup);
  1541. struct timespec to_sleep = {1, 0};
  1542. enum ast_test_result_state result = AST_TEST_NOT_RUN;
  1543. struct ast_party_caller alice_caller = ALICE_CALLERID;
  1544. struct ast_party_caller charlie_caller = CHARLIE_CALLERID;
  1545. struct ast_cdr charlie_expected_two = {
  1546. .clid = "\"Charlie\" <300>",
  1547. .src = "300",
  1548. .dst = "300",
  1549. .dcontext = "default",
  1550. .channel = CHANNEL_TECH_NAME "/Charlie",
  1551. .dstchannel = CHANNEL_TECH_NAME "/Bob",
  1552. .lastapp = "Dial",
  1553. .lastdata = CHANNEL_TECH_NAME "/David",
  1554. .amaflags = AST_AMA_DOCUMENTATION,
  1555. .billsec = 1,
  1556. .disposition = AST_CDR_ANSWERED,
  1557. .accountcode = "300",
  1558. .peeraccount = "200",
  1559. };
  1560. struct ast_cdr charlie_expected_one = {
  1561. .clid = "\"Charlie\" <300>",
  1562. .src = "300",
  1563. .dst = "300",
  1564. .dcontext = "default",
  1565. .channel = CHANNEL_TECH_NAME "/Charlie",
  1566. .dstchannel = CHANNEL_TECH_NAME "/David",
  1567. .lastapp = "Dial",
  1568. .lastdata = CHANNEL_TECH_NAME "/David",
  1569. .amaflags = AST_AMA_DOCUMENTATION,
  1570. .billsec = 1,
  1571. .disposition = AST_CDR_ANSWERED,
  1572. .accountcode = "300",
  1573. .peeraccount = "400",
  1574. .next = &charlie_expected_two,
  1575. };
  1576. struct ast_cdr bob_expected_one = {
  1577. .clid = "\"Bob\" <200>",
  1578. .src = "200",
  1579. .dst = "200",
  1580. .dcontext = "default",
  1581. .channel = CHANNEL_TECH_NAME "/Bob",
  1582. .dstchannel = CHANNEL_TECH_NAME "/David",
  1583. .lastapp = "AppDial",
  1584. .lastdata = "(Outgoing Line)",
  1585. .amaflags = AST_AMA_DOCUMENTATION,
  1586. .billsec = 1,
  1587. .disposition = AST_CDR_ANSWERED,
  1588. .accountcode = "200",
  1589. .peeraccount = "400",
  1590. .next = &charlie_expected_one,
  1591. };
  1592. struct ast_cdr alice_expected_three = {
  1593. .clid = "\"Alice\" <100>",
  1594. .src = "100",
  1595. .dst = "100",
  1596. .dcontext = "default",
  1597. .channel = CHANNEL_TECH_NAME "/Alice",
  1598. .dstchannel = CHANNEL_TECH_NAME "/David",
  1599. .lastapp = "Dial",
  1600. .lastdata = CHANNEL_TECH_NAME "/Bob",
  1601. .amaflags = AST_AMA_DOCUMENTATION,
  1602. .billsec = 1,
  1603. .disposition = AST_CDR_ANSWERED,
  1604. .accountcode = "100",
  1605. .peeraccount = "400",
  1606. .next = &bob_expected_one,
  1607. };
  1608. struct ast_cdr alice_expected_two = {
  1609. .clid = "\"Alice\" <100>",
  1610. .src = "100",
  1611. .dst = "100",
  1612. .dcontext = "default",
  1613. .channel = CHANNEL_TECH_NAME "/Alice",
  1614. .dstchannel = CHANNEL_TECH_NAME "/Charlie",
  1615. .lastapp = "Dial",
  1616. .lastdata = CHANNEL_TECH_NAME "/Bob",
  1617. .amaflags = AST_AMA_DOCUMENTATION,
  1618. .billsec = 1,
  1619. .disposition = AST_CDR_ANSWERED,
  1620. .accountcode = "100",
  1621. .peeraccount = "300",
  1622. .next = &alice_expected_three,
  1623. };
  1624. struct ast_cdr alice_expected_one = {
  1625. .clid = "\"Alice\" <100>",
  1626. .src = "100",
  1627. .dst = "100",
  1628. .dcontext = "default",
  1629. .channel = CHANNEL_TECH_NAME "/Alice",
  1630. .dstchannel = CHANNEL_TECH_NAME "/Bob",
  1631. .lastapp = "Dial",
  1632. .lastdata = CHANNEL_TECH_NAME "/Bob",
  1633. .amaflags = AST_AMA_DOCUMENTATION,
  1634. .billsec = 1,
  1635. .disposition = AST_CDR_ANSWERED,
  1636. .accountcode = "100",
  1637. .peeraccount = "200",
  1638. .next = &alice_expected_two,
  1639. };
  1640. switch (cmd) {
  1641. case TEST_INIT:
  1642. info->name = __func__;
  1643. info->category = TEST_CATEGORY;
  1644. info->summary = "Test dialing, answering, and going into a multi-party bridge";
  1645. info->description =
  1646. "A little tricky to get to do, but possible with some redirects.\n";
  1647. return AST_TEST_NOT_RUN;
  1648. case TEST_EXECUTE:
  1649. break;
  1650. }
  1651. SWAP_CONFIG(config, debug_cdr_config);
  1652. CREATE_ALICE_CHANNEL(chan_alice, &alice_caller, &alice_expected_one);
  1653. COPY_IDS(chan_alice, &alice_expected_two);
  1654. COPY_IDS(chan_alice, &alice_expected_three);
  1655. EMULATE_APP_DATA(chan_alice, 1, "Dial", CHANNEL_TECH_NAME "/Bob");
  1656. chan_bob = ast_channel_alloc(0, AST_STATE_DOWN, "200", "Bob", "200", "200", "default", NULL, NULL, 0, CHANNEL_TECH_NAME "/Bob");
  1657. ast_channel_unlock(chan_bob);
  1658. ast_set_flag(ast_channel_flags(chan_bob), AST_FLAG_OUTGOING);
  1659. EMULATE_APP_DATA(chan_bob, 0, "AppDial", "(Outgoing Line)");
  1660. ast_copy_string(bob_expected_one.uniqueid, ast_channel_uniqueid(chan_bob), sizeof(bob_expected_one.uniqueid));
  1661. ast_copy_string(bob_expected_one.linkedid, ast_channel_linkedid(chan_alice), sizeof(bob_expected_one.linkedid));
  1662. CREATE_CHARLIE_CHANNEL(chan_charlie, &charlie_caller, &charlie_expected_one);
  1663. EMULATE_APP_DATA(chan_charlie, 1, "Dial", CHANNEL_TECH_NAME "/David");
  1664. ast_copy_string(charlie_expected_one.uniqueid, ast_channel_uniqueid(chan_charlie), sizeof(charlie_expected_one.uniqueid));
  1665. ast_copy_string(charlie_expected_one.linkedid, ast_channel_linkedid(chan_alice), sizeof(charlie_expected_one.linkedid));
  1666. ast_copy_string(charlie_expected_two.uniqueid, ast_channel_uniqueid(chan_charlie), sizeof(charlie_expected_two.uniqueid));
  1667. ast_copy_string(charlie_expected_two.linkedid, ast_channel_linkedid(chan_alice), sizeof(charlie_expected_two.linkedid));
  1668. chan_david = ast_channel_alloc(0, AST_STATE_DOWN, "400", "David", "400", "400", "default", NULL, NULL, 0, CHANNEL_TECH_NAME "/David");
  1669. ast_channel_unlock(chan_david);
  1670. ast_set_flag(ast_channel_flags(chan_david), AST_FLAG_OUTGOING);
  1671. EMULATE_APP_DATA(chan_david, 0, "AppDial", "(Outgoing Line)");
  1672. ast_channel_publish_dial(chan_alice, chan_bob, "Bob", NULL);
  1673. ast_channel_state_set(chan_alice, AST_STATE_RINGING);
  1674. ast_channel_publish_dial(chan_charlie, chan_david, "David", NULL);
  1675. ast_channel_state_set(chan_charlie, AST_STATE_RINGING);
  1676. ast_channel_publish_dial(chan_alice, chan_bob, NULL, "ANSWER");
  1677. ast_channel_publish_dial(chan_charlie, chan_david, NULL, "ANSWER");
  1678. ast_channel_state_set(chan_alice, AST_STATE_UP);
  1679. ast_channel_state_set(chan_bob, AST_STATE_UP);
  1680. ast_channel_state_set(chan_charlie, AST_STATE_UP);
  1681. ast_channel_state_set(chan_david, AST_STATE_UP);
  1682. bridge = ast_bridge_basic_new();
  1683. ast_test_validate(test, bridge != NULL);
  1684. do_sleep(&to_sleep);
  1685. ast_test_validate(test, !ast_bridge_impart(bridge, chan_charlie, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
  1686. do_sleep(&to_sleep);
  1687. ast_test_validate(test, !ast_bridge_impart(bridge, chan_david, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
  1688. do_sleep(&to_sleep);
  1689. ast_test_validate(test, !ast_bridge_impart(bridge, chan_bob, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
  1690. do_sleep(&to_sleep);
  1691. ast_test_validate(test, !ast_bridge_impart(bridge, chan_alice, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
  1692. do_sleep(&to_sleep);
  1693. ast_test_validate(test, !ast_bridge_depart(chan_alice));
  1694. ast_test_validate(test, !ast_bridge_depart(chan_bob));
  1695. ast_test_validate(test, !ast_bridge_depart(chan_charlie));
  1696. ast_test_validate(test, !ast_bridge_depart(chan_david));
  1697. HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL);
  1698. HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL);
  1699. HANGUP_CHANNEL(chan_charlie, AST_CAUSE_NORMAL);
  1700. HANGUP_CHANNEL(chan_david, AST_CAUSE_NORMAL);
  1701. result = verify_mock_cdr_record(test, &alice_expected_one, 6);
  1702. return result;
  1703. }
  1704. AST_TEST_DEFINE(test_cdr_park)
  1705. {
  1706. RAII_VAR(struct ast_channel *, chan_alice, NULL, safe_channel_release);
  1707. RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release);
  1708. RAII_VAR(struct ast_bridge *, bridge, NULL, safe_bridge_destroy);
  1709. RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
  1710. ao2_cleanup);
  1711. struct timespec to_sleep = {1, 0};
  1712. struct ast_party_caller bob_caller = BOB_CALLERID;
  1713. struct ast_party_caller alice_caller = ALICE_CALLERID;
  1714. struct ast_cdr bob_expected = {
  1715. .clid = "\"Bob\" <200>",
  1716. .src = "200",
  1717. .dst = "200",
  1718. .dcontext = "default",
  1719. .channel = CHANNEL_TECH_NAME "/Bob",
  1720. .lastapp = "Park",
  1721. .lastdata = "701",
  1722. .billsec = 1,
  1723. .amaflags = AST_AMA_DOCUMENTATION,
  1724. .disposition = AST_CDR_ANSWERED,
  1725. .accountcode = "200",
  1726. };
  1727. struct ast_cdr alice_expected = {
  1728. .clid = "\"Alice\" <100>",
  1729. .src = "100",
  1730. .dst = "100",
  1731. .dcontext = "default",
  1732. .channel = CHANNEL_TECH_NAME "/Alice",
  1733. .lastapp = "Park",
  1734. .lastdata = "700",
  1735. .billsec = 1,
  1736. .amaflags = AST_AMA_DOCUMENTATION,
  1737. .disposition = AST_CDR_ANSWERED,
  1738. .accountcode = "100",
  1739. .next = &bob_expected,
  1740. };
  1741. enum ast_test_result_state result = AST_TEST_NOT_RUN;
  1742. switch (cmd) {
  1743. case TEST_INIT:
  1744. info->name = __func__;
  1745. info->category = TEST_CATEGORY;
  1746. info->summary = "Test cdrs for a single party entering Park";
  1747. info->description =
  1748. "Test the properties of a CDR for calls that are\n"
  1749. "answered, enters Park, and leaves it.\n";
  1750. return AST_TEST_NOT_RUN;
  1751. case TEST_EXECUTE:
  1752. break;
  1753. }
  1754. SWAP_CONFIG(config, debug_cdr_config);
  1755. CREATE_ALICE_CHANNEL(chan_alice, &alice_caller, &alice_expected);
  1756. CREATE_BOB_CHANNEL(chan_bob, &bob_caller, &bob_expected);
  1757. ast_channel_lock(chan_alice);
  1758. EMULATE_APP_DATA(chan_alice, 1, "Park", "700");
  1759. ast_setstate(chan_alice, AST_STATE_UP);
  1760. ast_channel_unlock(chan_alice);
  1761. ast_channel_lock(chan_bob);
  1762. EMULATE_APP_DATA(chan_bob, 1, "Park", "701");
  1763. ast_setstate(chan_bob, AST_STATE_UP);
  1764. ast_channel_unlock(chan_bob);
  1765. bridge = ast_bridge_base_new(AST_BRIDGE_CAPABILITY_HOLDING,
  1766. AST_BRIDGE_FLAG_MERGE_INHIBIT_TO | AST_BRIDGE_FLAG_MERGE_INHIBIT_FROM
  1767. | AST_BRIDGE_FLAG_SWAP_INHIBIT_FROM | AST_BRIDGE_FLAG_TRANSFER_PROHIBITED,
  1768. "test_cdr", "test_cdr_park", NULL);
  1769. ast_test_validate(test, bridge != NULL);
  1770. do_sleep(&to_sleep);
  1771. ast_test_validate(test, !ast_bridge_impart(bridge, chan_alice, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
  1772. do_sleep(&to_sleep);
  1773. ast_test_validate(test, !ast_bridge_impart(bridge, chan_bob, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
  1774. do_sleep(&to_sleep);
  1775. ast_bridge_depart(chan_alice);
  1776. ast_bridge_depart(chan_bob);
  1777. /* And then it hangs up */
  1778. HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL);
  1779. HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL);
  1780. result = verify_mock_cdr_record(test, &alice_expected, 2);
  1781. return result;
  1782. }
  1783. AST_TEST_DEFINE(test_cdr_fields)
  1784. {
  1785. RAII_VAR(struct ast_channel *, chan, NULL, safe_channel_release);
  1786. RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
  1787. ao2_cleanup);
  1788. char varbuffer[128];
  1789. int int_buffer;
  1790. double db_buffer;
  1791. struct timespec to_sleep = {2, 0};
  1792. struct ast_flags fork_options = { 0, };
  1793. struct ast_party_caller caller = ALICE_CALLERID;
  1794. struct ast_cdr original = {
  1795. .clid = "\"Alice\" <100>",
  1796. .src = "100",
  1797. .dst = "100",
  1798. .dcontext = "default",
  1799. .channel = CHANNEL_TECH_NAME "/Alice",
  1800. .lastapp = "Wait",
  1801. .lastdata = "10",
  1802. .billsec = 0,
  1803. .amaflags = AST_AMA_OMIT,
  1804. .disposition = AST_CDR_FAILED,
  1805. .accountcode = "XXX",
  1806. .userfield = "yackity",
  1807. };
  1808. struct ast_cdr fork_expected_one = {
  1809. .clid = "\"Alice\" <100>",
  1810. .src = "100",
  1811. .dst = "100",
  1812. .dcontext = "default",
  1813. .channel = CHANNEL_TECH_NAME "/Alice",
  1814. .lastapp = "Wait",
  1815. .lastdata = "10",
  1816. .billsec = 0,
  1817. .amaflags = AST_AMA_OMIT,
  1818. .disposition = AST_CDR_FAILED,
  1819. .accountcode = "XXX",
  1820. .userfield = "yackity",
  1821. };
  1822. struct ast_cdr fork_expected_two = {
  1823. .clid = "\"Alice\" <100>",
  1824. .src = "100",
  1825. .dst = "100",
  1826. .dcontext = "default",
  1827. .channel = CHANNEL_TECH_NAME "/Alice",
  1828. .lastapp = "Answer",
  1829. .billsec = 0,
  1830. .amaflags = AST_AMA_OMIT,
  1831. .disposition = AST_CDR_ANSWERED,
  1832. .accountcode = "ZZZ",
  1833. .userfield = "schmackity",
  1834. };
  1835. enum ast_test_result_state result = AST_TEST_NOT_RUN;
  1836. struct ast_cdr *expected = &original;
  1837. original.next = &fork_expected_one;
  1838. fork_expected_one.next = &fork_expected_two;
  1839. switch (cmd) {
  1840. case TEST_INIT:
  1841. info->name = __func__;
  1842. info->category = TEST_CATEGORY;
  1843. info->summary = "Test field access CDRs";
  1844. info->description =
  1845. "This tests setting/retrieving data on CDR records.\n";
  1846. return AST_TEST_NOT_RUN;
  1847. case TEST_EXECUTE:
  1848. break;
  1849. }
  1850. SWAP_CONFIG(config, unanswered_cdr_config);
  1851. CREATE_ALICE_CHANNEL(chan, &caller, &original);
  1852. ast_copy_string(fork_expected_one.uniqueid, ast_channel_uniqueid(chan), sizeof(fork_expected_one.uniqueid));
  1853. ast_copy_string(fork_expected_one.linkedid, ast_channel_linkedid(chan), sizeof(fork_expected_one.linkedid));
  1854. ast_copy_string(fork_expected_two.uniqueid, ast_channel_uniqueid(chan), sizeof(fork_expected_two.uniqueid));
  1855. ast_copy_string(fork_expected_two.linkedid, ast_channel_linkedid(chan), sizeof(fork_expected_two.linkedid));
  1856. /* Channel enters Wait app */
  1857. ast_channel_lock(chan);
  1858. ast_channel_appl_set(chan, "Wait");
  1859. ast_channel_data_set(chan, "10");
  1860. ast_channel_priority_set(chan, 1);
  1861. ast_channel_publish_snapshot(chan);
  1862. /* Set properties on the channel that propagate to the CDR */
  1863. ast_channel_amaflags_set(chan, AST_AMA_OMIT);
  1864. ast_channel_accountcode_set(chan, "XXX");
  1865. ast_channel_unlock(chan);
  1866. /* Wait one second so we get a duration. */
  1867. do_sleep(&to_sleep);
  1868. ast_cdr_setuserfield(ast_channel_name(chan), "foobar");
  1869. ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "test_variable", "record_1") == 0);
  1870. /* Verify that we can't set read-only fields or other fields directly */
  1871. ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "clid", "junk") != 0);
  1872. ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "src", "junk") != 0);
  1873. ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "dst", "junk") != 0);
  1874. ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "dcontext", "junk") != 0);
  1875. ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "channel", "junk") != 0);
  1876. ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "dstchannel", "junk") != 0);
  1877. ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "lastapp", "junk") != 0);
  1878. ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "lastdata", "junk") != 0);
  1879. ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "start", "junk") != 0);
  1880. ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "answer", "junk") != 0);
  1881. ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "end", "junk") != 0);
  1882. ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "duration", "junk") != 0);
  1883. ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "billsec", "junk") != 0);
  1884. ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "disposition", "junk") != 0);
  1885. ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "amaflags", "junk") != 0);
  1886. ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "accountcode", "junk") != 0);
  1887. ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "uniqueid", "junk") != 0);
  1888. ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "linkedid", "junk") != 0);
  1889. ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "userfield", "junk") != 0);
  1890. ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "sequence", "junk") != 0);
  1891. /* Verify the values */
  1892. ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "userfield", varbuffer, sizeof(varbuffer)) == 0);
  1893. ast_test_validate(test, strcmp(varbuffer, "foobar") == 0);
  1894. ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "test_variable", varbuffer, sizeof(varbuffer)) == 0);
  1895. ast_test_validate(test, strcmp(varbuffer, "record_1") == 0);
  1896. ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "amaflags", varbuffer, sizeof(varbuffer)) == 0);
  1897. sscanf(varbuffer, "%d", &int_buffer);
  1898. ast_test_validate(test, int_buffer == AST_AMA_OMIT);
  1899. ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "accountcode", varbuffer, sizeof(varbuffer)) == 0);
  1900. ast_test_validate(test, strcmp(varbuffer, "XXX") == 0);
  1901. ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "clid", varbuffer, sizeof(varbuffer)) == 0);
  1902. ast_test_validate(test, strcmp(varbuffer, "\"Alice\" <100>") == 0);
  1903. ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "src", varbuffer, sizeof(varbuffer)) == 0);
  1904. ast_test_validate(test, strcmp(varbuffer, "100") == 0);
  1905. ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "dst", varbuffer, sizeof(varbuffer)) == 0);
  1906. ast_test_validate(test, strcmp(varbuffer, "100") == 0);
  1907. ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "dcontext", varbuffer, sizeof(varbuffer)) == 0);
  1908. ast_test_validate(test, strcmp(varbuffer, "default") == 0);
  1909. ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "channel", varbuffer, sizeof(varbuffer)) == 0);
  1910. ast_test_validate(test, strcmp(varbuffer, CHANNEL_TECH_NAME "/Alice") == 0);
  1911. ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "dstchannel", varbuffer, sizeof(varbuffer)) == 0);
  1912. ast_test_validate(test, strcmp(varbuffer, "") == 0);
  1913. ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "lastapp", varbuffer, sizeof(varbuffer)) == 0);
  1914. ast_test_validate(test, strcmp(varbuffer, "Wait") == 0);
  1915. ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "lastdata", varbuffer, sizeof(varbuffer)) == 0);
  1916. ast_test_validate(test, strcmp(varbuffer, "10") == 0);
  1917. ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "start", varbuffer, sizeof(varbuffer)) == 0);
  1918. sscanf(varbuffer, "%lf", &db_buffer);
  1919. ast_test_validate(test, fabs(db_buffer) > 0);
  1920. ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "answer", varbuffer, sizeof(varbuffer)) == 0);
  1921. sscanf(varbuffer, "%lf", &db_buffer);
  1922. ast_test_validate(test, fabs(db_buffer) < EPSILON);
  1923. ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "end", varbuffer, sizeof(varbuffer)) == 0);
  1924. sscanf(varbuffer, "%lf", &db_buffer);
  1925. ast_test_validate(test, fabs(db_buffer) < EPSILON);
  1926. ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "duration", varbuffer, sizeof(varbuffer)) == 0);
  1927. sscanf(varbuffer, "%lf", &db_buffer);
  1928. ast_test_validate(test, fabs(db_buffer) > 0);
  1929. ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "billsec", varbuffer, sizeof(varbuffer)) == 0);
  1930. sscanf(varbuffer, "%lf", &db_buffer);
  1931. ast_test_validate(test, fabs(db_buffer) < EPSILON);
  1932. ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "disposition", varbuffer, sizeof(varbuffer)) == 0);
  1933. sscanf(varbuffer, "%d", &int_buffer);
  1934. ast_test_validate(test, int_buffer == AST_CDR_NULL);
  1935. ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "uniqueid", varbuffer, sizeof(varbuffer)) == 0);
  1936. ast_test_validate(test, strcmp(varbuffer, ast_channel_uniqueid(chan)) == 0);
  1937. ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "linkedid", varbuffer, sizeof(varbuffer)) == 0);
  1938. ast_test_validate(test, strcmp(varbuffer, ast_channel_linkedid(chan)) == 0);
  1939. ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "sequence", varbuffer, sizeof(varbuffer)) == 0);
  1940. /* Fork the CDR, and check that we change the properties on both CDRs. */
  1941. ast_set_flag(&fork_options, AST_CDR_FLAG_KEEP_VARS);
  1942. ast_test_validate(test, ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
  1943. /* Change some properties */
  1944. ast_cdr_setuserfield(ast_channel_name(chan), "yackity");
  1945. ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "test_variable", "record_1b") == 0);
  1946. /* Fork the CDR again, finalizing all current CDRs */
  1947. ast_set_flag(&fork_options, AST_CDR_FLAG_KEEP_VARS | AST_CDR_FLAG_FINALIZE);
  1948. ast_test_validate(test, ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
  1949. /* Channel enters Answer app */
  1950. ast_channel_lock(chan);
  1951. ast_channel_appl_set(chan, "Answer");
  1952. ast_channel_data_set(chan, "");
  1953. ast_channel_priority_set(chan, 1);
  1954. ast_channel_publish_snapshot(chan);
  1955. ast_setstate(chan, AST_STATE_UP);
  1956. /* Set properties on the last record */
  1957. ast_channel_accountcode_set(chan, "ZZZ");
  1958. ast_channel_unlock(chan);
  1959. ast_cdr_setuserfield(ast_channel_name(chan), "schmackity");
  1960. ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "test_variable", "record_2") == 0);
  1961. /* Hang up and verify */
  1962. ast_channel_hangupcause_set(chan, AST_CAUSE_NORMAL);
  1963. ast_hangup(chan);
  1964. chan = NULL;
  1965. result = verify_mock_cdr_record(test, expected, 3);
  1966. return result;
  1967. }
  1968. AST_TEST_DEFINE(test_cdr_no_reset_cdr)
  1969. {
  1970. RAII_VAR(struct ast_channel *, chan, NULL, safe_channel_release);
  1971. RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
  1972. ao2_cleanup);
  1973. struct ast_flags fork_options = { 0, };
  1974. struct timespec to_sleep = {1, 0};
  1975. struct ast_party_caller caller = ALICE_CALLERID;
  1976. struct ast_cdr expected = {
  1977. .clid = "\"Alice\" <100>",
  1978. .src = "100",
  1979. .dst = "100",
  1980. .dcontext = "default",
  1981. .channel = CHANNEL_TECH_NAME "/Alice",
  1982. .billsec = 0,
  1983. .amaflags = AST_AMA_DOCUMENTATION,
  1984. .disposition = AST_CDR_FAILED,
  1985. .accountcode = "100",
  1986. };
  1987. enum ast_test_result_state result = AST_TEST_NOT_RUN;
  1988. switch (cmd) {
  1989. case TEST_INIT:
  1990. info->name = __func__;
  1991. info->category = TEST_CATEGORY;
  1992. info->summary = "Test field access CDRs";
  1993. info->description =
  1994. "This tests setting/retrieving data on CDR records.\n";
  1995. return AST_TEST_NOT_RUN;
  1996. case TEST_EXECUTE:
  1997. break;
  1998. }
  1999. SWAP_CONFIG(config, unanswered_cdr_config);
  2000. CREATE_ALICE_CHANNEL(chan, &caller, &expected);
  2001. do_sleep(&to_sleep);
  2002. /* Disable the CDR */
  2003. ast_test_validate(test, ast_cdr_set_property(ast_channel_name(chan), AST_CDR_FLAG_DISABLE) == 0);
  2004. /* Fork the CDR. This should be enabled */
  2005. ast_set_flag(&fork_options, AST_CDR_FLAG_FINALIZE);
  2006. ast_test_validate(test, ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
  2007. /* Disable and enable the forked CDR */
  2008. ast_test_validate(test, ast_cdr_set_property(ast_channel_name(chan), AST_CDR_FLAG_DISABLE) == 0);
  2009. ast_test_validate(test, ast_cdr_clear_property(ast_channel_name(chan), AST_CDR_FLAG_DISABLE) == 0);
  2010. /* Fork and finalize again. This CDR should be propagated */
  2011. ast_test_validate(test, ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
  2012. /* Disable all future CDRs */
  2013. ast_test_validate(test, ast_cdr_set_property(ast_channel_name(chan), AST_CDR_FLAG_DISABLE_ALL) == 0);
  2014. /* Fork a few more */
  2015. ast_test_validate(test, ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
  2016. ast_test_validate(test, ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
  2017. ast_test_validate(test, ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
  2018. ast_channel_hangupcause_set(chan, AST_CAUSE_NORMAL);
  2019. ast_hangup(chan);
  2020. chan = NULL;
  2021. result = verify_mock_cdr_record(test, &expected, 1);
  2022. return result;
  2023. }
  2024. AST_TEST_DEFINE(test_cdr_fork_cdr)
  2025. {
  2026. RAII_VAR(struct ast_channel *, chan, NULL, safe_channel_release);
  2027. RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
  2028. ao2_cleanup);
  2029. char varbuffer[128];
  2030. char fork_varbuffer[128];
  2031. char answer_time[128];
  2032. char fork_answer_time[128];
  2033. char start_time[128];
  2034. char fork_start_time[128];
  2035. struct ast_flags fork_options = { 0, };
  2036. struct timespec to_sleep = {1, 10000};
  2037. struct ast_party_caller caller = ALICE_CALLERID;
  2038. struct ast_cdr original = {
  2039. .clid = "\"Alice\" <100>",
  2040. .src = "100",
  2041. .dst = "100",
  2042. .dcontext = "default",
  2043. .channel = CHANNEL_TECH_NAME "/Alice",
  2044. .amaflags = AST_AMA_DOCUMENTATION,
  2045. .disposition = AST_CDR_ANSWERED,
  2046. .accountcode = "100",
  2047. };
  2048. struct ast_cdr fork_expected_one = {
  2049. .clid = "\"Alice\" <100>",
  2050. .src = "100",
  2051. .dst = "100",
  2052. .dcontext = "default",
  2053. .channel = CHANNEL_TECH_NAME "/Alice",
  2054. .amaflags = AST_AMA_DOCUMENTATION,
  2055. .disposition = AST_CDR_ANSWERED,
  2056. .accountcode = "100",
  2057. };
  2058. struct ast_cdr fork_expected_two = {
  2059. .clid = "\"Alice\" <100>",
  2060. .src = "100",
  2061. .dst = "100",
  2062. .dcontext = "default",
  2063. .channel = CHANNEL_TECH_NAME "/Alice",
  2064. .amaflags = AST_AMA_DOCUMENTATION,
  2065. .disposition = AST_CDR_ANSWERED,
  2066. .accountcode = "100",
  2067. };
  2068. enum ast_test_result_state result = AST_TEST_NOT_RUN;
  2069. struct ast_cdr *expected = &original;
  2070. original.next = &fork_expected_one;
  2071. fork_expected_one.next = &fork_expected_two;
  2072. switch (cmd) {
  2073. case TEST_INIT:
  2074. info->name = __func__;
  2075. info->category = TEST_CATEGORY;
  2076. info->summary = "Test field access CDRs";
  2077. info->description =
  2078. "This tests setting/retrieving data on CDR records.\n";
  2079. return AST_TEST_NOT_RUN;
  2080. case TEST_EXECUTE:
  2081. break;
  2082. }
  2083. SWAP_CONFIG(config, debug_cdr_config);
  2084. CREATE_ALICE_CHANNEL(chan, &caller, &original);
  2085. ast_copy_string(fork_expected_one.uniqueid, ast_channel_uniqueid(chan), sizeof(fork_expected_one.uniqueid));
  2086. ast_copy_string(fork_expected_one.linkedid, ast_channel_linkedid(chan), sizeof(fork_expected_one.linkedid));
  2087. ast_copy_string(fork_expected_two.uniqueid, ast_channel_uniqueid(chan), sizeof(fork_expected_two.uniqueid));
  2088. ast_copy_string(fork_expected_two.linkedid, ast_channel_linkedid(chan), sizeof(fork_expected_two.linkedid));
  2089. do_sleep(&to_sleep);
  2090. /* Test blowing away variables */
  2091. ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "test_variable", "record_1") == 0);
  2092. ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "test_variable", varbuffer, sizeof(varbuffer)) == 0);
  2093. ast_test_validate(test, strcmp(varbuffer, "record_1") == 0);
  2094. ast_copy_string(varbuffer, "", sizeof(varbuffer));
  2095. ast_test_validate(test, ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
  2096. ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "test_variable", fork_varbuffer, sizeof(fork_varbuffer)) == 0);
  2097. ast_test_validate(test, strcmp(varbuffer, "record_1") != 0);
  2098. /* Test finalizing previous CDRs */
  2099. ast_set_flag(&fork_options, AST_CDR_FLAG_FINALIZE);
  2100. ast_test_validate(test, ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
  2101. /* Test keep variables; setting a new answer time */
  2102. ast_channel_lock(chan);
  2103. ast_setstate(chan, AST_STATE_UP);
  2104. ast_channel_unlock(chan);
  2105. do_sleep(&to_sleep);
  2106. ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "test_variable", "record_2") == 0);
  2107. ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "test_variable", varbuffer, sizeof(varbuffer)) == 0);
  2108. ast_test_validate(test, strcmp(varbuffer, "record_2") == 0);
  2109. ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "answer", answer_time, sizeof(answer_time)) == 0);
  2110. ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "start", start_time, sizeof(start_time)) == 0);
  2111. ast_set_flag(&fork_options, AST_CDR_FLAG_FINALIZE);
  2112. ast_set_flag(&fork_options, AST_CDR_FLAG_KEEP_VARS);
  2113. ast_set_flag(&fork_options, AST_CDR_FLAG_SET_ANSWER);
  2114. ast_test_validate(test, ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
  2115. ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "answer", fork_answer_time, sizeof(fork_answer_time)) == 0);
  2116. ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "start", fork_start_time, sizeof(fork_start_time)) == 0);
  2117. ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "test_variable", fork_varbuffer, sizeof(fork_varbuffer)) == 0);
  2118. ast_test_validate(test, strcmp(fork_varbuffer, varbuffer) == 0);
  2119. ast_test_validate(test, strcmp(fork_start_time, start_time) == 0);
  2120. ast_test_validate(test, strcmp(fork_answer_time, answer_time) != 0);
  2121. ast_clear_flag(&fork_options, AST_CDR_FLAG_SET_ANSWER);
  2122. ast_set_flag(&fork_options, AST_CDR_FLAG_RESET);
  2123. ast_test_validate(test, ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
  2124. ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "answer", fork_answer_time, sizeof(fork_answer_time)) == 0);
  2125. ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "start", fork_start_time, sizeof(fork_start_time)) == 0);
  2126. ast_test_validate(test, strcmp(fork_start_time, start_time) != 0);
  2127. ast_test_validate(test, strcmp(fork_answer_time, answer_time) != 0);
  2128. ast_channel_hangupcause_set(chan, AST_CAUSE_NORMAL);
  2129. ast_hangup(chan);
  2130. chan = NULL;
  2131. result = verify_mock_cdr_record(test, expected, 3);
  2132. return result;
  2133. }
  2134. /*!
  2135. * \internal
  2136. * \brief Callback function called before each test executes
  2137. */
  2138. static int test_cdr_init_cb(struct ast_test_info *info, struct ast_test *test)
  2139. {
  2140. /* Back up the real config */
  2141. saved_config = ast_cdr_get_config();
  2142. clear_mock_cdr_backend();
  2143. return 0;
  2144. }
  2145. /*!
  2146. * \internal
  2147. * \brief Callback function called after each test executes
  2148. */
  2149. static int test_cdr_cleanup_cb(struct ast_test_info *info, struct ast_test *test)
  2150. {
  2151. /* Restore the real config */
  2152. ast_cdr_set_config(saved_config);
  2153. ao2_cleanup(saved_config);
  2154. saved_config = NULL;
  2155. clear_mock_cdr_backend();
  2156. return 0;
  2157. }
  2158. static int unload_module(void)
  2159. {
  2160. AST_TEST_UNREGISTER(test_cdr_channel_creation);
  2161. AST_TEST_UNREGISTER(test_cdr_unanswered_inbound_call);
  2162. AST_TEST_UNREGISTER(test_cdr_unanswered_outbound_call);
  2163. AST_TEST_UNREGISTER(test_cdr_single_party);
  2164. AST_TEST_UNREGISTER(test_cdr_single_bridge);
  2165. AST_TEST_UNREGISTER(test_cdr_single_bridge_continue);
  2166. AST_TEST_UNREGISTER(test_cdr_single_twoparty_bridge_a);
  2167. AST_TEST_UNREGISTER(test_cdr_single_twoparty_bridge_b);
  2168. AST_TEST_UNREGISTER(test_cdr_single_multiparty_bridge);
  2169. AST_TEST_UNREGISTER(test_cdr_outbound_bridged_call);
  2170. AST_TEST_UNREGISTER(test_cdr_dial_unanswered);
  2171. AST_TEST_UNREGISTER(test_cdr_dial_congestion);
  2172. AST_TEST_UNREGISTER(test_cdr_dial_busy);
  2173. AST_TEST_UNREGISTER(test_cdr_dial_unavailable);
  2174. AST_TEST_UNREGISTER(test_cdr_dial_caller_cancel);
  2175. AST_TEST_UNREGISTER(test_cdr_dial_parallel_failed);
  2176. AST_TEST_UNREGISTER(test_cdr_dial_answer_no_bridge);
  2177. AST_TEST_UNREGISTER(test_cdr_dial_answer_twoparty_bridge_a);
  2178. AST_TEST_UNREGISTER(test_cdr_dial_answer_twoparty_bridge_b);
  2179. AST_TEST_UNREGISTER(test_cdr_dial_answer_multiparty);
  2180. AST_TEST_UNREGISTER(test_cdr_park);
  2181. AST_TEST_UNREGISTER(test_cdr_fields);
  2182. AST_TEST_UNREGISTER(test_cdr_no_reset_cdr);
  2183. AST_TEST_UNREGISTER(test_cdr_fork_cdr);
  2184. ast_cdr_unregister(MOCK_CDR_BACKEND);
  2185. ast_channel_unregister(&test_cdr_chan_tech);
  2186. clear_mock_cdr_backend();
  2187. return 0;
  2188. }
  2189. static int load_module(void)
  2190. {
  2191. ast_cond_init(&mock_cdr_cond, NULL);
  2192. AST_TEST_REGISTER(test_cdr_channel_creation);
  2193. AST_TEST_REGISTER(test_cdr_unanswered_inbound_call);
  2194. AST_TEST_REGISTER(test_cdr_unanswered_outbound_call);
  2195. AST_TEST_REGISTER(test_cdr_single_party);
  2196. AST_TEST_REGISTER(test_cdr_single_bridge);
  2197. AST_TEST_REGISTER(test_cdr_single_bridge_continue);
  2198. AST_TEST_REGISTER(test_cdr_single_twoparty_bridge_a);
  2199. AST_TEST_REGISTER(test_cdr_single_twoparty_bridge_b);
  2200. AST_TEST_REGISTER(test_cdr_single_multiparty_bridge);
  2201. AST_TEST_REGISTER(test_cdr_outbound_bridged_call);
  2202. AST_TEST_REGISTER(test_cdr_dial_unanswered);
  2203. AST_TEST_REGISTER(test_cdr_dial_congestion);
  2204. AST_TEST_REGISTER(test_cdr_dial_busy);
  2205. AST_TEST_REGISTER(test_cdr_dial_unavailable);
  2206. AST_TEST_REGISTER(test_cdr_dial_caller_cancel);
  2207. AST_TEST_REGISTER(test_cdr_dial_parallel_failed);
  2208. AST_TEST_REGISTER(test_cdr_dial_answer_no_bridge);
  2209. AST_TEST_REGISTER(test_cdr_dial_answer_twoparty_bridge_a);
  2210. AST_TEST_REGISTER(test_cdr_dial_answer_twoparty_bridge_b);
  2211. AST_TEST_REGISTER(test_cdr_dial_answer_multiparty);
  2212. AST_TEST_REGISTER(test_cdr_park);
  2213. AST_TEST_REGISTER(test_cdr_fields);
  2214. AST_TEST_REGISTER(test_cdr_no_reset_cdr);
  2215. AST_TEST_REGISTER(test_cdr_fork_cdr);
  2216. ast_test_register_init(TEST_CATEGORY, test_cdr_init_cb);
  2217. ast_test_register_cleanup(TEST_CATEGORY, test_cdr_cleanup_cb);
  2218. ast_channel_register(&test_cdr_chan_tech);
  2219. ast_cdr_register(MOCK_CDR_BACKEND, "Mock CDR backend", mock_cdr_backend_cb);
  2220. return AST_MODULE_LOAD_SUCCESS;
  2221. }
  2222. AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "CDR unit tests");