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/bridging.h"
46 #include "asterisk/bridging_basic.h"
47 #include "asterisk/stasis_channels.h"
48 #include "asterisk/stasis_bridging.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) do { \
282 ast_channel_hangupcause_set((channel), (cause)); \
283 if (!ast_hangup((channel))) { \
287 static enum ast_test_result_state verify_mock_cdr_record(struct ast_test *test, struct ast_cdr *expected, int record)
289 struct ast_cdr *actual = NULL;
290 struct test_cdr_entry *cdr_wrapper;
292 struct timeval wait_now = ast_tvnow();
293 struct timespec wait_time = { .tv_sec = wait_now.tv_sec + 5, .tv_nsec = wait_now.tv_usec * 1000 };
294 enum ast_test_result_state res = AST_TEST_PASS;
296 while (count < record) {
297 AST_LIST_LOCK(&actual_cdr_entries);
298 if (global_mock_cdr_count < record) {
299 ast_cond_timedwait(&mock_cdr_cond, &actual_cdr_entries.lock, &wait_time);
301 cdr_wrapper = AST_LIST_REMOVE_HEAD(&actual_cdr_entries, list);
302 AST_LIST_UNLOCK(&actual_cdr_entries);
305 ast_test_status_update(test, "Unable to find actual CDR record at %d\n", count);
306 return AST_TEST_FAIL;
308 actual = cdr_wrapper->cdr;
310 if (!expected && actual) {
311 ast_test_status_update(test, "CDRs recorded where no record expected\n");
312 return AST_TEST_FAIL;
315 VERIFY_STRING_FIELD(accountcode, actual, expected);
316 VERIFY_NUMERIC_FIELD(amaflags, actual, expected);
317 VERIFY_STRING_FIELD(channel, actual, expected);
318 VERIFY_STRING_FIELD(clid, actual, expected);
319 VERIFY_STRING_FIELD(dcontext, actual, expected);
320 VERIFY_NUMERIC_FIELD(disposition, actual, expected);
321 VERIFY_STRING_FIELD(dst, actual, expected);
322 VERIFY_STRING_FIELD(dstchannel, actual, expected);
323 VERIFY_STRING_FIELD(lastapp, actual, expected);
324 VERIFY_STRING_FIELD(lastdata, actual, expected);
325 VERIFY_STRING_FIELD(linkedid, actual, expected);
326 VERIFY_STRING_FIELD(peeraccount, actual, expected);
327 VERIFY_STRING_FIELD(src, actual, expected);
328 VERIFY_STRING_FIELD(uniqueid, actual, expected);
329 VERIFY_STRING_FIELD(userfield, actual, expected);
330 VERIFY_TIME_VALUE(start, actual);
331 VERIFY_TIME_VALUE(end, actual);
332 /* Note: there's no way we can really calculate a duration or
333 * billsec - the unit tests are too short. However, if billsec is
334 * non-zero in the expected, then make sure we have an answer time
336 if (expected->billsec) {
337 VERIFY_TIME_VALUE(answer, actual);
339 ast_test_debug(test, "Finished expected record %s, %s\n",
340 expected->channel, S_OR(expected->dstchannel, "<none>"));
341 expected = expected->next;
347 static void safe_channel_release(struct ast_channel *chan)
352 ast_channel_release(chan);
355 AST_TEST_DEFINE(test_cdr_channel_creation)
357 RAII_VAR(struct ast_channel *, chan, NULL, safe_channel_release);
358 RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
361 struct ast_party_caller caller = ALICE_CALLERID;
362 struct ast_cdr expected = {
363 .clid = "\"Alice\" <100>",
366 .dcontext = "default",
367 .channel = CHANNEL_TECH_NAME "/Alice",
368 .amaflags = AST_AMA_DOCUMENTATION,
369 .disposition = AST_CDR_NOANSWER,
370 .accountcode = "100",
372 enum ast_test_result_state result = AST_TEST_NOT_RUN;
376 info->name = __func__;
377 info->category = TEST_CATEGORY;
378 info->summary = "Test that a CDR is created when a channel is created";
380 "Test that a CDR is created when a channel is created";
381 return AST_TEST_NOT_RUN;
386 SWAP_CONFIG(config, unanswered_cdr_config);
388 CREATE_ALICE_CHANNEL(chan, (&caller), &expected);
390 HANGUP_CHANNEL(chan, AST_CAUSE_NORMAL);
392 result = verify_mock_cdr_record(test, &expected, 1);
397 AST_TEST_DEFINE(test_cdr_unanswered_inbound_call)
399 RAII_VAR(struct ast_channel *, chan, NULL, safe_channel_release);
400 RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
403 struct ast_party_caller caller = ALICE_CALLERID;
404 struct ast_cdr expected = {
405 .clid = "\"Alice\" <100>",
408 .dcontext = "default",
409 .channel = CHANNEL_TECH_NAME "/Alice",
412 .amaflags = AST_AMA_DOCUMENTATION,
413 .disposition = AST_CDR_NOANSWER,
414 .accountcode = "100",
416 enum ast_test_result_state result = AST_TEST_NOT_RUN;
420 info->name = __func__;
421 info->category = TEST_CATEGORY;
422 info->summary = "Test inbound unanswered calls";
424 "Test the properties of a CDR for a call that is\n"
425 "inbound to Asterisk, executes some dialplan, but\n"
426 "is never answered.\n";
427 return AST_TEST_NOT_RUN;
432 SWAP_CONFIG(config, unanswered_cdr_config);
434 CREATE_ALICE_CHANNEL(chan, &caller, &expected);
436 EMULATE_APP_DATA(chan, 1, "Wait", "1");
438 HANGUP_CHANNEL(chan, AST_CAUSE_NORMAL);
440 result = verify_mock_cdr_record(test, &expected, 1);
445 AST_TEST_DEFINE(test_cdr_unanswered_outbound_call)
447 RAII_VAR(struct ast_channel *, chan, NULL, safe_channel_release);
448 RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
451 struct ast_party_caller caller = {
455 .id.number.valid = 1, };
456 struct ast_cdr expected = {
459 .dcontext = "default",
460 .channel = CHANNEL_TECH_NAME "/Alice",
461 .lastapp = "AppDial",
462 .lastdata = "(Outgoing Line)",
463 .amaflags = AST_AMA_DOCUMENTATION,
464 .disposition = AST_CDR_NOANSWER,
465 .accountcode = "100",
467 enum ast_test_result_state result = AST_TEST_NOT_RUN;
471 info->name = __func__;
472 info->category = TEST_CATEGORY;
473 info->summary = "Test outbound unanswered calls";
475 "Test the properties of a CDR for a call that is\n"
476 "outbound to Asterisk but is never answered.\n";
477 return AST_TEST_NOT_RUN;
482 SWAP_CONFIG(config, unanswered_cdr_config);
484 CREATE_ALICE_CHANNEL(chan, &caller, &expected);
486 ast_channel_exten_set(chan, "s");
487 ast_channel_context_set(chan, "default");
488 ast_set_flag(ast_channel_flags(chan), AST_FLAG_ORIGINATED);
489 EMULATE_APP_DATA(chan, 0, "AppDial", "(Outgoing Line)");
490 HANGUP_CHANNEL(chan, AST_CAUSE_NORMAL);
492 result = verify_mock_cdr_record(test, &expected, 1);
497 AST_TEST_DEFINE(test_cdr_single_party)
499 RAII_VAR(struct ast_channel *, chan, NULL, safe_channel_release);
500 RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
503 struct ast_party_caller caller = ALICE_CALLERID;
504 struct ast_cdr expected = {
505 .clid = "\"Alice\" <100>",
508 .dcontext = "default",
509 .channel = CHANNEL_TECH_NAME "/Alice",
511 .lastapp = "VoiceMailMain",
514 .amaflags = AST_AMA_DOCUMENTATION,
515 .disposition = AST_CDR_ANSWERED,
516 .accountcode = "100",
518 enum ast_test_result_state result = AST_TEST_NOT_RUN;
522 info->name = __func__;
523 info->category = TEST_CATEGORY;
524 info->summary = "Test cdrs for a single party";
526 "Test the properties of a CDR for a call that is\n"
527 "answered, but only involves a single channel\n";
528 return AST_TEST_NOT_RUN;
532 SWAP_CONFIG(config, debug_cdr_config);
533 CREATE_ALICE_CHANNEL(chan, &caller, &expected);
535 EMULATE_APP_DATA(chan, 1, "Answer", "");
536 ast_setstate(chan, AST_STATE_UP);
537 EMULATE_APP_DATA(chan, 2, "VoiceMailMain", "1");
539 HANGUP_CHANNEL(chan, AST_CAUSE_NORMAL);
541 result = verify_mock_cdr_record(test, &expected, 1);
546 AST_TEST_DEFINE(test_cdr_single_bridge)
548 RAII_VAR(struct ast_channel *, chan, NULL, safe_channel_release);
549 RAII_VAR(struct ast_bridge *, bridge, NULL, ao2_cleanup);
550 RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
552 struct timespec to_sleep = {1, 0};
554 struct ast_party_caller caller = ALICE_CALLERID;
555 struct ast_cdr expected = {
556 .clid = "\"Alice\" <100>",
559 .dcontext = "default",
560 .channel = CHANNEL_TECH_NAME "/Alice",
563 .amaflags = AST_AMA_DOCUMENTATION,
564 .disposition = AST_CDR_ANSWERED,
565 .accountcode = "100",
567 enum ast_test_result_state result = AST_TEST_NOT_RUN;
571 info->name = __func__;
572 info->category = TEST_CATEGORY;
573 info->summary = "Test cdrs for a single party entering/leaving a bridge";
575 "Test the properties of a CDR for a call that is\n"
576 "answered, enters a bridge, and leaves it.\n";
577 return AST_TEST_NOT_RUN;
581 SWAP_CONFIG(config, debug_cdr_config);
582 CREATE_ALICE_CHANNEL(chan, &caller, &expected);
584 EMULATE_APP_DATA(chan, 1, "Answer", "");
585 ast_setstate(chan, AST_STATE_UP);
586 EMULATE_APP_DATA(chan, 2, "Bridge", "");
588 bridge = ast_bridge_basic_new();
589 ast_test_validate(test, bridge != NULL);
591 while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
592 ast_bridge_impart(bridge, chan, NULL, NULL, 0);
594 while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
596 ast_bridge_depart(chan);
598 HANGUP_CHANNEL(chan, AST_CAUSE_NORMAL);
600 result = verify_mock_cdr_record(test, &expected, 1);
605 AST_TEST_DEFINE(test_cdr_single_bridge_continue)
607 RAII_VAR(struct ast_channel *, chan, NULL, safe_channel_release);
608 RAII_VAR(struct ast_bridge *, bridge_one, NULL, ao2_cleanup);
609 RAII_VAR(struct ast_bridge *, bridge_two, NULL, ao2_cleanup);
610 RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
612 struct timespec to_sleep = {1, 0};
614 struct ast_party_caller caller = ALICE_CALLERID;
615 struct ast_cdr expected_two = {
616 .clid = "\"Alice\" <100>",
619 .dcontext = "default",
620 .channel = CHANNEL_TECH_NAME "/Alice",
623 .amaflags = AST_AMA_DOCUMENTATION,
624 .disposition = AST_CDR_ANSWERED,
625 .accountcode = "100",
627 struct ast_cdr expected_one = {
628 .clid = "\"Alice\" <100>",
631 .dcontext = "default",
632 .channel = CHANNEL_TECH_NAME "/Alice",
635 .amaflags = AST_AMA_DOCUMENTATION,
636 .disposition = AST_CDR_ANSWERED,
637 .accountcode = "100",
638 .next = &expected_two,
641 enum ast_test_result_state result = AST_TEST_NOT_RUN;
645 info->name = __func__;
646 info->category = TEST_CATEGORY;
647 info->summary = "Test cdrs for a single party entering/leaving a bridge";
649 "Test the properties of a CDR for a call that is\n"
650 "answered, enters a bridge, and leaves it.\n";
651 return AST_TEST_NOT_RUN;
655 SWAP_CONFIG(config, debug_cdr_config);
656 CREATE_ALICE_CHANNEL(chan, &caller, &expected_one);
657 COPY_IDS(chan, &expected_two);
659 EMULATE_APP_DATA(chan, 1, "Answer", "");
660 ast_setstate(chan, AST_STATE_UP);
661 EMULATE_APP_DATA(chan, 2, "Bridge", "");
663 bridge_one = ast_bridge_basic_new();
664 ast_test_validate(test, bridge_one != NULL);
665 while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
667 ast_bridge_impart(bridge_one, chan, NULL, NULL, 0);
669 while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
671 ast_bridge_depart(chan);
673 EMULATE_APP_DATA(chan, 3, "Wait", "");
675 /* And then it hangs up */
676 HANGUP_CHANNEL(chan, AST_CAUSE_NORMAL);
678 result = verify_mock_cdr_record(test, &expected_one, 2);
683 AST_TEST_DEFINE(test_cdr_single_twoparty_bridge_a)
685 RAII_VAR(struct ast_channel *, chan_alice, NULL, safe_channel_release);
686 RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release);
687 RAII_VAR(struct ast_bridge *, bridge, NULL, ao2_cleanup);
688 RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
690 struct timespec to_sleep = {1, 0};
692 struct ast_party_caller caller_alice = ALICE_CALLERID;
693 struct ast_party_caller caller_bob = BOB_CALLERID;
694 struct ast_cdr bob_expected = {
695 .clid = "\"Bob\" <200>",
698 .dcontext = "default",
699 .channel = CHANNEL_TECH_NAME "/Bob",
702 .amaflags = AST_AMA_DOCUMENTATION,
703 .disposition = AST_CDR_ANSWERED,
704 .accountcode = "200",
706 struct ast_cdr alice_expected = {
707 .clid = "\"Alice\" <100>",
710 .dcontext = "default",
711 .channel = CHANNEL_TECH_NAME "/Alice",
712 .dstchannel = CHANNEL_TECH_NAME "/Bob",
715 .amaflags = AST_AMA_DOCUMENTATION,
716 .disposition = AST_CDR_ANSWERED,
717 .accountcode = "100",
718 .peeraccount = "200",
719 .next = &bob_expected,
722 enum ast_test_result_state result = AST_TEST_NOT_RUN;
726 info->name = __func__;
727 info->category = TEST_CATEGORY;
728 info->summary = "Test cdrs for a single party entering/leaving a bridge";
730 "Test the properties of a CDR for a call that is\n"
731 "answered, enters a bridge, and leaves it. In this scenario, the\n"
732 "Party A should answer the bridge first.\n";
733 return AST_TEST_NOT_RUN;
737 SWAP_CONFIG(config, debug_cdr_config);
738 CREATE_ALICE_CHANNEL(chan_alice, &caller_alice, &alice_expected);
740 CREATE_BOB_CHANNEL(chan_bob, &caller_bob, &bob_expected);
741 ast_copy_string(bob_expected.linkedid, ast_channel_linkedid(chan_alice), sizeof(bob_expected.linkedid));
743 EMULATE_APP_DATA(chan_alice, 1, "Answer", "");
744 ast_setstate(chan_alice, AST_STATE_UP);
745 EMULATE_APP_DATA(chan_alice, 2, "Bridge", "");
747 bridge = ast_bridge_basic_new();
748 ast_test_validate(test, bridge != NULL);
750 ast_bridge_impart(bridge, chan_alice, NULL, NULL, 0);
751 while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
753 EMULATE_APP_DATA(chan_bob, 1, "Answer", "");
754 ast_setstate(chan_bob, AST_STATE_UP);
755 EMULATE_APP_DATA(chan_bob, 2, "Bridge", "");
757 ast_bridge_impart(bridge, chan_bob, NULL, NULL, 0);
758 while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
760 ast_bridge_depart(chan_alice);
761 ast_bridge_depart(chan_bob);
763 HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL);
764 HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL);
766 result = verify_mock_cdr_record(test, &alice_expected, 2);
771 AST_TEST_DEFINE(test_cdr_single_twoparty_bridge_b)
773 RAII_VAR(struct ast_channel *, chan_alice, NULL, safe_channel_release);
774 RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release);
775 RAII_VAR(struct ast_bridge *, bridge, NULL, ao2_cleanup);
776 RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
778 struct timespec to_sleep = {1, 0};
780 struct ast_party_caller caller_alice = ALICE_CALLERID;
781 struct ast_party_caller caller_bob = BOB_CALLERID;
782 struct ast_cdr bob_expected = {
783 .clid = "\"Bob\" <200>",
786 .dcontext = "default",
787 .channel = CHANNEL_TECH_NAME "/Bob",
790 .amaflags = AST_AMA_DOCUMENTATION,
791 .disposition = AST_CDR_ANSWERED,
792 .accountcode = "200",
794 struct ast_cdr alice_expected = {
795 .clid = "\"Alice\" <100>",
798 .dcontext = "default",
799 .channel = CHANNEL_TECH_NAME "/Alice",
800 .dstchannel = CHANNEL_TECH_NAME "/Bob",
803 .amaflags = AST_AMA_DOCUMENTATION,
804 .disposition = AST_CDR_ANSWERED,
805 .accountcode = "100",
806 .peeraccount = "200",
807 .next = &bob_expected,
810 enum ast_test_result_state result = AST_TEST_NOT_RUN;
814 info->name = __func__;
815 info->category = TEST_CATEGORY;
816 info->summary = "Test cdrs for a single party entering/leaving a bridge";
818 "Test the properties of a CDR for a call that is\n"
819 "answered, enters a bridge, and leaves it. In this scenario, the\n"
820 "Party B should answer the bridge first.\n";
821 return AST_TEST_NOT_RUN;
825 SWAP_CONFIG(config, debug_cdr_config);
826 CREATE_ALICE_CHANNEL(chan_alice, &caller_alice, &alice_expected);
828 CREATE_BOB_CHANNEL(chan_bob, &caller_bob, &bob_expected);
829 ast_copy_string(bob_expected.linkedid, ast_channel_linkedid(chan_alice), sizeof(bob_expected.linkedid));
831 EMULATE_APP_DATA(chan_alice, 1, "Answer", "");
832 ast_setstate(chan_alice, AST_STATE_UP);
833 EMULATE_APP_DATA(chan_alice, 2, "Bridge", "");
835 bridge = ast_bridge_basic_new();
836 ast_test_validate(test, bridge != NULL);
838 EMULATE_APP_DATA(chan_bob, 1, "Answer", "");
839 ast_setstate(chan_bob, AST_STATE_UP);
840 EMULATE_APP_DATA(chan_bob, 2, "Bridge", "");
841 while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
843 ast_bridge_impart(bridge, chan_bob, NULL, NULL, 0);
844 while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
846 ast_bridge_impart(bridge, chan_alice, NULL, NULL, 0);
847 while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
849 ast_bridge_depart(chan_alice);
850 ast_bridge_depart(chan_bob);
852 HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL);
853 HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL);
855 result = verify_mock_cdr_record(test, &alice_expected, 2);
860 AST_TEST_DEFINE(test_cdr_single_multiparty_bridge)
862 RAII_VAR(struct ast_channel *, chan_alice, NULL, safe_channel_release);
863 RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release);
864 RAII_VAR(struct ast_channel *, chan_charlie, NULL, safe_channel_release);
865 RAII_VAR(struct ast_bridge *, bridge, NULL, ao2_cleanup);
866 RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
868 struct timespec to_sleep = {1, 0};
870 struct ast_party_caller caller_alice = ALICE_CALLERID;
871 struct ast_party_caller caller_bob = BOB_CALLERID;
872 struct ast_party_caller caller_charlie = CHARLIE_CALLERID;
873 struct ast_cdr charlie_expected = {
874 .clid = "\"Charlie\" <300>",
877 .dcontext = "default",
878 .channel = CHANNEL_TECH_NAME "/Charlie",
881 .amaflags = AST_AMA_DOCUMENTATION,
882 .disposition = AST_CDR_ANSWERED,
883 .accountcode = "300",
885 struct ast_cdr bob_expected = {
886 .clid = "\"Bob\" <200>",
889 .dcontext = "default",
890 .channel = CHANNEL_TECH_NAME "/Bob",
891 .dstchannel = CHANNEL_TECH_NAME "/Charlie",
894 .amaflags = AST_AMA_DOCUMENTATION,
895 .disposition = AST_CDR_ANSWERED,
896 .accountcode = "200",
897 .peeraccount = "300",
898 .next = &charlie_expected,
900 struct ast_cdr alice_expected_two = {
901 .clid = "\"Alice\" <100>",
904 .dcontext = "default",
905 .channel = CHANNEL_TECH_NAME "/Alice",
906 .dstchannel = CHANNEL_TECH_NAME "/Charlie",
909 .amaflags = AST_AMA_DOCUMENTATION,
910 .disposition = AST_CDR_ANSWERED,
911 .accountcode = "100",
912 .peeraccount = "300",
913 .next = &bob_expected,
915 struct ast_cdr alice_expected_one = {
916 .clid = "\"Alice\" <100>",
919 .dcontext = "default",
920 .channel = CHANNEL_TECH_NAME "/Alice",
921 .dstchannel = CHANNEL_TECH_NAME "/Bob",
924 .amaflags = AST_AMA_DOCUMENTATION,
925 .disposition = AST_CDR_ANSWERED,
926 .accountcode = "100",
927 .peeraccount = "200",
928 .next = &alice_expected_two,
931 enum ast_test_result_state result = AST_TEST_NOT_RUN;
935 info->name = __func__;
936 info->category = TEST_CATEGORY;
937 info->summary = "Test cdrs for a single party entering/leaving a multi-party bridge";
939 "Test the properties of a CDR for a call that is\n"
940 "answered, enters a bridge, and leaves it. A total of three\n"
941 "parties perform this action.\n";
942 return AST_TEST_NOT_RUN;
946 SWAP_CONFIG(config, debug_cdr_config);
947 CREATE_ALICE_CHANNEL(chan_alice, &caller_alice, &alice_expected_one);
948 COPY_IDS(chan_alice, &alice_expected_two);
949 CREATE_BOB_CHANNEL(chan_bob, &caller_bob, &bob_expected);
950 ast_copy_string(bob_expected.linkedid, ast_channel_linkedid(chan_alice), sizeof(bob_expected.linkedid));
951 CREATE_CHARLIE_CHANNEL(chan_charlie, &caller_charlie, &charlie_expected);
952 ast_copy_string(charlie_expected.linkedid, ast_channel_linkedid(chan_alice), sizeof(charlie_expected.linkedid));
954 EMULATE_APP_DATA(chan_alice, 1, "Answer", "");
955 ast_setstate(chan_alice, AST_STATE_UP);
956 EMULATE_APP_DATA(chan_alice, 2, "Bridge", "");
958 bridge = ast_bridge_basic_new();
959 ast_test_validate(test, bridge != NULL);
960 while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
962 ast_bridge_impart(bridge, chan_alice, NULL, NULL, 0);
964 EMULATE_APP_DATA(chan_bob, 1, "Answer", "");
965 ast_setstate(chan_bob, AST_STATE_UP);
966 EMULATE_APP_DATA(chan_bob, 2, "Bridge", "");
967 while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
969 ast_bridge_impart(bridge, chan_bob, NULL, NULL, 0);
971 while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
973 EMULATE_APP_DATA(chan_charlie, 1, "Answer", "");
974 ast_setstate(chan_charlie, AST_STATE_UP);
975 EMULATE_APP_DATA(chan_charlie, 2, "Bridge", "");
976 ast_bridge_impart(bridge, chan_charlie, NULL, NULL, 0);
978 while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
980 ast_bridge_depart(chan_alice);
981 ast_bridge_depart(chan_bob);
982 ast_bridge_depart(chan_charlie);
984 HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL);
985 HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL);
986 HANGUP_CHANNEL(chan_charlie, AST_CAUSE_NORMAL);
988 result = verify_mock_cdr_record(test, &alice_expected_one, 4);
993 AST_TEST_DEFINE(test_cdr_dial_unanswered)
995 RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
996 RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
997 RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
1000 struct ast_party_caller caller = ALICE_CALLERID;
1001 struct ast_cdr expected = {
1002 .clid = "\"Alice\" <100>",
1005 .dcontext = "default",
1006 .channel = CHANNEL_TECH_NAME "/Alice",
1007 .dstchannel = CHANNEL_TECH_NAME "/Bob",
1009 .lastdata = CHANNEL_TECH_NAME "/Bob",
1011 .amaflags = AST_AMA_DOCUMENTATION,
1012 .disposition = AST_CDR_NOANSWER,
1013 .accountcode = "100",
1014 .peeraccount = "200",
1016 enum ast_test_result_state result = AST_TEST_NOT_RUN;
1020 info->name = __func__;
1021 info->category = TEST_CATEGORY;
1022 info->summary = "Test CDRs for a dial that isn't answered";
1024 "Test the properties of a CDR for a channel that\n"
1025 "performs a dial operation that isn't answered\n";
1026 return AST_TEST_NOT_RUN;
1031 SWAP_CONFIG(config, unanswered_cdr_config);
1033 CREATE_ALICE_CHANNEL(chan_caller, &caller, &expected);
1035 EMULATE_APP_DATA(chan_caller, 1, "Dial", "CDRTestChannel/Bob");
1037 chan_callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, ast_channel_linkedid(chan_caller), 0, CHANNEL_TECH_NAME "/Bob");
1038 ast_set_flag(ast_channel_flags(chan_callee), AST_FLAG_OUTGOING);
1039 EMULATE_APP_DATA(chan_callee, 0, "AppDial", "(Outgoing Line)");
1041 ast_channel_publish_dial(chan_caller, chan_callee, "Bob", NULL);
1042 ast_channel_state_set(chan_caller, AST_STATE_RINGING);
1043 ast_channel_publish_dial(chan_caller, chan_callee, NULL, "NOANSWER");
1045 HANGUP_CHANNEL(chan_caller, AST_CAUSE_NO_ANSWER);
1046 HANGUP_CHANNEL(chan_callee, AST_CAUSE_NO_ANSWER);
1048 result = verify_mock_cdr_record(test, &expected, 1);
1054 AST_TEST_DEFINE(test_cdr_dial_busy)
1056 RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
1057 RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
1058 RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
1061 struct ast_party_caller caller = ALICE_CALLERID;
1062 struct ast_cdr expected = {
1063 .clid = "\"Alice\" <100>",
1066 .dcontext = "default",
1067 .channel = CHANNEL_TECH_NAME "/Alice",
1068 .dstchannel = CHANNEL_TECH_NAME "/Bob",
1070 .lastdata = CHANNEL_TECH_NAME "/Bob",
1072 .amaflags = AST_AMA_DOCUMENTATION,
1073 .disposition = AST_CDR_BUSY,
1074 .accountcode = "100",
1075 .peeraccount = "200",
1077 enum ast_test_result_state result = AST_TEST_NOT_RUN;
1081 info->name = __func__;
1082 info->category = TEST_CATEGORY;
1083 info->summary = "Test CDRs for a dial that results in a busy";
1085 "Test the properties of a CDR for a channel that\n"
1086 "performs a dial operation to an endpoint that's busy\n";
1087 return AST_TEST_NOT_RUN;
1092 SWAP_CONFIG(config, unanswered_cdr_config);
1094 CREATE_ALICE_CHANNEL(chan_caller, &caller, &expected);
1096 EMULATE_APP_DATA(chan_caller, 1, "Dial", CHANNEL_TECH_NAME "/Bob");
1098 chan_callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, ast_channel_linkedid(chan_caller), 0, CHANNEL_TECH_NAME "/Bob");
1099 ast_set_flag(ast_channel_flags(chan_callee), AST_FLAG_OUTGOING);
1100 EMULATE_APP_DATA(chan_callee, 0, "AppDial", "(Outgoing Line)");
1102 ast_channel_publish_dial(chan_caller, chan_callee, "Bob", NULL);
1103 ast_channel_state_set(chan_caller, AST_STATE_RINGING);
1104 ast_channel_publish_dial(chan_caller, chan_callee, NULL, "BUSY");
1106 HANGUP_CHANNEL(chan_caller, AST_CAUSE_BUSY);
1107 HANGUP_CHANNEL(chan_callee, AST_CAUSE_BUSY);
1109 result = verify_mock_cdr_record(test, &expected, 1);
1114 AST_TEST_DEFINE(test_cdr_dial_congestion)
1116 RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
1117 RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
1118 RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
1121 struct ast_party_caller caller = ALICE_CALLERID;
1122 struct ast_cdr expected = {
1123 .clid = "\"Alice\" <100>",
1126 .dcontext = "default",
1127 .channel = CHANNEL_TECH_NAME "/Alice",
1128 .dstchannel = CHANNEL_TECH_NAME "/Bob",
1130 .lastdata = CHANNEL_TECH_NAME "/Bob",
1132 .amaflags = AST_AMA_DOCUMENTATION,
1133 .disposition = AST_CDR_CONGESTION,
1134 .accountcode = "100",
1135 .peeraccount = "200",
1137 enum ast_test_result_state result = AST_TEST_NOT_RUN;
1141 info->name = __func__;
1142 info->category = TEST_CATEGORY;
1143 info->summary = "Test CDRs for a dial that results in congestion";
1145 "Test the properties of a CDR for a channel that\n"
1146 "performs a dial operation to an endpoint that's congested\n";
1147 return AST_TEST_NOT_RUN;
1152 SWAP_CONFIG(config, congestion_cdr_config);
1154 CREATE_ALICE_CHANNEL(chan_caller, &caller, &expected);
1156 EMULATE_APP_DATA(chan_caller, 1, "Dial", CHANNEL_TECH_NAME "/Bob");
1158 chan_callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, ast_channel_linkedid(chan_caller), 0, CHANNEL_TECH_NAME "/Bob");
1159 ast_set_flag(ast_channel_flags(chan_callee), AST_FLAG_OUTGOING);
1160 EMULATE_APP_DATA(chan_callee, 0, "AppDial", "(Outgoing Line)");
1162 ast_channel_publish_dial(chan_caller, chan_callee, "Bob", NULL);
1163 ast_channel_state_set(chan_caller, AST_STATE_RINGING);
1164 ast_channel_publish_dial(chan_caller, chan_callee, NULL, "CONGESTION");
1166 HANGUP_CHANNEL(chan_caller, AST_CAUSE_CONGESTION);
1167 HANGUP_CHANNEL(chan_callee, AST_CAUSE_CONGESTION);
1169 result = verify_mock_cdr_record(test, &expected, 1);
1174 AST_TEST_DEFINE(test_cdr_dial_unavailable)
1176 RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
1177 RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
1178 RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
1181 struct ast_party_caller caller = ALICE_CALLERID;
1182 struct ast_cdr expected = {
1183 .clid = "\"Alice\" <100>",
1186 .dcontext = "default",
1187 .channel = CHANNEL_TECH_NAME "/Alice",
1188 .dstchannel = CHANNEL_TECH_NAME "/Bob",
1190 .lastdata = CHANNEL_TECH_NAME "/Bob",
1192 .amaflags = AST_AMA_DOCUMENTATION,
1193 .disposition = AST_CDR_FAILED,
1194 .accountcode = "100",
1195 .peeraccount = "200",
1197 enum ast_test_result_state result = AST_TEST_NOT_RUN;
1201 info->name = __func__;
1202 info->category = TEST_CATEGORY;
1203 info->summary = "Test CDRs for a dial that results in unavailable";
1205 "Test the properties of a CDR for a channel that\n"
1206 "performs a dial operation to an endpoint that's unavailable\n";
1207 return AST_TEST_NOT_RUN;
1212 SWAP_CONFIG(config, unanswered_cdr_config);
1214 CREATE_ALICE_CHANNEL(chan_caller, &caller, &expected);
1216 EMULATE_APP_DATA(chan_caller, 1, "Dial", CHANNEL_TECH_NAME "/Bob");
1218 chan_callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, ast_channel_linkedid(chan_caller), 0, CHANNEL_TECH_NAME "/Bob");
1219 ast_set_flag(ast_channel_flags(chan_callee), AST_FLAG_OUTGOING);
1220 EMULATE_APP_DATA(chan_callee, 0, "AppDial", "(Outgoing Line)");
1222 ast_channel_publish_dial(chan_caller, chan_callee, "Bob", NULL);
1223 ast_channel_state_set(chan_caller, AST_STATE_RINGING);
1224 ast_channel_publish_dial(chan_caller, chan_callee, NULL, "CHANUNAVAIL");
1226 HANGUP_CHANNEL(chan_caller, AST_CAUSE_NO_ROUTE_DESTINATION);
1227 HANGUP_CHANNEL(chan_callee, AST_CAUSE_NO_ROUTE_DESTINATION);
1229 result = verify_mock_cdr_record(test, &expected, 1);
1234 AST_TEST_DEFINE(test_cdr_dial_caller_cancel)
1236 RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
1237 RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
1238 RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
1241 struct ast_party_caller caller = ALICE_CALLERID;
1242 struct ast_cdr expected = {
1243 .clid = "\"Alice\" <100>",
1246 .dcontext = "default",
1247 .channel = CHANNEL_TECH_NAME "/Alice",
1248 .dstchannel = CHANNEL_TECH_NAME "/Bob",
1250 .lastdata = CHANNEL_TECH_NAME "/Bob",
1252 .amaflags = AST_AMA_DOCUMENTATION,
1253 .disposition = AST_CDR_NOANSWER,
1254 .accountcode = "100",
1255 .peeraccount = "200",
1257 enum ast_test_result_state result = AST_TEST_NOT_RUN;
1261 info->name = __func__;
1262 info->category = TEST_CATEGORY;
1263 info->summary = "Test CDRs for a dial where the caller cancels";
1265 "Test the properties of a CDR for a channel that\n"
1266 "performs a dial operation to an endpoint but then decides\n"
1267 "to hang up, cancelling the dial\n";
1268 return AST_TEST_NOT_RUN;
1273 SWAP_CONFIG(config, unanswered_cdr_config);
1275 CREATE_ALICE_CHANNEL(chan_caller, &caller, &expected);
1277 EMULATE_APP_DATA(chan_caller, 1, "Dial", CHANNEL_TECH_NAME "/Bob");
1279 chan_callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, ast_channel_linkedid(chan_caller), 0, CHANNEL_TECH_NAME "/Bob");
1280 ast_set_flag(ast_channel_flags(chan_callee), AST_FLAG_OUTGOING);
1281 EMULATE_APP_DATA(chan_callee, 0, "AppDial", "(Outgoing Line)");
1283 ast_channel_publish_dial(chan_caller, chan_callee, "Bob", NULL);
1284 ast_channel_state_set(chan_caller, AST_STATE_RINGING);
1285 ast_channel_publish_dial(chan_caller, chan_callee, NULL, "CANCEL");
1287 HANGUP_CHANNEL(chan_callee, AST_CAUSE_NORMAL);
1288 HANGUP_CHANNEL(chan_caller, AST_CAUSE_NORMAL);
1290 result = verify_mock_cdr_record(test, &expected, 1);
1295 AST_TEST_DEFINE(test_cdr_dial_parallel_failed)
1297 RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
1298 RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release);
1299 RAII_VAR(struct ast_channel *, chan_charlie, NULL, safe_channel_release);
1300 RAII_VAR(struct ast_channel *, chan_david, NULL, safe_channel_release);
1301 RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
1304 struct ast_party_caller caller = ALICE_CALLERID;
1305 struct ast_cdr bob_expected = {
1306 .clid = "\"Alice\" <100>",
1309 .dcontext = "default",
1310 .channel = CHANNEL_TECH_NAME "/Alice",
1311 .dstchannel = CHANNEL_TECH_NAME "/Bob",
1313 .lastdata = CHANNEL_TECH_NAME "/Bob&" CHANNEL_TECH_NAME "/Charlie&" CHANNEL_TECH_NAME "/David",
1315 .amaflags = AST_AMA_DOCUMENTATION,
1316 .disposition = AST_CDR_NOANSWER,
1317 .accountcode = "100",
1318 .peeraccount = "200",
1320 struct ast_cdr charlie_expected = {
1321 .clid = "\"Alice\" <100>",
1324 .dcontext = "default",
1325 .channel = CHANNEL_TECH_NAME "/Alice",
1326 .dstchannel = CHANNEL_TECH_NAME "/Charlie",
1328 .lastdata = CHANNEL_TECH_NAME "/Bob&" CHANNEL_TECH_NAME "/Charlie&" CHANNEL_TECH_NAME "/David",
1330 .amaflags = AST_AMA_DOCUMENTATION,
1331 .disposition = AST_CDR_BUSY,
1332 .accountcode = "100",
1333 .peeraccount = "300",
1335 struct ast_cdr david_expected = {
1336 .clid = "\"Alice\" <100>",
1339 .dcontext = "default",
1340 .channel = CHANNEL_TECH_NAME "/Alice",
1341 .dstchannel = CHANNEL_TECH_NAME "/David",
1343 .lastdata = CHANNEL_TECH_NAME "/Bob&" CHANNEL_TECH_NAME "/Charlie&" CHANNEL_TECH_NAME "/David",
1345 .amaflags = AST_AMA_DOCUMENTATION,
1346 .disposition = AST_CDR_CONGESTION,
1347 .accountcode = "100",
1348 .peeraccount = "400",
1350 enum ast_test_result_state result = AST_TEST_NOT_RUN;
1352 struct ast_cdr *expected = &bob_expected;
1353 bob_expected.next = &charlie_expected;
1354 charlie_expected.next = &david_expected;
1358 info->name = __func__;
1359 info->category = TEST_CATEGORY;
1360 info->summary = "Test a parallel dial where all channels fail to answer";
1362 "This tests dialing three parties: Bob, Charlie, David. Charlie\n"
1363 "returns BUSY; David returns CONGESTION; Bob fails to answer and\n"
1364 "Alice hangs up. Three records are created for Alice as a result.\n";
1365 return AST_TEST_NOT_RUN;
1370 SWAP_CONFIG(config, congestion_cdr_config);
1372 CREATE_ALICE_CHANNEL(chan_caller, &caller, &bob_expected);
1373 COPY_IDS(chan_caller, &charlie_expected);
1374 COPY_IDS(chan_caller, &david_expected);
1376 /* Channel enters Dial app */
1377 EMULATE_APP_DATA(chan_caller, 1, "Dial", CHANNEL_TECH_NAME "/Bob&" CHANNEL_TECH_NAME "/Charlie&" CHANNEL_TECH_NAME "/David");
1379 /* Outbound channels are created */
1380 chan_bob = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, ast_channel_linkedid(chan_caller), 0, CHANNEL_TECH_NAME "/Bob");
1381 ast_set_flag(ast_channel_flags(chan_bob), AST_FLAG_OUTGOING);
1382 EMULATE_APP_DATA(chan_bob, 0, "AppDial", "(Outgoing Line)");
1384 chan_charlie = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "300", NULL, NULL, ast_channel_linkedid(chan_caller), 0, CHANNEL_TECH_NAME "/Charlie");
1385 ast_set_flag(ast_channel_flags(chan_charlie), AST_FLAG_OUTGOING);
1386 EMULATE_APP_DATA(chan_charlie, 0, "AppDial", "(Outgoing Line)");
1388 chan_david = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "400", NULL, NULL, ast_channel_linkedid(chan_caller), 0, CHANNEL_TECH_NAME "/David");
1389 ast_set_flag(ast_channel_flags(chan_david), AST_FLAG_OUTGOING);
1390 EMULATE_APP_DATA(chan_david, 0, "AppDial", "(Outgoing Line)");
1393 ast_channel_publish_dial(chan_caller, chan_bob, "Bob", NULL);
1394 ast_channel_publish_dial(chan_caller, chan_charlie, "Charlie", NULL);
1395 ast_channel_publish_dial(chan_caller, chan_david, "David", NULL);
1396 ast_channel_state_set(chan_caller, AST_STATE_RINGING);
1398 /* Charlie is busy */
1399 ast_channel_publish_dial(chan_caller, chan_charlie, NULL, "BUSY");
1400 HANGUP_CHANNEL(chan_charlie, AST_CAUSE_BUSY);
1402 /* David is congested */
1403 ast_channel_publish_dial(chan_caller, chan_david, NULL, "CONGESTION");
1404 HANGUP_CHANNEL(chan_david, AST_CAUSE_CONGESTION);
1406 /* Bob is canceled */
1407 ast_channel_publish_dial(chan_caller, chan_bob, NULL, "CANCEL");
1408 HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL);
1410 /* Alice hangs up */
1411 HANGUP_CHANNEL(chan_caller, AST_CAUSE_NORMAL);
1413 result = verify_mock_cdr_record(test, expected, 3);
1418 AST_TEST_DEFINE(test_cdr_dial_answer_no_bridge)
1420 RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
1421 RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
1422 RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
1425 struct ast_party_caller caller = ALICE_CALLERID;
1426 struct ast_cdr bob_expected_one = {
1430 .dcontext = "default",
1431 .channel = CHANNEL_TECH_NAME "/Bob",
1434 .amaflags = AST_AMA_DOCUMENTATION,
1435 .disposition = AST_CDR_ANSWERED,
1436 .accountcode = "200",
1438 struct ast_cdr alice_expected_two = {
1439 .clid = "\"Alice\" <100>",
1442 .dcontext = "default",
1443 .channel = CHANNEL_TECH_NAME "/Alice",
1446 .amaflags = AST_AMA_DOCUMENTATION,
1447 .disposition = AST_CDR_ANSWERED,
1448 .accountcode = "100",
1449 .next = &bob_expected_one,
1451 struct ast_cdr alice_expected_one = {
1452 .clid = "\"Alice\" <100>",
1455 .dcontext = "default",
1456 .channel = CHANNEL_TECH_NAME "/Alice",
1457 .dstchannel = CHANNEL_TECH_NAME "/Bob",
1459 .lastdata = CHANNEL_TECH_NAME "/Bob",
1460 .amaflags = AST_AMA_DOCUMENTATION,
1461 .disposition = AST_CDR_ANSWERED,
1462 .accountcode = "100",
1463 .peeraccount = "200",
1464 .next = &alice_expected_two,
1466 enum ast_test_result_state result = AST_TEST_NOT_RUN;
1470 info->name = __func__;
1471 info->category = TEST_CATEGORY;
1472 info->summary = "Test dialing, answering, and not going into a bridge.";
1474 "This is a weird one, but theoretically possible. You can perform\n"
1475 "a dial, then bounce both channels to different priorities and\n"
1476 "never have them enter a bridge together. Ew. This makes sure that\n"
1477 "when we answer, we get a CDR, it gets ended at that point, and\n"
1478 "that it gets finalized appropriately. We should get three CDRs in\n"
1479 "the end - one for the dial, and one for each CDR as they continued\n"
1481 return AST_TEST_NOT_RUN;
1486 SWAP_CONFIG(config, debug_cdr_config);
1488 CREATE_ALICE_CHANNEL(chan_caller, &caller, &alice_expected_one);
1489 COPY_IDS(chan_caller, &alice_expected_two);
1491 EMULATE_APP_DATA(chan_caller, 1, "Dial", CHANNEL_TECH_NAME "/Bob");
1493 chan_callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, ast_channel_linkedid(chan_caller), 0, CHANNEL_TECH_NAME "/Bob");
1494 ast_set_flag(ast_channel_flags(chan_callee), AST_FLAG_OUTGOING);
1495 COPY_IDS(chan_callee, &bob_expected_one);
1497 ast_channel_publish_dial(chan_caller, chan_callee, "Bob", NULL);
1498 ast_channel_state_set(chan_caller, AST_STATE_RINGING);
1499 ast_channel_publish_dial(chan_caller, chan_callee, NULL, "ANSWER");
1501 ast_channel_state_set(chan_caller, AST_STATE_UP);
1502 ast_clear_flag(ast_channel_flags(chan_callee), AST_FLAG_OUTGOING);
1503 ast_channel_state_set(chan_callee, AST_STATE_UP);
1505 EMULATE_APP_DATA(chan_caller, 2, "Wait", "1");
1506 EMULATE_APP_DATA(chan_callee, 1, "Wait", "1");
1508 HANGUP_CHANNEL(chan_caller, AST_CAUSE_NORMAL);
1509 HANGUP_CHANNEL(chan_callee, AST_CAUSE_NORMAL);
1511 result = verify_mock_cdr_record(test, &alice_expected_one, 3);
1515 AST_TEST_DEFINE(test_cdr_dial_answer_twoparty_bridge_a)
1517 RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
1518 RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
1519 RAII_VAR(struct ast_bridge *, bridge, NULL, ao2_cleanup);
1520 RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
1522 struct timespec to_sleep = {1, 0};
1523 enum ast_test_result_state result = AST_TEST_NOT_RUN;
1525 struct ast_party_caller caller = ALICE_CALLERID;
1526 struct ast_cdr expected = {
1527 .clid = "\"Alice\" <100>",
1530 .dcontext = "default",
1531 .channel = CHANNEL_TECH_NAME "/Alice",
1532 .dstchannel = CHANNEL_TECH_NAME "/Bob",
1534 .lastdata = CHANNEL_TECH_NAME "/Bob",
1535 .amaflags = AST_AMA_DOCUMENTATION,
1537 .disposition = AST_CDR_ANSWERED,
1538 .accountcode = "100",
1539 .peeraccount = "200",
1544 info->name = __func__;
1545 info->category = TEST_CATEGORY;
1546 info->summary = "Test dialing, answering, and going into a 2-party bridge";
1548 "The most 'basic' of scenarios\n";
1549 return AST_TEST_NOT_RUN;
1554 SWAP_CONFIG(config, debug_cdr_config);
1556 CREATE_ALICE_CHANNEL(chan_caller, &caller, &expected);
1558 EMULATE_APP_DATA(chan_caller, 1, "Dial", CHANNEL_TECH_NAME "/Bob");
1560 chan_callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, ast_channel_linkedid(chan_caller), 0, CHANNEL_TECH_NAME "/Bob");
1561 ast_set_flag(ast_channel_flags(chan_callee), AST_FLAG_OUTGOING);
1562 EMULATE_APP_DATA(chan_callee, 0, "AppDial", "(Outgoing Line)");
1564 ast_channel_publish_dial(chan_caller, chan_callee, "Bob", NULL);
1565 ast_channel_state_set(chan_caller, AST_STATE_RINGING);
1566 ast_channel_publish_dial(chan_caller, chan_callee, NULL, "ANSWER");
1568 ast_channel_state_set(chan_caller, AST_STATE_UP);
1569 ast_channel_state_set(chan_callee, AST_STATE_UP);
1571 bridge = ast_bridge_basic_new();
1572 ast_test_validate(test, bridge != NULL);
1573 while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
1575 ast_bridge_impart(bridge, chan_caller, NULL, NULL, 0);
1576 ast_bridge_impart(bridge, chan_callee, NULL, NULL, 0);
1578 while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
1580 ast_bridge_depart(chan_caller);
1581 ast_bridge_depart(chan_callee);
1583 HANGUP_CHANNEL(chan_caller, AST_CAUSE_NORMAL);
1584 HANGUP_CHANNEL(chan_callee, AST_CAUSE_NORMAL);
1586 result = verify_mock_cdr_record(test, &expected, 1);
1590 AST_TEST_DEFINE(test_cdr_dial_answer_twoparty_bridge_b)
1592 RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
1593 RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
1594 RAII_VAR(struct ast_bridge *, bridge, NULL, ao2_cleanup);
1595 RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
1597 struct timespec to_sleep = {1, 0};
1598 enum ast_test_result_state result = AST_TEST_NOT_RUN;
1600 struct ast_party_caller caller = ALICE_CALLERID;
1601 struct ast_cdr expected = {
1602 .clid = "\"Alice\" <100>",
1605 .dcontext = "default",
1606 .channel = CHANNEL_TECH_NAME "/Alice",
1607 .dstchannel = CHANNEL_TECH_NAME "/Bob",
1609 .lastdata = CHANNEL_TECH_NAME "/Bob",
1610 .amaflags = AST_AMA_DOCUMENTATION,
1612 .disposition = AST_CDR_ANSWERED,
1613 .accountcode = "100",
1614 .peeraccount = "200",
1619 info->name = __func__;
1620 info->category = TEST_CATEGORY;
1621 info->summary = "Test dialing, answering, and going into a 2-party bridge";
1623 "The most 'basic' of scenarios\n";
1624 return AST_TEST_NOT_RUN;
1629 SWAP_CONFIG(config, debug_cdr_config);
1631 CREATE_ALICE_CHANNEL(chan_caller, &caller, &expected);
1633 EMULATE_APP_DATA(chan_caller, 1, "Dial", CHANNEL_TECH_NAME "/Bob");
1635 chan_callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, ast_channel_linkedid(chan_caller), 0, CHANNEL_TECH_NAME "/Bob");
1636 ast_set_flag(ast_channel_flags(chan_callee), AST_FLAG_OUTGOING);
1637 EMULATE_APP_DATA(chan_callee, 0, "AppDial", "(Outgoing Line)");
1639 ast_channel_publish_dial(chan_caller, chan_callee, "Bob", NULL);
1640 ast_channel_state_set(chan_caller, AST_STATE_RINGING);
1641 ast_channel_publish_dial(chan_caller, chan_callee, NULL, "ANSWER");
1643 ast_channel_state_set(chan_caller, AST_STATE_UP);
1644 ast_channel_state_set(chan_callee, AST_STATE_UP);
1646 bridge = ast_bridge_basic_new();
1647 ast_test_validate(test, bridge != NULL);
1648 while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
1649 ast_bridge_impart(bridge, chan_callee, NULL, NULL, 0);
1650 while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
1651 ast_bridge_impart(bridge, chan_caller, NULL, NULL, 0);
1652 while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
1653 ast_bridge_depart(chan_caller);
1654 ast_bridge_depart(chan_callee);
1656 HANGUP_CHANNEL(chan_caller, AST_CAUSE_NORMAL);
1657 HANGUP_CHANNEL(chan_callee, AST_CAUSE_NORMAL);
1659 result = verify_mock_cdr_record(test, &expected, 1);
1663 AST_TEST_DEFINE(test_cdr_dial_answer_multiparty)
1665 RAII_VAR(struct ast_channel *, chan_alice, NULL, safe_channel_release);
1666 RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release);
1667 RAII_VAR(struct ast_channel *, chan_charlie, NULL, safe_channel_release);
1668 RAII_VAR(struct ast_channel *, chan_david, NULL, safe_channel_release);
1669 RAII_VAR(struct ast_bridge *, bridge, NULL, ao2_cleanup);
1670 RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
1672 struct timespec to_sleep = {1, 0};
1673 enum ast_test_result_state result = AST_TEST_NOT_RUN;
1675 struct ast_party_caller alice_caller = ALICE_CALLERID;
1676 struct ast_party_caller charlie_caller = CHARLIE_CALLERID;
1677 struct ast_cdr charlie_expected_two = {
1678 .clid = "\"Charlie\" <300>",
1681 .dcontext = "default",
1682 .channel = CHANNEL_TECH_NAME "/Charlie",
1683 .dstchannel = CHANNEL_TECH_NAME "/Bob",
1685 .lastdata = CHANNEL_TECH_NAME "/David",
1686 .amaflags = AST_AMA_DOCUMENTATION,
1688 .disposition = AST_CDR_ANSWERED,
1689 .accountcode = "300",
1690 .peeraccount = "200",
1692 struct ast_cdr charlie_expected_one = {
1693 .clid = "\"Charlie\" <300>",
1696 .dcontext = "default",
1697 .channel = CHANNEL_TECH_NAME "/Charlie",
1698 .dstchannel = CHANNEL_TECH_NAME "/David",
1700 .lastdata = CHANNEL_TECH_NAME "/David",
1701 .amaflags = AST_AMA_DOCUMENTATION,
1703 .disposition = AST_CDR_ANSWERED,
1704 .accountcode = "300",
1705 .peeraccount = "400",
1706 .next = &charlie_expected_two,
1708 struct ast_cdr alice_expected_three = {
1709 .clid = "\"Alice\" <100>",
1712 .dcontext = "default",
1713 .channel = CHANNEL_TECH_NAME "/Alice",
1714 .dstchannel = CHANNEL_TECH_NAME "/David",
1716 .lastdata = CHANNEL_TECH_NAME "/Bob",
1717 .amaflags = AST_AMA_DOCUMENTATION,
1719 .disposition = AST_CDR_ANSWERED,
1720 .accountcode = "100",
1721 .peeraccount = "400",
1722 .next = &charlie_expected_one,
1724 struct ast_cdr alice_expected_two = {
1725 .clid = "\"Alice\" <100>",
1728 .dcontext = "default",
1729 .channel = CHANNEL_TECH_NAME "/Alice",
1730 .dstchannel = CHANNEL_TECH_NAME "/Charlie",
1732 .lastdata = CHANNEL_TECH_NAME "/Bob",
1733 .amaflags = AST_AMA_DOCUMENTATION,
1735 .disposition = AST_CDR_ANSWERED,
1736 .accountcode = "100",
1737 .peeraccount = "300",
1738 .next = &alice_expected_three,
1740 struct ast_cdr alice_expected_one = {
1741 .clid = "\"Alice\" <100>",
1744 .dcontext = "default",
1745 .channel = CHANNEL_TECH_NAME "/Alice",
1746 .dstchannel = CHANNEL_TECH_NAME "/Bob",
1748 .lastdata = CHANNEL_TECH_NAME "/Bob",
1749 .amaflags = AST_AMA_DOCUMENTATION,
1751 .disposition = AST_CDR_ANSWERED,
1752 .accountcode = "100",
1753 .peeraccount = "200",
1754 .next = &alice_expected_two,
1759 info->name = __func__;
1760 info->category = TEST_CATEGORY;
1761 info->summary = "Test dialing, answering, and going into a multi-party bridge";
1763 "A little tricky to get to do, but possible with some redirects.\n";
1764 return AST_TEST_NOT_RUN;
1769 SWAP_CONFIG(config, debug_cdr_config);
1771 CREATE_ALICE_CHANNEL(chan_alice, &alice_caller, &alice_expected_one);
1772 COPY_IDS(chan_alice, &alice_expected_two);
1773 COPY_IDS(chan_alice, &alice_expected_three);
1775 EMULATE_APP_DATA(chan_alice, 1, "Dial", CHANNEL_TECH_NAME "/Bob");
1777 chan_bob = ast_channel_alloc(0, AST_STATE_DOWN, "200", "Bob", "200", "200", "default", NULL, 0, CHANNEL_TECH_NAME "/Bob");
1778 ast_set_flag(ast_channel_flags(chan_bob), AST_FLAG_OUTGOING);
1779 EMULATE_APP_DATA(chan_bob, 0, "AppDial", "(Outgoing Line)");
1781 CREATE_CHARLIE_CHANNEL(chan_charlie, &charlie_caller, &charlie_expected_one);
1782 EMULATE_APP_DATA(chan_charlie, 1, "Dial", CHANNEL_TECH_NAME "/David");
1783 ast_copy_string(charlie_expected_one.uniqueid, ast_channel_uniqueid(chan_charlie), sizeof(charlie_expected_one.uniqueid));
1784 ast_copy_string(charlie_expected_one.linkedid, ast_channel_linkedid(chan_alice), sizeof(charlie_expected_one.linkedid));
1785 ast_copy_string(charlie_expected_two.uniqueid, ast_channel_uniqueid(chan_charlie), sizeof(charlie_expected_two.uniqueid));
1786 ast_copy_string(charlie_expected_two.linkedid, ast_channel_linkedid(chan_alice), sizeof(charlie_expected_two.linkedid));
1788 chan_david = ast_channel_alloc(0, AST_STATE_DOWN, "400", "David", "400", "400", "default", NULL, 0, CHANNEL_TECH_NAME "/David");
1789 ast_set_flag(ast_channel_flags(chan_david), AST_FLAG_OUTGOING);
1790 EMULATE_APP_DATA(chan_david, 0, "AppDial", "(Outgoing Line)");
1792 ast_channel_publish_dial(chan_alice, chan_bob, "Bob", NULL);
1793 ast_channel_state_set(chan_alice, AST_STATE_RINGING);
1794 ast_channel_publish_dial(chan_charlie, chan_david, "David", NULL);
1795 ast_channel_state_set(chan_charlie, AST_STATE_RINGING);
1796 ast_channel_publish_dial(chan_alice, chan_bob, NULL, "ANSWER");
1797 ast_channel_publish_dial(chan_charlie, chan_david, NULL, "ANSWER");
1799 ast_channel_state_set(chan_alice, AST_STATE_UP);
1800 ast_channel_state_set(chan_bob, AST_STATE_UP);
1801 ast_channel_state_set(chan_charlie, AST_STATE_UP);
1802 ast_channel_state_set(chan_david, AST_STATE_UP);
1804 bridge = ast_bridge_basic_new();
1805 ast_test_validate(test, bridge != NULL);
1807 while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
1808 ast_test_validate(test, 0 == ast_bridge_impart(bridge, chan_charlie, NULL, NULL, 0));
1809 while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
1810 ast_test_validate(test, 0 == ast_bridge_impart(bridge, chan_david, NULL, NULL, 0));
1811 while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
1812 ast_test_validate(test, 0 == ast_bridge_impart(bridge, chan_bob, NULL, NULL, 0));
1813 while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
1814 ast_test_validate(test, 0 == ast_bridge_impart(bridge, chan_alice, NULL, NULL, 0));
1815 while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
1816 ast_test_validate(test, 0 == ast_bridge_depart(chan_alice));
1817 ast_test_validate(test, 0 == ast_bridge_depart(chan_bob));
1818 ast_test_validate(test, 0 == ast_bridge_depart(chan_charlie));
1819 ast_test_validate(test, 0 == ast_bridge_depart(chan_david));
1821 HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL);
1822 HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL);
1823 HANGUP_CHANNEL(chan_charlie, AST_CAUSE_NORMAL);
1824 HANGUP_CHANNEL(chan_david, AST_CAUSE_NORMAL);
1826 result = verify_mock_cdr_record(test, &alice_expected_one, 5);
1831 AST_TEST_DEFINE(test_cdr_park)
1833 RAII_VAR(struct ast_channel *, chan_alice, NULL, safe_channel_release);
1834 RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release);
1835 RAII_VAR(struct ast_bridge *, bridge, NULL, ao2_cleanup);
1836 RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
1838 struct timespec to_sleep = {1, 0};
1840 struct ast_party_caller bob_caller = BOB_CALLERID;
1841 struct ast_party_caller alice_caller = ALICE_CALLERID;
1842 struct ast_cdr bob_expected = {
1843 .clid = "\"Bob\" <200>",
1846 .dcontext = "default",
1847 .channel = CHANNEL_TECH_NAME "/Bob",
1851 .amaflags = AST_AMA_DOCUMENTATION,
1852 .disposition = AST_CDR_ANSWERED,
1853 .accountcode = "200",
1855 struct ast_cdr alice_expected = {
1856 .clid = "\"Alice\" <100>",
1859 .dcontext = "default",
1860 .channel = CHANNEL_TECH_NAME "/Alice",
1864 .amaflags = AST_AMA_DOCUMENTATION,
1865 .disposition = AST_CDR_ANSWERED,
1866 .accountcode = "100",
1867 .next = &bob_expected,
1869 enum ast_test_result_state result = AST_TEST_NOT_RUN;
1873 info->name = __func__;
1874 info->category = TEST_CATEGORY;
1875 info->summary = "Test cdrs for a single party entering Park";
1877 "Test the properties of a CDR for calls that are\n"
1878 "answered, enters Park, and leaves it.\n";
1879 return AST_TEST_NOT_RUN;
1883 SWAP_CONFIG(config, debug_cdr_config);
1884 CREATE_ALICE_CHANNEL(chan_alice, &alice_caller, &alice_expected);
1885 CREATE_BOB_CHANNEL(chan_bob, &bob_caller, &bob_expected);
1887 EMULATE_APP_DATA(chan_alice, 1, "Park", "700");
1888 ast_setstate(chan_alice, AST_STATE_UP);
1889 EMULATE_APP_DATA(chan_bob, 1, "Park", "701");
1890 ast_setstate(chan_bob, AST_STATE_UP);
1892 bridge = ast_bridge_base_new(AST_BRIDGE_CAPABILITY_HOLDING,
1893 AST_BRIDGE_FLAG_MERGE_INHIBIT_TO | AST_BRIDGE_FLAG_MERGE_INHIBIT_FROM
1894 | AST_BRIDGE_FLAG_SWAP_INHIBIT_FROM | AST_BRIDGE_FLAG_TRANSFER_PROHIBITED);
1895 ast_test_validate(test, bridge != NULL);
1897 while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
1898 ast_bridge_impart(bridge, chan_alice, NULL, NULL, 0);
1899 while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
1900 ast_bridge_impart(bridge, chan_bob, NULL, NULL, 0);
1901 while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
1902 ast_bridge_depart(chan_alice);
1903 ast_bridge_depart(chan_bob);
1905 /* And then it hangs up */
1906 HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL);
1907 HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL);
1909 result = verify_mock_cdr_record(test, &alice_expected, 2);
1915 AST_TEST_DEFINE(test_cdr_fields)
1917 RAII_VAR(struct ast_channel *, chan, NULL, safe_channel_release);
1918 RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
1920 char varbuffer[128];
1923 struct timespec to_sleep = {2, 0};
1924 struct ast_flags fork_options = { 0, };
1926 struct ast_party_caller caller = ALICE_CALLERID;
1927 struct ast_cdr original = {
1928 .clid = "\"Alice\" <100>",
1931 .dcontext = "default",
1932 .channel = CHANNEL_TECH_NAME "/Alice",
1936 .amaflags = AST_AMA_OMIT,
1937 .disposition = AST_CDR_FAILED,
1938 .accountcode = "XXX",
1939 .userfield = "yackity",
1941 struct ast_cdr fork_expected_one = {
1942 .clid = "\"Alice\" <100>",
1945 .dcontext = "default",
1946 .channel = CHANNEL_TECH_NAME "/Alice",
1950 .amaflags = AST_AMA_OMIT,
1951 .disposition = AST_CDR_FAILED,
1952 .accountcode = "XXX",
1953 .userfield = "yackity",
1955 struct ast_cdr fork_expected_two = {
1956 .clid = "\"Alice\" <100>",
1959 .dcontext = "default",
1960 .channel = CHANNEL_TECH_NAME "/Alice",
1961 .lastapp = "Answer",
1963 .amaflags = AST_AMA_OMIT,
1964 .disposition = AST_CDR_ANSWERED,
1965 .accountcode = "ZZZ",
1966 .userfield = "schmackity",
1968 enum ast_test_result_state result = AST_TEST_NOT_RUN;
1970 struct ast_cdr *expected = &original;
1971 original.next = &fork_expected_one;
1972 fork_expected_one.next = &fork_expected_two;
1976 info->name = __func__;
1977 info->category = TEST_CATEGORY;
1978 info->summary = "Test field access CDRs";
1980 "This tests setting/retrieving data on CDR records.\n";
1981 return AST_TEST_NOT_RUN;
1986 SWAP_CONFIG(config, unanswered_cdr_config);
1988 CREATE_ALICE_CHANNEL(chan, &caller, &original);
1989 ast_copy_string(fork_expected_one.uniqueid, ast_channel_uniqueid(chan), sizeof(fork_expected_one.uniqueid));
1990 ast_copy_string(fork_expected_one.linkedid, ast_channel_linkedid(chan), sizeof(fork_expected_one.linkedid));
1991 ast_copy_string(fork_expected_two.uniqueid, ast_channel_uniqueid(chan), sizeof(fork_expected_two.uniqueid));
1992 ast_copy_string(fork_expected_two.linkedid, ast_channel_linkedid(chan), sizeof(fork_expected_two.linkedid));
1994 /* Channel enters Wait app */
1995 ast_channel_appl_set(chan, "Wait");
1996 ast_channel_data_set(chan, "10");
1997 ast_channel_priority_set(chan, 1);
1998 ast_channel_publish_snapshot(chan);
2000 /* Set properties on the channel that propagate to the CDR */
2001 ast_channel_amaflags_set(chan, AST_AMA_OMIT);
2002 ast_channel_accountcode_set(chan, "XXX");
2004 /* Wait one second so we get a duration. */
2005 while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
2007 ast_cdr_setuserfield(ast_channel_name(chan), "foobar");
2008 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "test_variable", "record_1") == 0);
2010 /* Verify that we can't set read-only fields or other fields directly */
2011 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "clid", "junk") != 0);
2012 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "src", "junk") != 0);
2013 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "dst", "junk") != 0);
2014 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "dcontext", "junk") != 0);
2015 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "channel", "junk") != 0);
2016 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "dstchannel", "junk") != 0);
2017 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "lastapp", "junk") != 0);
2018 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "lastdata", "junk") != 0);
2019 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "start", "junk") != 0);
2020 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "answer", "junk") != 0);
2021 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "end", "junk") != 0);
2022 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "duration", "junk") != 0);
2023 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "billsec", "junk") != 0);
2024 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "disposition", "junk") != 0);
2025 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "amaflags", "junk") != 0);
2026 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "accountcode", "junk") != 0);
2027 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "uniqueid", "junk") != 0);
2028 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "linkedid", "junk") != 0);
2029 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "userfield", "junk") != 0);
2030 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "sequence", "junk") != 0);
2032 /* Verify the values */
2033 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "userfield", varbuffer, sizeof(varbuffer)) == 0);
2034 ast_test_validate(test, strcmp(varbuffer, "foobar") == 0);
2035 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "test_variable", varbuffer, sizeof(varbuffer)) == 0);
2036 ast_test_validate(test, strcmp(varbuffer, "record_1") == 0);
2037 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "amaflags", varbuffer, sizeof(varbuffer)) == 0);
2038 sscanf(varbuffer, "%d", &int_buffer);
2039 ast_test_validate(test, int_buffer == AST_AMA_OMIT);
2040 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "accountcode", varbuffer, sizeof(varbuffer)) == 0);
2041 ast_test_validate(test, strcmp(varbuffer, "XXX") == 0);
2042 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "clid", varbuffer, sizeof(varbuffer)) == 0);
2043 ast_test_validate(test, strcmp(varbuffer, "\"Alice\" <100>") == 0);
2044 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "src", varbuffer, sizeof(varbuffer)) == 0);
2045 ast_test_validate(test, strcmp(varbuffer, "100") == 0);
2046 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "dst", varbuffer, sizeof(varbuffer)) == 0);
2047 ast_test_validate(test, strcmp(varbuffer, "100") == 0);
2048 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "dcontext", varbuffer, sizeof(varbuffer)) == 0);
2049 ast_test_validate(test, strcmp(varbuffer, "default") == 0);
2050 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "channel", varbuffer, sizeof(varbuffer)) == 0);
2051 ast_test_validate(test, strcmp(varbuffer, CHANNEL_TECH_NAME "/Alice") == 0);
2052 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "dstchannel", varbuffer, sizeof(varbuffer)) == 0);
2053 ast_test_validate(test, strcmp(varbuffer, "") == 0);
2054 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "lastapp", varbuffer, sizeof(varbuffer)) == 0);
2055 ast_test_validate(test, strcmp(varbuffer, "Wait") == 0);
2056 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "lastdata", varbuffer, sizeof(varbuffer)) == 0);
2057 ast_test_validate(test, strcmp(varbuffer, "10") == 0);
2058 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "start", varbuffer, sizeof(varbuffer)) == 0);
2059 sscanf(varbuffer, "%lf", &db_buffer);
2060 ast_test_validate(test, fabs(db_buffer) > 0);
2061 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "answer", varbuffer, sizeof(varbuffer)) == 0);
2062 sscanf(varbuffer, "%lf", &db_buffer);
2063 ast_test_validate(test, fabs(db_buffer) < EPSILON);
2064 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "end", varbuffer, sizeof(varbuffer)) == 0);
2065 sscanf(varbuffer, "%lf", &db_buffer);
2066 ast_test_validate(test, fabs(db_buffer) < EPSILON);
2067 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "duration", varbuffer, sizeof(varbuffer)) == 0);
2068 sscanf(varbuffer, "%lf", &db_buffer);
2069 ast_test_validate(test, fabs(db_buffer) > 0);
2070 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "billsec", varbuffer, sizeof(varbuffer)) == 0);
2071 sscanf(varbuffer, "%lf", &db_buffer);
2072 ast_test_validate(test, fabs(db_buffer) < EPSILON);
2073 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "disposition", varbuffer, sizeof(varbuffer)) == 0);
2074 sscanf(varbuffer, "%d", &int_buffer);
2075 ast_test_validate(test, int_buffer == AST_CDR_NULL);
2076 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "uniqueid", varbuffer, sizeof(varbuffer)) == 0);
2077 ast_test_validate(test, strcmp(varbuffer, ast_channel_uniqueid(chan)) == 0);
2078 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "linkedid", varbuffer, sizeof(varbuffer)) == 0);
2079 ast_test_validate(test, strcmp(varbuffer, ast_channel_linkedid(chan)) == 0);
2080 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "sequence", varbuffer, sizeof(varbuffer)) == 0);
2082 /* Fork the CDR, and check that we change the properties on both CDRs. */
2083 ast_set_flag(&fork_options, AST_CDR_FLAG_KEEP_VARS);
2084 ast_test_validate(test, ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
2086 /* Change some properties */
2087 ast_cdr_setuserfield(ast_channel_name(chan), "yackity");
2088 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "test_variable", "record_1b") == 0);
2090 /* Fork the CDR again, finalizing all current CDRs */
2091 ast_set_flag(&fork_options, AST_CDR_FLAG_KEEP_VARS | AST_CDR_FLAG_FINALIZE);
2092 ast_test_validate(test, ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
2094 /* Channel enters Answer app */
2095 ast_channel_appl_set(chan, "Answer");
2096 ast_channel_data_set(chan, "");
2097 ast_channel_priority_set(chan, 1);
2098 ast_channel_publish_snapshot(chan);
2099 ast_setstate(chan, AST_STATE_UP);
2101 /* Set properties on the last record */
2102 ast_channel_accountcode_set(chan, "ZZZ");
2103 ast_cdr_setuserfield(ast_channel_name(chan), "schmackity");
2104 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "test_variable", "record_2") == 0);
2106 /* Hang up and verify */
2107 ast_channel_hangupcause_set(chan, AST_CAUSE_NORMAL);
2108 if (!ast_hangup(chan)) {
2111 result = verify_mock_cdr_record(test, expected, 3);
2116 AST_TEST_DEFINE(test_cdr_no_reset_cdr)
2118 RAII_VAR(struct ast_channel *, chan, NULL, safe_channel_release);
2119 RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
2121 struct ast_flags fork_options = { 0, };
2122 struct timespec to_sleep = {1, 0};
2124 struct ast_party_caller caller = ALICE_CALLERID;
2125 struct ast_cdr expected = {
2126 .clid = "\"Alice\" <100>",
2129 .dcontext = "default",
2130 .channel = CHANNEL_TECH_NAME "/Alice",
2132 .amaflags = AST_AMA_DOCUMENTATION,
2133 .disposition = AST_CDR_FAILED,
2134 .accountcode = "100",
2136 enum ast_test_result_state result = AST_TEST_NOT_RUN;
2140 info->name = __func__;
2141 info->category = TEST_CATEGORY;
2142 info->summary = "Test field access CDRs";
2144 "This tests setting/retrieving data on CDR records.\n";
2145 return AST_TEST_NOT_RUN;
2150 SWAP_CONFIG(config, unanswered_cdr_config);
2152 CREATE_ALICE_CHANNEL(chan, &caller, &expected);
2154 while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
2156 /* Disable the CDR */
2157 ast_test_validate(test, ast_cdr_set_property(ast_channel_name(chan), AST_CDR_FLAG_DISABLE) == 0);
2159 /* Fork the CDR. This should be enabled */
2160 ast_set_flag(&fork_options, AST_CDR_FLAG_FINALIZE);
2161 ast_test_validate(test, ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
2163 /* Disable and enable the forked CDR */
2164 ast_test_validate(test, ast_cdr_set_property(ast_channel_name(chan), AST_CDR_FLAG_DISABLE) == 0);
2165 ast_test_validate(test, ast_cdr_clear_property(ast_channel_name(chan), AST_CDR_FLAG_DISABLE) == 0);
2167 /* Fork and finalize again. This CDR should be propagated */
2168 ast_test_validate(test, ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
2170 /* Disable all future CDRs */
2171 ast_test_validate(test, ast_cdr_set_property(ast_channel_name(chan), AST_CDR_FLAG_DISABLE_ALL) == 0);
2173 /* Fork a few more */
2174 ast_test_validate(test, ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
2175 ast_test_validate(test, ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
2176 ast_test_validate(test, ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
2178 ast_channel_hangupcause_set(chan, AST_CAUSE_NORMAL);
2179 if (!ast_hangup(chan)) {
2182 result = verify_mock_cdr_record(test, &expected, 1);
2187 AST_TEST_DEFINE(test_cdr_fork_cdr)
2189 RAII_VAR(struct ast_channel *, chan, NULL, safe_channel_release);
2190 RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
2192 char varbuffer[128];
2193 char fork_varbuffer[128];
2194 char answer_time[128];
2195 char fork_answer_time[128];
2196 char start_time[128];
2197 char fork_start_time[128];
2198 struct ast_flags fork_options = { 0, };
2199 struct timespec to_sleep = {1, 10000};
2201 struct ast_party_caller caller = ALICE_CALLERID;
2202 struct ast_cdr original = {
2203 .clid = "\"Alice\" <100>",
2206 .dcontext = "default",
2207 .channel = CHANNEL_TECH_NAME "/Alice",
2208 .amaflags = AST_AMA_DOCUMENTATION,
2209 .disposition = AST_CDR_ANSWERED,
2210 .accountcode = "100",
2212 struct ast_cdr fork_expected_one = {
2213 .clid = "\"Alice\" <100>",
2216 .dcontext = "default",
2217 .channel = CHANNEL_TECH_NAME "/Alice",
2218 .amaflags = AST_AMA_DOCUMENTATION,
2219 .disposition = AST_CDR_ANSWERED,
2220 .accountcode = "100",
2222 struct ast_cdr fork_expected_two = {
2223 .clid = "\"Alice\" <100>",
2226 .dcontext = "default",
2227 .channel = CHANNEL_TECH_NAME "/Alice",
2228 .amaflags = AST_AMA_DOCUMENTATION,
2229 .disposition = AST_CDR_ANSWERED,
2230 .accountcode = "100",
2232 enum ast_test_result_state result = AST_TEST_NOT_RUN;
2233 struct ast_cdr *expected = &original;
2234 original.next = &fork_expected_one;
2235 fork_expected_one.next = &fork_expected_two;
2239 info->name = __func__;
2240 info->category = TEST_CATEGORY;
2241 info->summary = "Test field access CDRs";
2243 "This tests setting/retrieving data on CDR records.\n";
2244 return AST_TEST_NOT_RUN;
2249 SWAP_CONFIG(config, debug_cdr_config);
2251 CREATE_ALICE_CHANNEL(chan, &caller, &original);
2252 ast_copy_string(fork_expected_one.uniqueid, ast_channel_uniqueid(chan), sizeof(fork_expected_one.uniqueid));
2253 ast_copy_string(fork_expected_one.linkedid, ast_channel_linkedid(chan), sizeof(fork_expected_one.linkedid));
2254 ast_copy_string(fork_expected_two.uniqueid, ast_channel_uniqueid(chan), sizeof(fork_expected_two.uniqueid));
2255 ast_copy_string(fork_expected_two.linkedid, ast_channel_linkedid(chan), sizeof(fork_expected_two.linkedid));
2257 while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
2259 /* Test blowing away variables */
2260 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "test_variable", "record_1") == 0);
2261 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "test_variable", varbuffer, sizeof(varbuffer)) == 0);
2262 ast_test_validate(test, strcmp(varbuffer, "record_1") == 0);
2263 ast_copy_string(varbuffer, "", sizeof(varbuffer));
2265 ast_test_validate(test, ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
2266 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "test_variable", fork_varbuffer, sizeof(fork_varbuffer)) == 0);
2267 ast_test_validate(test, strcmp(varbuffer, "record_1") != 0);
2269 /* Test finalizing previous CDRs */
2270 ast_set_flag(&fork_options, AST_CDR_FLAG_FINALIZE);
2271 ast_test_validate(test, ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
2273 /* Test keep variables; setting a new answer time */
2274 ast_setstate(chan, AST_STATE_UP);
2275 while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
2276 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "test_variable", "record_2") == 0);
2277 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "test_variable", varbuffer, sizeof(varbuffer)) == 0);
2278 ast_test_validate(test, strcmp(varbuffer, "record_2") == 0);
2279 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "answer", answer_time, sizeof(answer_time)) == 0);
2280 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "start", start_time, sizeof(start_time)) == 0);
2282 ast_set_flag(&fork_options, AST_CDR_FLAG_FINALIZE);
2283 ast_set_flag(&fork_options, AST_CDR_FLAG_KEEP_VARS);
2284 ast_set_flag(&fork_options, AST_CDR_FLAG_SET_ANSWER);
2285 ast_test_validate(test, ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
2286 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "answer", fork_answer_time, sizeof(fork_answer_time)) == 0);
2287 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "start", fork_start_time, sizeof(fork_start_time)) == 0);
2288 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "test_variable", fork_varbuffer, sizeof(fork_varbuffer)) == 0);
2289 ast_test_validate(test, strcmp(fork_varbuffer, varbuffer) == 0);
2290 ast_test_validate(test, strcmp(fork_start_time, start_time) == 0);
2291 ast_test_validate(test, strcmp(fork_answer_time, answer_time) != 0);
2293 ast_clear_flag(&fork_options, AST_CDR_FLAG_SET_ANSWER);
2294 ast_set_flag(&fork_options, AST_CDR_FLAG_RESET);
2295 ast_test_validate(test, ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
2296 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "answer", fork_answer_time, sizeof(fork_answer_time)) == 0);
2297 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "start", fork_start_time, sizeof(fork_start_time)) == 0);
2298 ast_test_validate(test, strcmp(fork_start_time, start_time) != 0);
2299 ast_test_validate(test, strcmp(fork_answer_time, answer_time) != 0);
2301 ast_channel_hangupcause_set(chan, AST_CAUSE_NORMAL);
2302 if (!ast_hangup(chan)) {
2305 result = verify_mock_cdr_record(test, expected, 3);
2311 * \internal \brief Callback function called before each test executes
2313 static int test_cdr_init_cb(struct ast_test_info *info, struct ast_test *test)
2315 /* Back up the real config */
2316 saved_config = ast_cdr_get_config();
2317 clear_mock_cdr_backend();
2322 * \internal \brief Callback function called after each test executes
2324 static int test_cdr_cleanup_cb(struct ast_test_info *info, struct ast_test *test)
2326 /* Restore the real config */
2327 ast_cdr_set_config(saved_config);
2328 ao2_cleanup(saved_config);
2329 saved_config = NULL;
2330 clear_mock_cdr_backend();
2336 static int unload_module(void)
2338 AST_TEST_UNREGISTER(test_cdr_channel_creation);
2339 AST_TEST_UNREGISTER(test_cdr_unanswered_inbound_call);
2340 AST_TEST_UNREGISTER(test_cdr_unanswered_outbound_call);
2341 AST_TEST_UNREGISTER(test_cdr_single_party);
2342 AST_TEST_UNREGISTER(test_cdr_single_bridge);
2343 AST_TEST_UNREGISTER(test_cdr_single_bridge_continue);
2344 AST_TEST_UNREGISTER(test_cdr_single_twoparty_bridge_a);
2345 AST_TEST_UNREGISTER(test_cdr_single_twoparty_bridge_b);
2346 AST_TEST_UNREGISTER(test_cdr_single_multiparty_bridge);
2348 AST_TEST_UNREGISTER(test_cdr_dial_unanswered);
2349 AST_TEST_UNREGISTER(test_cdr_dial_congestion);
2350 AST_TEST_UNREGISTER(test_cdr_dial_busy);
2351 AST_TEST_UNREGISTER(test_cdr_dial_unavailable);
2352 AST_TEST_UNREGISTER(test_cdr_dial_caller_cancel);
2353 AST_TEST_UNREGISTER(test_cdr_dial_parallel_failed);
2354 AST_TEST_UNREGISTER(test_cdr_dial_answer_no_bridge);
2355 AST_TEST_UNREGISTER(test_cdr_dial_answer_twoparty_bridge_a);
2356 AST_TEST_UNREGISTER(test_cdr_dial_answer_twoparty_bridge_b);
2357 AST_TEST_UNREGISTER(test_cdr_dial_answer_multiparty);
2359 AST_TEST_UNREGISTER(test_cdr_park);
2361 AST_TEST_UNREGISTER(test_cdr_fields);
2362 AST_TEST_UNREGISTER(test_cdr_no_reset_cdr);
2363 AST_TEST_UNREGISTER(test_cdr_fork_cdr);
2365 ast_cdr_unregister(MOCK_CDR_BACKEND);
2366 ast_channel_unregister(&test_cdr_chan_tech);
2367 clear_mock_cdr_backend();
2372 static int load_module(void)
2374 ast_cond_init(&mock_cdr_cond, NULL);
2376 AST_TEST_REGISTER(test_cdr_channel_creation);
2377 AST_TEST_REGISTER(test_cdr_unanswered_inbound_call);
2378 AST_TEST_REGISTER(test_cdr_unanswered_outbound_call);
2380 AST_TEST_REGISTER(test_cdr_single_party);
2381 AST_TEST_REGISTER(test_cdr_single_bridge);
2382 AST_TEST_REGISTER(test_cdr_single_bridge_continue);
2383 AST_TEST_REGISTER(test_cdr_single_twoparty_bridge_a);
2384 AST_TEST_REGISTER(test_cdr_single_twoparty_bridge_b);
2385 AST_TEST_REGISTER(test_cdr_single_multiparty_bridge);
2387 AST_TEST_REGISTER(test_cdr_dial_unanswered);
2388 AST_TEST_REGISTER(test_cdr_dial_congestion);
2389 AST_TEST_REGISTER(test_cdr_dial_busy);
2390 AST_TEST_REGISTER(test_cdr_dial_unavailable);
2391 AST_TEST_REGISTER(test_cdr_dial_caller_cancel);
2392 AST_TEST_REGISTER(test_cdr_dial_parallel_failed);
2393 AST_TEST_REGISTER(test_cdr_dial_answer_no_bridge);
2394 AST_TEST_REGISTER(test_cdr_dial_answer_twoparty_bridge_a);
2395 AST_TEST_REGISTER(test_cdr_dial_answer_twoparty_bridge_b);
2396 AST_TEST_REGISTER(test_cdr_dial_answer_multiparty);
2398 AST_TEST_REGISTER(test_cdr_park);
2400 AST_TEST_REGISTER(test_cdr_fields);
2401 AST_TEST_REGISTER(test_cdr_no_reset_cdr);
2402 AST_TEST_REGISTER(test_cdr_fork_cdr);
2404 ast_test_register_init(TEST_CATEGORY, test_cdr_init_cb);
2405 ast_test_register_cleanup(TEST_CATEGORY, test_cdr_cleanup_cb);
2407 ast_channel_register(&test_cdr_chan_tech);
2408 ast_cdr_register(MOCK_CDR_BACKEND, "Mock CDR backend", mock_cdr_backend_cb);
2410 return AST_MODULE_LOAD_SUCCESS;
2413 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "CDR unit tests");