2 * Asterisk -- An open source telephony toolkit.
4 * Copyright (C) 2013, Digium, Inc.
6 * Matt Jordan <mjordan@digium.com>
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.
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.
21 * \brief CDR unit tests
23 * \author Matt Jordan <mjordan@digium.com>
28 <depend>TEST_FRAMEWORK</depend>
29 <support_level>core</support_level>
34 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
37 #include "asterisk/module.h"
38 #include "asterisk/test.h"
39 #include "asterisk/cdr.h"
40 #include "asterisk/linkedlists.h"
41 #include "asterisk/chanvars.h"
42 #include "asterisk/utils.h"
43 #include "asterisk/causes.h"
44 #include "asterisk/time.h"
45 #include "asterisk/bridge.h"
46 #include "asterisk/bridge_basic.h"
47 #include "asterisk/stasis_channels.h"
48 #include "asterisk/stasis_bridges.h"
52 #define TEST_CATEGORY "/main/cdr/"
54 #define MOCK_CDR_BACKEND "mock_cdr_backend"
56 #define CHANNEL_TECH_NAME "CDRTestChannel"
58 /*! \brief A placeholder for Asterisk's 'real' CDR configuration */
59 static struct ast_cdr_config *saved_config;
61 /*! \brief A configuration suitable for 'normal' CDRs */
62 static struct ast_cdr_config debug_cdr_config = {
63 .settings.flags = CDR_ENABLED | CDR_DEBUG,
66 /*! \brief A configuration suitable for CDRs with unanswered records */
67 static struct ast_cdr_config unanswered_cdr_config = {
68 .settings.flags = CDR_ENABLED | CDR_UNANSWERED | CDR_DEBUG,
71 /*! \brief A configuration suitable for CDRs with congestion enabled */
72 static struct ast_cdr_config congestion_cdr_config = {
73 .settings.flags = CDR_ENABLED | CDR_UNANSWERED | CDR_DEBUG | CDR_CONGESTION,
76 /*! \brief Macro to swap a configuration out from the CDR engine. This should be
77 * used at the beginning of each test to set the needed configuration for that
80 #define SWAP_CONFIG(ao2_config, template) do { \
81 *(ao2_config) = (template); \
82 ast_cdr_set_config((ao2_config)); \
85 /*! \brief A linked list of received CDR entries from the engine */
86 static AST_LIST_HEAD(, test_cdr_entry) actual_cdr_entries = AST_LIST_HEAD_INIT_VALUE;
88 /*! \brief The Mock CDR backend condition wait */
89 static ast_cond_t mock_cdr_cond;
91 /*! \brief A channel technology used for the unit tests */
92 static struct ast_channel_tech test_cdr_chan_tech = {
93 .type = CHANNEL_TECH_NAME,
94 .description = "Mock channel technology for CDR tests",
97 struct test_cdr_entry {
99 AST_LIST_ENTRY(test_cdr_entry) list;
102 /*! \brief The number of CDRs the mock backend has received */
103 static int global_mock_cdr_count;
106 * \brief Callback function for the mock CDR backend
108 * This function 'processes' a dispatched CDR record by adding it to the
109 * \ref actual_cdr_entries list. When a test completes, it can verify the
110 * expected records against this list of actual CDRs created by the engine.
112 * \param cdr The public CDR object created by the engine
114 * \retval -1 on error
115 * \retval 0 on success
117 static int mock_cdr_backend_cb(struct ast_cdr *cdr)
119 struct ast_cdr *cdr_copy, *cdr_prev = NULL;
120 struct ast_cdr *mock_cdr = NULL;
121 struct test_cdr_entry *cdr_wrapper;
123 cdr_wrapper = ast_calloc(1, sizeof(*cdr_wrapper));
128 for (; cdr; cdr = cdr->next) {
129 struct ast_var_t *var_entry, *var_copy;
131 cdr_copy = ast_calloc(1, sizeof(*cdr_copy));
136 cdr_copy->varshead.first = NULL;
137 cdr_copy->varshead.last = NULL;
138 cdr_copy->next = NULL;
140 AST_LIST_TRAVERSE(&cdr->varshead, var_entry, entries) {
141 var_copy = ast_var_assign(var_entry->name, var_entry->value);
145 AST_LIST_INSERT_TAIL(&cdr_copy->varshead, var_copy, entries);
152 cdr_prev->next = cdr_copy;
156 cdr_wrapper->cdr = mock_cdr;
158 AST_LIST_LOCK(&actual_cdr_entries);
159 AST_LIST_INSERT_TAIL(&actual_cdr_entries, cdr_wrapper, list);
160 global_mock_cdr_count++;
161 ast_cond_signal(&mock_cdr_cond);
162 AST_LIST_UNLOCK(&actual_cdr_entries);
168 * \brief Remove all entries from \ref actual_cdr_entries
170 static void clear_mock_cdr_backend(void)
172 struct test_cdr_entry *cdr_wrapper;
174 AST_LIST_LOCK(&actual_cdr_entries);
175 while ((cdr_wrapper = AST_LIST_REMOVE_HEAD(&actual_cdr_entries, list))) {
176 ast_cdr_free(cdr_wrapper->cdr);
177 ast_free(cdr_wrapper);
179 global_mock_cdr_count = 0;
180 AST_LIST_UNLOCK(&actual_cdr_entries);
183 /*! \brief Verify a string field. This will set the test status result to fail;
184 * as such, it assumes that (a) test is the test object variable, and (b) that
185 * a return variable res exists.
187 #define VERIFY_STRING_FIELD(field, actual, expected) do { \
188 if (strcmp((actual)->field, (expected)->field)) { \
189 ast_test_status_update(test, "Field %s failed: actual %s, expected %s\n", #field, (actual)->field, (expected)->field); \
190 ast_test_set_result(test, AST_TEST_FAIL); \
191 res = AST_TEST_FAIL; \
194 /*! \brief Verify a numeric field. This will set the test status result to fail;
195 * as such, it assumes that (a) test is the test object variable, and (b) that
196 * a return variable res exists.
198 #define VERIFY_NUMERIC_FIELD(field, actual, expected) do { \
199 if ((actual)->field != (expected)->field) { \
200 ast_test_status_update(test, "Field %s failed: actual %ld, expected %ld\n", #field, (long)(actual)->field, (long)(expected)->field); \
201 ast_test_set_result(test, AST_TEST_FAIL); \
202 res = AST_TEST_FAIL; \
205 /*! \brief Verify a time field. This will set the test status result to fail;
206 * as such, it assumes that (a) test is the test object variable, and (b) that
207 * a return variable res exists.
209 #define VERIFY_TIME_VALUE(field, actual) do { \
210 if (ast_tvzero((actual)->field)) { \
211 ast_test_status_update(test, "Field %s failed: should not be 0\n", #field); \
212 ast_test_set_result(test, AST_TEST_FAIL); \
213 res = AST_TEST_FAIL; \
216 /*! \brief Alice's Caller ID */
217 #define ALICE_CALLERID { .id.name.str = "Alice", .id.name.valid = 1, .id.number.str = "100", .id.number.valid = 1, }
219 /*! \brief Bob's Caller ID */
220 #define BOB_CALLERID { .id.name.str = "Bob", .id.name.valid = 1, .id.number.str = "200", .id.number.valid = 1, }
222 /*! \brief Charlie's Caller ID */
223 #define CHARLIE_CALLERID { .id.name.str = "Charlie", .id.name.valid = 1, .id.number.str = "300", .id.number.valid = 1, }
225 /*! \brief David's Caller ID */
226 #define DAVID_CALLERID { .id.name.str = "David", .id.name.valid = 1, .id.number.str = "400", .id.number.valid = 1, }
228 /*! \brief Copy the linkedid and uniqueid from a channel to an expected CDR */
229 #define COPY_IDS(channel_var, expected_record) do { \
230 ast_copy_string((expected_record)->uniqueid, ast_channel_uniqueid((channel_var)), sizeof((expected_record)->uniqueid)); \
231 ast_copy_string((expected_record)->linkedid, ast_channel_linkedid((channel_var)), sizeof((expected_record)->linkedid)); \
234 /*! \brief Create a \ref test_cdr_chan_tech for Alice, and set the expected
235 * CDR records' linkedid and uniqueid. */
236 #define CREATE_ALICE_CHANNEL(channel_var, caller_id, expected_record) do { \
237 (channel_var) = ast_channel_alloc(0, AST_STATE_DOWN, "100", "Alice", "100", "100", "default", NULL, 0, CHANNEL_TECH_NAME "/Alice"); \
238 ast_channel_set_caller((channel_var), (caller_id), NULL); \
239 ast_copy_string((expected_record)->uniqueid, ast_channel_uniqueid((channel_var)), sizeof((expected_record)->uniqueid)); \
240 ast_copy_string((expected_record)->linkedid, ast_channel_linkedid((channel_var)), sizeof((expected_record)->linkedid)); \
243 /*! \brief Create a \ref test_cdr_chan_tech for Bob, and set the expected
244 * CDR records' linkedid and uniqueid. */
245 #define CREATE_BOB_CHANNEL(channel_var, caller_id, expected_record) do { \
246 (channel_var) = ast_channel_alloc(0, AST_STATE_DOWN, "200", "Bob", "200", "200", "default", NULL, 0, CHANNEL_TECH_NAME "/Bob"); \
247 ast_channel_set_caller((channel_var), (caller_id), NULL); \
248 ast_copy_string((expected_record)->uniqueid, ast_channel_uniqueid((channel_var)), sizeof((expected_record)->uniqueid)); \
249 ast_copy_string((expected_record)->linkedid, ast_channel_linkedid((channel_var)), sizeof((expected_record)->linkedid)); \
252 /*! \brief Create a \ref test_cdr_chan_tech for Charlie, and set the expected
253 * CDR records' linkedid and uniqueid. */
254 #define CREATE_CHARLIE_CHANNEL(channel_var, caller_id, expected_record) do { \
255 (channel_var) = ast_channel_alloc(0, AST_STATE_DOWN, "300", "Charlie", "300", "300", "default", NULL, 0, CHANNEL_TECH_NAME "/Charlie"); \
256 ast_channel_set_caller((channel_var), (caller_id), NULL); \
257 ast_copy_string((expected_record)->uniqueid, ast_channel_uniqueid((channel_var)), sizeof((expected_record)->uniqueid)); \
258 ast_copy_string((expected_record)->linkedid, ast_channel_linkedid((channel_var)), sizeof((expected_record)->linkedid)); \
261 /*! \brief Create a \ref test_cdr_chan_tech for Charlie, and set the expected
262 * CDR records' linkedid and uniqueid. */
263 #define CREATE_DAVID_CHANNEL(channel_var, caller_id, expected_record) do { \
264 (channel_var) = ast_channel_alloc(0, AST_STATE_DOWN, "400", "David", "400", "400", "default", NULL, 0, CHANNEL_TECH_NAME "/David"); \
265 ast_channel_set_caller((channel_var), (caller_id), NULL); \
266 ast_copy_string((expected_record)->uniqueid, ast_channel_uniqueid((channel_var)), sizeof((expected_record)->uniqueid)); \
267 ast_copy_string((expected_record)->linkedid, ast_channel_linkedid((channel_var)), sizeof((expected_record)->linkedid)); \
270 /*! \brief Emulate a channel entering into an application */
271 #define EMULATE_APP_DATA(channel, priority, application, data) do { \
272 if ((priority) > 0) { \
273 ast_channel_priority_set((channel), (priority)); \
275 ast_channel_appl_set((channel), (application)); \
276 ast_channel_data_set((channel), (data)); \
277 ast_channel_publish_snapshot((channel)); \
280 /*! \brief Hang up a test channel safely */
281 #define HANGUP_CHANNEL(channel, cause) \
283 ast_channel_hangupcause_set((channel), (cause)); \
284 ast_hangup(channel); \
288 static enum ast_test_result_state verify_mock_cdr_record(struct ast_test *test, struct ast_cdr *expected, int record)
290 struct ast_cdr *actual = NULL;
291 struct test_cdr_entry *cdr_wrapper;
293 struct timeval wait_now = ast_tvnow();
294 struct timespec wait_time = { .tv_sec = wait_now.tv_sec + 5, .tv_nsec = wait_now.tv_usec * 1000 };
295 enum ast_test_result_state res = AST_TEST_PASS;
297 while (count < record) {
298 AST_LIST_LOCK(&actual_cdr_entries);
299 if (global_mock_cdr_count < record) {
300 ast_cond_timedwait(&mock_cdr_cond, &actual_cdr_entries.lock, &wait_time);
302 cdr_wrapper = AST_LIST_REMOVE_HEAD(&actual_cdr_entries, list);
303 AST_LIST_UNLOCK(&actual_cdr_entries);
306 ast_test_status_update(test, "Unable to find actual CDR record at %d\n", count);
307 return AST_TEST_FAIL;
309 actual = cdr_wrapper->cdr;
311 if (!expected && actual) {
312 ast_test_status_update(test, "CDRs recorded where no record expected\n");
313 return AST_TEST_FAIL;
315 ast_test_debug(test, "Verifying expected record %s, %s\n",
316 expected->channel, S_OR(expected->dstchannel, "<none>"));
317 VERIFY_STRING_FIELD(accountcode, actual, expected);
318 VERIFY_NUMERIC_FIELD(amaflags, actual, expected);
319 VERIFY_STRING_FIELD(channel, actual, expected);
320 VERIFY_STRING_FIELD(clid, actual, expected);
321 VERIFY_STRING_FIELD(dcontext, actual, expected);
322 VERIFY_NUMERIC_FIELD(disposition, actual, expected);
323 VERIFY_STRING_FIELD(dst, actual, expected);
324 VERIFY_STRING_FIELD(dstchannel, actual, expected);
325 VERIFY_STRING_FIELD(lastapp, actual, expected);
326 VERIFY_STRING_FIELD(lastdata, actual, expected);
327 VERIFY_STRING_FIELD(linkedid, actual, expected);
328 VERIFY_STRING_FIELD(peeraccount, actual, expected);
329 VERIFY_STRING_FIELD(src, actual, expected);
330 VERIFY_STRING_FIELD(uniqueid, actual, expected);
331 VERIFY_STRING_FIELD(userfield, actual, expected);
332 VERIFY_TIME_VALUE(start, actual);
333 VERIFY_TIME_VALUE(end, actual);
334 /* Note: there's no way we can really calculate a duration or
335 * billsec - the unit tests are too short. However, if billsec is
336 * non-zero in the expected, then make sure we have an answer time
338 if (expected->billsec) {
339 VERIFY_TIME_VALUE(answer, actual);
341 ast_test_debug(test, "Finished expected record %s, %s\n",
342 expected->channel, S_OR(expected->dstchannel, "<none>"));
343 expected = expected->next;
349 static void safe_channel_release(struct ast_channel *chan)
354 ast_channel_release(chan);
357 AST_TEST_DEFINE(test_cdr_channel_creation)
359 RAII_VAR(struct ast_channel *, chan, NULL, safe_channel_release);
360 RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
363 struct ast_party_caller caller = ALICE_CALLERID;
364 struct ast_cdr expected = {
365 .clid = "\"Alice\" <100>",
368 .dcontext = "default",
369 .channel = CHANNEL_TECH_NAME "/Alice",
370 .amaflags = AST_AMA_DOCUMENTATION,
371 .disposition = AST_CDR_NOANSWER,
372 .accountcode = "100",
374 enum ast_test_result_state result = AST_TEST_NOT_RUN;
378 info->name = __func__;
379 info->category = TEST_CATEGORY;
380 info->summary = "Test that a CDR is created when a channel is created";
382 "Test that a CDR is created when a channel is created";
383 return AST_TEST_NOT_RUN;
388 SWAP_CONFIG(config, unanswered_cdr_config);
390 CREATE_ALICE_CHANNEL(chan, (&caller), &expected);
392 HANGUP_CHANNEL(chan, AST_CAUSE_NORMAL);
394 result = verify_mock_cdr_record(test, &expected, 1);
399 AST_TEST_DEFINE(test_cdr_unanswered_inbound_call)
401 RAII_VAR(struct ast_channel *, chan, NULL, safe_channel_release);
402 RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
405 struct ast_party_caller caller = ALICE_CALLERID;
406 struct ast_cdr expected = {
407 .clid = "\"Alice\" <100>",
410 .dcontext = "default",
411 .channel = CHANNEL_TECH_NAME "/Alice",
414 .amaflags = AST_AMA_DOCUMENTATION,
415 .disposition = AST_CDR_NOANSWER,
416 .accountcode = "100",
418 enum ast_test_result_state result = AST_TEST_NOT_RUN;
422 info->name = __func__;
423 info->category = TEST_CATEGORY;
424 info->summary = "Test inbound unanswered calls";
426 "Test the properties of a CDR for a call that is\n"
427 "inbound to Asterisk, executes some dialplan, but\n"
428 "is never answered.\n";
429 return AST_TEST_NOT_RUN;
434 SWAP_CONFIG(config, unanswered_cdr_config);
436 CREATE_ALICE_CHANNEL(chan, &caller, &expected);
438 EMULATE_APP_DATA(chan, 1, "Wait", "1");
440 HANGUP_CHANNEL(chan, AST_CAUSE_NORMAL);
442 result = verify_mock_cdr_record(test, &expected, 1);
447 AST_TEST_DEFINE(test_cdr_unanswered_outbound_call)
449 RAII_VAR(struct ast_channel *, chan, NULL, safe_channel_release);
450 RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
453 struct ast_party_caller caller = {
457 .id.number.valid = 1, };
458 struct ast_cdr expected = {
461 .dcontext = "default",
462 .channel = CHANNEL_TECH_NAME "/Alice",
463 .lastapp = "AppDial",
464 .lastdata = "(Outgoing Line)",
465 .amaflags = AST_AMA_DOCUMENTATION,
466 .disposition = AST_CDR_NOANSWER,
467 .accountcode = "100",
469 enum ast_test_result_state result = AST_TEST_NOT_RUN;
473 info->name = __func__;
474 info->category = TEST_CATEGORY;
475 info->summary = "Test outbound unanswered calls";
477 "Test the properties of a CDR for a call that is\n"
478 "outbound to Asterisk but is never answered.\n";
479 return AST_TEST_NOT_RUN;
484 SWAP_CONFIG(config, unanswered_cdr_config);
486 CREATE_ALICE_CHANNEL(chan, &caller, &expected);
488 ast_channel_exten_set(chan, "s");
489 ast_channel_context_set(chan, "default");
490 ast_set_flag(ast_channel_flags(chan), AST_FLAG_ORIGINATED);
491 EMULATE_APP_DATA(chan, 0, "AppDial", "(Outgoing Line)");
492 HANGUP_CHANNEL(chan, AST_CAUSE_NORMAL);
494 result = verify_mock_cdr_record(test, &expected, 1);
499 AST_TEST_DEFINE(test_cdr_outbound_bridged_call)
501 RAII_VAR(struct ast_channel *, chan_alice, NULL, safe_channel_release);
502 RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release);
503 RAII_VAR(struct ast_bridge *, bridge, NULL, ao2_cleanup);
504 RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
506 struct timespec to_sleep = {1, 0};
507 enum ast_test_result_state result = AST_TEST_NOT_RUN;
509 struct ast_party_caller caller = ALICE_CALLERID;
510 struct ast_cdr alice_expected = {
511 .clid = "\"Alice\" <100>",
514 .dcontext = "default",
515 .channel = CHANNEL_TECH_NAME "/Alice",
516 .dstchannel = CHANNEL_TECH_NAME "/Bob",
519 .amaflags = AST_AMA_DOCUMENTATION,
521 .disposition = AST_CDR_ANSWERED,
522 .accountcode = "100",
523 .peeraccount = "200",
525 struct ast_cdr bob_expected = {
529 .dcontext = "default",
530 .channel = CHANNEL_TECH_NAME "/Bob",
532 .lastapp = "AppDial",
533 .lastdata = "(Outgoing Line)",
534 .amaflags = AST_AMA_DOCUMENTATION,
536 .disposition = AST_CDR_ANSWERED,
537 .accountcode = "200",
539 .next = &alice_expected,
544 info->name = __func__;
545 info->category = TEST_CATEGORY;
546 info->summary = "Test dialing, answering, and going into a 2-party bridge";
548 "The most 'basic' of scenarios\n";
549 return AST_TEST_NOT_RUN;
554 SWAP_CONFIG(config, debug_cdr_config);
556 CREATE_ALICE_CHANNEL(chan_alice, &caller, &alice_expected);
557 ast_channel_state_set(chan_alice, AST_STATE_UP);
559 bridge = ast_bridge_basic_new();
560 ast_test_validate(test, bridge != NULL);
561 while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
563 ast_test_validate(test, !ast_bridge_impart(bridge, chan_alice, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
565 chan_bob = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, ast_channel_linkedid(chan_alice), 0, CHANNEL_TECH_NAME "/Bob");
566 ast_copy_string(bob_expected.linkedid, ast_channel_linkedid(chan_bob), sizeof(bob_expected.linkedid));
567 ast_copy_string(bob_expected.uniqueid, ast_channel_uniqueid(chan_bob), sizeof(bob_expected.uniqueid));
568 ast_set_flag(ast_channel_flags(chan_bob), AST_FLAG_OUTGOING);
569 ast_set_flag(ast_channel_flags(chan_bob), AST_FLAG_ORIGINATED);
570 EMULATE_APP_DATA(chan_bob, 0, "AppDial", "(Outgoing Line)");
572 ast_channel_publish_dial(NULL, chan_bob, "Bob", NULL);
573 ast_channel_state_set(chan_bob, AST_STATE_RINGING);
574 ast_channel_publish_dial(NULL, chan_bob, NULL, "ANSWER");
576 ast_channel_state_set(chan_bob, AST_STATE_UP);
578 while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
580 ast_test_validate(test, !ast_bridge_impart(bridge, chan_bob, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
582 while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
584 ast_bridge_depart(chan_bob);
585 ast_bridge_depart(chan_alice);
587 HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL);
588 HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL);
590 result = verify_mock_cdr_record(test, &bob_expected, 2);
595 AST_TEST_DEFINE(test_cdr_single_party)
597 RAII_VAR(struct ast_channel *, chan, NULL, safe_channel_release);
598 RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
601 struct ast_party_caller caller = ALICE_CALLERID;
602 struct ast_cdr expected = {
603 .clid = "\"Alice\" <100>",
606 .dcontext = "default",
607 .channel = CHANNEL_TECH_NAME "/Alice",
609 .lastapp = "VoiceMailMain",
612 .amaflags = AST_AMA_DOCUMENTATION,
613 .disposition = AST_CDR_ANSWERED,
614 .accountcode = "100",
616 enum ast_test_result_state result = AST_TEST_NOT_RUN;
620 info->name = __func__;
621 info->category = TEST_CATEGORY;
622 info->summary = "Test cdrs for a single party";
624 "Test the properties of a CDR for a call that is\n"
625 "answered, but only involves a single channel\n";
626 return AST_TEST_NOT_RUN;
630 SWAP_CONFIG(config, debug_cdr_config);
631 CREATE_ALICE_CHANNEL(chan, &caller, &expected);
633 EMULATE_APP_DATA(chan, 1, "Answer", "");
634 ast_setstate(chan, AST_STATE_UP);
635 EMULATE_APP_DATA(chan, 2, "VoiceMailMain", "1");
637 HANGUP_CHANNEL(chan, AST_CAUSE_NORMAL);
639 result = verify_mock_cdr_record(test, &expected, 1);
644 AST_TEST_DEFINE(test_cdr_single_bridge)
646 RAII_VAR(struct ast_channel *, chan, NULL, safe_channel_release);
647 RAII_VAR(struct ast_bridge *, bridge, NULL, ao2_cleanup);
648 RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
650 struct timespec to_sleep = {1, 0};
652 struct ast_party_caller caller = ALICE_CALLERID;
653 struct ast_cdr expected = {
654 .clid = "\"Alice\" <100>",
657 .dcontext = "default",
658 .channel = CHANNEL_TECH_NAME "/Alice",
661 .amaflags = AST_AMA_DOCUMENTATION,
662 .disposition = AST_CDR_ANSWERED,
663 .accountcode = "100",
665 enum ast_test_result_state result = AST_TEST_NOT_RUN;
669 info->name = __func__;
670 info->category = TEST_CATEGORY;
671 info->summary = "Test cdrs for a single party entering/leaving a bridge";
673 "Test the properties of a CDR for a call that is\n"
674 "answered, enters a bridge, and leaves it.\n";
675 return AST_TEST_NOT_RUN;
679 SWAP_CONFIG(config, debug_cdr_config);
680 CREATE_ALICE_CHANNEL(chan, &caller, &expected);
682 EMULATE_APP_DATA(chan, 1, "Answer", "");
683 ast_setstate(chan, AST_STATE_UP);
684 EMULATE_APP_DATA(chan, 2, "Bridge", "");
686 bridge = ast_bridge_basic_new();
687 ast_test_validate(test, bridge != NULL);
689 while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
690 ast_test_validate(test, !ast_bridge_impart(bridge, chan, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
692 while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
694 ast_bridge_depart(chan);
696 HANGUP_CHANNEL(chan, AST_CAUSE_NORMAL);
698 result = verify_mock_cdr_record(test, &expected, 1);
703 AST_TEST_DEFINE(test_cdr_single_bridge_continue)
705 RAII_VAR(struct ast_channel *, chan, NULL, safe_channel_release);
706 RAII_VAR(struct ast_bridge *, bridge_one, NULL, ao2_cleanup);
707 RAII_VAR(struct ast_bridge *, bridge_two, NULL, ao2_cleanup);
708 RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
710 struct timespec to_sleep = {1, 0};
712 struct ast_party_caller caller = ALICE_CALLERID;
713 struct ast_cdr expected_two = {
714 .clid = "\"Alice\" <100>",
717 .dcontext = "default",
718 .channel = CHANNEL_TECH_NAME "/Alice",
721 .amaflags = AST_AMA_DOCUMENTATION,
722 .disposition = AST_CDR_ANSWERED,
723 .accountcode = "100",
725 struct ast_cdr expected_one = {
726 .clid = "\"Alice\" <100>",
729 .dcontext = "default",
730 .channel = CHANNEL_TECH_NAME "/Alice",
733 .amaflags = AST_AMA_DOCUMENTATION,
734 .disposition = AST_CDR_ANSWERED,
735 .accountcode = "100",
736 .next = &expected_two,
739 enum ast_test_result_state result = AST_TEST_NOT_RUN;
743 info->name = __func__;
744 info->category = TEST_CATEGORY;
745 info->summary = "Test cdrs for a single party entering/leaving a bridge";
747 "Test the properties of a CDR for a call that is\n"
748 "answered, enters a bridge, and leaves it.\n";
749 return AST_TEST_NOT_RUN;
753 SWAP_CONFIG(config, debug_cdr_config);
754 CREATE_ALICE_CHANNEL(chan, &caller, &expected_one);
755 COPY_IDS(chan, &expected_two);
757 EMULATE_APP_DATA(chan, 1, "Answer", "");
758 ast_setstate(chan, AST_STATE_UP);
759 EMULATE_APP_DATA(chan, 2, "Bridge", "");
761 bridge_one = ast_bridge_basic_new();
762 ast_test_validate(test, bridge_one != NULL);
763 while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
765 ast_test_validate(test, !ast_bridge_impart(bridge_one, chan, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
767 while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
769 ast_bridge_depart(chan);
771 EMULATE_APP_DATA(chan, 3, "Wait", "");
773 /* And then it hangs up */
774 HANGUP_CHANNEL(chan, AST_CAUSE_NORMAL);
776 result = verify_mock_cdr_record(test, &expected_one, 2);
781 AST_TEST_DEFINE(test_cdr_single_twoparty_bridge_a)
783 RAII_VAR(struct ast_channel *, chan_alice, NULL, safe_channel_release);
784 RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release);
785 RAII_VAR(struct ast_bridge *, bridge, NULL, ao2_cleanup);
786 RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
788 struct timespec to_sleep = {1, 0};
790 struct ast_party_caller caller_alice = ALICE_CALLERID;
791 struct ast_party_caller caller_bob = BOB_CALLERID;
792 struct ast_cdr bob_expected = {
793 .clid = "\"Bob\" <200>",
796 .dcontext = "default",
797 .channel = CHANNEL_TECH_NAME "/Bob",
800 .amaflags = AST_AMA_DOCUMENTATION,
801 .disposition = AST_CDR_ANSWERED,
802 .accountcode = "200",
804 struct ast_cdr alice_expected = {
805 .clid = "\"Alice\" <100>",
808 .dcontext = "default",
809 .channel = CHANNEL_TECH_NAME "/Alice",
810 .dstchannel = CHANNEL_TECH_NAME "/Bob",
813 .amaflags = AST_AMA_DOCUMENTATION,
814 .disposition = AST_CDR_ANSWERED,
815 .accountcode = "100",
816 .peeraccount = "200",
817 .next = &bob_expected,
820 enum ast_test_result_state result = AST_TEST_NOT_RUN;
824 info->name = __func__;
825 info->category = TEST_CATEGORY;
826 info->summary = "Test cdrs for a single party entering/leaving a bridge";
828 "Test the properties of a CDR for a call that is\n"
829 "answered, enters a bridge, and leaves it. In this scenario, the\n"
830 "Party A should answer the bridge first.\n";
831 return AST_TEST_NOT_RUN;
835 SWAP_CONFIG(config, debug_cdr_config);
836 CREATE_ALICE_CHANNEL(chan_alice, &caller_alice, &alice_expected);
838 CREATE_BOB_CHANNEL(chan_bob, &caller_bob, &bob_expected);
839 ast_copy_string(bob_expected.linkedid, ast_channel_linkedid(chan_alice), sizeof(bob_expected.linkedid));
841 EMULATE_APP_DATA(chan_alice, 1, "Answer", "");
842 ast_setstate(chan_alice, AST_STATE_UP);
843 EMULATE_APP_DATA(chan_alice, 2, "Bridge", "");
845 bridge = ast_bridge_basic_new();
846 ast_test_validate(test, bridge != NULL);
848 ast_test_validate(test, !ast_bridge_impart(bridge, chan_alice, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
849 while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
851 EMULATE_APP_DATA(chan_bob, 1, "Answer", "");
852 ast_setstate(chan_bob, AST_STATE_UP);
853 EMULATE_APP_DATA(chan_bob, 2, "Bridge", "");
855 ast_test_validate(test, !ast_bridge_impart(bridge, chan_bob, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
856 while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
858 ast_bridge_depart(chan_alice);
859 ast_bridge_depart(chan_bob);
861 HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL);
862 HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL);
864 result = verify_mock_cdr_record(test, &alice_expected, 2);
869 AST_TEST_DEFINE(test_cdr_single_twoparty_bridge_b)
871 RAII_VAR(struct ast_channel *, chan_alice, NULL, safe_channel_release);
872 RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release);
873 RAII_VAR(struct ast_bridge *, bridge, NULL, ao2_cleanup);
874 RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
876 struct timespec to_sleep = {1, 0};
878 struct ast_party_caller caller_alice = ALICE_CALLERID;
879 struct ast_party_caller caller_bob = BOB_CALLERID;
880 struct ast_cdr bob_expected = {
881 .clid = "\"Bob\" <200>",
884 .dcontext = "default",
885 .channel = CHANNEL_TECH_NAME "/Bob",
888 .amaflags = AST_AMA_DOCUMENTATION,
889 .disposition = AST_CDR_ANSWERED,
890 .accountcode = "200",
892 struct ast_cdr alice_expected = {
893 .clid = "\"Alice\" <100>",
896 .dcontext = "default",
897 .channel = CHANNEL_TECH_NAME "/Alice",
898 .dstchannel = CHANNEL_TECH_NAME "/Bob",
901 .amaflags = AST_AMA_DOCUMENTATION,
902 .disposition = AST_CDR_ANSWERED,
903 .accountcode = "100",
904 .peeraccount = "200",
905 .next = &bob_expected,
908 enum ast_test_result_state result = AST_TEST_NOT_RUN;
912 info->name = __func__;
913 info->category = TEST_CATEGORY;
914 info->summary = "Test cdrs for a single party entering/leaving a bridge";
916 "Test the properties of a CDR for a call that is\n"
917 "answered, enters a bridge, and leaves it. In this scenario, the\n"
918 "Party B should answer the bridge first.\n";
919 return AST_TEST_NOT_RUN;
923 SWAP_CONFIG(config, debug_cdr_config);
924 CREATE_ALICE_CHANNEL(chan_alice, &caller_alice, &alice_expected);
926 CREATE_BOB_CHANNEL(chan_bob, &caller_bob, &bob_expected);
927 ast_copy_string(bob_expected.linkedid, ast_channel_linkedid(chan_alice), sizeof(bob_expected.linkedid));
929 EMULATE_APP_DATA(chan_alice, 1, "Answer", "");
930 ast_setstate(chan_alice, AST_STATE_UP);
931 EMULATE_APP_DATA(chan_alice, 2, "Bridge", "");
933 bridge = ast_bridge_basic_new();
934 ast_test_validate(test, bridge != NULL);
936 EMULATE_APP_DATA(chan_bob, 1, "Answer", "");
937 ast_setstate(chan_bob, AST_STATE_UP);
938 EMULATE_APP_DATA(chan_bob, 2, "Bridge", "");
939 while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
941 ast_test_validate(test, !ast_bridge_impart(bridge, chan_bob, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
942 while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
944 ast_test_validate(test, !ast_bridge_impart(bridge, chan_alice, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
945 while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
947 ast_bridge_depart(chan_alice);
948 ast_bridge_depart(chan_bob);
950 HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL);
951 HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL);
953 result = verify_mock_cdr_record(test, &alice_expected, 2);
958 AST_TEST_DEFINE(test_cdr_single_multiparty_bridge)
960 RAII_VAR(struct ast_channel *, chan_alice, NULL, safe_channel_release);
961 RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release);
962 RAII_VAR(struct ast_channel *, chan_charlie, NULL, safe_channel_release);
963 RAII_VAR(struct ast_bridge *, bridge, NULL, ao2_cleanup);
964 RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
966 struct timespec to_sleep = {1, 0};
968 struct ast_party_caller caller_alice = ALICE_CALLERID;
969 struct ast_party_caller caller_bob = BOB_CALLERID;
970 struct ast_party_caller caller_charlie = CHARLIE_CALLERID;
971 struct ast_cdr charlie_expected = {
972 .clid = "\"Charlie\" <300>",
975 .dcontext = "default",
976 .channel = CHANNEL_TECH_NAME "/Charlie",
979 .amaflags = AST_AMA_DOCUMENTATION,
980 .disposition = AST_CDR_ANSWERED,
981 .accountcode = "300",
983 struct ast_cdr bob_expected = {
984 .clid = "\"Bob\" <200>",
987 .dcontext = "default",
988 .channel = CHANNEL_TECH_NAME "/Bob",
989 .dstchannel = CHANNEL_TECH_NAME "/Charlie",
992 .amaflags = AST_AMA_DOCUMENTATION,
993 .disposition = AST_CDR_ANSWERED,
994 .accountcode = "200",
995 .peeraccount = "300",
996 .next = &charlie_expected,
998 struct ast_cdr alice_expected_two = {
999 .clid = "\"Alice\" <100>",
1002 .dcontext = "default",
1003 .channel = CHANNEL_TECH_NAME "/Alice",
1004 .dstchannel = CHANNEL_TECH_NAME "/Charlie",
1005 .lastapp = "Bridge",
1007 .amaflags = AST_AMA_DOCUMENTATION,
1008 .disposition = AST_CDR_ANSWERED,
1009 .accountcode = "100",
1010 .peeraccount = "300",
1011 .next = &bob_expected,
1013 struct ast_cdr alice_expected_one = {
1014 .clid = "\"Alice\" <100>",
1017 .dcontext = "default",
1018 .channel = CHANNEL_TECH_NAME "/Alice",
1019 .dstchannel = CHANNEL_TECH_NAME "/Bob",
1020 .lastapp = "Bridge",
1022 .amaflags = AST_AMA_DOCUMENTATION,
1023 .disposition = AST_CDR_ANSWERED,
1024 .accountcode = "100",
1025 .peeraccount = "200",
1026 .next = &alice_expected_two,
1029 enum ast_test_result_state result = AST_TEST_NOT_RUN;
1033 info->name = __func__;
1034 info->category = TEST_CATEGORY;
1035 info->summary = "Test cdrs for a single party entering/leaving a multi-party bridge";
1037 "Test the properties of a CDR for a call that is\n"
1038 "answered, enters a bridge, and leaves it. A total of three\n"
1039 "parties perform this action.\n";
1040 return AST_TEST_NOT_RUN;
1044 SWAP_CONFIG(config, debug_cdr_config);
1045 CREATE_ALICE_CHANNEL(chan_alice, &caller_alice, &alice_expected_one);
1046 COPY_IDS(chan_alice, &alice_expected_two);
1047 CREATE_BOB_CHANNEL(chan_bob, &caller_bob, &bob_expected);
1048 ast_copy_string(bob_expected.linkedid, ast_channel_linkedid(chan_alice), sizeof(bob_expected.linkedid));
1049 CREATE_CHARLIE_CHANNEL(chan_charlie, &caller_charlie, &charlie_expected);
1050 ast_copy_string(charlie_expected.linkedid, ast_channel_linkedid(chan_alice), sizeof(charlie_expected.linkedid));
1052 EMULATE_APP_DATA(chan_alice, 1, "Answer", "");
1053 ast_setstate(chan_alice, AST_STATE_UP);
1054 EMULATE_APP_DATA(chan_alice, 2, "Bridge", "");
1056 bridge = ast_bridge_basic_new();
1057 ast_test_validate(test, bridge != NULL);
1058 while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
1060 ast_test_validate(test, !ast_bridge_impart(bridge, chan_alice, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
1062 EMULATE_APP_DATA(chan_bob, 1, "Answer", "");
1063 ast_setstate(chan_bob, AST_STATE_UP);
1064 EMULATE_APP_DATA(chan_bob, 2, "Bridge", "");
1065 while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
1067 ast_test_validate(test, !ast_bridge_impart(bridge, chan_bob, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
1069 while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
1071 EMULATE_APP_DATA(chan_charlie, 1, "Answer", "");
1072 ast_setstate(chan_charlie, AST_STATE_UP);
1073 EMULATE_APP_DATA(chan_charlie, 2, "Bridge", "");
1074 ast_test_validate(test, !ast_bridge_impart(bridge, chan_charlie, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
1076 while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
1078 ast_bridge_depart(chan_alice);
1079 ast_bridge_depart(chan_bob);
1080 ast_bridge_depart(chan_charlie);
1082 HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL);
1083 HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL);
1084 HANGUP_CHANNEL(chan_charlie, AST_CAUSE_NORMAL);
1086 result = verify_mock_cdr_record(test, &alice_expected_one, 4);
1091 AST_TEST_DEFINE(test_cdr_dial_unanswered)
1093 RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
1094 RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
1095 RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
1098 struct ast_party_caller caller = ALICE_CALLERID;
1099 struct ast_cdr expected = {
1100 .clid = "\"Alice\" <100>",
1103 .dcontext = "default",
1104 .channel = CHANNEL_TECH_NAME "/Alice",
1105 .dstchannel = CHANNEL_TECH_NAME "/Bob",
1107 .lastdata = CHANNEL_TECH_NAME "/Bob",
1109 .amaflags = AST_AMA_DOCUMENTATION,
1110 .disposition = AST_CDR_NOANSWER,
1111 .accountcode = "100",
1112 .peeraccount = "200",
1114 enum ast_test_result_state result = AST_TEST_NOT_RUN;
1118 info->name = __func__;
1119 info->category = TEST_CATEGORY;
1120 info->summary = "Test CDRs for a dial that isn't answered";
1122 "Test the properties of a CDR for a channel that\n"
1123 "performs a dial operation that isn't answered\n";
1124 return AST_TEST_NOT_RUN;
1129 SWAP_CONFIG(config, unanswered_cdr_config);
1131 CREATE_ALICE_CHANNEL(chan_caller, &caller, &expected);
1133 EMULATE_APP_DATA(chan_caller, 1, "Dial", "CDRTestChannel/Bob");
1135 chan_callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, ast_channel_linkedid(chan_caller), 0, CHANNEL_TECH_NAME "/Bob");
1136 ast_set_flag(ast_channel_flags(chan_callee), AST_FLAG_OUTGOING);
1137 EMULATE_APP_DATA(chan_callee, 0, "AppDial", "(Outgoing Line)");
1139 ast_channel_publish_dial(chan_caller, chan_callee, "Bob", NULL);
1140 ast_channel_state_set(chan_caller, AST_STATE_RINGING);
1141 ast_channel_publish_dial(chan_caller, chan_callee, NULL, "NOANSWER");
1143 HANGUP_CHANNEL(chan_caller, AST_CAUSE_NO_ANSWER);
1144 HANGUP_CHANNEL(chan_callee, AST_CAUSE_NO_ANSWER);
1146 result = verify_mock_cdr_record(test, &expected, 1);
1152 AST_TEST_DEFINE(test_cdr_dial_busy)
1154 RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
1155 RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
1156 RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
1159 struct ast_party_caller caller = ALICE_CALLERID;
1160 struct ast_cdr expected = {
1161 .clid = "\"Alice\" <100>",
1164 .dcontext = "default",
1165 .channel = CHANNEL_TECH_NAME "/Alice",
1166 .dstchannel = CHANNEL_TECH_NAME "/Bob",
1168 .lastdata = CHANNEL_TECH_NAME "/Bob",
1170 .amaflags = AST_AMA_DOCUMENTATION,
1171 .disposition = AST_CDR_BUSY,
1172 .accountcode = "100",
1173 .peeraccount = "200",
1175 enum ast_test_result_state result = AST_TEST_NOT_RUN;
1179 info->name = __func__;
1180 info->category = TEST_CATEGORY;
1181 info->summary = "Test CDRs for a dial that results in a busy";
1183 "Test the properties of a CDR for a channel that\n"
1184 "performs a dial operation to an endpoint that's busy\n";
1185 return AST_TEST_NOT_RUN;
1190 SWAP_CONFIG(config, unanswered_cdr_config);
1192 CREATE_ALICE_CHANNEL(chan_caller, &caller, &expected);
1194 EMULATE_APP_DATA(chan_caller, 1, "Dial", CHANNEL_TECH_NAME "/Bob");
1196 chan_callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, ast_channel_linkedid(chan_caller), 0, CHANNEL_TECH_NAME "/Bob");
1197 ast_set_flag(ast_channel_flags(chan_callee), AST_FLAG_OUTGOING);
1198 EMULATE_APP_DATA(chan_callee, 0, "AppDial", "(Outgoing Line)");
1200 ast_channel_publish_dial(chan_caller, chan_callee, "Bob", NULL);
1201 ast_channel_state_set(chan_caller, AST_STATE_RINGING);
1202 ast_channel_publish_dial(chan_caller, chan_callee, NULL, "BUSY");
1204 HANGUP_CHANNEL(chan_caller, AST_CAUSE_BUSY);
1205 HANGUP_CHANNEL(chan_callee, AST_CAUSE_BUSY);
1207 result = verify_mock_cdr_record(test, &expected, 1);
1212 AST_TEST_DEFINE(test_cdr_dial_congestion)
1214 RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
1215 RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
1216 RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
1219 struct ast_party_caller caller = ALICE_CALLERID;
1220 struct ast_cdr expected = {
1221 .clid = "\"Alice\" <100>",
1224 .dcontext = "default",
1225 .channel = CHANNEL_TECH_NAME "/Alice",
1226 .dstchannel = CHANNEL_TECH_NAME "/Bob",
1228 .lastdata = CHANNEL_TECH_NAME "/Bob",
1230 .amaflags = AST_AMA_DOCUMENTATION,
1231 .disposition = AST_CDR_CONGESTION,
1232 .accountcode = "100",
1233 .peeraccount = "200",
1235 enum ast_test_result_state result = AST_TEST_NOT_RUN;
1239 info->name = __func__;
1240 info->category = TEST_CATEGORY;
1241 info->summary = "Test CDRs for a dial that results in congestion";
1243 "Test the properties of a CDR for a channel that\n"
1244 "performs a dial operation to an endpoint that's congested\n";
1245 return AST_TEST_NOT_RUN;
1250 SWAP_CONFIG(config, congestion_cdr_config);
1252 CREATE_ALICE_CHANNEL(chan_caller, &caller, &expected);
1254 EMULATE_APP_DATA(chan_caller, 1, "Dial", CHANNEL_TECH_NAME "/Bob");
1256 chan_callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, ast_channel_linkedid(chan_caller), 0, CHANNEL_TECH_NAME "/Bob");
1257 ast_set_flag(ast_channel_flags(chan_callee), AST_FLAG_OUTGOING);
1258 EMULATE_APP_DATA(chan_callee, 0, "AppDial", "(Outgoing Line)");
1260 ast_channel_publish_dial(chan_caller, chan_callee, "Bob", NULL);
1261 ast_channel_state_set(chan_caller, AST_STATE_RINGING);
1262 ast_channel_publish_dial(chan_caller, chan_callee, NULL, "CONGESTION");
1264 HANGUP_CHANNEL(chan_caller, AST_CAUSE_CONGESTION);
1265 HANGUP_CHANNEL(chan_callee, AST_CAUSE_CONGESTION);
1267 result = verify_mock_cdr_record(test, &expected, 1);
1272 AST_TEST_DEFINE(test_cdr_dial_unavailable)
1274 RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
1275 RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
1276 RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
1279 struct ast_party_caller caller = ALICE_CALLERID;
1280 struct ast_cdr expected = {
1281 .clid = "\"Alice\" <100>",
1284 .dcontext = "default",
1285 .channel = CHANNEL_TECH_NAME "/Alice",
1286 .dstchannel = CHANNEL_TECH_NAME "/Bob",
1288 .lastdata = CHANNEL_TECH_NAME "/Bob",
1290 .amaflags = AST_AMA_DOCUMENTATION,
1291 .disposition = AST_CDR_FAILED,
1292 .accountcode = "100",
1293 .peeraccount = "200",
1295 enum ast_test_result_state result = AST_TEST_NOT_RUN;
1299 info->name = __func__;
1300 info->category = TEST_CATEGORY;
1301 info->summary = "Test CDRs for a dial that results in unavailable";
1303 "Test the properties of a CDR for a channel that\n"
1304 "performs a dial operation to an endpoint that's unavailable\n";
1305 return AST_TEST_NOT_RUN;
1310 SWAP_CONFIG(config, unanswered_cdr_config);
1312 CREATE_ALICE_CHANNEL(chan_caller, &caller, &expected);
1314 EMULATE_APP_DATA(chan_caller, 1, "Dial", CHANNEL_TECH_NAME "/Bob");
1316 chan_callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, ast_channel_linkedid(chan_caller), 0, CHANNEL_TECH_NAME "/Bob");
1317 ast_set_flag(ast_channel_flags(chan_callee), AST_FLAG_OUTGOING);
1318 EMULATE_APP_DATA(chan_callee, 0, "AppDial", "(Outgoing Line)");
1320 ast_channel_publish_dial(chan_caller, chan_callee, "Bob", NULL);
1321 ast_channel_state_set(chan_caller, AST_STATE_RINGING);
1322 ast_channel_publish_dial(chan_caller, chan_callee, NULL, "CHANUNAVAIL");
1324 HANGUP_CHANNEL(chan_caller, AST_CAUSE_NO_ROUTE_DESTINATION);
1325 HANGUP_CHANNEL(chan_callee, AST_CAUSE_NO_ROUTE_DESTINATION);
1327 result = verify_mock_cdr_record(test, &expected, 1);
1332 AST_TEST_DEFINE(test_cdr_dial_caller_cancel)
1334 RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
1335 RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
1336 RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
1339 struct ast_party_caller caller = ALICE_CALLERID;
1340 struct ast_cdr expected = {
1341 .clid = "\"Alice\" <100>",
1344 .dcontext = "default",
1345 .channel = CHANNEL_TECH_NAME "/Alice",
1346 .dstchannel = CHANNEL_TECH_NAME "/Bob",
1348 .lastdata = CHANNEL_TECH_NAME "/Bob",
1350 .amaflags = AST_AMA_DOCUMENTATION,
1351 .disposition = AST_CDR_NOANSWER,
1352 .accountcode = "100",
1353 .peeraccount = "200",
1355 enum ast_test_result_state result = AST_TEST_NOT_RUN;
1359 info->name = __func__;
1360 info->category = TEST_CATEGORY;
1361 info->summary = "Test CDRs for a dial where the caller cancels";
1363 "Test the properties of a CDR for a channel that\n"
1364 "performs a dial operation to an endpoint but then decides\n"
1365 "to hang up, cancelling the dial\n";
1366 return AST_TEST_NOT_RUN;
1371 SWAP_CONFIG(config, unanswered_cdr_config);
1373 CREATE_ALICE_CHANNEL(chan_caller, &caller, &expected);
1375 EMULATE_APP_DATA(chan_caller, 1, "Dial", CHANNEL_TECH_NAME "/Bob");
1377 chan_callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, ast_channel_linkedid(chan_caller), 0, CHANNEL_TECH_NAME "/Bob");
1378 ast_set_flag(ast_channel_flags(chan_callee), AST_FLAG_OUTGOING);
1379 EMULATE_APP_DATA(chan_callee, 0, "AppDial", "(Outgoing Line)");
1381 ast_channel_publish_dial(chan_caller, chan_callee, "Bob", NULL);
1382 ast_channel_state_set(chan_caller, AST_STATE_RINGING);
1383 ast_channel_publish_dial(chan_caller, chan_callee, NULL, "CANCEL");
1385 HANGUP_CHANNEL(chan_callee, AST_CAUSE_NORMAL);
1386 HANGUP_CHANNEL(chan_caller, AST_CAUSE_NORMAL);
1388 result = verify_mock_cdr_record(test, &expected, 1);
1393 AST_TEST_DEFINE(test_cdr_dial_parallel_failed)
1395 RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
1396 RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release);
1397 RAII_VAR(struct ast_channel *, chan_charlie, NULL, safe_channel_release);
1398 RAII_VAR(struct ast_channel *, chan_david, NULL, safe_channel_release);
1399 RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
1402 struct ast_party_caller caller = ALICE_CALLERID;
1403 struct ast_cdr bob_expected = {
1404 .clid = "\"Alice\" <100>",
1407 .dcontext = "default",
1408 .channel = CHANNEL_TECH_NAME "/Alice",
1409 .dstchannel = CHANNEL_TECH_NAME "/Bob",
1411 .lastdata = CHANNEL_TECH_NAME "/Bob&" CHANNEL_TECH_NAME "/Charlie&" CHANNEL_TECH_NAME "/David",
1413 .amaflags = AST_AMA_DOCUMENTATION,
1414 .disposition = AST_CDR_NOANSWER,
1415 .accountcode = "100",
1416 .peeraccount = "200",
1418 struct ast_cdr charlie_expected = {
1419 .clid = "\"Alice\" <100>",
1422 .dcontext = "default",
1423 .channel = CHANNEL_TECH_NAME "/Alice",
1424 .dstchannel = CHANNEL_TECH_NAME "/Charlie",
1426 .lastdata = CHANNEL_TECH_NAME "/Bob&" CHANNEL_TECH_NAME "/Charlie&" CHANNEL_TECH_NAME "/David",
1428 .amaflags = AST_AMA_DOCUMENTATION,
1429 .disposition = AST_CDR_BUSY,
1430 .accountcode = "100",
1431 .peeraccount = "300",
1433 struct ast_cdr david_expected = {
1434 .clid = "\"Alice\" <100>",
1437 .dcontext = "default",
1438 .channel = CHANNEL_TECH_NAME "/Alice",
1439 .dstchannel = CHANNEL_TECH_NAME "/David",
1441 .lastdata = CHANNEL_TECH_NAME "/Bob&" CHANNEL_TECH_NAME "/Charlie&" CHANNEL_TECH_NAME "/David",
1443 .amaflags = AST_AMA_DOCUMENTATION,
1444 .disposition = AST_CDR_CONGESTION,
1445 .accountcode = "100",
1446 .peeraccount = "400",
1448 enum ast_test_result_state result = AST_TEST_NOT_RUN;
1450 struct ast_cdr *expected = &bob_expected;
1451 bob_expected.next = &charlie_expected;
1452 charlie_expected.next = &david_expected;
1456 info->name = __func__;
1457 info->category = TEST_CATEGORY;
1458 info->summary = "Test a parallel dial where all channels fail to answer";
1460 "This tests dialing three parties: Bob, Charlie, David. Charlie\n"
1461 "returns BUSY; David returns CONGESTION; Bob fails to answer and\n"
1462 "Alice hangs up. Three records are created for Alice as a result.\n";
1463 return AST_TEST_NOT_RUN;
1468 SWAP_CONFIG(config, congestion_cdr_config);
1470 CREATE_ALICE_CHANNEL(chan_caller, &caller, &bob_expected);
1471 COPY_IDS(chan_caller, &charlie_expected);
1472 COPY_IDS(chan_caller, &david_expected);
1474 /* Channel enters Dial app */
1475 EMULATE_APP_DATA(chan_caller, 1, "Dial", CHANNEL_TECH_NAME "/Bob&" CHANNEL_TECH_NAME "/Charlie&" CHANNEL_TECH_NAME "/David");
1477 /* Outbound channels are created */
1478 chan_bob = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, ast_channel_linkedid(chan_caller), 0, CHANNEL_TECH_NAME "/Bob");
1479 ast_set_flag(ast_channel_flags(chan_bob), AST_FLAG_OUTGOING);
1480 EMULATE_APP_DATA(chan_bob, 0, "AppDial", "(Outgoing Line)");
1482 chan_charlie = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "300", NULL, NULL, ast_channel_linkedid(chan_caller), 0, CHANNEL_TECH_NAME "/Charlie");
1483 ast_set_flag(ast_channel_flags(chan_charlie), AST_FLAG_OUTGOING);
1484 EMULATE_APP_DATA(chan_charlie, 0, "AppDial", "(Outgoing Line)");
1486 chan_david = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "400", NULL, NULL, ast_channel_linkedid(chan_caller), 0, CHANNEL_TECH_NAME "/David");
1487 ast_set_flag(ast_channel_flags(chan_david), AST_FLAG_OUTGOING);
1488 EMULATE_APP_DATA(chan_david, 0, "AppDial", "(Outgoing Line)");
1491 ast_channel_publish_dial(chan_caller, chan_bob, "Bob", NULL);
1492 ast_channel_publish_dial(chan_caller, chan_charlie, "Charlie", NULL);
1493 ast_channel_publish_dial(chan_caller, chan_david, "David", NULL);
1494 ast_channel_state_set(chan_caller, AST_STATE_RINGING);
1496 /* Charlie is busy */
1497 ast_channel_publish_dial(chan_caller, chan_charlie, NULL, "BUSY");
1498 HANGUP_CHANNEL(chan_charlie, AST_CAUSE_BUSY);
1500 /* David is congested */
1501 ast_channel_publish_dial(chan_caller, chan_david, NULL, "CONGESTION");
1502 HANGUP_CHANNEL(chan_david, AST_CAUSE_CONGESTION);
1504 /* Bob is canceled */
1505 ast_channel_publish_dial(chan_caller, chan_bob, NULL, "CANCEL");
1506 HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL);
1508 /* Alice hangs up */
1509 HANGUP_CHANNEL(chan_caller, AST_CAUSE_NORMAL);
1511 result = verify_mock_cdr_record(test, expected, 3);
1516 AST_TEST_DEFINE(test_cdr_dial_answer_no_bridge)
1518 RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
1519 RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
1520 RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
1523 struct ast_party_caller caller = ALICE_CALLERID;
1524 struct ast_cdr bob_expected_one = {
1528 .dcontext = "default",
1529 .channel = CHANNEL_TECH_NAME "/Bob",
1532 .amaflags = AST_AMA_DOCUMENTATION,
1533 .disposition = AST_CDR_ANSWERED,
1534 .accountcode = "200",
1536 struct ast_cdr alice_expected_two = {
1537 .clid = "\"Alice\" <100>",
1540 .dcontext = "default",
1541 .channel = CHANNEL_TECH_NAME "/Alice",
1544 .amaflags = AST_AMA_DOCUMENTATION,
1545 .disposition = AST_CDR_ANSWERED,
1546 .accountcode = "100",
1547 .next = &bob_expected_one,
1549 struct ast_cdr alice_expected_one = {
1550 .clid = "\"Alice\" <100>",
1553 .dcontext = "default",
1554 .channel = CHANNEL_TECH_NAME "/Alice",
1555 .dstchannel = CHANNEL_TECH_NAME "/Bob",
1557 .lastdata = CHANNEL_TECH_NAME "/Bob",
1558 .amaflags = AST_AMA_DOCUMENTATION,
1559 .disposition = AST_CDR_ANSWERED,
1560 .accountcode = "100",
1561 .peeraccount = "200",
1562 .next = &alice_expected_two,
1564 enum ast_test_result_state result = AST_TEST_NOT_RUN;
1568 info->name = __func__;
1569 info->category = TEST_CATEGORY;
1570 info->summary = "Test dialing, answering, and not going into a bridge.";
1572 "This is a weird one, but theoretically possible. You can perform\n"
1573 "a dial, then bounce both channels to different priorities and\n"
1574 "never have them enter a bridge together. Ew. This makes sure that\n"
1575 "when we answer, we get a CDR, it gets ended at that point, and\n"
1576 "that it gets finalized appropriately. We should get three CDRs in\n"
1577 "the end - one for the dial, and one for each CDR as they continued\n"
1579 return AST_TEST_NOT_RUN;
1584 SWAP_CONFIG(config, debug_cdr_config);
1586 CREATE_ALICE_CHANNEL(chan_caller, &caller, &alice_expected_one);
1587 COPY_IDS(chan_caller, &alice_expected_two);
1589 EMULATE_APP_DATA(chan_caller, 1, "Dial", CHANNEL_TECH_NAME "/Bob");
1591 chan_callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, ast_channel_linkedid(chan_caller), 0, CHANNEL_TECH_NAME "/Bob");
1592 ast_set_flag(ast_channel_flags(chan_callee), AST_FLAG_OUTGOING);
1593 COPY_IDS(chan_callee, &bob_expected_one);
1595 ast_channel_publish_dial(chan_caller, chan_callee, "Bob", NULL);
1596 ast_channel_state_set(chan_caller, AST_STATE_RINGING);
1597 ast_channel_publish_dial(chan_caller, chan_callee, NULL, "ANSWER");
1599 ast_channel_state_set(chan_caller, AST_STATE_UP);
1600 ast_clear_flag(ast_channel_flags(chan_callee), AST_FLAG_OUTGOING);
1601 ast_channel_state_set(chan_callee, AST_STATE_UP);
1603 EMULATE_APP_DATA(chan_caller, 2, "Wait", "1");
1604 EMULATE_APP_DATA(chan_callee, 1, "Wait", "1");
1606 HANGUP_CHANNEL(chan_caller, AST_CAUSE_NORMAL);
1607 HANGUP_CHANNEL(chan_callee, AST_CAUSE_NORMAL);
1609 result = verify_mock_cdr_record(test, &alice_expected_one, 3);
1613 AST_TEST_DEFINE(test_cdr_dial_answer_twoparty_bridge_a)
1615 RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
1616 RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
1617 RAII_VAR(struct ast_bridge *, bridge, NULL, ao2_cleanup);
1618 RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
1620 struct timespec to_sleep = {1, 0};
1621 enum ast_test_result_state result = AST_TEST_NOT_RUN;
1623 struct ast_party_caller caller = ALICE_CALLERID;
1624 struct ast_cdr expected = {
1625 .clid = "\"Alice\" <100>",
1628 .dcontext = "default",
1629 .channel = CHANNEL_TECH_NAME "/Alice",
1630 .dstchannel = CHANNEL_TECH_NAME "/Bob",
1632 .lastdata = CHANNEL_TECH_NAME "/Bob",
1633 .amaflags = AST_AMA_DOCUMENTATION,
1635 .disposition = AST_CDR_ANSWERED,
1636 .accountcode = "100",
1637 .peeraccount = "200",
1642 info->name = __func__;
1643 info->category = TEST_CATEGORY;
1644 info->summary = "Test dialing, answering, and going into a 2-party bridge";
1646 "The most 'basic' of scenarios\n";
1647 return AST_TEST_NOT_RUN;
1652 SWAP_CONFIG(config, debug_cdr_config);
1654 CREATE_ALICE_CHANNEL(chan_caller, &caller, &expected);
1656 EMULATE_APP_DATA(chan_caller, 1, "Dial", CHANNEL_TECH_NAME "/Bob");
1658 chan_callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, ast_channel_linkedid(chan_caller), 0, CHANNEL_TECH_NAME "/Bob");
1659 ast_set_flag(ast_channel_flags(chan_callee), AST_FLAG_OUTGOING);
1660 EMULATE_APP_DATA(chan_callee, 0, "AppDial", "(Outgoing Line)");
1662 ast_channel_publish_dial(chan_caller, chan_callee, "Bob", NULL);
1663 ast_channel_state_set(chan_caller, AST_STATE_RINGING);
1664 ast_channel_publish_dial(chan_caller, chan_callee, NULL, "ANSWER");
1666 ast_channel_state_set(chan_caller, AST_STATE_UP);
1667 ast_channel_state_set(chan_callee, AST_STATE_UP);
1669 bridge = ast_bridge_basic_new();
1670 ast_test_validate(test, bridge != NULL);
1671 while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
1673 ast_test_validate(test, !ast_bridge_impart(bridge, chan_caller, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
1674 ast_test_validate(test, !ast_bridge_impart(bridge, chan_callee, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
1676 while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
1678 ast_bridge_depart(chan_caller);
1679 ast_bridge_depart(chan_callee);
1681 HANGUP_CHANNEL(chan_caller, AST_CAUSE_NORMAL);
1682 HANGUP_CHANNEL(chan_callee, AST_CAUSE_NORMAL);
1684 result = verify_mock_cdr_record(test, &expected, 1);
1688 AST_TEST_DEFINE(test_cdr_dial_answer_twoparty_bridge_b)
1690 RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
1691 RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
1692 RAII_VAR(struct ast_bridge *, bridge, NULL, ao2_cleanup);
1693 RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
1695 struct timespec to_sleep = {1, 0};
1696 enum ast_test_result_state result = AST_TEST_NOT_RUN;
1698 struct ast_party_caller caller = ALICE_CALLERID;
1699 struct ast_cdr expected = {
1700 .clid = "\"Alice\" <100>",
1703 .dcontext = "default",
1704 .channel = CHANNEL_TECH_NAME "/Alice",
1705 .dstchannel = CHANNEL_TECH_NAME "/Bob",
1707 .lastdata = CHANNEL_TECH_NAME "/Bob",
1708 .amaflags = AST_AMA_DOCUMENTATION,
1710 .disposition = AST_CDR_ANSWERED,
1711 .accountcode = "100",
1712 .peeraccount = "200",
1717 info->name = __func__;
1718 info->category = TEST_CATEGORY;
1719 info->summary = "Test dialing, answering, and going into a 2-party bridge";
1721 "The most 'basic' of scenarios\n";
1722 return AST_TEST_NOT_RUN;
1727 SWAP_CONFIG(config, debug_cdr_config);
1729 CREATE_ALICE_CHANNEL(chan_caller, &caller, &expected);
1731 EMULATE_APP_DATA(chan_caller, 1, "Dial", CHANNEL_TECH_NAME "/Bob");
1733 chan_callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, ast_channel_linkedid(chan_caller), 0, CHANNEL_TECH_NAME "/Bob");
1734 ast_set_flag(ast_channel_flags(chan_callee), AST_FLAG_OUTGOING);
1735 EMULATE_APP_DATA(chan_callee, 0, "AppDial", "(Outgoing Line)");
1737 ast_channel_publish_dial(chan_caller, chan_callee, "Bob", NULL);
1738 ast_channel_state_set(chan_caller, AST_STATE_RINGING);
1739 ast_channel_publish_dial(chan_caller, chan_callee, NULL, "ANSWER");
1741 ast_channel_state_set(chan_caller, AST_STATE_UP);
1742 ast_channel_state_set(chan_callee, AST_STATE_UP);
1744 bridge = ast_bridge_basic_new();
1745 ast_test_validate(test, bridge != NULL);
1746 while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
1747 ast_test_validate(test, !ast_bridge_impart(bridge, chan_callee, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
1748 while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
1749 ast_test_validate(test, !ast_bridge_impart(bridge, chan_caller, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
1750 while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
1751 ast_bridge_depart(chan_caller);
1752 ast_bridge_depart(chan_callee);
1754 HANGUP_CHANNEL(chan_caller, AST_CAUSE_NORMAL);
1755 HANGUP_CHANNEL(chan_callee, AST_CAUSE_NORMAL);
1757 result = verify_mock_cdr_record(test, &expected, 1);
1761 AST_TEST_DEFINE(test_cdr_dial_answer_multiparty)
1763 RAII_VAR(struct ast_channel *, chan_alice, NULL, safe_channel_release);
1764 RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release);
1765 RAII_VAR(struct ast_channel *, chan_charlie, NULL, safe_channel_release);
1766 RAII_VAR(struct ast_channel *, chan_david, NULL, safe_channel_release);
1767 RAII_VAR(struct ast_bridge *, bridge, NULL, ao2_cleanup);
1768 RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
1770 struct timespec to_sleep = {1, 0};
1771 enum ast_test_result_state result = AST_TEST_NOT_RUN;
1773 struct ast_party_caller alice_caller = ALICE_CALLERID;
1774 struct ast_party_caller charlie_caller = CHARLIE_CALLERID;
1775 struct ast_cdr charlie_expected_two = {
1776 .clid = "\"Charlie\" <300>",
1779 .dcontext = "default",
1780 .channel = CHANNEL_TECH_NAME "/Charlie",
1781 .dstchannel = CHANNEL_TECH_NAME "/Bob",
1783 .lastdata = CHANNEL_TECH_NAME "/David",
1784 .amaflags = AST_AMA_DOCUMENTATION,
1786 .disposition = AST_CDR_ANSWERED,
1787 .accountcode = "300",
1788 .peeraccount = "200",
1790 struct ast_cdr charlie_expected_one = {
1791 .clid = "\"Charlie\" <300>",
1794 .dcontext = "default",
1795 .channel = CHANNEL_TECH_NAME "/Charlie",
1796 .dstchannel = CHANNEL_TECH_NAME "/David",
1798 .lastdata = CHANNEL_TECH_NAME "/David",
1799 .amaflags = AST_AMA_DOCUMENTATION,
1801 .disposition = AST_CDR_ANSWERED,
1802 .accountcode = "300",
1803 .peeraccount = "400",
1804 .next = &charlie_expected_two,
1806 struct ast_cdr bob_expected_one = {
1807 .clid = "\"Bob\" <200>",
1810 .dcontext = "default",
1811 .channel = CHANNEL_TECH_NAME "/Bob",
1812 .dstchannel = CHANNEL_TECH_NAME "/David",
1813 .lastapp = "AppDial",
1814 .lastdata = "(Outgoing Line)",
1815 .amaflags = AST_AMA_DOCUMENTATION,
1817 .disposition = AST_CDR_ANSWERED,
1818 .accountcode = "200",
1819 .peeraccount = "400",
1820 .next = &charlie_expected_one,
1822 struct ast_cdr alice_expected_three = {
1823 .clid = "\"Alice\" <100>",
1826 .dcontext = "default",
1827 .channel = CHANNEL_TECH_NAME "/Alice",
1828 .dstchannel = CHANNEL_TECH_NAME "/David",
1830 .lastdata = CHANNEL_TECH_NAME "/Bob",
1831 .amaflags = AST_AMA_DOCUMENTATION,
1833 .disposition = AST_CDR_ANSWERED,
1834 .accountcode = "100",
1835 .peeraccount = "400",
1836 .next = &bob_expected_one,
1838 struct ast_cdr alice_expected_two = {
1839 .clid = "\"Alice\" <100>",
1842 .dcontext = "default",
1843 .channel = CHANNEL_TECH_NAME "/Alice",
1844 .dstchannel = CHANNEL_TECH_NAME "/Charlie",
1846 .lastdata = CHANNEL_TECH_NAME "/Bob",
1847 .amaflags = AST_AMA_DOCUMENTATION,
1849 .disposition = AST_CDR_ANSWERED,
1850 .accountcode = "100",
1851 .peeraccount = "300",
1852 .next = &alice_expected_three,
1854 struct ast_cdr alice_expected_one = {
1855 .clid = "\"Alice\" <100>",
1858 .dcontext = "default",
1859 .channel = CHANNEL_TECH_NAME "/Alice",
1860 .dstchannel = CHANNEL_TECH_NAME "/Bob",
1862 .lastdata = CHANNEL_TECH_NAME "/Bob",
1863 .amaflags = AST_AMA_DOCUMENTATION,
1865 .disposition = AST_CDR_ANSWERED,
1866 .accountcode = "100",
1867 .peeraccount = "200",
1868 .next = &alice_expected_two,
1873 info->name = __func__;
1874 info->category = TEST_CATEGORY;
1875 info->summary = "Test dialing, answering, and going into a multi-party bridge";
1877 "A little tricky to get to do, but possible with some redirects.\n";
1878 return AST_TEST_NOT_RUN;
1883 SWAP_CONFIG(config, debug_cdr_config);
1885 CREATE_ALICE_CHANNEL(chan_alice, &alice_caller, &alice_expected_one);
1886 COPY_IDS(chan_alice, &alice_expected_two);
1887 COPY_IDS(chan_alice, &alice_expected_three);
1889 EMULATE_APP_DATA(chan_alice, 1, "Dial", CHANNEL_TECH_NAME "/Bob");
1891 chan_bob = ast_channel_alloc(0, AST_STATE_DOWN, "200", "Bob", "200", "200", "default", NULL, 0, CHANNEL_TECH_NAME "/Bob");
1892 ast_set_flag(ast_channel_flags(chan_bob), AST_FLAG_OUTGOING);
1893 EMULATE_APP_DATA(chan_bob, 0, "AppDial", "(Outgoing Line)");
1894 ast_copy_string(bob_expected_one.uniqueid, ast_channel_uniqueid(chan_bob), sizeof(bob_expected_one.uniqueid));
1895 ast_copy_string(bob_expected_one.linkedid, ast_channel_linkedid(chan_alice), sizeof(bob_expected_one.linkedid));
1897 CREATE_CHARLIE_CHANNEL(chan_charlie, &charlie_caller, &charlie_expected_one);
1898 EMULATE_APP_DATA(chan_charlie, 1, "Dial", CHANNEL_TECH_NAME "/David");
1899 ast_copy_string(charlie_expected_one.uniqueid, ast_channel_uniqueid(chan_charlie), sizeof(charlie_expected_one.uniqueid));
1900 ast_copy_string(charlie_expected_one.linkedid, ast_channel_linkedid(chan_alice), sizeof(charlie_expected_one.linkedid));
1901 ast_copy_string(charlie_expected_two.uniqueid, ast_channel_uniqueid(chan_charlie), sizeof(charlie_expected_two.uniqueid));
1902 ast_copy_string(charlie_expected_two.linkedid, ast_channel_linkedid(chan_alice), sizeof(charlie_expected_two.linkedid));
1904 chan_david = ast_channel_alloc(0, AST_STATE_DOWN, "400", "David", "400", "400", "default", NULL, 0, CHANNEL_TECH_NAME "/David");
1905 ast_set_flag(ast_channel_flags(chan_david), AST_FLAG_OUTGOING);
1906 EMULATE_APP_DATA(chan_david, 0, "AppDial", "(Outgoing Line)");
1908 ast_channel_publish_dial(chan_alice, chan_bob, "Bob", NULL);
1909 ast_channel_state_set(chan_alice, AST_STATE_RINGING);
1910 ast_channel_publish_dial(chan_charlie, chan_david, "David", NULL);
1911 ast_channel_state_set(chan_charlie, AST_STATE_RINGING);
1912 ast_channel_publish_dial(chan_alice, chan_bob, NULL, "ANSWER");
1913 ast_channel_publish_dial(chan_charlie, chan_david, NULL, "ANSWER");
1915 ast_channel_state_set(chan_alice, AST_STATE_UP);
1916 ast_channel_state_set(chan_bob, AST_STATE_UP);
1917 ast_channel_state_set(chan_charlie, AST_STATE_UP);
1918 ast_channel_state_set(chan_david, AST_STATE_UP);
1920 bridge = ast_bridge_basic_new();
1921 ast_test_validate(test, bridge != NULL);
1923 while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
1924 ast_test_validate(test, !ast_bridge_impart(bridge, chan_charlie, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
1925 while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
1926 ast_test_validate(test, !ast_bridge_impart(bridge, chan_david, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
1927 while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
1928 ast_test_validate(test, !ast_bridge_impart(bridge, chan_bob, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
1929 while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
1930 ast_test_validate(test, !ast_bridge_impart(bridge, chan_alice, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
1931 while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
1932 ast_test_validate(test, !ast_bridge_depart(chan_alice));
1933 ast_test_validate(test, !ast_bridge_depart(chan_bob));
1934 ast_test_validate(test, !ast_bridge_depart(chan_charlie));
1935 ast_test_validate(test, !ast_bridge_depart(chan_david));
1937 HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL);
1938 HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL);
1939 HANGUP_CHANNEL(chan_charlie, AST_CAUSE_NORMAL);
1940 HANGUP_CHANNEL(chan_david, AST_CAUSE_NORMAL);
1942 result = verify_mock_cdr_record(test, &alice_expected_one, 6);
1947 AST_TEST_DEFINE(test_cdr_park)
1949 RAII_VAR(struct ast_channel *, chan_alice, NULL, safe_channel_release);
1950 RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release);
1951 RAII_VAR(struct ast_bridge *, bridge, NULL, ao2_cleanup);
1952 RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
1954 struct timespec to_sleep = {1, 0};
1956 struct ast_party_caller bob_caller = BOB_CALLERID;
1957 struct ast_party_caller alice_caller = ALICE_CALLERID;
1958 struct ast_cdr bob_expected = {
1959 .clid = "\"Bob\" <200>",
1962 .dcontext = "default",
1963 .channel = CHANNEL_TECH_NAME "/Bob",
1967 .amaflags = AST_AMA_DOCUMENTATION,
1968 .disposition = AST_CDR_ANSWERED,
1969 .accountcode = "200",
1971 struct ast_cdr alice_expected = {
1972 .clid = "\"Alice\" <100>",
1975 .dcontext = "default",
1976 .channel = CHANNEL_TECH_NAME "/Alice",
1980 .amaflags = AST_AMA_DOCUMENTATION,
1981 .disposition = AST_CDR_ANSWERED,
1982 .accountcode = "100",
1983 .next = &bob_expected,
1985 enum ast_test_result_state result = AST_TEST_NOT_RUN;
1989 info->name = __func__;
1990 info->category = TEST_CATEGORY;
1991 info->summary = "Test cdrs for a single party entering Park";
1993 "Test the properties of a CDR for calls that are\n"
1994 "answered, enters Park, and leaves it.\n";
1995 return AST_TEST_NOT_RUN;
1999 SWAP_CONFIG(config, debug_cdr_config);
2000 CREATE_ALICE_CHANNEL(chan_alice, &alice_caller, &alice_expected);
2001 CREATE_BOB_CHANNEL(chan_bob, &bob_caller, &bob_expected);
2003 EMULATE_APP_DATA(chan_alice, 1, "Park", "700");
2004 ast_setstate(chan_alice, AST_STATE_UP);
2005 EMULATE_APP_DATA(chan_bob, 1, "Park", "701");
2006 ast_setstate(chan_bob, AST_STATE_UP);
2008 bridge = ast_bridge_base_new(AST_BRIDGE_CAPABILITY_HOLDING,
2009 AST_BRIDGE_FLAG_MERGE_INHIBIT_TO | AST_BRIDGE_FLAG_MERGE_INHIBIT_FROM
2010 | AST_BRIDGE_FLAG_SWAP_INHIBIT_FROM | AST_BRIDGE_FLAG_TRANSFER_PROHIBITED);
2011 ast_test_validate(test, bridge != NULL);
2013 while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
2014 ast_test_validate(test, !ast_bridge_impart(bridge, chan_alice, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
2015 while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
2016 ast_test_validate(test, !ast_bridge_impart(bridge, chan_bob, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
2017 while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
2018 ast_bridge_depart(chan_alice);
2019 ast_bridge_depart(chan_bob);
2021 /* And then it hangs up */
2022 HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL);
2023 HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL);
2025 result = verify_mock_cdr_record(test, &alice_expected, 2);
2031 AST_TEST_DEFINE(test_cdr_fields)
2033 RAII_VAR(struct ast_channel *, chan, NULL, safe_channel_release);
2034 RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
2036 char varbuffer[128];
2039 struct timespec to_sleep = {2, 0};
2040 struct ast_flags fork_options = { 0, };
2042 struct ast_party_caller caller = ALICE_CALLERID;
2043 struct ast_cdr original = {
2044 .clid = "\"Alice\" <100>",
2047 .dcontext = "default",
2048 .channel = CHANNEL_TECH_NAME "/Alice",
2052 .amaflags = AST_AMA_OMIT,
2053 .disposition = AST_CDR_FAILED,
2054 .accountcode = "XXX",
2055 .userfield = "yackity",
2057 struct ast_cdr fork_expected_one = {
2058 .clid = "\"Alice\" <100>",
2061 .dcontext = "default",
2062 .channel = CHANNEL_TECH_NAME "/Alice",
2066 .amaflags = AST_AMA_OMIT,
2067 .disposition = AST_CDR_FAILED,
2068 .accountcode = "XXX",
2069 .userfield = "yackity",
2071 struct ast_cdr fork_expected_two = {
2072 .clid = "\"Alice\" <100>",
2075 .dcontext = "default",
2076 .channel = CHANNEL_TECH_NAME "/Alice",
2077 .lastapp = "Answer",
2079 .amaflags = AST_AMA_OMIT,
2080 .disposition = AST_CDR_ANSWERED,
2081 .accountcode = "ZZZ",
2082 .userfield = "schmackity",
2084 enum ast_test_result_state result = AST_TEST_NOT_RUN;
2086 struct ast_cdr *expected = &original;
2087 original.next = &fork_expected_one;
2088 fork_expected_one.next = &fork_expected_two;
2092 info->name = __func__;
2093 info->category = TEST_CATEGORY;
2094 info->summary = "Test field access CDRs";
2096 "This tests setting/retrieving data on CDR records.\n";
2097 return AST_TEST_NOT_RUN;
2102 SWAP_CONFIG(config, unanswered_cdr_config);
2104 CREATE_ALICE_CHANNEL(chan, &caller, &original);
2105 ast_copy_string(fork_expected_one.uniqueid, ast_channel_uniqueid(chan), sizeof(fork_expected_one.uniqueid));
2106 ast_copy_string(fork_expected_one.linkedid, ast_channel_linkedid(chan), sizeof(fork_expected_one.linkedid));
2107 ast_copy_string(fork_expected_two.uniqueid, ast_channel_uniqueid(chan), sizeof(fork_expected_two.uniqueid));
2108 ast_copy_string(fork_expected_two.linkedid, ast_channel_linkedid(chan), sizeof(fork_expected_two.linkedid));
2110 /* Channel enters Wait app */
2111 ast_channel_appl_set(chan, "Wait");
2112 ast_channel_data_set(chan, "10");
2113 ast_channel_priority_set(chan, 1);
2114 ast_channel_publish_snapshot(chan);
2116 /* Set properties on the channel that propagate to the CDR */
2117 ast_channel_amaflags_set(chan, AST_AMA_OMIT);
2118 ast_channel_accountcode_set(chan, "XXX");
2120 /* Wait one second so we get a duration. */
2121 while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
2123 ast_cdr_setuserfield(ast_channel_name(chan), "foobar");
2124 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "test_variable", "record_1") == 0);
2126 /* Verify that we can't set read-only fields or other fields directly */
2127 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "clid", "junk") != 0);
2128 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "src", "junk") != 0);
2129 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "dst", "junk") != 0);
2130 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "dcontext", "junk") != 0);
2131 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "channel", "junk") != 0);
2132 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "dstchannel", "junk") != 0);
2133 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "lastapp", "junk") != 0);
2134 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "lastdata", "junk") != 0);
2135 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "start", "junk") != 0);
2136 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "answer", "junk") != 0);
2137 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "end", "junk") != 0);
2138 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "duration", "junk") != 0);
2139 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "billsec", "junk") != 0);
2140 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "disposition", "junk") != 0);
2141 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "amaflags", "junk") != 0);
2142 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "accountcode", "junk") != 0);
2143 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "uniqueid", "junk") != 0);
2144 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "linkedid", "junk") != 0);
2145 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "userfield", "junk") != 0);
2146 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "sequence", "junk") != 0);
2148 /* Verify the values */
2149 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "userfield", varbuffer, sizeof(varbuffer)) == 0);
2150 ast_test_validate(test, strcmp(varbuffer, "foobar") == 0);
2151 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "test_variable", varbuffer, sizeof(varbuffer)) == 0);
2152 ast_test_validate(test, strcmp(varbuffer, "record_1") == 0);
2153 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "amaflags", varbuffer, sizeof(varbuffer)) == 0);
2154 sscanf(varbuffer, "%d", &int_buffer);
2155 ast_test_validate(test, int_buffer == AST_AMA_OMIT);
2156 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "accountcode", varbuffer, sizeof(varbuffer)) == 0);
2157 ast_test_validate(test, strcmp(varbuffer, "XXX") == 0);
2158 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "clid", varbuffer, sizeof(varbuffer)) == 0);
2159 ast_test_validate(test, strcmp(varbuffer, "\"Alice\" <100>") == 0);
2160 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "src", varbuffer, sizeof(varbuffer)) == 0);
2161 ast_test_validate(test, strcmp(varbuffer, "100") == 0);
2162 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "dst", varbuffer, sizeof(varbuffer)) == 0);
2163 ast_test_validate(test, strcmp(varbuffer, "100") == 0);
2164 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "dcontext", varbuffer, sizeof(varbuffer)) == 0);
2165 ast_test_validate(test, strcmp(varbuffer, "default") == 0);
2166 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "channel", varbuffer, sizeof(varbuffer)) == 0);
2167 ast_test_validate(test, strcmp(varbuffer, CHANNEL_TECH_NAME "/Alice") == 0);
2168 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "dstchannel", varbuffer, sizeof(varbuffer)) == 0);
2169 ast_test_validate(test, strcmp(varbuffer, "") == 0);
2170 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "lastapp", varbuffer, sizeof(varbuffer)) == 0);
2171 ast_test_validate(test, strcmp(varbuffer, "Wait") == 0);
2172 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "lastdata", varbuffer, sizeof(varbuffer)) == 0);
2173 ast_test_validate(test, strcmp(varbuffer, "10") == 0);
2174 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "start", varbuffer, sizeof(varbuffer)) == 0);
2175 sscanf(varbuffer, "%lf", &db_buffer);
2176 ast_test_validate(test, fabs(db_buffer) > 0);
2177 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "answer", varbuffer, sizeof(varbuffer)) == 0);
2178 sscanf(varbuffer, "%lf", &db_buffer);
2179 ast_test_validate(test, fabs(db_buffer) < EPSILON);
2180 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "end", varbuffer, sizeof(varbuffer)) == 0);
2181 sscanf(varbuffer, "%lf", &db_buffer);
2182 ast_test_validate(test, fabs(db_buffer) < EPSILON);
2183 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "duration", varbuffer, sizeof(varbuffer)) == 0);
2184 sscanf(varbuffer, "%lf", &db_buffer);
2185 ast_test_validate(test, fabs(db_buffer) > 0);
2186 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "billsec", varbuffer, sizeof(varbuffer)) == 0);
2187 sscanf(varbuffer, "%lf", &db_buffer);
2188 ast_test_validate(test, fabs(db_buffer) < EPSILON);
2189 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "disposition", varbuffer, sizeof(varbuffer)) == 0);
2190 sscanf(varbuffer, "%d", &int_buffer);
2191 ast_test_validate(test, int_buffer == AST_CDR_NULL);
2192 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "uniqueid", varbuffer, sizeof(varbuffer)) == 0);
2193 ast_test_validate(test, strcmp(varbuffer, ast_channel_uniqueid(chan)) == 0);
2194 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "linkedid", varbuffer, sizeof(varbuffer)) == 0);
2195 ast_test_validate(test, strcmp(varbuffer, ast_channel_linkedid(chan)) == 0);
2196 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "sequence", varbuffer, sizeof(varbuffer)) == 0);
2198 /* Fork the CDR, and check that we change the properties on both CDRs. */
2199 ast_set_flag(&fork_options, AST_CDR_FLAG_KEEP_VARS);
2200 ast_test_validate(test, ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
2202 /* Change some properties */
2203 ast_cdr_setuserfield(ast_channel_name(chan), "yackity");
2204 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "test_variable", "record_1b") == 0);
2206 /* Fork the CDR again, finalizing all current CDRs */
2207 ast_set_flag(&fork_options, AST_CDR_FLAG_KEEP_VARS | AST_CDR_FLAG_FINALIZE);
2208 ast_test_validate(test, ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
2210 /* Channel enters Answer app */
2211 ast_channel_appl_set(chan, "Answer");
2212 ast_channel_data_set(chan, "");
2213 ast_channel_priority_set(chan, 1);
2214 ast_channel_publish_snapshot(chan);
2215 ast_setstate(chan, AST_STATE_UP);
2217 /* Set properties on the last record */
2218 ast_channel_accountcode_set(chan, "ZZZ");
2219 ast_cdr_setuserfield(ast_channel_name(chan), "schmackity");
2220 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "test_variable", "record_2") == 0);
2222 /* Hang up and verify */
2223 ast_channel_hangupcause_set(chan, AST_CAUSE_NORMAL);
2226 result = verify_mock_cdr_record(test, expected, 3);
2231 AST_TEST_DEFINE(test_cdr_no_reset_cdr)
2233 RAII_VAR(struct ast_channel *, chan, NULL, safe_channel_release);
2234 RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
2236 struct ast_flags fork_options = { 0, };
2237 struct timespec to_sleep = {1, 0};
2239 struct ast_party_caller caller = ALICE_CALLERID;
2240 struct ast_cdr expected = {
2241 .clid = "\"Alice\" <100>",
2244 .dcontext = "default",
2245 .channel = CHANNEL_TECH_NAME "/Alice",
2247 .amaflags = AST_AMA_DOCUMENTATION,
2248 .disposition = AST_CDR_FAILED,
2249 .accountcode = "100",
2251 enum ast_test_result_state result = AST_TEST_NOT_RUN;
2255 info->name = __func__;
2256 info->category = TEST_CATEGORY;
2257 info->summary = "Test field access CDRs";
2259 "This tests setting/retrieving data on CDR records.\n";
2260 return AST_TEST_NOT_RUN;
2265 SWAP_CONFIG(config, unanswered_cdr_config);
2267 CREATE_ALICE_CHANNEL(chan, &caller, &expected);
2269 while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
2271 /* Disable the CDR */
2272 ast_test_validate(test, ast_cdr_set_property(ast_channel_name(chan), AST_CDR_FLAG_DISABLE) == 0);
2274 /* Fork the CDR. This should be enabled */
2275 ast_set_flag(&fork_options, AST_CDR_FLAG_FINALIZE);
2276 ast_test_validate(test, ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
2278 /* Disable and enable the forked CDR */
2279 ast_test_validate(test, ast_cdr_set_property(ast_channel_name(chan), AST_CDR_FLAG_DISABLE) == 0);
2280 ast_test_validate(test, ast_cdr_clear_property(ast_channel_name(chan), AST_CDR_FLAG_DISABLE) == 0);
2282 /* Fork and finalize again. This CDR should be propagated */
2283 ast_test_validate(test, ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
2285 /* Disable all future CDRs */
2286 ast_test_validate(test, ast_cdr_set_property(ast_channel_name(chan), AST_CDR_FLAG_DISABLE_ALL) == 0);
2288 /* Fork a few more */
2289 ast_test_validate(test, ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
2290 ast_test_validate(test, ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
2291 ast_test_validate(test, ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
2293 ast_channel_hangupcause_set(chan, AST_CAUSE_NORMAL);
2296 result = verify_mock_cdr_record(test, &expected, 1);
2301 AST_TEST_DEFINE(test_cdr_fork_cdr)
2303 RAII_VAR(struct ast_channel *, chan, NULL, safe_channel_release);
2304 RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
2306 char varbuffer[128];
2307 char fork_varbuffer[128];
2308 char answer_time[128];
2309 char fork_answer_time[128];
2310 char start_time[128];
2311 char fork_start_time[128];
2312 struct ast_flags fork_options = { 0, };
2313 struct timespec to_sleep = {1, 10000};
2315 struct ast_party_caller caller = ALICE_CALLERID;
2316 struct ast_cdr original = {
2317 .clid = "\"Alice\" <100>",
2320 .dcontext = "default",
2321 .channel = CHANNEL_TECH_NAME "/Alice",
2322 .amaflags = AST_AMA_DOCUMENTATION,
2323 .disposition = AST_CDR_ANSWERED,
2324 .accountcode = "100",
2326 struct ast_cdr fork_expected_one = {
2327 .clid = "\"Alice\" <100>",
2330 .dcontext = "default",
2331 .channel = CHANNEL_TECH_NAME "/Alice",
2332 .amaflags = AST_AMA_DOCUMENTATION,
2333 .disposition = AST_CDR_ANSWERED,
2334 .accountcode = "100",
2336 struct ast_cdr fork_expected_two = {
2337 .clid = "\"Alice\" <100>",
2340 .dcontext = "default",
2341 .channel = CHANNEL_TECH_NAME "/Alice",
2342 .amaflags = AST_AMA_DOCUMENTATION,
2343 .disposition = AST_CDR_ANSWERED,
2344 .accountcode = "100",
2346 enum ast_test_result_state result = AST_TEST_NOT_RUN;
2347 struct ast_cdr *expected = &original;
2348 original.next = &fork_expected_one;
2349 fork_expected_one.next = &fork_expected_two;
2353 info->name = __func__;
2354 info->category = TEST_CATEGORY;
2355 info->summary = "Test field access CDRs";
2357 "This tests setting/retrieving data on CDR records.\n";
2358 return AST_TEST_NOT_RUN;
2363 SWAP_CONFIG(config, debug_cdr_config);
2365 CREATE_ALICE_CHANNEL(chan, &caller, &original);
2366 ast_copy_string(fork_expected_one.uniqueid, ast_channel_uniqueid(chan), sizeof(fork_expected_one.uniqueid));
2367 ast_copy_string(fork_expected_one.linkedid, ast_channel_linkedid(chan), sizeof(fork_expected_one.linkedid));
2368 ast_copy_string(fork_expected_two.uniqueid, ast_channel_uniqueid(chan), sizeof(fork_expected_two.uniqueid));
2369 ast_copy_string(fork_expected_two.linkedid, ast_channel_linkedid(chan), sizeof(fork_expected_two.linkedid));
2371 while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
2373 /* Test blowing away variables */
2374 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "test_variable", "record_1") == 0);
2375 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "test_variable", varbuffer, sizeof(varbuffer)) == 0);
2376 ast_test_validate(test, strcmp(varbuffer, "record_1") == 0);
2377 ast_copy_string(varbuffer, "", sizeof(varbuffer));
2379 ast_test_validate(test, ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
2380 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "test_variable", fork_varbuffer, sizeof(fork_varbuffer)) == 0);
2381 ast_test_validate(test, strcmp(varbuffer, "record_1") != 0);
2383 /* Test finalizing previous CDRs */
2384 ast_set_flag(&fork_options, AST_CDR_FLAG_FINALIZE);
2385 ast_test_validate(test, ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
2387 /* Test keep variables; setting a new answer time */
2388 ast_setstate(chan, AST_STATE_UP);
2389 while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
2390 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "test_variable", "record_2") == 0);
2391 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "test_variable", varbuffer, sizeof(varbuffer)) == 0);
2392 ast_test_validate(test, strcmp(varbuffer, "record_2") == 0);
2393 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "answer", answer_time, sizeof(answer_time)) == 0);
2394 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "start", start_time, sizeof(start_time)) == 0);
2396 ast_set_flag(&fork_options, AST_CDR_FLAG_FINALIZE);
2397 ast_set_flag(&fork_options, AST_CDR_FLAG_KEEP_VARS);
2398 ast_set_flag(&fork_options, AST_CDR_FLAG_SET_ANSWER);
2399 ast_test_validate(test, ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
2400 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "answer", fork_answer_time, sizeof(fork_answer_time)) == 0);
2401 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "start", fork_start_time, sizeof(fork_start_time)) == 0);
2402 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "test_variable", fork_varbuffer, sizeof(fork_varbuffer)) == 0);
2403 ast_test_validate(test, strcmp(fork_varbuffer, varbuffer) == 0);
2404 ast_test_validate(test, strcmp(fork_start_time, start_time) == 0);
2405 ast_test_validate(test, strcmp(fork_answer_time, answer_time) != 0);
2407 ast_clear_flag(&fork_options, AST_CDR_FLAG_SET_ANSWER);
2408 ast_set_flag(&fork_options, AST_CDR_FLAG_RESET);
2409 ast_test_validate(test, ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
2410 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "answer", fork_answer_time, sizeof(fork_answer_time)) == 0);
2411 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "start", fork_start_time, sizeof(fork_start_time)) == 0);
2412 ast_test_validate(test, strcmp(fork_start_time, start_time) != 0);
2413 ast_test_validate(test, strcmp(fork_answer_time, answer_time) != 0);
2415 ast_channel_hangupcause_set(chan, AST_CAUSE_NORMAL);
2418 result = verify_mock_cdr_record(test, expected, 3);
2425 * \brief Callback function called before each test executes
2427 static int test_cdr_init_cb(struct ast_test_info *info, struct ast_test *test)
2429 /* Back up the real config */
2430 saved_config = ast_cdr_get_config();
2431 clear_mock_cdr_backend();
2437 * \brief Callback function called after each test executes
2439 static int test_cdr_cleanup_cb(struct ast_test_info *info, struct ast_test *test)
2441 /* Restore the real config */
2442 ast_cdr_set_config(saved_config);
2443 ao2_cleanup(saved_config);
2444 saved_config = NULL;
2445 clear_mock_cdr_backend();
2451 static int unload_module(void)
2453 AST_TEST_UNREGISTER(test_cdr_channel_creation);
2454 AST_TEST_UNREGISTER(test_cdr_unanswered_inbound_call);
2455 AST_TEST_UNREGISTER(test_cdr_unanswered_outbound_call);
2457 AST_TEST_UNREGISTER(test_cdr_single_party);
2458 AST_TEST_UNREGISTER(test_cdr_single_bridge);
2459 AST_TEST_UNREGISTER(test_cdr_single_bridge_continue);
2460 AST_TEST_UNREGISTER(test_cdr_single_twoparty_bridge_a);
2461 AST_TEST_UNREGISTER(test_cdr_single_twoparty_bridge_b);
2462 AST_TEST_UNREGISTER(test_cdr_single_multiparty_bridge);
2464 AST_TEST_UNREGISTER(test_cdr_outbound_bridged_call);
2466 AST_TEST_UNREGISTER(test_cdr_dial_unanswered);
2467 AST_TEST_UNREGISTER(test_cdr_dial_congestion);
2468 AST_TEST_UNREGISTER(test_cdr_dial_busy);
2469 AST_TEST_UNREGISTER(test_cdr_dial_unavailable);
2470 AST_TEST_UNREGISTER(test_cdr_dial_caller_cancel);
2471 AST_TEST_UNREGISTER(test_cdr_dial_parallel_failed);
2472 AST_TEST_UNREGISTER(test_cdr_dial_answer_no_bridge);
2473 AST_TEST_UNREGISTER(test_cdr_dial_answer_twoparty_bridge_a);
2474 AST_TEST_UNREGISTER(test_cdr_dial_answer_twoparty_bridge_b);
2475 AST_TEST_UNREGISTER(test_cdr_dial_answer_multiparty);
2477 AST_TEST_UNREGISTER(test_cdr_park);
2479 AST_TEST_UNREGISTER(test_cdr_fields);
2480 AST_TEST_UNREGISTER(test_cdr_no_reset_cdr);
2481 AST_TEST_UNREGISTER(test_cdr_fork_cdr);
2483 ast_cdr_unregister(MOCK_CDR_BACKEND);
2484 ast_channel_unregister(&test_cdr_chan_tech);
2485 clear_mock_cdr_backend();
2490 static int load_module(void)
2492 ast_cond_init(&mock_cdr_cond, NULL);
2494 AST_TEST_REGISTER(test_cdr_channel_creation);
2495 AST_TEST_REGISTER(test_cdr_unanswered_inbound_call);
2496 AST_TEST_REGISTER(test_cdr_unanswered_outbound_call);
2498 AST_TEST_REGISTER(test_cdr_single_party);
2499 AST_TEST_REGISTER(test_cdr_single_bridge);
2500 AST_TEST_REGISTER(test_cdr_single_bridge_continue);
2501 AST_TEST_REGISTER(test_cdr_single_twoparty_bridge_a);
2502 AST_TEST_REGISTER(test_cdr_single_twoparty_bridge_b);
2503 AST_TEST_REGISTER(test_cdr_single_multiparty_bridge);
2505 AST_TEST_REGISTER(test_cdr_outbound_bridged_call);
2507 AST_TEST_REGISTER(test_cdr_dial_unanswered);
2508 AST_TEST_REGISTER(test_cdr_dial_congestion);
2509 AST_TEST_REGISTER(test_cdr_dial_busy);
2510 AST_TEST_REGISTER(test_cdr_dial_unavailable);
2511 AST_TEST_REGISTER(test_cdr_dial_caller_cancel);
2512 AST_TEST_REGISTER(test_cdr_dial_parallel_failed);
2513 AST_TEST_REGISTER(test_cdr_dial_answer_no_bridge);
2514 AST_TEST_REGISTER(test_cdr_dial_answer_twoparty_bridge_a);
2515 AST_TEST_REGISTER(test_cdr_dial_answer_twoparty_bridge_b);
2516 AST_TEST_REGISTER(test_cdr_dial_answer_multiparty);
2518 AST_TEST_REGISTER(test_cdr_park);
2520 AST_TEST_REGISTER(test_cdr_fields);
2521 AST_TEST_REGISTER(test_cdr_no_reset_cdr);
2522 AST_TEST_REGISTER(test_cdr_fork_cdr);
2524 ast_test_register_init(TEST_CATEGORY, test_cdr_init_cb);
2525 ast_test_register_cleanup(TEST_CATEGORY, test_cdr_cleanup_cb);
2527 ast_channel_register(&test_cdr_chan_tech);
2528 ast_cdr_register(MOCK_CDR_BACKEND, "Mock CDR backend", mock_cdr_backend_cb);
2530 return AST_MODULE_LOAD_SUCCESS;
2533 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "CDR unit tests");