test_cdr.c 89 KB

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