45 #include "asterisk/stasis_channels.h"
46 #include "asterisk/stasis_bridges.h"
51 #define TEST_CATEGORY "/main/cdr/"
53 #define MOCK_CDR_BACKEND "mock_cdr_backend"
55 #define CHANNEL_TECH_NAME "CDRTestChannel"
79 #define SWAP_CONFIG(ao2_config, template) do { \
80 *(ao2_config) = (template); \
81 ast_cdr_set_config((ao2_config)); \
92 .type = CHANNEL_TECH_NAME,
93 .description =
"Mock channel technology for CDR tests",
116 static int mock_cdr_backend_cb(
struct ast_cdr *cdr)
118 struct ast_cdr *cdr_copy, *cdr_prev = NULL;
119 struct ast_cdr *mock_cdr = NULL;
122 cdr_wrapper =
ast_calloc(1,
sizeof(*cdr_wrapper));
127 for (; cdr; cdr = cdr->next) {
137 cdr_copy->next = NULL;
140 var_copy = ast_var_assign(var_entry->name, var_entry->value);
151 cdr_prev->next = cdr_copy;
155 cdr_wrapper->cdr = mock_cdr;
169 static void clear_mock_cdr_backend(
void)
176 ast_free(cdr_wrapper);
186 #define VERIFY_STRING_FIELD(field, actual, expected) do { \
187 if (strcmp((actual)->field, (expected)->field)) { \
188 ast_test_status_update(test, "Field %s failed: actual %s, expected %s\n", #field, (actual)->field, (expected)->field); \
189 ast_test_set_result(test, AST_TEST_FAIL); \
190 res = AST_TEST_FAIL; \
197 #define VERIFY_NUMERIC_FIELD(field, actual, expected) do { \
198 if ((actual)->field != (expected)->field) { \
199 ast_test_status_update(test, "Field %s failed: actual %ld, expected %ld\n", #field, (long)(actual)->field, (long)(expected)->field); \
200 ast_test_set_result(test, AST_TEST_FAIL); \
201 res = AST_TEST_FAIL; \
208 #define VERIFY_TIME_VALUE(field, actual) do { \
209 if (ast_tvzero((actual)->field)) { \
210 ast_test_status_update(test, "Field %s failed: should not be 0\n", #field); \
211 ast_test_set_result(test, AST_TEST_FAIL); \
212 res = AST_TEST_FAIL; \
216 #define ALICE_CALLERID { .id.name.str = "Alice", .id.name.valid = 1, .id.number.str = "100", .id.number.valid = 1, }
219 #define BOB_CALLERID { .id.name.str = "Bob", .id.name.valid = 1, .id.number.str = "200", .id.number.valid = 1, }
222 #define CHARLIE_CALLERID { .id.name.str = "Charlie", .id.name.valid = 1, .id.number.str = "300", .id.number.valid = 1, }
225 #define DAVID_CALLERID { .id.name.str = "David", .id.name.valid = 1, .id.number.str = "400", .id.number.valid = 1, }
228 #define COPY_IDS(channel_var, expected_record) do { \
229 ast_copy_string((expected_record)->uniqueid, ast_channel_uniqueid((channel_var)), sizeof((expected_record)->uniqueid)); \
230 ast_copy_string((expected_record)->linkedid, ast_channel_linkedid((channel_var)), sizeof((expected_record)->linkedid)); \
234 #define SET_FORMATS(chan) do {\
235 struct ast_format_cap *caps;\
236 caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);\
237 ast_format_cap_append(caps, ast_format_ulaw, 0);\
238 ast_channel_nativeformats_set((chan), caps);\
239 ast_channel_set_writeformat((chan), ast_format_ulaw);\
240 ast_channel_set_rawwriteformat((chan), ast_format_ulaw);\
241 ast_channel_set_readformat((chan), ast_format_ulaw);\
242 ast_channel_set_rawreadformat((chan), ast_format_ulaw);\
248 #define CREATE_ALICE_CHANNEL(channel_var, caller_id, expected_record) do { \
249 (channel_var) = ast_channel_alloc(0, AST_STATE_DOWN, "100", "Alice", "100", "100", "default", NULL, NULL, 0, CHANNEL_TECH_NAME "/Alice"); \
250 SET_FORMATS((channel_var));\
251 ast_channel_set_caller((channel_var), (caller_id), NULL); \
252 ast_copy_string((expected_record)->uniqueid, ast_channel_uniqueid((channel_var)), sizeof((expected_record)->uniqueid)); \
253 ast_copy_string((expected_record)->linkedid, ast_channel_linkedid((channel_var)), sizeof((expected_record)->linkedid)); \
254 ast_channel_unlock((channel_var)); \
259 #define CREATE_BOB_CHANNEL(channel_var, caller_id, expected_record) do { \
260 (channel_var) = ast_channel_alloc(0, AST_STATE_DOWN, "200", "Bob", "200", "200", "default", NULL, NULL, 0, CHANNEL_TECH_NAME "/Bob"); \
261 SET_FORMATS((channel_var));\
262 ast_channel_set_caller((channel_var), (caller_id), NULL); \
263 ast_copy_string((expected_record)->uniqueid, ast_channel_uniqueid((channel_var)), sizeof((expected_record)->uniqueid)); \
264 ast_copy_string((expected_record)->linkedid, ast_channel_linkedid((channel_var)), sizeof((expected_record)->linkedid)); \
265 ast_channel_unlock((channel_var)); \
270 #define CREATE_CHARLIE_CHANNEL(channel_var, caller_id, expected_record) do { \
271 (channel_var) = ast_channel_alloc(0, AST_STATE_DOWN, "300", "Charlie", "300", "300", "default", NULL, NULL, 0, CHANNEL_TECH_NAME "/Charlie"); \
272 SET_FORMATS((channel_var));\
273 ast_channel_set_caller((channel_var), (caller_id), NULL); \
274 ast_copy_string((expected_record)->uniqueid, ast_channel_uniqueid((channel_var)), sizeof((expected_record)->uniqueid)); \
275 ast_copy_string((expected_record)->linkedid, ast_channel_linkedid((channel_var)), sizeof((expected_record)->linkedid)); \
276 ast_channel_unlock((channel_var)); \
281 #define CREATE_DAVID_CHANNEL(channel_var, caller_id, expected_record) do { \
282 (channel_var) = ast_channel_alloc(0, AST_STATE_DOWN, "400", "David", "400", "400", "default", NULL, NULL, 0, CHANNEL_TECH_NAME "/David"); \
283 SET_FORMATS((channel_var));\
284 ast_channel_set_caller((channel_var), (caller_id), NULL); \
285 ast_copy_string((expected_record)->uniqueid, ast_channel_uniqueid((channel_var)), sizeof((expected_record)->uniqueid)); \
286 ast_copy_string((expected_record)->linkedid, ast_channel_linkedid((channel_var)), sizeof((expected_record)->linkedid)); \
287 ast_channel_unlock((channel_var)); \
291 #define EMULATE_APP_DATA(channel, priority, application, data) do { \
292 if ((priority) > 0) { \
293 ast_channel_priority_set((channel), (priority)); \
295 ast_channel_lock((channel)); \
296 ast_channel_appl_set((channel), (application)); \
297 ast_channel_data_set((channel), (data)); \
298 ast_channel_publish_snapshot((channel)); \
299 ast_channel_unlock((channel)); \
303 #define HANGUP_CHANNEL(channel, cause) \
305 ast_channel_hangupcause_set((channel), (cause)); \
306 ast_hangup(channel); \
310 static enum ast_test_result_state verify_mock_cdr_record(
struct ast_test *
test,
struct ast_cdr *expected,
int record)
316 struct timespec wait_time = { .tv_sec = wait_now.tv_sec + 5, .tv_nsec = wait_now.tv_usec * 1000 };
317 enum ast_test_result_state res = AST_TEST_PASS;
319 while (count < record) {
328 ast_test_status_update(test,
"Unable to find actual CDR record at %d\n", count);
329 return AST_TEST_FAIL;
331 actual = cdr_wrapper->cdr;
333 if (!expected && actual) {
334 ast_test_status_update(test,
"CDRs recorded where no record expected\n");
335 return AST_TEST_FAIL;
337 ast_test_debug(test,
"Verifying expected record %s, %s\n",
363 ast_test_debug(test,
"Finished expected record %s, %s\n",
365 expected = expected->next;
371 static void safe_channel_release(
struct ast_channel *chan)
379 static void safe_bridge_destroy(
struct ast_bridge *bridge)
387 static void do_sleep(
struct timespec *
to_sleep)
389 while ((nanosleep(to_sleep, to_sleep) == -1) && (errno == EINTR)) {
401 .
clid =
"\"Alice\" <100>",
404 .dcontext =
"default",
405 .channel = CHANNEL_TECH_NAME
"/Alice",
406 .amaflags = AST_AMA_DOCUMENTATION,
407 .disposition = AST_CDR_NOANSWER,
408 .accountcode =
"100",
410 enum ast_test_result_state result = AST_TEST_NOT_RUN;
414 info->name = __func__;
415 info->category = TEST_CATEGORY;
416 info->summary =
"Test that a CDR is created when a channel is created";
418 "Test that a CDR is created when a channel is created";
419 return AST_TEST_NOT_RUN;
430 result = verify_mock_cdr_record(
test, &expected, 1);
443 .
clid =
"\"Alice\" <100>",
446 .dcontext =
"default",
447 .channel = CHANNEL_TECH_NAME
"/Alice",
450 .amaflags = AST_AMA_DOCUMENTATION,
451 .disposition = AST_CDR_NOANSWER,
452 .accountcode =
"100",
454 enum ast_test_result_state result = AST_TEST_NOT_RUN;
458 info->name = __func__;
459 info->category = TEST_CATEGORY;
460 info->summary =
"Test inbound unanswered calls";
462 "Test the properties of a CDR for a call that is\n"
463 "inbound to Asterisk, executes some dialplan, but\n"
464 "is never answered.";
465 return AST_TEST_NOT_RUN;
478 result = verify_mock_cdr_record(
test, &expected, 1);
493 .id.number.valid = 1, };
497 .dcontext =
"default",
498 .channel = CHANNEL_TECH_NAME
"/Alice",
499 .lastapp =
"AppDial",
500 .lastdata =
"(Outgoing Line)",
501 .amaflags = AST_AMA_DOCUMENTATION,
502 .disposition = AST_CDR_NOANSWER,
503 .accountcode =
"100",
505 enum ast_test_result_state result = AST_TEST_NOT_RUN;
509 info->name = __func__;
510 info->category = TEST_CATEGORY;
511 info->summary =
"Test outbound unanswered calls";
513 "Test the properties of a CDR for a call that is\n"
514 "outbound to Asterisk but is never answered.";
515 return AST_TEST_NOT_RUN;
524 ast_channel_exten_set(chan,
"s");
525 ast_channel_context_set(chan,
"default");
530 result = verify_mock_cdr_record(
test, &expected, 1);
542 struct timespec to_sleep = {1, 0};
543 enum ast_test_result_state result = AST_TEST_NOT_RUN;
546 struct ast_cdr alice_expected = {
547 .
clid =
"\"Alice\" <100>",
550 .dcontext =
"default",
551 .channel = CHANNEL_TECH_NAME
"/Alice",
552 .dstchannel = CHANNEL_TECH_NAME
"/Bob",
555 .amaflags = AST_AMA_DOCUMENTATION,
557 .disposition = AST_CDR_ANSWERED,
558 .accountcode =
"100",
559 .peeraccount =
"200",
561 struct ast_cdr bob_expected = {
565 .dcontext =
"default",
566 .channel = CHANNEL_TECH_NAME
"/Bob",
568 .lastapp =
"AppDial",
569 .lastdata =
"(Outgoing Line)",
570 .amaflags = AST_AMA_DOCUMENTATION,
572 .disposition = AST_CDR_ANSWERED,
573 .accountcode =
"200",
575 .next = &alice_expected,
580 info->name = __func__;
581 info->category = TEST_CATEGORY;
582 info->summary =
"Test dialing, answering, and going into a 2-party bridge";
584 "The most 'basic' of scenarios";
585 return AST_TEST_NOT_RUN;
596 ast_test_validate(
test, bridge != NULL);
601 chan_bob =
ast_channel_alloc(0,
AST_STATE_DOWN, NULL, NULL,
"200", NULL, NULL, NULL, chan_alice, 0, CHANNEL_TECH_NAME
"/Bob");
603 ast_channel_unlock(chan_bob);
628 result = verify_mock_cdr_record(
test, &bob_expected, 2);
641 .
clid =
"\"Alice\" <100>",
644 .dcontext =
"default",
645 .channel = CHANNEL_TECH_NAME
"/Alice",
647 .lastapp =
"VoiceMailMain",
650 .amaflags = AST_AMA_DOCUMENTATION,
651 .disposition = AST_CDR_ANSWERED,
652 .accountcode =
"100",
654 enum ast_test_result_state result = AST_TEST_NOT_RUN;
658 info->name = __func__;
659 info->category = TEST_CATEGORY;
660 info->summary =
"Test cdrs for a single party";
662 "Test the properties of a CDR for a call that is\n"
663 "answered, but only involves a single channel";
664 return AST_TEST_NOT_RUN;
671 ast_channel_lock(chan);
675 ast_channel_unlock(chan);
679 result = verify_mock_cdr_record(
test, &expected, 1);
690 struct timespec to_sleep = {1, 0};
694 .
clid =
"\"Alice\" <100>",
697 .dcontext =
"default",
698 .channel = CHANNEL_TECH_NAME
"/Alice",
701 .amaflags = AST_AMA_DOCUMENTATION,
702 .disposition = AST_CDR_ANSWERED,
703 .accountcode =
"100",
705 enum ast_test_result_state result = AST_TEST_NOT_RUN;
709 info->name = __func__;
710 info->category = TEST_CATEGORY;
711 info->summary =
"Test cdrs for a single party entering/leaving a bridge";
713 "Test the properties of a CDR for a call that is\n"
714 "answered, enters a bridge, and leaves it.";
715 return AST_TEST_NOT_RUN;
722 ast_channel_lock(chan);
726 ast_channel_unlock(chan);
729 ast_test_validate(
test, bridge != NULL);
740 result = verify_mock_cdr_record(
test, &expected, 1);
751 struct timespec to_sleep = {1, 0};
754 struct ast_cdr expected_two = {
755 .
clid =
"\"Alice\" <100>",
758 .dcontext =
"default",
759 .channel = CHANNEL_TECH_NAME
"/Alice",
762 .amaflags = AST_AMA_DOCUMENTATION,
763 .disposition = AST_CDR_ANSWERED,
764 .accountcode =
"100",
766 struct ast_cdr expected_one = {
767 .
clid =
"\"Alice\" <100>",
770 .dcontext =
"default",
771 .channel = CHANNEL_TECH_NAME
"/Alice",
774 .amaflags = AST_AMA_DOCUMENTATION,
775 .disposition = AST_CDR_ANSWERED,
776 .accountcode =
"100",
777 .next = &expected_two,
780 enum ast_test_result_state result = AST_TEST_NOT_RUN;
784 info->name = __func__;
785 info->category = TEST_CATEGORY;
786 info->summary =
"Test cdrs for a single party entering/leaving a bridge";
788 "Test the properties of a CDR for a call that is\n"
789 "answered, enters a bridge, and leaves it.";
790 return AST_TEST_NOT_RUN;
798 ast_channel_lock(chan);
802 ast_channel_unlock(chan);
805 ast_test_validate(
test, bridge != NULL);
819 result = verify_mock_cdr_record(
test, &expected_one, 2);
831 struct timespec to_sleep = {1, 0};
835 struct ast_cdr bob_expected = {
836 .
clid =
"\"Bob\" <200>",
839 .dcontext =
"default",
840 .channel = CHANNEL_TECH_NAME
"/Bob",
843 .amaflags = AST_AMA_DOCUMENTATION,
844 .disposition = AST_CDR_ANSWERED,
845 .accountcode =
"200",
847 struct ast_cdr alice_expected = {
848 .
clid =
"\"Alice\" <100>",
851 .dcontext =
"default",
852 .channel = CHANNEL_TECH_NAME
"/Alice",
853 .dstchannel = CHANNEL_TECH_NAME
"/Bob",
856 .amaflags = AST_AMA_DOCUMENTATION,
857 .disposition = AST_CDR_ANSWERED,
858 .accountcode =
"100",
859 .peeraccount =
"200",
860 .next = &bob_expected,
863 enum ast_test_result_state result = AST_TEST_NOT_RUN;
867 info->name = __func__;
868 info->category = TEST_CATEGORY;
869 info->summary =
"Test cdrs for a single party entering/leaving a bridge";
871 "Test the properties of a CDR for a call that is\n"
872 "answered, enters a bridge, and leaves it. In this scenario, the\n"
873 "Party A should answer the bridge first.";
874 return AST_TEST_NOT_RUN;
884 ast_channel_lock(chan_alice);
888 ast_channel_unlock(chan_alice);
891 ast_test_validate(
test, bridge != NULL);
896 ast_channel_lock(chan_bob);
900 ast_channel_unlock(chan_bob);
911 result = verify_mock_cdr_record(
test, &alice_expected, 2);
923 struct timespec to_sleep = {1, 0};
927 struct ast_cdr bob_expected = {
928 .
clid =
"\"Bob\" <200>",
931 .dcontext =
"default",
932 .channel = CHANNEL_TECH_NAME
"/Bob",
935 .amaflags = AST_AMA_DOCUMENTATION,
936 .disposition = AST_CDR_ANSWERED,
937 .accountcode =
"200",
939 struct ast_cdr alice_expected = {
940 .
clid =
"\"Alice\" <100>",
943 .dcontext =
"default",
944 .channel = CHANNEL_TECH_NAME
"/Alice",
945 .dstchannel = CHANNEL_TECH_NAME
"/Bob",
948 .amaflags = AST_AMA_DOCUMENTATION,
949 .disposition = AST_CDR_ANSWERED,
950 .accountcode =
"100",
951 .peeraccount =
"200",
952 .next = &bob_expected,
955 enum ast_test_result_state result = AST_TEST_NOT_RUN;
959 info->name = __func__;
960 info->category = TEST_CATEGORY;
961 info->summary =
"Test cdrs for a single party entering/leaving a bridge";
963 "Test the properties of a CDR for a call that is\n"
964 "answered, enters a bridge, and leaves it. In this scenario, the\n"
965 "Party B should answer the bridge first.";
966 return AST_TEST_NOT_RUN;
976 ast_channel_unlock(chan_alice);
980 ast_channel_unlock(chan_alice);
983 ast_test_validate(
test, bridge != NULL);
985 ast_channel_lock(chan_bob);
989 ast_channel_unlock(chan_bob);
1004 result = verify_mock_cdr_record(
test, &alice_expected, 2);
1017 struct timespec to_sleep = {1, 0};
1022 struct ast_cdr charlie_expected = {
1023 .
clid =
"\"Charlie\" <300>",
1026 .dcontext =
"default",
1027 .channel = CHANNEL_TECH_NAME
"/Charlie",
1028 .lastapp =
"Bridge",
1030 .amaflags = AST_AMA_DOCUMENTATION,
1031 .disposition = AST_CDR_ANSWERED,
1032 .accountcode =
"300",
1034 struct ast_cdr bob_expected = {
1035 .
clid =
"\"Bob\" <200>",
1038 .dcontext =
"default",
1039 .channel = CHANNEL_TECH_NAME
"/Bob",
1040 .dstchannel = CHANNEL_TECH_NAME
"/Charlie",
1041 .lastapp =
"Bridge",
1043 .amaflags = AST_AMA_DOCUMENTATION,
1044 .disposition = AST_CDR_ANSWERED,
1045 .accountcode =
"200",
1046 .peeraccount =
"300",
1047 .next = &charlie_expected,
1049 struct ast_cdr alice_expected_two = {
1050 .
clid =
"\"Alice\" <100>",
1053 .dcontext =
"default",
1054 .channel = CHANNEL_TECH_NAME
"/Alice",
1055 .dstchannel = CHANNEL_TECH_NAME
"/Charlie",
1056 .lastapp =
"Bridge",
1058 .amaflags = AST_AMA_DOCUMENTATION,
1059 .disposition = AST_CDR_ANSWERED,
1060 .accountcode =
"100",
1061 .peeraccount =
"300",
1062 .next = &bob_expected,
1064 struct ast_cdr alice_expected_one = {
1065 .
clid =
"\"Alice\" <100>",
1068 .dcontext =
"default",
1069 .channel = CHANNEL_TECH_NAME
"/Alice",
1070 .dstchannel = CHANNEL_TECH_NAME
"/Bob",
1071 .lastapp =
"Bridge",
1073 .amaflags = AST_AMA_DOCUMENTATION,
1074 .disposition = AST_CDR_ANSWERED,
1075 .accountcode =
"100",
1076 .peeraccount =
"200",
1077 .next = &alice_expected_two,
1080 enum ast_test_result_state result = AST_TEST_NOT_RUN;
1084 info->name = __func__;
1085 info->category = TEST_CATEGORY;
1086 info->summary =
"Test cdrs for a single party entering/leaving a multi-party bridge";
1088 "Test the properties of a CDR for a call that is\n"
1089 "answered, enters a bridge, and leaves it. A total of three\n"
1090 "parties perform this action.";
1091 return AST_TEST_NOT_RUN;
1097 COPY_IDS(chan_alice, &alice_expected_two);
1103 ast_channel_lock(chan_alice);
1107 ast_channel_unlock(chan_alice);
1110 ast_test_validate(
test, bridge != NULL);
1111 do_sleep(&to_sleep);
1115 ast_channel_lock(chan_bob);
1119 ast_channel_unlock(chan_bob);
1120 do_sleep(&to_sleep);
1124 do_sleep(&to_sleep);
1126 ast_channel_lock(chan_charlie);
1130 ast_channel_unlock(chan_charlie);
1133 do_sleep(&to_sleep);
1143 result = verify_mock_cdr_record(
test, &alice_expected_one, 4);
1157 .
clid =
"\"Alice\" <100>",
1160 .dcontext =
"default",
1161 .channel = CHANNEL_TECH_NAME
"/Alice",
1162 .dstchannel = CHANNEL_TECH_NAME
"/Bob",
1164 .lastdata = CHANNEL_TECH_NAME
"/Bob",
1166 .amaflags = AST_AMA_DOCUMENTATION,
1167 .disposition = AST_CDR_NOANSWER,
1168 .accountcode =
"100",
1169 .peeraccount =
"200",
1171 enum ast_test_result_state result = AST_TEST_NOT_RUN;
1175 info->name = __func__;
1176 info->category = TEST_CATEGORY;
1177 info->summary =
"Test CDRs for a dial that isn't answered";
1179 "Test the properties of a CDR for a channel that\n"
1180 "performs a dial operation that isn't answered";
1181 return AST_TEST_NOT_RUN;
1192 chan_callee =
ast_channel_alloc(0,
AST_STATE_DOWN, NULL, NULL,
"200", NULL, NULL, NULL, chan_caller, 0, CHANNEL_TECH_NAME
"/Bob");
1194 ast_channel_unlock(chan_callee);
1205 result = verify_mock_cdr_record(
test, &expected, 1);
1220 .
clid =
"\"Alice\" <100>",
1223 .dcontext =
"default",
1224 .channel = CHANNEL_TECH_NAME
"/Alice",
1225 .dstchannel = CHANNEL_TECH_NAME
"/Bob",
1227 .lastdata = CHANNEL_TECH_NAME
"/Bob",
1229 .amaflags = AST_AMA_DOCUMENTATION,
1230 .disposition = AST_CDR_BUSY,
1231 .accountcode =
"100",
1232 .peeraccount =
"200",
1234 enum ast_test_result_state result = AST_TEST_NOT_RUN;
1238 info->name = __func__;
1239 info->category = TEST_CATEGORY;
1240 info->summary =
"Test CDRs for a dial that results in a busy";
1242 "Test the properties of a CDR for a channel that\n"
1243 "performs a dial operation to an endpoint that's busy";
1244 return AST_TEST_NOT_RUN;
1255 chan_callee =
ast_channel_alloc(0,
AST_STATE_DOWN, NULL, NULL,
"200", NULL, NULL, NULL, chan_caller, 0, CHANNEL_TECH_NAME
"/Bob");
1257 ast_channel_unlock(chan_callee);
1268 result = verify_mock_cdr_record(
test, &expected, 1);
1282 .
clid =
"\"Alice\" <100>",
1285 .dcontext =
"default",
1286 .channel = CHANNEL_TECH_NAME
"/Alice",
1287 .dstchannel = CHANNEL_TECH_NAME
"/Bob",
1289 .lastdata = CHANNEL_TECH_NAME
"/Bob",
1291 .amaflags = AST_AMA_DOCUMENTATION,
1292 .disposition = AST_CDR_CONGESTION,
1293 .accountcode =
"100",
1294 .peeraccount =
"200",
1296 enum ast_test_result_state result = AST_TEST_NOT_RUN;
1300 info->name = __func__;
1301 info->category = TEST_CATEGORY;
1302 info->summary =
"Test CDRs for a dial that results in congestion";
1304 "Test the properties of a CDR for a channel that\n"
1305 "performs a dial operation to an endpoint that's congested";
1306 return AST_TEST_NOT_RUN;
1317 chan_callee =
ast_channel_alloc(0,
AST_STATE_DOWN, NULL, NULL,
"200", NULL, NULL, NULL, chan_caller, 0, CHANNEL_TECH_NAME
"/Bob");
1319 ast_channel_unlock(chan_callee);
1330 result = verify_mock_cdr_record(
test, &expected, 1);
1344 .
clid =
"\"Alice\" <100>",
1347 .dcontext =
"default",
1348 .channel = CHANNEL_TECH_NAME
"/Alice",
1349 .dstchannel = CHANNEL_TECH_NAME
"/Bob",
1351 .lastdata = CHANNEL_TECH_NAME
"/Bob",
1353 .amaflags = AST_AMA_DOCUMENTATION,
1354 .disposition = AST_CDR_FAILED,
1355 .accountcode =
"100",
1356 .peeraccount =
"200",
1358 enum ast_test_result_state result = AST_TEST_NOT_RUN;
1362 info->name = __func__;
1363 info->category = TEST_CATEGORY;
1364 info->summary =
"Test CDRs for a dial that results in unavailable";
1366 "Test the properties of a CDR for a channel that\n"
1367 "performs a dial operation to an endpoint that's unavailable";
1368 return AST_TEST_NOT_RUN;
1379 chan_callee =
ast_channel_alloc(0,
AST_STATE_DOWN, NULL, NULL,
"200", NULL, NULL, NULL, chan_caller, 0, CHANNEL_TECH_NAME
"/Bob");
1381 ast_channel_unlock(chan_callee);
1392 result = verify_mock_cdr_record(
test, &expected, 1);
1406 .
clid =
"\"Alice\" <100>",
1409 .dcontext =
"default",
1410 .channel = CHANNEL_TECH_NAME
"/Alice",
1411 .dstchannel = CHANNEL_TECH_NAME
"/Bob",
1413 .lastdata = CHANNEL_TECH_NAME
"/Bob",
1415 .amaflags = AST_AMA_DOCUMENTATION,
1416 .disposition = AST_CDR_NOANSWER,
1417 .accountcode =
"100",
1418 .peeraccount =
"200",
1420 enum ast_test_result_state result = AST_TEST_NOT_RUN;
1424 info->name = __func__;
1425 info->category = TEST_CATEGORY;
1426 info->summary =
"Test CDRs for a dial where the caller cancels";
1428 "Test the properties of a CDR for a channel that\n"
1429 "performs a dial operation to an endpoint but then decides\n"
1430 "to hang up, cancelling the dial";
1431 return AST_TEST_NOT_RUN;
1442 chan_callee =
ast_channel_alloc(0,
AST_STATE_DOWN, NULL, NULL,
"200", NULL, NULL, NULL, chan_caller, 0, CHANNEL_TECH_NAME
"/Bob");
1444 ast_channel_unlock(chan_callee);
1455 result = verify_mock_cdr_record(
test, &expected, 1);
1470 struct ast_cdr bob_expected = {
1471 .
clid =
"\"Alice\" <100>",
1474 .dcontext =
"default",
1475 .channel = CHANNEL_TECH_NAME
"/Alice",
1476 .dstchannel = CHANNEL_TECH_NAME
"/Bob",
1478 .lastdata = CHANNEL_TECH_NAME
"/Bob&" CHANNEL_TECH_NAME
"/Charlie&" CHANNEL_TECH_NAME
"/David",
1480 .amaflags = AST_AMA_DOCUMENTATION,
1481 .disposition = AST_CDR_NOANSWER,
1482 .accountcode =
"100",
1483 .peeraccount =
"200",
1485 struct ast_cdr charlie_expected = {
1486 .
clid =
"\"Alice\" <100>",
1489 .dcontext =
"default",
1490 .channel = CHANNEL_TECH_NAME
"/Alice",
1491 .dstchannel = CHANNEL_TECH_NAME
"/Charlie",
1493 .lastdata = CHANNEL_TECH_NAME
"/Bob&" CHANNEL_TECH_NAME
"/Charlie&" CHANNEL_TECH_NAME
"/David",
1495 .amaflags = AST_AMA_DOCUMENTATION,
1496 .disposition = AST_CDR_BUSY,
1497 .accountcode =
"100",
1498 .peeraccount =
"300",
1500 struct ast_cdr david_expected = {
1501 .
clid =
"\"Alice\" <100>",
1504 .dcontext =
"default",
1505 .channel = CHANNEL_TECH_NAME
"/Alice",
1506 .dstchannel = CHANNEL_TECH_NAME
"/David",
1508 .lastdata = CHANNEL_TECH_NAME
"/Bob&" CHANNEL_TECH_NAME
"/Charlie&" CHANNEL_TECH_NAME
"/David",
1510 .amaflags = AST_AMA_DOCUMENTATION,
1511 .disposition = AST_CDR_CONGESTION,
1512 .accountcode =
"100",
1513 .peeraccount =
"400",
1515 enum ast_test_result_state result = AST_TEST_NOT_RUN;
1517 struct ast_cdr *expected = &bob_expected;
1518 bob_expected.next = &charlie_expected;
1519 charlie_expected.next = &david_expected;
1523 info->name = __func__;
1524 info->category = TEST_CATEGORY;
1525 info->summary =
"Test a parallel dial where all channels fail to answer";
1527 "This tests dialing three parties: Bob, Charlie, David. Charlie\n"
1528 "returns BUSY; David returns CONGESTION; Bob fails to answer and\n"
1529 "Alice hangs up. Three records are created for Alice as a result.";
1530 return AST_TEST_NOT_RUN;
1538 COPY_IDS(chan_caller, &charlie_expected);
1539 COPY_IDS(chan_caller, &david_expected);
1542 EMULATE_APP_DATA(chan_caller, 1,
"Dial", CHANNEL_TECH_NAME
"/Bob&" CHANNEL_TECH_NAME
"/Charlie&" CHANNEL_TECH_NAME
"/David");
1545 chan_bob =
ast_channel_alloc(0,
AST_STATE_DOWN, NULL, NULL,
"200", NULL, NULL, NULL, chan_caller, 0, CHANNEL_TECH_NAME
"/Bob");
1547 ast_channel_unlock(chan_bob);
1551 chan_charlie =
ast_channel_alloc(0,
AST_STATE_DOWN, NULL, NULL,
"300", NULL, NULL, NULL, chan_caller, 0, CHANNEL_TECH_NAME
"/Charlie");
1553 ast_channel_unlock(chan_charlie);
1557 chan_david =
ast_channel_alloc(0,
AST_STATE_DOWN, NULL, NULL,
"400", NULL, NULL, NULL, chan_caller, 0, CHANNEL_TECH_NAME
"/David");
1559 ast_channel_unlock(chan_david);
1584 result = verify_mock_cdr_record(
test, expected, 3);
1597 struct ast_cdr bob_expected_one = {
1601 .dcontext =
"default",
1602 .channel = CHANNEL_TECH_NAME
"/Bob",
1605 .amaflags = AST_AMA_DOCUMENTATION,
1606 .disposition = AST_CDR_ANSWERED,
1607 .accountcode =
"200",
1609 struct ast_cdr alice_expected_two = {
1610 .
clid =
"\"Alice\" <100>",
1613 .dcontext =
"default",
1614 .channel = CHANNEL_TECH_NAME
"/Alice",
1617 .amaflags = AST_AMA_DOCUMENTATION,
1618 .disposition = AST_CDR_ANSWERED,
1619 .accountcode =
"100",
1620 .next = &bob_expected_one,
1622 struct ast_cdr alice_expected_one = {
1623 .
clid =
"\"Alice\" <100>",
1626 .dcontext =
"default",
1627 .channel = CHANNEL_TECH_NAME
"/Alice",
1628 .dstchannel = CHANNEL_TECH_NAME
"/Bob",
1630 .lastdata = CHANNEL_TECH_NAME
"/Bob",
1631 .amaflags = AST_AMA_DOCUMENTATION,
1632 .disposition = AST_CDR_ANSWERED,
1633 .accountcode =
"100",
1634 .peeraccount =
"200",
1635 .next = &alice_expected_two,
1637 enum ast_test_result_state result = AST_TEST_NOT_RUN;
1641 info->name = __func__;
1642 info->category = TEST_CATEGORY;
1643 info->summary =
"Test dialing, answering, and not going into a bridge.";
1645 "This is a weird one, but theoretically possible. You can perform\n"
1646 "a dial, then bounce both channels to different priorities and\n"
1647 "never have them enter a bridge together. Ew. This makes sure that\n"
1648 "when we answer, we get a CDR, it gets ended at that point, and\n"
1649 "that it gets finalized appropriately. We should get three CDRs in\n"
1650 "the end - one for the dial, and one for each CDR as they continued\n"
1652 return AST_TEST_NOT_RUN;
1660 COPY_IDS(chan_caller, &alice_expected_two);
1664 chan_callee =
ast_channel_alloc(0,
AST_STATE_DOWN, NULL, NULL,
"200", NULL, NULL, NULL, chan_caller, 0, CHANNEL_TECH_NAME
"/Bob");
1666 ast_channel_unlock(chan_callee);
1668 COPY_IDS(chan_callee, &bob_expected_one);
1684 result = verify_mock_cdr_record(
test, &alice_expected_one, 3);
1695 struct timespec to_sleep = {1, 0};
1696 enum ast_test_result_state result = AST_TEST_NOT_RUN;
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";
1722 return AST_TEST_NOT_RUN;
1733 chan_callee =
ast_channel_alloc(0,
AST_STATE_DOWN, NULL, NULL,
"200", NULL, NULL, NULL, chan_caller, 0, CHANNEL_TECH_NAME
"/Bob");
1735 ast_channel_unlock(chan_callee);
1747 ast_test_validate(
test, bridge != NULL);
1748 do_sleep(&to_sleep);
1753 do_sleep(&to_sleep);
1761 result = verify_mock_cdr_record(
test, &expected, 1);
1772 struct timespec to_sleep = {1, 0};
1773 enum ast_test_result_state result = AST_TEST_NOT_RUN;
1777 .
clid =
"\"Alice\" <100>",
1780 .dcontext =
"default",
1781 .channel = CHANNEL_TECH_NAME
"/Alice",
1782 .dstchannel = CHANNEL_TECH_NAME
"/Bob",
1784 .lastdata = CHANNEL_TECH_NAME
"/Bob",
1785 .amaflags = AST_AMA_DOCUMENTATION,
1787 .disposition = AST_CDR_ANSWERED,
1788 .accountcode =
"100",
1789 .peeraccount =
"200",
1794 info->name = __func__;
1795 info->category = TEST_CATEGORY;
1796 info->summary =
"Test dialing, answering, and going into a 2-party bridge";
1798 "The most 'basic' of scenarios";
1799 return AST_TEST_NOT_RUN;
1810 chan_callee =
ast_channel_alloc(0,
AST_STATE_DOWN, NULL, NULL,
"200", NULL, NULL, NULL, chan_caller, 0, CHANNEL_TECH_NAME
"/Bob");
1812 ast_channel_unlock(chan_callee);
1824 ast_test_validate(
test, bridge != NULL);
1825 do_sleep(&to_sleep);
1827 do_sleep(&to_sleep);
1829 do_sleep(&to_sleep);
1836 result = verify_mock_cdr_record(
test, &expected, 1);
1849 struct timespec to_sleep = {1, 0};
1850 enum ast_test_result_state result = AST_TEST_NOT_RUN;
1854 struct ast_cdr charlie_expected_two = {
1855 .
clid =
"\"Charlie\" <300>",
1858 .dcontext =
"default",
1859 .channel = CHANNEL_TECH_NAME
"/Charlie",
1860 .dstchannel = CHANNEL_TECH_NAME
"/Bob",
1862 .lastdata = CHANNEL_TECH_NAME
"/David",
1863 .amaflags = AST_AMA_DOCUMENTATION,
1865 .disposition = AST_CDR_ANSWERED,
1866 .accountcode =
"300",
1867 .peeraccount =
"200",
1869 struct ast_cdr charlie_expected_one = {
1870 .
clid =
"\"Charlie\" <300>",
1873 .dcontext =
"default",
1874 .channel = CHANNEL_TECH_NAME
"/Charlie",
1875 .dstchannel = CHANNEL_TECH_NAME
"/David",
1877 .lastdata = CHANNEL_TECH_NAME
"/David",
1878 .amaflags = AST_AMA_DOCUMENTATION,
1880 .disposition = AST_CDR_ANSWERED,
1881 .accountcode =
"300",
1882 .peeraccount =
"400",
1883 .next = &charlie_expected_two,
1885 struct ast_cdr bob_expected_one = {
1886 .
clid =
"\"Bob\" <200>",
1889 .dcontext =
"default",
1890 .channel = CHANNEL_TECH_NAME
"/Bob",
1891 .dstchannel = CHANNEL_TECH_NAME
"/David",
1892 .lastapp =
"AppDial",
1893 .lastdata =
"(Outgoing Line)",
1894 .amaflags = AST_AMA_DOCUMENTATION,
1896 .disposition = AST_CDR_ANSWERED,
1897 .accountcode =
"200",
1898 .peeraccount =
"400",
1899 .next = &charlie_expected_one,
1901 struct ast_cdr alice_expected_three = {
1902 .
clid =
"\"Alice\" <100>",
1905 .dcontext =
"default",
1906 .channel = CHANNEL_TECH_NAME
"/Alice",
1907 .dstchannel = CHANNEL_TECH_NAME
"/David",
1909 .lastdata = CHANNEL_TECH_NAME
"/Bob",
1910 .amaflags = AST_AMA_DOCUMENTATION,
1912 .disposition = AST_CDR_ANSWERED,
1913 .accountcode =
"100",
1914 .peeraccount =
"400",
1915 .next = &bob_expected_one,
1917 struct ast_cdr alice_expected_two = {
1918 .
clid =
"\"Alice\" <100>",
1921 .dcontext =
"default",
1922 .channel = CHANNEL_TECH_NAME
"/Alice",
1923 .dstchannel = CHANNEL_TECH_NAME
"/Charlie",
1925 .lastdata = CHANNEL_TECH_NAME
"/Bob",
1926 .amaflags = AST_AMA_DOCUMENTATION,
1928 .disposition = AST_CDR_ANSWERED,
1929 .accountcode =
"100",
1930 .peeraccount =
"300",
1931 .next = &alice_expected_three,
1933 struct ast_cdr alice_expected_one = {
1934 .
clid =
"\"Alice\" <100>",
1937 .dcontext =
"default",
1938 .channel = CHANNEL_TECH_NAME
"/Alice",
1939 .dstchannel = CHANNEL_TECH_NAME
"/Bob",
1941 .lastdata = CHANNEL_TECH_NAME
"/Bob",
1942 .amaflags = AST_AMA_DOCUMENTATION,
1944 .disposition = AST_CDR_ANSWERED,
1945 .accountcode =
"100",
1946 .peeraccount =
"200",
1947 .next = &alice_expected_two,
1952 info->name = __func__;
1953 info->category = TEST_CATEGORY;
1954 info->summary =
"Test dialing, answering, and going into a multi-party bridge";
1956 "A little tricky to get to do, but possible with some redirects.";
1957 return AST_TEST_NOT_RUN;
1965 COPY_IDS(chan_alice, &alice_expected_two);
1966 COPY_IDS(chan_alice, &alice_expected_three);
1970 chan_bob =
ast_channel_alloc(0,
AST_STATE_DOWN,
"200",
"Bob",
"200",
"200",
"default", NULL, NULL, 0, CHANNEL_TECH_NAME
"/Bob");
1972 ast_channel_unlock(chan_bob);
1985 chan_david =
ast_channel_alloc(0,
AST_STATE_DOWN,
"400",
"David",
"400",
"400",
"default", NULL, NULL, 0, CHANNEL_TECH_NAME
"/David");
1987 ast_channel_unlock(chan_david);
2004 ast_test_validate(
test, bridge != NULL);
2006 do_sleep(&to_sleep);
2008 do_sleep(&to_sleep);
2010 do_sleep(&to_sleep);
2012 do_sleep(&to_sleep);
2014 do_sleep(&to_sleep);
2025 result = verify_mock_cdr_record(
test, &alice_expected_one, 6);
2037 struct timespec to_sleep = {1, 0};
2041 struct ast_cdr bob_expected = {
2042 .
clid =
"\"Bob\" <200>",
2045 .dcontext =
"default",
2046 .channel = CHANNEL_TECH_NAME
"/Bob",
2050 .amaflags = AST_AMA_DOCUMENTATION,
2051 .disposition = AST_CDR_ANSWERED,
2052 .accountcode =
"200",
2054 struct ast_cdr alice_expected = {
2055 .
clid =
"\"Alice\" <100>",
2058 .dcontext =
"default",
2059 .channel = CHANNEL_TECH_NAME
"/Alice",
2063 .amaflags = AST_AMA_DOCUMENTATION,
2064 .disposition = AST_CDR_ANSWERED,
2065 .accountcode =
"100",
2066 .next = &bob_expected,
2068 enum ast_test_result_state result = AST_TEST_NOT_RUN;
2072 info->name = __func__;
2073 info->category = TEST_CATEGORY;
2074 info->summary =
"Test cdrs for a single party entering Park";
2076 "Test the properties of a CDR for calls that are\n"
2077 "answered, enters Park, and leaves it.";
2078 return AST_TEST_NOT_RUN;
2086 ast_channel_lock(chan_alice);
2089 ast_channel_unlock(chan_alice);
2091 ast_channel_lock(chan_bob);
2094 ast_channel_unlock(chan_bob);
2099 "test_cdr",
"test_cdr_park", NULL);
2100 ast_test_validate(
test, bridge != NULL);
2102 do_sleep(&to_sleep);
2104 do_sleep(&to_sleep);
2106 do_sleep(&to_sleep);
2114 result = verify_mock_cdr_record(
test, &alice_expected, 2);
2125 char varbuffer[128];
2128 struct timespec to_sleep = {2, 0};
2133 .
clid =
"\"Alice\" <100>",
2136 .dcontext =
"default",
2137 .channel = CHANNEL_TECH_NAME
"/Alice",
2141 .amaflags = AST_AMA_OMIT,
2142 .disposition = AST_CDR_FAILED,
2143 .accountcode =
"XXX",
2144 .userfield =
"yackity",
2146 struct ast_cdr fork_expected_one = {
2147 .
clid =
"\"Alice\" <100>",
2150 .dcontext =
"default",
2151 .channel = CHANNEL_TECH_NAME
"/Alice",
2155 .amaflags = AST_AMA_OMIT,
2156 .disposition = AST_CDR_FAILED,
2157 .accountcode =
"XXX",
2158 .userfield =
"yackity",
2160 struct ast_cdr fork_expected_two = {
2161 .
clid =
"\"Alice\" <100>",
2164 .dcontext =
"default",
2165 .channel = CHANNEL_TECH_NAME
"/Alice",
2166 .lastapp =
"Answer",
2168 .amaflags = AST_AMA_OMIT,
2169 .disposition = AST_CDR_ANSWERED,
2170 .accountcode =
"ZZZ",
2171 .userfield =
"schmackity",
2173 enum ast_test_result_state result = AST_TEST_NOT_RUN;
2175 struct ast_cdr *expected = &original;
2176 original.next = &fork_expected_one;
2177 fork_expected_one.next = &fork_expected_two;
2181 info->name = __func__;
2182 info->category = TEST_CATEGORY;
2183 info->summary =
"Test field access CDRs";
2185 "This tests setting/retrieving data on CDR records.";
2186 return AST_TEST_NOT_RUN;
2200 ast_channel_lock(chan);
2201 ast_channel_appl_set(chan,
"Wait");
2202 ast_channel_data_set(chan,
"10");
2203 ast_channel_priority_set(chan, 1);
2208 ast_channel_accountcode_set(chan,
"XXX");
2209 ast_channel_unlock(chan);
2212 do_sleep(&to_sleep);
2215 ast_test_validate(
test,
ast_cdr_setvar(ast_channel_name(chan),
"test_variable",
"record_1") == 0);
2218 ast_test_validate(
test,
ast_cdr_setvar(ast_channel_name(chan),
"clid",
"junk") != 0);
2221 ast_test_validate(
test,
ast_cdr_setvar(ast_channel_name(chan),
"dcontext",
"junk") != 0);
2222 ast_test_validate(
test,
ast_cdr_setvar(ast_channel_name(chan),
"channel",
"junk") != 0);
2223 ast_test_validate(
test,
ast_cdr_setvar(ast_channel_name(chan),
"dstchannel",
"junk") != 0);
2224 ast_test_validate(
test,
ast_cdr_setvar(ast_channel_name(chan),
"lastapp",
"junk") != 0);
2225 ast_test_validate(
test,
ast_cdr_setvar(ast_channel_name(chan),
"lastdata",
"junk") != 0);
2226 ast_test_validate(
test,
ast_cdr_setvar(ast_channel_name(chan),
"start",
"junk") != 0);
2227 ast_test_validate(
test,
ast_cdr_setvar(ast_channel_name(chan),
"answer",
"junk") != 0);
2229 ast_test_validate(
test,
ast_cdr_setvar(ast_channel_name(chan),
"duration",
"junk") != 0);
2230 ast_test_validate(
test,
ast_cdr_setvar(ast_channel_name(chan),
"billsec",
"junk") != 0);
2231 ast_test_validate(
test,
ast_cdr_setvar(ast_channel_name(chan),
"disposition",
"junk") != 0);
2232 ast_test_validate(
test,
ast_cdr_setvar(ast_channel_name(chan),
"amaflags",
"junk") != 0);
2233 ast_test_validate(
test,
ast_cdr_setvar(ast_channel_name(chan),
"accountcode",
"junk") != 0);
2234 ast_test_validate(
test,
ast_cdr_setvar(ast_channel_name(chan),
"uniqueid",
"junk") != 0);
2235 ast_test_validate(
test,
ast_cdr_setvar(ast_channel_name(chan),
"linkedid",
"junk") != 0);
2236 ast_test_validate(
test,
ast_cdr_setvar(ast_channel_name(chan),
"userfield",
"junk") != 0);
2237 ast_test_validate(
test,
ast_cdr_setvar(ast_channel_name(chan),
"sequence",
"junk") != 0);
2240 ast_test_validate(
test,
ast_cdr_getvar(ast_channel_name(chan),
"userfield", varbuffer,
sizeof(varbuffer)) == 0);
2241 ast_test_validate(
test, strcmp(varbuffer,
"foobar") == 0);
2242 ast_test_validate(
test,
ast_cdr_getvar(ast_channel_name(chan),
"test_variable", varbuffer,
sizeof(varbuffer)) == 0);
2243 ast_test_validate(
test, strcmp(varbuffer,
"record_1") == 0);
2244 ast_test_validate(
test,
ast_cdr_getvar(ast_channel_name(chan),
"amaflags", varbuffer,
sizeof(varbuffer)) == 0);
2245 sscanf(varbuffer,
"%d", &int_buffer);
2246 ast_test_validate(
test, int_buffer == AST_AMA_OMIT);
2247 ast_test_validate(
test,
ast_cdr_getvar(ast_channel_name(chan),
"accountcode", varbuffer,
sizeof(varbuffer)) == 0);
2248 ast_test_validate(
test, strcmp(varbuffer,
"XXX") == 0);
2249 ast_test_validate(
test,
ast_cdr_getvar(ast_channel_name(chan),
"clid", varbuffer,
sizeof(varbuffer)) == 0);
2250 ast_test_validate(
test, strcmp(varbuffer,
"\"Alice\" <100>") == 0);
2251 ast_test_validate(
test,
ast_cdr_getvar(ast_channel_name(chan),
"src", varbuffer,
sizeof(varbuffer)) == 0);
2252 ast_test_validate(
test, strcmp(varbuffer,
"100") == 0);
2253 ast_test_validate(
test,
ast_cdr_getvar(ast_channel_name(chan),
"dst", varbuffer,
sizeof(varbuffer)) == 0);
2254 ast_test_validate(
test, strcmp(varbuffer,
"100") == 0);
2255 ast_test_validate(
test,
ast_cdr_getvar(ast_channel_name(chan),
"dcontext", varbuffer,
sizeof(varbuffer)) == 0);
2256 ast_test_validate(
test, strcmp(varbuffer,
"default") == 0);
2257 ast_test_validate(
test,
ast_cdr_getvar(ast_channel_name(chan),
"channel", varbuffer,
sizeof(varbuffer)) == 0);
2258 ast_test_validate(
test, strcmp(varbuffer, CHANNEL_TECH_NAME
"/Alice") == 0);
2259 ast_test_validate(
test,
ast_cdr_getvar(ast_channel_name(chan),
"dstchannel", varbuffer,
sizeof(varbuffer)) == 0);
2260 ast_test_validate(
test, strcmp(varbuffer,
"") == 0);
2261 ast_test_validate(
test,
ast_cdr_getvar(ast_channel_name(chan),
"lastapp", varbuffer,
sizeof(varbuffer)) == 0);
2262 ast_test_validate(
test, strcmp(varbuffer,
"Wait") == 0);
2263 ast_test_validate(
test,
ast_cdr_getvar(ast_channel_name(chan),
"lastdata", varbuffer,
sizeof(varbuffer)) == 0);
2264 ast_test_validate(
test, strcmp(varbuffer,
"10") == 0);
2265 ast_test_validate(
test,
ast_cdr_getvar(ast_channel_name(chan),
"start", varbuffer,
sizeof(varbuffer)) == 0);
2266 sscanf(varbuffer,
"%lf", &db_buffer);
2267 ast_test_validate(
test, fabs(db_buffer) > 0);
2268 ast_test_validate(
test,
ast_cdr_getvar(ast_channel_name(chan),
"answer", varbuffer,
sizeof(varbuffer)) == 0);
2269 sscanf(varbuffer,
"%lf", &db_buffer);
2270 ast_test_validate(
test, fabs(db_buffer) < EPSILON);
2271 ast_test_validate(
test,
ast_cdr_getvar(ast_channel_name(chan),
"end", varbuffer,
sizeof(varbuffer)) == 0);
2272 sscanf(varbuffer,
"%lf", &db_buffer);
2273 ast_test_validate(
test, fabs(db_buffer) < EPSILON);
2274 ast_test_validate(
test,
ast_cdr_getvar(ast_channel_name(chan),
"duration", varbuffer,
sizeof(varbuffer)) == 0);
2275 sscanf(varbuffer,
"%lf", &db_buffer);
2276 ast_test_validate(
test, fabs(db_buffer) > 0);
2277 ast_test_validate(
test,
ast_cdr_getvar(ast_channel_name(chan),
"billsec", varbuffer,
sizeof(varbuffer)) == 0);
2278 sscanf(varbuffer,
"%lf", &db_buffer);
2279 ast_test_validate(
test, fabs(db_buffer) < EPSILON);
2280 ast_test_validate(
test,
ast_cdr_getvar(ast_channel_name(chan),
"disposition", varbuffer,
sizeof(varbuffer)) == 0);
2281 sscanf(varbuffer,
"%d", &int_buffer);
2282 ast_test_validate(
test, int_buffer == AST_CDR_NULL);
2283 ast_test_validate(
test,
ast_cdr_getvar(ast_channel_name(chan),
"uniqueid", varbuffer,
sizeof(varbuffer)) == 0);
2284 ast_test_validate(
test, strcmp(varbuffer, ast_channel_uniqueid(chan)) == 0);
2285 ast_test_validate(
test,
ast_cdr_getvar(ast_channel_name(chan),
"linkedid", varbuffer,
sizeof(varbuffer)) == 0);
2286 ast_test_validate(
test, strcmp(varbuffer, ast_channel_linkedid(chan)) == 0);
2287 ast_test_validate(
test,
ast_cdr_getvar(ast_channel_name(chan),
"sequence", varbuffer,
sizeof(varbuffer)) == 0);
2291 ast_test_validate(
test,
ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
2295 ast_test_validate(
test,
ast_cdr_setvar(ast_channel_name(chan),
"test_variable",
"record_1b") == 0);
2299 ast_test_validate(
test,
ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
2302 ast_channel_lock(chan);
2303 ast_channel_appl_set(chan,
"Answer");
2304 ast_channel_data_set(chan,
"");
2305 ast_channel_priority_set(chan, 1);
2310 ast_channel_accountcode_set(chan,
"ZZZ");
2311 ast_channel_unlock(chan);
2313 ast_test_validate(
test,
ast_cdr_setvar(ast_channel_name(chan),
"test_variable",
"record_2") == 0);
2316 ast_channel_hangupcause_set(chan, AST_CAUSE_NORMAL);
2319 result = verify_mock_cdr_record(
test, expected, 3);
2330 struct timespec to_sleep = {1, 0};
2334 .
clid =
"\"Alice\" <100>",
2337 .dcontext =
"default",
2338 .channel = CHANNEL_TECH_NAME
"/Alice",
2340 .amaflags = AST_AMA_DOCUMENTATION,
2341 .disposition = AST_CDR_FAILED,
2342 .accountcode =
"100",
2344 enum ast_test_result_state result = AST_TEST_NOT_RUN;
2348 info->name = __func__;
2349 info->category = TEST_CATEGORY;
2350 info->summary =
"Test field access CDRs";
2352 "This tests setting/retrieving data on CDR records.";
2353 return AST_TEST_NOT_RUN;
2362 do_sleep(&to_sleep);
2369 ast_test_validate(
test,
ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
2376 ast_test_validate(
test,
ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
2382 ast_test_validate(
test,
ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
2383 ast_test_validate(
test,
ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
2384 ast_test_validate(
test,
ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
2386 ast_channel_hangupcause_set(chan, AST_CAUSE_NORMAL);
2389 result = verify_mock_cdr_record(
test, &expected, 1);
2399 char varbuffer[128];
2400 char fork_varbuffer[128];
2401 char answer_time[128];
2402 char fork_answer_time[128];
2403 char start_time[128];
2404 char fork_start_time[128];
2406 struct timespec to_sleep = {1, 10000};
2410 .
clid =
"\"Alice\" <100>",
2413 .dcontext =
"default",
2414 .channel = CHANNEL_TECH_NAME
"/Alice",
2415 .amaflags = AST_AMA_DOCUMENTATION,
2416 .disposition = AST_CDR_ANSWERED,
2417 .accountcode =
"100",
2419 struct ast_cdr fork_expected_one = {
2420 .
clid =
"\"Alice\" <100>",
2423 .dcontext =
"default",
2424 .channel = CHANNEL_TECH_NAME
"/Alice",
2425 .amaflags = AST_AMA_DOCUMENTATION,
2426 .disposition = AST_CDR_ANSWERED,
2427 .accountcode =
"100",
2429 struct ast_cdr fork_expected_two = {
2430 .
clid =
"\"Alice\" <100>",
2433 .dcontext =
"default",
2434 .channel = CHANNEL_TECH_NAME
"/Alice",
2435 .amaflags = AST_AMA_DOCUMENTATION,
2436 .disposition = AST_CDR_ANSWERED,
2437 .accountcode =
"100",
2439 enum ast_test_result_state result = AST_TEST_NOT_RUN;
2440 struct ast_cdr *expected = &original;
2441 original.next = &fork_expected_one;
2442 fork_expected_one.next = &fork_expected_two;
2446 info->name = __func__;
2447 info->category = TEST_CATEGORY;
2448 info->summary =
"Test field access CDRs";
2450 "This tests setting/retrieving data on CDR records.";
2451 return AST_TEST_NOT_RUN;
2464 do_sleep(&to_sleep);
2467 ast_test_validate(
test,
ast_cdr_setvar(ast_channel_name(chan),
"test_variable",
"record_1") == 0);
2468 ast_test_validate(
test,
ast_cdr_getvar(ast_channel_name(chan),
"test_variable", varbuffer,
sizeof(varbuffer)) == 0);
2469 ast_test_validate(
test, strcmp(varbuffer,
"record_1") == 0);
2472 ast_test_validate(
test,
ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
2473 ast_test_validate(
test,
ast_cdr_getvar(ast_channel_name(chan),
"test_variable", fork_varbuffer,
sizeof(fork_varbuffer)) == 0);
2474 ast_test_validate(
test, strcmp(varbuffer,
"record_1") != 0);
2478 ast_test_validate(
test,
ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
2481 ast_channel_lock(chan);
2483 ast_channel_unlock(chan);
2484 do_sleep(&to_sleep);
2485 ast_test_validate(
test,
ast_cdr_setvar(ast_channel_name(chan),
"test_variable",
"record_2") == 0);
2486 ast_test_validate(
test,
ast_cdr_getvar(ast_channel_name(chan),
"test_variable", varbuffer,
sizeof(varbuffer)) == 0);
2487 ast_test_validate(
test, strcmp(varbuffer,
"record_2") == 0);
2488 ast_test_validate(
test,
ast_cdr_getvar(ast_channel_name(chan),
"answer", answer_time,
sizeof(answer_time)) == 0);
2489 ast_test_validate(
test,
ast_cdr_getvar(ast_channel_name(chan),
"start", start_time,
sizeof(start_time)) == 0);
2494 ast_test_validate(
test,
ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
2495 ast_test_validate(
test,
ast_cdr_getvar(ast_channel_name(chan),
"answer", fork_answer_time,
sizeof(fork_answer_time)) == 0);
2496 ast_test_validate(
test,
ast_cdr_getvar(ast_channel_name(chan),
"start", fork_start_time,
sizeof(fork_start_time)) == 0);
2497 ast_test_validate(
test,
ast_cdr_getvar(ast_channel_name(chan),
"test_variable", fork_varbuffer,
sizeof(fork_varbuffer)) == 0);
2498 ast_test_validate(
test, strcmp(fork_varbuffer, varbuffer) == 0);
2499 ast_test_validate(
test, strcmp(fork_start_time, start_time) == 0);
2500 ast_test_validate(
test, strcmp(fork_answer_time, answer_time) != 0);
2504 ast_test_validate(
test,
ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
2505 ast_test_validate(
test,
ast_cdr_getvar(ast_channel_name(chan),
"answer", fork_answer_time,
sizeof(fork_answer_time)) == 0);
2506 ast_test_validate(
test,
ast_cdr_getvar(ast_channel_name(chan),
"start", fork_start_time,
sizeof(fork_start_time)) == 0);
2507 ast_test_validate(
test, strcmp(fork_start_time, start_time) != 0);
2508 ast_test_validate(
test, strcmp(fork_answer_time, answer_time) != 0);
2510 ast_channel_hangupcause_set(chan, AST_CAUSE_NORMAL);
2513 result = verify_mock_cdr_record(
test, expected, 3);
2526 clear_mock_cdr_backend();
2534 static int test_cdr_cleanup_cb(
struct ast_test_info *info,
struct ast_test *
test)
2538 ao2_cleanup(saved_config);
2539 saved_config = NULL;
2540 clear_mock_cdr_backend();
2546 static int unload_module(
void)
2548 AST_TEST_UNREGISTER(test_cdr_channel_creation);
2549 AST_TEST_UNREGISTER(test_cdr_unanswered_inbound_call);
2550 AST_TEST_UNREGISTER(test_cdr_unanswered_outbound_call);
2552 AST_TEST_UNREGISTER(test_cdr_single_party);
2553 AST_TEST_UNREGISTER(test_cdr_single_bridge);
2554 AST_TEST_UNREGISTER(test_cdr_single_bridge_continue);
2555 AST_TEST_UNREGISTER(test_cdr_single_twoparty_bridge_a);
2556 AST_TEST_UNREGISTER(test_cdr_single_twoparty_bridge_b);
2557 AST_TEST_UNREGISTER(test_cdr_single_multiparty_bridge);
2559 AST_TEST_UNREGISTER(test_cdr_outbound_bridged_call);
2561 AST_TEST_UNREGISTER(test_cdr_dial_unanswered);
2562 AST_TEST_UNREGISTER(test_cdr_dial_congestion);
2563 AST_TEST_UNREGISTER(test_cdr_dial_busy);
2564 AST_TEST_UNREGISTER(test_cdr_dial_unavailable);
2565 AST_TEST_UNREGISTER(test_cdr_dial_caller_cancel);
2566 AST_TEST_UNREGISTER(test_cdr_dial_parallel_failed);
2567 AST_TEST_UNREGISTER(test_cdr_dial_answer_no_bridge);
2568 AST_TEST_UNREGISTER(test_cdr_dial_answer_twoparty_bridge_a);
2569 AST_TEST_UNREGISTER(test_cdr_dial_answer_twoparty_bridge_b);
2570 AST_TEST_UNREGISTER(test_cdr_dial_answer_multiparty);
2572 AST_TEST_UNREGISTER(test_cdr_park);
2574 AST_TEST_UNREGISTER(test_cdr_fields);
2575 AST_TEST_UNREGISTER(test_cdr_no_reset_cdr);
2576 AST_TEST_UNREGISTER(test_cdr_fork_cdr);
2580 clear_mock_cdr_backend();
2585 static int load_module(
void)
2589 AST_TEST_REGISTER(test_cdr_channel_creation);
2590 AST_TEST_REGISTER(test_cdr_unanswered_inbound_call);
2591 AST_TEST_REGISTER(test_cdr_unanswered_outbound_call);
2593 AST_TEST_REGISTER(test_cdr_single_party);
2594 AST_TEST_REGISTER(test_cdr_single_bridge);
2595 AST_TEST_REGISTER(test_cdr_single_bridge_continue);
2596 AST_TEST_REGISTER(test_cdr_single_twoparty_bridge_a);
2597 AST_TEST_REGISTER(test_cdr_single_twoparty_bridge_b);
2598 AST_TEST_REGISTER(test_cdr_single_multiparty_bridge);
2600 AST_TEST_REGISTER(test_cdr_outbound_bridged_call);
2602 AST_TEST_REGISTER(test_cdr_dial_unanswered);
2603 AST_TEST_REGISTER(test_cdr_dial_congestion);
2604 AST_TEST_REGISTER(test_cdr_dial_busy);
2605 AST_TEST_REGISTER(test_cdr_dial_unavailable);
2606 AST_TEST_REGISTER(test_cdr_dial_caller_cancel);
2607 AST_TEST_REGISTER(test_cdr_dial_parallel_failed);
2608 AST_TEST_REGISTER(test_cdr_dial_answer_no_bridge);
2609 AST_TEST_REGISTER(test_cdr_dial_answer_twoparty_bridge_a);
2610 AST_TEST_REGISTER(test_cdr_dial_answer_twoparty_bridge_b);
2611 AST_TEST_REGISTER(test_cdr_dial_answer_multiparty);
2613 AST_TEST_REGISTER(test_cdr_park);
2615 AST_TEST_REGISTER(test_cdr_fields);
2616 AST_TEST_REGISTER(test_cdr_no_reset_cdr);
2617 AST_TEST_REGISTER(test_cdr_fork_cdr);
2619 ast_test_register_init(TEST_CATEGORY, test_cdr_init_cb);
2620 ast_test_register_cleanup(TEST_CATEGORY, test_cdr_cleanup_cb);
2623 ast_cdr_register(MOCK_CDR_BACKEND,
"Mock CDR backend", mock_cdr_backend_cb);
#define EMULATE_APP_DATA(channel, priority, application, data)
Emulate a channel entering into an application.
Contains all the initialization information required to store a new test definition.
Main Channel structure associated with a channel.
#define AST_LIST_LOCK(head)
Locks a list.
int ast_cdr_setvar(const char *channel_name, const char *name, const char *value)
Set a variable on a CDR.
static struct @500 actual_cdr_entries
A linked list of received CDR entries from the engine.
Asterisk main include file. File version handling, generic pbx functions.
int ast_cdr_unregister(const char *name)
Unregister a CDR handling engine.
#define AST_LIST_HEAD(name, type)
Defines a structure to be used to hold a list of specified type.
char dstchannel[AST_MAX_EXTENSION]
struct ast_flags settings
Time-related functions and macros.
struct ast_party_name name
Subscriber name.
void ast_channel_unregister(const struct ast_channel_tech *tech)
Unregister a channel technology.
void ast_channel_publish_dial(struct ast_channel *caller, struct ast_channel *peer, const char *dialstring, const char *dialstatus)
Publish in the ast_channel_topic or ast_channel_topic_all topics a stasis message for the channels in...
int ast_cdr_getvar(const char *channel_name, const char *name, char *value, size_t length)
Retrieve a CDR variable from a channel's current CDR.
static struct ast_cdr_config congestion_cdr_config
A configuration suitable for CDRs with congestion enabled.
#define CREATE_ALICE_CHANNEL(channel_var, caller_id, expected_record)
Create a test_cdr_chan_tech for Alice, and set the expected CDR records' linkedid and uniqueid...
struct ast_channel * ast_channel_release(struct ast_channel *chan)
Unlink and release reference to a channel.
void ast_cdr_set_config(struct ast_cdr_config *config)
Set the current CDR configuration.
#define COPY_IDS(channel_var, expected_record)
Copy the linkedid and uniqueid from a channel to an expected CDR.
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
int ast_cdr_fork(const char *channel_name, struct ast_flags *options)
Fork a CDR.
#define SET_FORMATS(chan)
Set ulaw format on channel.
char * str
Subscriber name (Malloced)
int ast_bridge_destroy(struct ast_bridge *bridge, int cause)
Destroy a bridge.
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
#define SWAP_CONFIG(ao2_config, template)
Macro to swap a configuration out from the CDR engine. This should be used at the beginning of each t...
int ast_channel_register(const struct ast_channel_tech *tech)
Register a channel technology (a new channel driver) Called by a channel module to register the kind ...
#define HANGUP_CHANNEL(channel, cause)
Hang up a test channel safely.
static struct timespec to_sleep
A 1 second sleep.
struct ast_party_id id
Caller party ID.
#define ALICE_CALLERID
Alice's Caller ID.
int ast_cdr_register(const char *name, const char *desc, ast_cdrbe be)
Register a CDR handling engine.
int ast_bridge_impart(struct ast_bridge *bridge, struct ast_channel *chan, struct ast_channel *swap, struct ast_bridge_features *features, enum ast_bridge_impart_flags flags) attribute_warn_unused_result
Impart a channel to a bridge (non-blocking)
#define CREATE_CHARLIE_CHANNEL(channel_var, caller_id, expected_record)
Create a test_cdr_chan_tech for Charlie, and set the expected CDR records' linkedid and uniqueid...
char linkedid[AST_MAX_UNIQUEID]
Caller Party information.
#define CHARLIE_CALLERID
Charlie's Caller ID.
char uniqueid[AST_MAX_UNIQUEID]
static struct ast_cdr_config * saved_config
A placeholder for Asterisk's 'real' CDR configuration.
void ast_channel_amaflags_set(struct ast_channel *chan, enum ama_flags value)
A set of macros to manage forward-linked lists.
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
struct ast_bridge * ast_bridge_base_new(uint32_t capabilities, unsigned int flags, const char *creator, const char *name, const char *id)
Create a new base class bridge.
Structure to describe a channel "technology", ie a channel driver See for examples: ...
int ast_cdr_set_property(const char *channel_name, enum ast_cdr_options option)
Set a property on a CDR for a channel.
Responsible for call detail data.
Structure that contains information about a bridge.
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
#define CREATE_BOB_CHANNEL(channel_var, caller_id, expected_record)
Create a test_cdr_chan_tech for Bob, and set the expected CDR records' linkedid and uniqueid...
int ast_bridge_depart(struct ast_channel *chan)
Depart a channel from a bridge.
static ast_cond_t mock_cdr_cond
The Mock CDR backend condition wait.
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
#define AST_LIST_ENTRY(type)
Declare a forward link structure inside a list entry.
#define VERIFY_TIME_VALUE(field, actual)
Verify a time field. This will set the test status result to fail; as such, it assumes that (a) test ...
static struct ast_cdr_config unanswered_cdr_config
A configuration suitable for CDRs with unanswered records.
#define ast_calloc(num, len)
A wrapper for calloc()
struct ast_cdr_config * ast_cdr_get_config(void)
Obtain the current CDR configuration.
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
static struct ast_channel_tech test_cdr_chan_tech
A channel technology used for the unit tests.
Basic bridge subclass API.
void ast_cdr_setuserfield(const char *channel_name, const char *userfield)
Set CDR user field for channel (stored in CDR)
Structure used to handle boolean flags.
struct ast_bridge * ast_bridge_basic_new(void)
Create a new basic class bridge.
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
void ast_cdr_free(struct ast_cdr *cdr)
Free a CDR record.
Internal Asterisk hangup causes.
int ast_cdr_clear_property(const char *channel_name, enum ast_cdr_options option)
Clear a property on a CDR for a channel.
#define AST_TEST_DEFINE(hdr)
#define BOB_CALLERID
Bob's Caller ID.
The global options available for CDRs.
void ast_channel_publish_snapshot(struct ast_channel *chan)
Publish a ast_channel_snapshot for a channel.
char clid[AST_MAX_EXTENSION]
static struct ast_cdr_config debug_cdr_config
A configuration suitable for 'normal' CDRs.
#define AST_LIST_HEAD_INIT_VALUE
Defines initial values for a declaration of AST_LIST_HEAD.
#define ASTERISK_GPL_KEY
The text the key() function should return.
#define ast_channel_alloc(needqueue, state, cid_num, cid_name, acctcode, exten, context, assignedids, requestor, amaflag,...)
Create a channel structure.
Asterisk module definitions.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
#define VERIFY_STRING_FIELD(field, actual, expected)
Verify a string field. This will set the test status result to fail; as such, it assumes that (a) tes...
#define VERIFY_NUMERIC_FIELD(field, actual, expected)
Verify a numeric field. This will set the test status result to fail; as such, it assumes that (a) te...
static int global_mock_cdr_count
The number of CDRs the mock backend has received.