c9621a450ff3ee2a185238671642f28e9db6b64b
[asterisk/asterisk.git] / tests / test_cdr.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2013, Digium, Inc.
5  *
6  * Matt Jordan <mjordan@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18
19 /*!
20  * \file
21  * \brief CDR unit tests
22  *
23  * \author Matt Jordan <mjordan@digium.com>
24  *
25  */
26
27 /*** MODULEINFO
28         <depend>TEST_FRAMEWORK</depend>
29         <support_level>core</support_level>
30  ***/
31
32 #include "asterisk.h"
33
34 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
35
36 #include <math.h>
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"
49
50 #define EPSILON 0.001
51
52 #define TEST_CATEGORY "/main/cdr/"
53
54 #define MOCK_CDR_BACKEND "mock_cdr_backend"
55
56 #define CHANNEL_TECH_NAME "CDRTestChannel"
57
58 /*! \brief A placeholder for Asterisk's 'real' CDR configuration */
59 static struct ast_cdr_config *saved_config;
60
61 /*! \brief A configuration suitable for 'normal' CDRs */
62 static struct ast_cdr_config debug_cdr_config = {
63         .settings.flags = CDR_ENABLED | CDR_DEBUG,
64 };
65
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,
69 };
70
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,
74 };
75
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
78  * test.
79  */
80 #define SWAP_CONFIG(ao2_config, template) do { \
81         *(ao2_config) = (template); \
82         ast_cdr_set_config((ao2_config)); \
83         } while (0)
84
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;
87
88 /*! \brief The Mock CDR backend condition wait */
89 static ast_cond_t mock_cdr_cond;
90
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",
95 };
96
97 struct test_cdr_entry {
98         struct ast_cdr *cdr;
99         AST_LIST_ENTRY(test_cdr_entry) list;
100 };
101
102 /*! \brief The number of CDRs the mock backend has received */
103 static int global_mock_cdr_count;
104
105 /*! \internal
106  * \brief Callback function for the mock CDR backend
107  *
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.
111  *
112  * \param cdr The public CDR object created by the engine
113  *
114  * \retval -1 on error
115  * \retval 0 on success
116  */
117 static int mock_cdr_backend_cb(struct ast_cdr *cdr)
118 {
119         struct ast_cdr *cdr_copy, *cdr_prev = NULL;
120         struct ast_cdr *mock_cdr = NULL;
121         struct test_cdr_entry *cdr_wrapper;
122
123         cdr_wrapper = ast_calloc(1, sizeof(*cdr_wrapper));
124         if (!cdr_wrapper) {
125                 return -1;
126         }
127
128         for (; cdr; cdr = cdr->next) {
129                 struct ast_var_t *var_entry, *var_copy;
130
131                 cdr_copy = ast_calloc(1, sizeof(*cdr_copy));
132                 if (!cdr_copy) {
133                         return -1;
134                 }
135                 *cdr_copy = *cdr;
136                 cdr_copy->varshead.first = NULL;
137                 cdr_copy->varshead.last = NULL;
138                 cdr_copy->next = NULL;
139
140                 AST_LIST_TRAVERSE(&cdr->varshead, var_entry, entries) {
141                         var_copy = ast_var_assign(var_entry->name, var_entry->value);
142                         if (!var_copy) {
143                                 return -1;
144                         }
145                         AST_LIST_INSERT_TAIL(&cdr_copy->varshead, var_copy, entries);
146                 }
147
148                 if (!mock_cdr) {
149                         mock_cdr = cdr_copy;
150                 }
151                 if (cdr_prev) {
152                         cdr_prev->next = cdr_copy;
153                 }
154                 cdr_prev = cdr_copy;
155         }
156         cdr_wrapper->cdr = mock_cdr;
157
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);
163
164         return 0;
165 }
166
167 /*! \internal
168  * \brief Remove all entries from \ref actual_cdr_entries
169  */
170 static void clear_mock_cdr_backend(void)
171 {
172         struct test_cdr_entry *cdr_wrapper;
173
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);
178         }
179         global_mock_cdr_count = 0;
180         AST_LIST_UNLOCK(&actual_cdr_entries);
181 }
182
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.
186  */
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; \
192         } } while (0)
193
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.
197  */
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; \
203         } } while (0)
204
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.
208  */
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; \
214         } } while (0)
215
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, }
218
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, }
221
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, }
224
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, }
227
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)); \
232         } while (0)
233
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)); \
241         } while (0)
242
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)); \
250         } while (0)
251
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)); \
259         } while (0)
260
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)); \
268         } while (0)
269
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)); \
274         } \
275         ast_channel_appl_set((channel), (application)); \
276         ast_channel_data_set((channel), (data)); \
277         ast_channel_publish_snapshot((channel)); \
278         } while (0)
279
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))) { \
284                 channel = NULL; \
285         } } while (0)
286
287 static enum ast_test_result_state verify_mock_cdr_record(struct ast_test *test, struct ast_cdr *expected, int record)
288 {
289         struct ast_cdr *actual = NULL;
290         struct test_cdr_entry *cdr_wrapper;
291         int count = 0;
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;
295
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);
300                 }
301                 cdr_wrapper = AST_LIST_REMOVE_HEAD(&actual_cdr_entries, list);
302                 AST_LIST_UNLOCK(&actual_cdr_entries);
303
304                 if (!cdr_wrapper) {
305                         ast_test_status_update(test, "Unable to find actual CDR record at %d\n", count);
306                         return AST_TEST_FAIL;
307                 }
308                 actual = cdr_wrapper->cdr;
309
310                 if (!expected && actual) {
311                         ast_test_status_update(test, "CDRs recorded where no record expected\n");
312                         return AST_TEST_FAIL;
313                 }
314
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
335                  */
336                 if (expected->billsec) {
337                         VERIFY_TIME_VALUE(answer, actual);
338                 }
339                 ast_test_debug(test, "Finished expected record %s, %s\n",
340                                 expected->channel, S_OR(expected->dstchannel, "<none>"));
341                 expected = expected->next;
342                 ++count;
343         }
344         return res;
345 }
346
347 static void safe_channel_release(struct ast_channel *chan)
348 {
349         if (!chan) {
350                 return;
351         }
352         ast_channel_release(chan);
353 }
354
355 AST_TEST_DEFINE(test_cdr_channel_creation)
356 {
357         RAII_VAR(struct ast_channel *, chan, NULL, safe_channel_release);
358         RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
359                         ao2_cleanup);
360
361         struct ast_party_caller caller = ALICE_CALLERID;
362         struct ast_cdr expected = {
363                 .clid = "\"Alice\" <100>",
364                 .src = "100",
365                 .dst = "100",
366                 .dcontext = "default",
367                 .channel = CHANNEL_TECH_NAME "/Alice",
368                 .amaflags = AST_AMA_DOCUMENTATION,
369                 .disposition = AST_CDR_NOANSWER,
370                 .accountcode = "100",
371         };
372         enum ast_test_result_state result = AST_TEST_NOT_RUN;
373
374         switch (cmd) {
375         case TEST_INIT:
376                 info->name = __func__;
377                 info->category = TEST_CATEGORY;
378                 info->summary = "Test that a CDR is created when a channel is created";
379                 info->description =
380                         "Test that a CDR is created when a channel is created";
381                 return AST_TEST_NOT_RUN;
382         case TEST_EXECUTE:
383                 break;
384         }
385
386         SWAP_CONFIG(config, unanswered_cdr_config);
387
388         CREATE_ALICE_CHANNEL(chan, (&caller), &expected);
389
390         HANGUP_CHANNEL(chan, AST_CAUSE_NORMAL);
391
392         result = verify_mock_cdr_record(test, &expected, 1);
393
394         return result;
395 }
396
397 AST_TEST_DEFINE(test_cdr_unanswered_inbound_call)
398 {
399         RAII_VAR(struct ast_channel *, chan, NULL, safe_channel_release);
400         RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
401                         ao2_cleanup);
402
403         struct ast_party_caller caller = ALICE_CALLERID;
404         struct ast_cdr expected = {
405                 .clid = "\"Alice\" <100>",
406                 .src = "100",
407                 .dst = "100",
408                 .dcontext = "default",
409                 .channel = CHANNEL_TECH_NAME "/Alice",
410                 .lastapp = "Wait",
411                 .lastdata = "1",
412                 .amaflags = AST_AMA_DOCUMENTATION,
413                 .disposition = AST_CDR_NOANSWER,
414                 .accountcode = "100",
415         };
416         enum ast_test_result_state result = AST_TEST_NOT_RUN;
417
418         switch (cmd) {
419         case TEST_INIT:
420                 info->name = __func__;
421                 info->category = TEST_CATEGORY;
422                 info->summary = "Test inbound unanswered calls";
423                 info->description =
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;
428         case TEST_EXECUTE:
429                 break;
430         }
431
432         SWAP_CONFIG(config, unanswered_cdr_config);
433
434         CREATE_ALICE_CHANNEL(chan, &caller, &expected);
435
436         EMULATE_APP_DATA(chan, 1, "Wait", "1");
437
438         HANGUP_CHANNEL(chan, AST_CAUSE_NORMAL);
439
440         result = verify_mock_cdr_record(test, &expected, 1);
441
442         return result;
443 }
444
445 AST_TEST_DEFINE(test_cdr_unanswered_outbound_call)
446 {
447         RAII_VAR(struct ast_channel *, chan, NULL, safe_channel_release);
448         RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
449                         ao2_cleanup);
450
451         struct ast_party_caller caller = {
452                         .id.name.str = "",
453                         .id.name.valid = 1,
454                         .id.number.str = "",
455                         .id.number.valid = 1, };
456         struct ast_cdr expected = {
457                 .clid = "\"\" <>",
458                 .dst = "s",
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",
466         };
467         enum ast_test_result_state result = AST_TEST_NOT_RUN;
468
469         switch (cmd) {
470         case TEST_INIT:
471                 info->name = __func__;
472                 info->category = TEST_CATEGORY;
473                 info->summary = "Test outbound unanswered calls";
474                 info->description =
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;
478         case TEST_EXECUTE:
479                 break;
480         }
481
482         SWAP_CONFIG(config, unanswered_cdr_config);
483
484         CREATE_ALICE_CHANNEL(chan, &caller, &expected);
485
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);
491
492         result = verify_mock_cdr_record(test, &expected, 1);
493
494         return result;
495 }
496
497 AST_TEST_DEFINE(test_cdr_single_party)
498 {
499         RAII_VAR(struct ast_channel *, chan, NULL, safe_channel_release);
500         RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
501                         ao2_cleanup);
502
503         struct ast_party_caller caller = ALICE_CALLERID;
504         struct ast_cdr expected = {
505                 .clid = "\"Alice\" <100>",
506                 .src = "100",
507                 .dst = "100",
508                 .dcontext = "default",
509                 .channel = CHANNEL_TECH_NAME "/Alice",
510                 .dstchannel = "",
511                 .lastapp = "VoiceMailMain",
512                 .lastdata = "1",
513                 .billsec = 1,
514                 .amaflags = AST_AMA_DOCUMENTATION,
515                 .disposition = AST_CDR_ANSWERED,
516                 .accountcode = "100",
517         };
518         enum ast_test_result_state result = AST_TEST_NOT_RUN;
519
520         switch (cmd) {
521         case TEST_INIT:
522                 info->name = __func__;
523                 info->category = TEST_CATEGORY;
524                 info->summary = "Test cdrs for a single party";
525                 info->description =
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;
529         case TEST_EXECUTE:
530                 break;
531         }
532         SWAP_CONFIG(config, debug_cdr_config);
533         CREATE_ALICE_CHANNEL(chan, &caller, &expected);
534
535         EMULATE_APP_DATA(chan, 1, "Answer", "");
536         ast_setstate(chan, AST_STATE_UP);
537         EMULATE_APP_DATA(chan, 2, "VoiceMailMain", "1");
538
539         HANGUP_CHANNEL(chan, AST_CAUSE_NORMAL);
540
541         result = verify_mock_cdr_record(test, &expected, 1);
542
543         return result;
544 }
545
546 AST_TEST_DEFINE(test_cdr_single_bridge)
547 {
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),
551                         ao2_cleanup);
552         struct timespec to_sleep = {1, 0};
553
554         struct ast_party_caller caller = ALICE_CALLERID;
555         struct ast_cdr expected = {
556                 .clid = "\"Alice\" <100>",
557                 .src = "100",
558                 .dst = "100",
559                 .dcontext = "default",
560                 .channel = CHANNEL_TECH_NAME "/Alice",
561                 .lastapp = "Bridge",
562                 .billsec = 1,
563                 .amaflags = AST_AMA_DOCUMENTATION,
564                 .disposition = AST_CDR_ANSWERED,
565                 .accountcode = "100",
566         };
567         enum ast_test_result_state result = AST_TEST_NOT_RUN;
568
569         switch (cmd) {
570         case TEST_INIT:
571                 info->name = __func__;
572                 info->category = TEST_CATEGORY;
573                 info->summary = "Test cdrs for a single party entering/leaving a bridge";
574                 info->description =
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;
578         case TEST_EXECUTE:
579                 break;
580         }
581         SWAP_CONFIG(config, debug_cdr_config);
582         CREATE_ALICE_CHANNEL(chan, &caller, &expected);
583
584         EMULATE_APP_DATA(chan, 1, "Answer", "");
585         ast_setstate(chan, AST_STATE_UP);
586         EMULATE_APP_DATA(chan, 2, "Bridge", "");
587
588         bridge = ast_bridge_basic_new();
589         ast_test_validate(test, bridge != NULL);
590
591         while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
592         ast_bridge_impart(bridge, chan, NULL, NULL, 0);
593
594         while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
595
596         ast_bridge_depart(chan);
597
598         HANGUP_CHANNEL(chan, AST_CAUSE_NORMAL);
599
600         result = verify_mock_cdr_record(test, &expected, 1);
601
602         return result;
603 }
604
605 AST_TEST_DEFINE(test_cdr_single_bridge_continue)
606 {
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),
611                         ao2_cleanup);
612         struct timespec to_sleep = {1, 0};
613
614         struct ast_party_caller caller = ALICE_CALLERID;
615         struct ast_cdr expected_two = {
616                 .clid = "\"Alice\" <100>",
617                 .src = "100",
618                 .dst = "100",
619                 .dcontext = "default",
620                 .channel = CHANNEL_TECH_NAME "/Alice",
621                 .lastapp = "Wait",
622                 .billsec = 1,
623                 .amaflags = AST_AMA_DOCUMENTATION,
624                 .disposition = AST_CDR_ANSWERED,
625                 .accountcode = "100",
626         };
627         struct ast_cdr expected_one = {
628                 .clid = "\"Alice\" <100>",
629                 .src = "100",
630                 .dst = "100",
631                 .dcontext = "default",
632                 .channel = CHANNEL_TECH_NAME "/Alice",
633                 .lastapp = "Bridge",
634                 .billsec = 1,
635                 .amaflags = AST_AMA_DOCUMENTATION,
636                 .disposition = AST_CDR_ANSWERED,
637                 .accountcode = "100",
638                 .next = &expected_two,
639         };
640
641         enum ast_test_result_state result = AST_TEST_NOT_RUN;
642
643         switch (cmd) {
644         case TEST_INIT:
645                 info->name = __func__;
646                 info->category = TEST_CATEGORY;
647                 info->summary = "Test cdrs for a single party entering/leaving a bridge";
648                 info->description =
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;
652         case TEST_EXECUTE:
653                 break;
654         }
655         SWAP_CONFIG(config, debug_cdr_config);
656         CREATE_ALICE_CHANNEL(chan, &caller, &expected_one);
657         COPY_IDS(chan, &expected_two);
658
659         EMULATE_APP_DATA(chan, 1, "Answer", "");
660         ast_setstate(chan, AST_STATE_UP);
661         EMULATE_APP_DATA(chan, 2, "Bridge", "");
662
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));
666
667         ast_bridge_impart(bridge_one, chan, NULL, NULL, 0);
668
669         while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
670
671         ast_bridge_depart(chan);
672
673         EMULATE_APP_DATA(chan, 3, "Wait", "");
674
675         /* And then it hangs up */
676         HANGUP_CHANNEL(chan, AST_CAUSE_NORMAL);
677
678         result = verify_mock_cdr_record(test, &expected_one, 2);
679
680         return result;
681 }
682
683 AST_TEST_DEFINE(test_cdr_single_twoparty_bridge_a)
684 {
685         RAII_VAR(struct ast_channel *, chan_alice, NULL, safe_channel_release);
686         RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release);
687         RAII_VAR(struct ast_bridge *, bridge, NULL, ao2_cleanup);
688         RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
689                         ao2_cleanup);
690         struct timespec to_sleep = {1, 0};
691
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>",
696                 .src = "200",
697                 .dst = "200",
698                 .dcontext = "default",
699                 .channel = CHANNEL_TECH_NAME "/Bob",
700                 .lastapp = "Bridge",
701                 .billsec = 1,
702                 .amaflags = AST_AMA_DOCUMENTATION,
703                 .disposition = AST_CDR_ANSWERED,
704                 .accountcode = "200",
705         };
706         struct ast_cdr alice_expected = {
707                 .clid = "\"Alice\" <100>",
708                 .src = "100",
709                 .dst = "100",
710                 .dcontext = "default",
711                 .channel = CHANNEL_TECH_NAME "/Alice",
712                 .dstchannel = CHANNEL_TECH_NAME "/Bob",
713                 .lastapp = "Bridge",
714                 .billsec = 1,
715                 .amaflags = AST_AMA_DOCUMENTATION,
716                 .disposition = AST_CDR_ANSWERED,
717                 .accountcode = "100",
718                 .peeraccount = "200",
719                 .next = &bob_expected,
720         };
721
722         enum ast_test_result_state result = AST_TEST_NOT_RUN;
723
724         switch (cmd) {
725         case TEST_INIT:
726                 info->name = __func__;
727                 info->category = TEST_CATEGORY;
728                 info->summary = "Test cdrs for a single party entering/leaving a bridge";
729                 info->description =
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;
734         case TEST_EXECUTE:
735                 break;
736         }
737         SWAP_CONFIG(config, debug_cdr_config);
738         CREATE_ALICE_CHANNEL(chan_alice, &caller_alice, &alice_expected);
739
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));
742
743         EMULATE_APP_DATA(chan_alice, 1, "Answer", "");
744         ast_setstate(chan_alice, AST_STATE_UP);
745         EMULATE_APP_DATA(chan_alice, 2, "Bridge", "");
746
747         bridge = ast_bridge_basic_new();
748         ast_test_validate(test, bridge != NULL);
749
750         ast_bridge_impart(bridge, chan_alice, NULL, NULL, 0);
751         while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
752
753         EMULATE_APP_DATA(chan_bob, 1, "Answer", "");
754         ast_setstate(chan_bob, AST_STATE_UP);
755         EMULATE_APP_DATA(chan_bob, 2, "Bridge", "");
756
757         ast_bridge_impart(bridge, chan_bob, NULL, NULL, 0);
758         while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
759
760         ast_bridge_depart(chan_alice);
761         ast_bridge_depart(chan_bob);
762
763         HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL);
764         HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL);
765
766         result = verify_mock_cdr_record(test, &alice_expected, 2);
767
768         return result;
769 }
770
771 AST_TEST_DEFINE(test_cdr_single_twoparty_bridge_b)
772 {
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),
777                         ao2_cleanup);
778         struct timespec to_sleep = {1, 0};
779
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>",
784                 .src = "200",
785                 .dst = "200",
786                 .dcontext = "default",
787                 .channel = CHANNEL_TECH_NAME "/Bob",
788                 .lastapp = "Bridge",
789                 .billsec = 1,
790                 .amaflags = AST_AMA_DOCUMENTATION,
791                 .disposition = AST_CDR_ANSWERED,
792                 .accountcode = "200",
793         };
794         struct ast_cdr alice_expected = {
795                 .clid = "\"Alice\" <100>",
796                 .src = "100",
797                 .dst = "100",
798                 .dcontext = "default",
799                 .channel = CHANNEL_TECH_NAME "/Alice",
800                 .dstchannel = CHANNEL_TECH_NAME "/Bob",
801                 .lastapp = "Bridge",
802                 .billsec = 1,
803                 .amaflags = AST_AMA_DOCUMENTATION,
804                 .disposition = AST_CDR_ANSWERED,
805                 .accountcode = "100",
806                 .peeraccount = "200",
807                 .next = &bob_expected,
808         };
809
810         enum ast_test_result_state result = AST_TEST_NOT_RUN;
811
812         switch (cmd) {
813         case TEST_INIT:
814                 info->name = __func__;
815                 info->category = TEST_CATEGORY;
816                 info->summary = "Test cdrs for a single party entering/leaving a bridge";
817                 info->description =
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;
822         case TEST_EXECUTE:
823                 break;
824         }
825         SWAP_CONFIG(config, debug_cdr_config);
826         CREATE_ALICE_CHANNEL(chan_alice, &caller_alice, &alice_expected);
827
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));
830
831         EMULATE_APP_DATA(chan_alice, 1, "Answer", "");
832         ast_setstate(chan_alice, AST_STATE_UP);
833         EMULATE_APP_DATA(chan_alice, 2, "Bridge", "");
834
835         bridge = ast_bridge_basic_new();
836         ast_test_validate(test, bridge != NULL);
837
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));
842
843         ast_bridge_impart(bridge, chan_bob, NULL, NULL, 0);
844         while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
845
846         ast_bridge_impart(bridge, chan_alice, NULL, NULL, 0);
847         while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
848
849         ast_bridge_depart(chan_alice);
850         ast_bridge_depart(chan_bob);
851
852         HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL);
853         HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL);
854
855         result = verify_mock_cdr_record(test, &alice_expected, 2);
856
857         return result;
858 }
859
860 AST_TEST_DEFINE(test_cdr_single_multiparty_bridge)
861 {
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),
867                         ao2_cleanup);
868         struct timespec to_sleep = {1, 0};
869
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>",
875                 .src = "300",
876                 .dst = "300",
877                 .dcontext = "default",
878                 .channel = CHANNEL_TECH_NAME "/Charlie",
879                 .lastapp = "Bridge",
880                 .billsec = 1,
881                 .amaflags = AST_AMA_DOCUMENTATION,
882                 .disposition = AST_CDR_ANSWERED,
883                 .accountcode = "300",
884         };
885         struct ast_cdr bob_expected = {
886                 .clid = "\"Bob\" <200>",
887                 .src = "200",
888                 .dst = "200",
889                 .dcontext = "default",
890                 .channel = CHANNEL_TECH_NAME "/Bob",
891                 .dstchannel = CHANNEL_TECH_NAME "/Charlie",
892                 .lastapp = "Bridge",
893                 .billsec = 1,
894                 .amaflags = AST_AMA_DOCUMENTATION,
895                 .disposition = AST_CDR_ANSWERED,
896                 .accountcode = "200",
897                 .peeraccount = "300",
898                 .next = &charlie_expected,
899         };
900         struct ast_cdr alice_expected_two = {
901                 .clid = "\"Alice\" <100>",
902                 .src = "100",
903                 .dst = "100",
904                 .dcontext = "default",
905                 .channel = CHANNEL_TECH_NAME "/Alice",
906                 .dstchannel = CHANNEL_TECH_NAME "/Charlie",
907                 .lastapp = "Bridge",
908                 .billsec = 1,
909                 .amaflags = AST_AMA_DOCUMENTATION,
910                 .disposition = AST_CDR_ANSWERED,
911                 .accountcode = "100",
912                 .peeraccount = "300",
913                 .next = &bob_expected,
914         };
915         struct ast_cdr alice_expected_one = {
916                 .clid = "\"Alice\" <100>",
917                 .src = "100",
918                 .dst = "100",
919                 .dcontext = "default",
920                 .channel = CHANNEL_TECH_NAME "/Alice",
921                 .dstchannel = CHANNEL_TECH_NAME "/Bob",
922                 .lastapp = "Bridge",
923                 .billsec = 1,
924                 .amaflags = AST_AMA_DOCUMENTATION,
925                 .disposition = AST_CDR_ANSWERED,
926                 .accountcode = "100",
927                 .peeraccount = "200",
928                 .next = &alice_expected_two,
929         };
930
931         enum ast_test_result_state result = AST_TEST_NOT_RUN;
932
933         switch (cmd) {
934         case TEST_INIT:
935                 info->name = __func__;
936                 info->category = TEST_CATEGORY;
937                 info->summary = "Test cdrs for a single party entering/leaving a multi-party bridge";
938                 info->description =
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;
943         case TEST_EXECUTE:
944                 break;
945         }
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));
953
954         EMULATE_APP_DATA(chan_alice, 1, "Answer", "");
955         ast_setstate(chan_alice, AST_STATE_UP);
956         EMULATE_APP_DATA(chan_alice, 2, "Bridge", "");
957
958         bridge = ast_bridge_basic_new();
959         ast_test_validate(test, bridge != NULL);
960         while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
961
962         ast_bridge_impart(bridge, chan_alice, NULL, NULL, 0);
963
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));
968
969         ast_bridge_impart(bridge, chan_bob, NULL, NULL, 0);
970
971         while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
972
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);
977
978         while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
979
980         ast_bridge_depart(chan_alice);
981         ast_bridge_depart(chan_bob);
982         ast_bridge_depart(chan_charlie);
983
984         HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL);
985         HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL);
986         HANGUP_CHANNEL(chan_charlie, AST_CAUSE_NORMAL);
987
988         result = verify_mock_cdr_record(test, &alice_expected_one, 4);
989
990         return result;
991 }
992
993 AST_TEST_DEFINE(test_cdr_dial_unanswered)
994 {
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),
998                         ao2_cleanup);
999
1000         struct ast_party_caller caller = ALICE_CALLERID;
1001         struct ast_cdr expected = {
1002                 .clid = "\"Alice\" <100>",
1003                 .src = "100",
1004                 .dst = "100",
1005                 .dcontext = "default",
1006                 .channel = CHANNEL_TECH_NAME "/Alice",
1007                 .dstchannel = CHANNEL_TECH_NAME "/Bob",
1008                 .lastapp = "Dial",
1009                 .lastdata = CHANNEL_TECH_NAME "/Bob",
1010                 .billsec = 0,
1011                 .amaflags = AST_AMA_DOCUMENTATION,
1012                 .disposition = AST_CDR_NOANSWER,
1013                 .accountcode = "100",
1014                 .peeraccount = "200",
1015         };
1016         enum ast_test_result_state result = AST_TEST_NOT_RUN;
1017
1018         switch (cmd) {
1019         case TEST_INIT:
1020                 info->name = __func__;
1021                 info->category = TEST_CATEGORY;
1022                 info->summary = "Test CDRs for a dial that isn't answered";
1023                 info->description =
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;
1027         case TEST_EXECUTE:
1028                 break;
1029         }
1030
1031         SWAP_CONFIG(config, unanswered_cdr_config);
1032
1033         CREATE_ALICE_CHANNEL(chan_caller, &caller, &expected);
1034
1035         EMULATE_APP_DATA(chan_caller, 1, "Dial", "CDRTestChannel/Bob");
1036
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)");
1040
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");
1044
1045         HANGUP_CHANNEL(chan_caller, AST_CAUSE_NO_ANSWER);
1046         HANGUP_CHANNEL(chan_callee, AST_CAUSE_NO_ANSWER);
1047
1048         result = verify_mock_cdr_record(test, &expected, 1);
1049
1050         return result;
1051 }
1052
1053
1054 AST_TEST_DEFINE(test_cdr_dial_busy)
1055 {
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),
1059                         ao2_cleanup);
1060
1061         struct ast_party_caller caller = ALICE_CALLERID;
1062         struct ast_cdr expected = {
1063                 .clid = "\"Alice\" <100>",
1064                 .src = "100",
1065                 .dst = "100",
1066                 .dcontext = "default",
1067                 .channel = CHANNEL_TECH_NAME "/Alice",
1068                 .dstchannel = CHANNEL_TECH_NAME "/Bob",
1069                 .lastapp = "Dial",
1070                 .lastdata = CHANNEL_TECH_NAME "/Bob",
1071                 .billsec = 0,
1072                 .amaflags = AST_AMA_DOCUMENTATION,
1073                 .disposition = AST_CDR_BUSY,
1074                 .accountcode = "100",
1075                 .peeraccount = "200",
1076         };
1077         enum ast_test_result_state result = AST_TEST_NOT_RUN;
1078
1079         switch (cmd) {
1080         case TEST_INIT:
1081                 info->name = __func__;
1082                 info->category = TEST_CATEGORY;
1083                 info->summary = "Test CDRs for a dial that results in a busy";
1084                 info->description =
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;
1088         case TEST_EXECUTE:
1089                 break;
1090         }
1091
1092         SWAP_CONFIG(config, unanswered_cdr_config);
1093
1094         CREATE_ALICE_CHANNEL(chan_caller, &caller, &expected);
1095
1096         EMULATE_APP_DATA(chan_caller, 1, "Dial", CHANNEL_TECH_NAME "/Bob");
1097
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)");
1101
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");
1105
1106         HANGUP_CHANNEL(chan_caller, AST_CAUSE_BUSY);
1107         HANGUP_CHANNEL(chan_callee, AST_CAUSE_BUSY);
1108
1109         result = verify_mock_cdr_record(test, &expected, 1);
1110
1111         return result;
1112 }
1113
1114 AST_TEST_DEFINE(test_cdr_dial_congestion)
1115 {
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),
1119                         ao2_cleanup);
1120
1121         struct ast_party_caller caller = ALICE_CALLERID;
1122         struct ast_cdr expected = {
1123                 .clid = "\"Alice\" <100>",
1124                 .src = "100",
1125                 .dst = "100",
1126                 .dcontext = "default",
1127                 .channel = CHANNEL_TECH_NAME "/Alice",
1128                 .dstchannel = CHANNEL_TECH_NAME "/Bob",
1129                 .lastapp = "Dial",
1130                 .lastdata = CHANNEL_TECH_NAME "/Bob",
1131                 .billsec = 0,
1132                 .amaflags = AST_AMA_DOCUMENTATION,
1133                 .disposition = AST_CDR_CONGESTION,
1134                 .accountcode = "100",
1135                 .peeraccount = "200",
1136         };
1137         enum ast_test_result_state result = AST_TEST_NOT_RUN;
1138
1139         switch (cmd) {
1140         case TEST_INIT:
1141                 info->name = __func__;
1142                 info->category = TEST_CATEGORY;
1143                 info->summary = "Test CDRs for a dial that results in congestion";
1144                 info->description =
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;
1148         case TEST_EXECUTE:
1149                 break;
1150         }
1151
1152         SWAP_CONFIG(config, congestion_cdr_config);
1153
1154         CREATE_ALICE_CHANNEL(chan_caller, &caller, &expected);
1155
1156         EMULATE_APP_DATA(chan_caller, 1, "Dial", CHANNEL_TECH_NAME "/Bob");
1157
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)");
1161
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");
1165
1166         HANGUP_CHANNEL(chan_caller, AST_CAUSE_CONGESTION);
1167         HANGUP_CHANNEL(chan_callee, AST_CAUSE_CONGESTION);
1168
1169         result = verify_mock_cdr_record(test, &expected, 1);
1170
1171         return result;
1172 }
1173
1174 AST_TEST_DEFINE(test_cdr_dial_unavailable)
1175 {
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),
1179                         ao2_cleanup);
1180
1181         struct ast_party_caller caller = ALICE_CALLERID;
1182         struct ast_cdr expected = {
1183                 .clid = "\"Alice\" <100>",
1184                 .src = "100",
1185                 .dst = "100",
1186                 .dcontext = "default",
1187                 .channel = CHANNEL_TECH_NAME "/Alice",
1188                 .dstchannel = CHANNEL_TECH_NAME "/Bob",
1189                 .lastapp = "Dial",
1190                 .lastdata = CHANNEL_TECH_NAME "/Bob",
1191                 .billsec = 0,
1192                 .amaflags = AST_AMA_DOCUMENTATION,
1193                 .disposition = AST_CDR_FAILED,
1194                 .accountcode = "100",
1195                 .peeraccount = "200",
1196         };
1197         enum ast_test_result_state result = AST_TEST_NOT_RUN;
1198
1199         switch (cmd) {
1200         case TEST_INIT:
1201                 info->name = __func__;
1202                 info->category = TEST_CATEGORY;
1203                 info->summary = "Test CDRs for a dial that results in unavailable";
1204                 info->description =
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;
1208         case TEST_EXECUTE:
1209                 break;
1210         }
1211
1212         SWAP_CONFIG(config, unanswered_cdr_config);
1213
1214         CREATE_ALICE_CHANNEL(chan_caller, &caller, &expected);
1215
1216         EMULATE_APP_DATA(chan_caller, 1, "Dial", CHANNEL_TECH_NAME "/Bob");
1217
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)");
1221
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");
1225
1226         HANGUP_CHANNEL(chan_caller, AST_CAUSE_NO_ROUTE_DESTINATION);
1227         HANGUP_CHANNEL(chan_callee, AST_CAUSE_NO_ROUTE_DESTINATION);
1228
1229         result = verify_mock_cdr_record(test, &expected, 1);
1230
1231         return result;
1232 }
1233
1234 AST_TEST_DEFINE(test_cdr_dial_caller_cancel)
1235 {
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),
1239                         ao2_cleanup);
1240
1241         struct ast_party_caller caller = ALICE_CALLERID;
1242         struct ast_cdr expected = {
1243                 .clid = "\"Alice\" <100>",
1244                 .src = "100",
1245                 .dst = "100",
1246                 .dcontext = "default",
1247                 .channel = CHANNEL_TECH_NAME "/Alice",
1248                 .dstchannel = CHANNEL_TECH_NAME "/Bob",
1249                 .lastapp = "Dial",
1250                 .lastdata = CHANNEL_TECH_NAME "/Bob",
1251                 .billsec = 0,
1252                 .amaflags = AST_AMA_DOCUMENTATION,
1253                 .disposition = AST_CDR_NOANSWER,
1254                 .accountcode = "100",
1255                 .peeraccount = "200",
1256         };
1257         enum ast_test_result_state result = AST_TEST_NOT_RUN;
1258
1259         switch (cmd) {
1260         case TEST_INIT:
1261                 info->name = __func__;
1262                 info->category = TEST_CATEGORY;
1263                 info->summary = "Test CDRs for a dial where the caller cancels";
1264                 info->description =
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;
1269         case TEST_EXECUTE:
1270                 break;
1271         }
1272
1273         SWAP_CONFIG(config, unanswered_cdr_config);
1274
1275         CREATE_ALICE_CHANNEL(chan_caller, &caller, &expected);
1276
1277         EMULATE_APP_DATA(chan_caller, 1, "Dial", CHANNEL_TECH_NAME "/Bob");
1278
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)");
1282
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");
1286
1287         HANGUP_CHANNEL(chan_callee, AST_CAUSE_NORMAL);
1288         HANGUP_CHANNEL(chan_caller, AST_CAUSE_NORMAL);
1289
1290         result = verify_mock_cdr_record(test, &expected, 1);
1291
1292         return result;
1293 }
1294
1295 AST_TEST_DEFINE(test_cdr_dial_parallel_failed)
1296 {
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),
1302                         ao2_cleanup);
1303
1304         struct ast_party_caller caller = ALICE_CALLERID;
1305         struct ast_cdr bob_expected = {
1306                 .clid = "\"Alice\" <100>",
1307                 .src = "100",
1308                 .dst = "100",
1309                 .dcontext = "default",
1310                 .channel = CHANNEL_TECH_NAME "/Alice",
1311                 .dstchannel = CHANNEL_TECH_NAME "/Bob",
1312                 .lastapp = "Dial",
1313                 .lastdata = CHANNEL_TECH_NAME "/Bob&" CHANNEL_TECH_NAME "/Charlie&" CHANNEL_TECH_NAME "/David",
1314                 .billsec = 0,
1315                 .amaflags = AST_AMA_DOCUMENTATION,
1316                 .disposition = AST_CDR_NOANSWER,
1317                 .accountcode = "100",
1318                 .peeraccount = "200",
1319         };
1320         struct ast_cdr charlie_expected = {
1321                 .clid = "\"Alice\" <100>",
1322                 .src = "100",
1323                 .dst = "100",
1324                 .dcontext = "default",
1325                 .channel = CHANNEL_TECH_NAME "/Alice",
1326                 .dstchannel = CHANNEL_TECH_NAME "/Charlie",
1327                 .lastapp = "Dial",
1328                 .lastdata = CHANNEL_TECH_NAME "/Bob&" CHANNEL_TECH_NAME "/Charlie&" CHANNEL_TECH_NAME "/David",
1329                 .billsec = 0,
1330                 .amaflags = AST_AMA_DOCUMENTATION,
1331                 .disposition = AST_CDR_BUSY,
1332                 .accountcode = "100",
1333                 .peeraccount = "300",
1334         };
1335         struct ast_cdr david_expected = {
1336                 .clid = "\"Alice\" <100>",
1337                 .src = "100",
1338                 .dst = "100",
1339                 .dcontext = "default",
1340                 .channel = CHANNEL_TECH_NAME "/Alice",
1341                 .dstchannel = CHANNEL_TECH_NAME "/David",
1342                 .lastapp = "Dial",
1343                 .lastdata = CHANNEL_TECH_NAME "/Bob&" CHANNEL_TECH_NAME "/Charlie&" CHANNEL_TECH_NAME "/David",
1344                 .billsec = 0,
1345                 .amaflags = AST_AMA_DOCUMENTATION,
1346                 .disposition = AST_CDR_CONGESTION,
1347                 .accountcode = "100",
1348                 .peeraccount = "400",
1349         };
1350         enum ast_test_result_state result = AST_TEST_NOT_RUN;
1351
1352         struct ast_cdr *expected = &bob_expected;
1353         bob_expected.next = &charlie_expected;
1354         charlie_expected.next = &david_expected;
1355
1356         switch (cmd) {
1357         case TEST_INIT:
1358                 info->name = __func__;
1359                 info->category = TEST_CATEGORY;
1360                 info->summary = "Test a parallel dial where all channels fail to answer";
1361                 info->description =
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;
1366         case TEST_EXECUTE:
1367                 break;
1368         }
1369
1370         SWAP_CONFIG(config, congestion_cdr_config);
1371
1372         CREATE_ALICE_CHANNEL(chan_caller, &caller, &bob_expected);
1373         COPY_IDS(chan_caller, &charlie_expected);
1374         COPY_IDS(chan_caller, &david_expected);
1375
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");
1378
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)");
1383
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)");
1387
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)");
1391
1392         /* Dial starts */
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);
1397
1398         /* Charlie is busy */
1399         ast_channel_publish_dial(chan_caller, chan_charlie, NULL, "BUSY");
1400         HANGUP_CHANNEL(chan_charlie, AST_CAUSE_BUSY);
1401
1402         /* David is congested */
1403         ast_channel_publish_dial(chan_caller, chan_david, NULL, "CONGESTION");
1404         HANGUP_CHANNEL(chan_david, AST_CAUSE_CONGESTION);
1405
1406         /* Bob is canceled */
1407         ast_channel_publish_dial(chan_caller, chan_bob, NULL, "CANCEL");
1408         HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL);
1409
1410         /* Alice hangs up */
1411         HANGUP_CHANNEL(chan_caller, AST_CAUSE_NORMAL);
1412
1413         result = verify_mock_cdr_record(test, expected, 3);
1414
1415         return result;
1416 }
1417
1418 AST_TEST_DEFINE(test_cdr_dial_answer_no_bridge)
1419 {
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),
1423                         ao2_cleanup);
1424
1425         struct ast_party_caller caller = ALICE_CALLERID;
1426         struct ast_cdr bob_expected_one = {
1427                 .clid = "\"\" <>",
1428                 .src = "",
1429                 .dst = "s",
1430                 .dcontext = "default",
1431                 .channel = CHANNEL_TECH_NAME "/Bob",
1432                 .lastapp = "Wait",
1433                 .lastdata = "1",
1434                 .amaflags = AST_AMA_DOCUMENTATION,
1435                 .disposition = AST_CDR_ANSWERED,
1436                 .accountcode = "200",
1437         };
1438         struct ast_cdr alice_expected_two = {
1439                 .clid = "\"Alice\" <100>",
1440                 .src = "100",
1441                 .dst = "100",
1442                 .dcontext = "default",
1443                 .channel = CHANNEL_TECH_NAME "/Alice",
1444                 .lastapp = "Wait",
1445                 .lastdata = "1",
1446                 .amaflags = AST_AMA_DOCUMENTATION,
1447                 .disposition = AST_CDR_ANSWERED,
1448                 .accountcode = "100",
1449                 .next = &bob_expected_one,
1450         };
1451         struct ast_cdr alice_expected_one = {
1452                 .clid = "\"Alice\" <100>",
1453                 .src = "100",
1454                 .dst = "100",
1455                 .dcontext = "default",
1456                 .channel = CHANNEL_TECH_NAME "/Alice",
1457                 .dstchannel = CHANNEL_TECH_NAME "/Bob",
1458                 .lastapp = "Dial",
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,
1465         };
1466         enum ast_test_result_state result = AST_TEST_NOT_RUN;
1467
1468         switch (cmd) {
1469         case TEST_INIT:
1470                 info->name = __func__;
1471                 info->category = TEST_CATEGORY;
1472                 info->summary = "Test dialing, answering, and not going into a bridge.";
1473                 info->description =
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"
1480                         "on.\n";
1481                 return AST_TEST_NOT_RUN;
1482         case TEST_EXECUTE:
1483                 break;
1484         }
1485
1486         SWAP_CONFIG(config, debug_cdr_config);
1487
1488         CREATE_ALICE_CHANNEL(chan_caller, &caller, &alice_expected_one);
1489         COPY_IDS(chan_caller, &alice_expected_two);
1490
1491         EMULATE_APP_DATA(chan_caller, 1, "Dial", CHANNEL_TECH_NAME "/Bob");
1492
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);
1496
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");
1500
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);
1504
1505         EMULATE_APP_DATA(chan_caller, 2, "Wait", "1");
1506         EMULATE_APP_DATA(chan_callee, 1, "Wait", "1");
1507
1508         HANGUP_CHANNEL(chan_caller, AST_CAUSE_NORMAL);
1509         HANGUP_CHANNEL(chan_callee, AST_CAUSE_NORMAL);
1510
1511         result = verify_mock_cdr_record(test, &alice_expected_one, 3);
1512         return result;
1513 }
1514
1515 AST_TEST_DEFINE(test_cdr_dial_answer_twoparty_bridge_a)
1516 {
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),
1521                         ao2_cleanup);
1522         struct timespec to_sleep = {1, 0};
1523         enum ast_test_result_state result = AST_TEST_NOT_RUN;
1524
1525         struct ast_party_caller caller = ALICE_CALLERID;
1526         struct ast_cdr expected = {
1527                 .clid = "\"Alice\" <100>",
1528                 .src = "100",
1529                 .dst = "100",
1530                 .dcontext = "default",
1531                 .channel = CHANNEL_TECH_NAME "/Alice",
1532                 .dstchannel = CHANNEL_TECH_NAME "/Bob",
1533                 .lastapp = "Dial",
1534                 .lastdata = CHANNEL_TECH_NAME "/Bob",
1535                 .amaflags = AST_AMA_DOCUMENTATION,
1536                 .billsec = 1,
1537                 .disposition = AST_CDR_ANSWERED,
1538                 .accountcode = "100",
1539                 .peeraccount = "200",
1540         };
1541
1542         switch (cmd) {
1543         case TEST_INIT:
1544                 info->name = __func__;
1545                 info->category = TEST_CATEGORY;
1546                 info->summary = "Test dialing, answering, and going into a 2-party bridge";
1547                 info->description =
1548                         "The most 'basic' of scenarios\n";
1549                 return AST_TEST_NOT_RUN;
1550         case TEST_EXECUTE:
1551                 break;
1552         }
1553
1554         SWAP_CONFIG(config, debug_cdr_config);
1555
1556         CREATE_ALICE_CHANNEL(chan_caller, &caller, &expected);
1557
1558         EMULATE_APP_DATA(chan_caller, 1, "Dial", CHANNEL_TECH_NAME "/Bob");
1559
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)");
1563
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");
1567
1568         ast_channel_state_set(chan_caller, AST_STATE_UP);
1569         ast_channel_state_set(chan_callee, AST_STATE_UP);
1570
1571         bridge = ast_bridge_basic_new();
1572         ast_test_validate(test, bridge != NULL);
1573         while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
1574
1575         ast_bridge_impart(bridge, chan_caller, NULL, NULL, 0);
1576         ast_bridge_impart(bridge, chan_callee, NULL, NULL, 0);
1577
1578         while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
1579
1580         ast_bridge_depart(chan_caller);
1581         ast_bridge_depart(chan_callee);
1582
1583         HANGUP_CHANNEL(chan_caller, AST_CAUSE_NORMAL);
1584         HANGUP_CHANNEL(chan_callee, AST_CAUSE_NORMAL);
1585
1586         result = verify_mock_cdr_record(test, &expected, 1);
1587         return result;
1588 }
1589
1590 AST_TEST_DEFINE(test_cdr_dial_answer_twoparty_bridge_b)
1591 {
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),
1596                         ao2_cleanup);
1597         struct timespec to_sleep = {1, 0};
1598         enum ast_test_result_state result = AST_TEST_NOT_RUN;
1599
1600         struct ast_party_caller caller = ALICE_CALLERID;
1601         struct ast_cdr expected = {
1602                 .clid = "\"Alice\" <100>",
1603                 .src = "100",
1604                 .dst = "100",
1605                 .dcontext = "default",
1606                 .channel = CHANNEL_TECH_NAME "/Alice",
1607                 .dstchannel = CHANNEL_TECH_NAME "/Bob",
1608                 .lastapp = "Dial",
1609                 .lastdata = CHANNEL_TECH_NAME "/Bob",
1610                 .amaflags = AST_AMA_DOCUMENTATION,
1611                 .billsec = 1,
1612                 .disposition = AST_CDR_ANSWERED,
1613                 .accountcode = "100",
1614                 .peeraccount = "200",
1615         };
1616
1617         switch (cmd) {
1618         case TEST_INIT:
1619                 info->name = __func__;
1620                 info->category = TEST_CATEGORY;
1621                 info->summary = "Test dialing, answering, and going into a 2-party bridge";
1622                 info->description =
1623                         "The most 'basic' of scenarios\n";
1624                 return AST_TEST_NOT_RUN;
1625         case TEST_EXECUTE:
1626                 break;
1627         }
1628
1629         SWAP_CONFIG(config, debug_cdr_config);
1630
1631         CREATE_ALICE_CHANNEL(chan_caller, &caller, &expected);
1632
1633         EMULATE_APP_DATA(chan_caller, 1, "Dial", CHANNEL_TECH_NAME "/Bob");
1634
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)");
1638
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");
1642
1643         ast_channel_state_set(chan_caller, AST_STATE_UP);
1644         ast_channel_state_set(chan_callee, AST_STATE_UP);
1645
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);
1655
1656         HANGUP_CHANNEL(chan_caller, AST_CAUSE_NORMAL);
1657         HANGUP_CHANNEL(chan_callee, AST_CAUSE_NORMAL);
1658
1659         result = verify_mock_cdr_record(test, &expected, 1);
1660         return result;
1661 }
1662
1663 AST_TEST_DEFINE(test_cdr_dial_answer_multiparty)
1664 {
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),
1671                         ao2_cleanup);
1672         struct timespec to_sleep = {1, 0};
1673         enum ast_test_result_state result = AST_TEST_NOT_RUN;
1674
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>",
1679                 .src = "300",
1680                 .dst = "300",
1681                 .dcontext = "default",
1682                 .channel = CHANNEL_TECH_NAME "/Charlie",
1683                 .dstchannel = CHANNEL_TECH_NAME "/Bob",
1684                 .lastapp = "Dial",
1685                 .lastdata = CHANNEL_TECH_NAME "/David",
1686                 .amaflags = AST_AMA_DOCUMENTATION,
1687                 .billsec = 1,
1688                 .disposition = AST_CDR_ANSWERED,
1689                 .accountcode = "300",
1690                 .peeraccount = "200",
1691         };
1692         struct ast_cdr charlie_expected_one = {
1693                 .clid = "\"Charlie\" <300>",
1694                 .src = "300",
1695                 .dst = "300",
1696                 .dcontext = "default",
1697                 .channel = CHANNEL_TECH_NAME "/Charlie",
1698                 .dstchannel = CHANNEL_TECH_NAME "/David",
1699                 .lastapp = "Dial",
1700                 .lastdata = CHANNEL_TECH_NAME "/David",
1701                 .amaflags = AST_AMA_DOCUMENTATION,
1702                 .billsec = 1,
1703                 .disposition = AST_CDR_ANSWERED,
1704                 .accountcode = "300",
1705                 .peeraccount = "400",
1706                 .next = &charlie_expected_two,
1707         };
1708         struct ast_cdr alice_expected_three = {
1709                 .clid = "\"Alice\" <100>",
1710                 .src = "100",
1711                 .dst = "100",
1712                 .dcontext = "default",
1713                 .channel = CHANNEL_TECH_NAME "/Alice",
1714                 .dstchannel = CHANNEL_TECH_NAME "/David",
1715                 .lastapp = "Dial",
1716                 .lastdata = CHANNEL_TECH_NAME "/Bob",
1717                 .amaflags = AST_AMA_DOCUMENTATION,
1718                 .billsec = 1,
1719                 .disposition = AST_CDR_ANSWERED,
1720                 .accountcode = "100",
1721                 .peeraccount = "400",
1722                 .next = &charlie_expected_one,
1723         };
1724         struct ast_cdr alice_expected_two = {
1725                 .clid = "\"Alice\" <100>",
1726                 .src = "100",
1727                 .dst = "100",
1728                 .dcontext = "default",
1729                 .channel = CHANNEL_TECH_NAME "/Alice",
1730                 .dstchannel = CHANNEL_TECH_NAME "/Charlie",
1731                 .lastapp = "Dial",
1732                 .lastdata = CHANNEL_TECH_NAME "/Bob",
1733                 .amaflags = AST_AMA_DOCUMENTATION,
1734                 .billsec = 1,
1735                 .disposition = AST_CDR_ANSWERED,
1736                 .accountcode = "100",
1737                 .peeraccount = "300",
1738                 .next = &alice_expected_three,
1739         };
1740         struct ast_cdr alice_expected_one = {
1741                 .clid = "\"Alice\" <100>",
1742                 .src = "100",
1743                 .dst = "100",
1744                 .dcontext = "default",
1745                 .channel = CHANNEL_TECH_NAME "/Alice",
1746                 .dstchannel = CHANNEL_TECH_NAME "/Bob",
1747                 .lastapp = "Dial",
1748                 .lastdata = CHANNEL_TECH_NAME "/Bob",
1749                 .amaflags = AST_AMA_DOCUMENTATION,
1750                 .billsec = 1,
1751                 .disposition = AST_CDR_ANSWERED,
1752                 .accountcode = "100",
1753                 .peeraccount = "200",
1754                 .next = &alice_expected_two,
1755         };
1756
1757         switch (cmd) {
1758         case TEST_INIT:
1759                 info->name = __func__;
1760                 info->category = TEST_CATEGORY;
1761                 info->summary = "Test dialing, answering, and going into a multi-party bridge";
1762                 info->description =
1763                         "A little tricky to get to do, but possible with some redirects.\n";
1764                 return AST_TEST_NOT_RUN;
1765         case TEST_EXECUTE:
1766                 break;
1767         }
1768
1769         SWAP_CONFIG(config, debug_cdr_config);
1770
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);
1774
1775         EMULATE_APP_DATA(chan_alice, 1, "Dial", CHANNEL_TECH_NAME "/Bob");
1776
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)");
1780
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));
1787
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)");
1791
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");
1798
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);
1803
1804         bridge = ast_bridge_basic_new();
1805         ast_test_validate(test, bridge != NULL);
1806
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));
1820
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);
1825
1826         result = verify_mock_cdr_record(test, &alice_expected_one, 5);
1827
1828         return result;
1829 }
1830
1831 AST_TEST_DEFINE(test_cdr_park)
1832 {
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),
1837                         ao2_cleanup);
1838         struct timespec to_sleep = {1, 0};
1839
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>",
1844                 .src = "200",
1845                 .dst = "200",
1846                 .dcontext = "default",
1847                 .channel = CHANNEL_TECH_NAME "/Bob",
1848                 .lastapp = "Park",
1849                 .lastdata = "701",
1850                 .billsec = 1,
1851                 .amaflags = AST_AMA_DOCUMENTATION,
1852                 .disposition = AST_CDR_ANSWERED,
1853                 .accountcode = "200",
1854         };
1855         struct ast_cdr alice_expected = {
1856                 .clid = "\"Alice\" <100>",
1857                 .src = "100",
1858                 .dst = "100",
1859                 .dcontext = "default",
1860                 .channel = CHANNEL_TECH_NAME "/Alice",
1861                 .lastapp = "Park",
1862                 .lastdata = "700",
1863                 .billsec = 1,
1864                 .amaflags = AST_AMA_DOCUMENTATION,
1865                 .disposition = AST_CDR_ANSWERED,
1866                 .accountcode = "100",
1867                 .next = &bob_expected,
1868         };
1869         enum ast_test_result_state result = AST_TEST_NOT_RUN;
1870
1871         switch (cmd) {
1872         case TEST_INIT:
1873                 info->name = __func__;
1874                 info->category = TEST_CATEGORY;
1875                 info->summary = "Test cdrs for a single party entering Park";
1876                 info->description =
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;
1880         case TEST_EXECUTE:
1881                 break;
1882         }
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);
1886
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);
1891
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);
1896
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);
1904
1905         /* And then it hangs up */
1906         HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL);
1907         HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL);
1908
1909         result = verify_mock_cdr_record(test, &alice_expected, 2);
1910
1911         return result;
1912 }
1913
1914
1915 AST_TEST_DEFINE(test_cdr_fields)
1916 {
1917         RAII_VAR(struct ast_channel *, chan, NULL, safe_channel_release);
1918         RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
1919                         ao2_cleanup);
1920         char varbuffer[128];
1921         int int_buffer;
1922         double db_buffer;
1923         struct timespec to_sleep = {2, 0};
1924         struct ast_flags fork_options = { 0, };
1925
1926         struct ast_party_caller caller = ALICE_CALLERID;
1927         struct ast_cdr original = {
1928                 .clid = "\"Alice\" <100>",
1929                 .src = "100",
1930                 .dst = "100",
1931                 .dcontext = "default",
1932                 .channel = CHANNEL_TECH_NAME "/Alice",
1933                 .lastapp = "Wait",
1934                 .lastdata = "10",
1935                 .billsec = 0,
1936                 .amaflags = AST_AMA_OMIT,
1937                 .disposition = AST_CDR_FAILED,
1938                 .accountcode = "XXX",
1939                 .userfield = "yackity",
1940         };
1941         struct ast_cdr fork_expected_one = {
1942                 .clid = "\"Alice\" <100>",
1943                 .src = "100",
1944                 .dst = "100",
1945                 .dcontext = "default",
1946                 .channel = CHANNEL_TECH_NAME "/Alice",
1947                 .lastapp = "Wait",
1948                 .lastdata = "10",
1949                 .billsec = 0,
1950                 .amaflags = AST_AMA_OMIT,
1951                 .disposition = AST_CDR_FAILED,
1952                 .accountcode = "XXX",
1953                 .userfield = "yackity",
1954         };
1955         struct ast_cdr fork_expected_two = {
1956                 .clid = "\"Alice\" <100>",
1957                 .src = "100",
1958                 .dst = "100",
1959                 .dcontext = "default",
1960                 .channel = CHANNEL_TECH_NAME "/Alice",
1961                 .lastapp = "Answer",
1962                 .billsec = 0,
1963                 .amaflags = AST_AMA_OMIT,
1964                 .disposition = AST_CDR_ANSWERED,
1965                 .accountcode = "ZZZ",
1966                 .userfield = "schmackity",
1967         };
1968         enum ast_test_result_state result = AST_TEST_NOT_RUN;
1969
1970         struct ast_cdr *expected = &original;
1971         original.next = &fork_expected_one;
1972         fork_expected_one.next = &fork_expected_two;
1973
1974         switch (cmd) {
1975         case TEST_INIT:
1976                 info->name = __func__;
1977                 info->category = TEST_CATEGORY;
1978                 info->summary = "Test field access CDRs";
1979                 info->description =
1980                         "This tests setting/retrieving data on CDR records.\n";
1981                 return AST_TEST_NOT_RUN;
1982         case TEST_EXECUTE:
1983                 break;
1984         }
1985
1986         SWAP_CONFIG(config, unanswered_cdr_config);
1987
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));
1993
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);
1999
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");
2003
2004         /* Wait one second so we get a duration. */
2005         while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
2006
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);
2009
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);
2031
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);
2081
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);
2085
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);
2089
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);
2093
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);
2100
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);
2105
2106         /* Hang up and verify */
2107         ast_channel_hangupcause_set(chan, AST_CAUSE_NORMAL);
2108         if (!ast_hangup(chan)) {
2109                 chan = NULL;
2110         }
2111         result = verify_mock_cdr_record(test, expected, 3);
2112
2113         return result;
2114 }
2115
2116 AST_TEST_DEFINE(test_cdr_no_reset_cdr)
2117 {
2118         RAII_VAR(struct ast_channel *, chan, NULL, safe_channel_release);
2119         RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
2120                         ao2_cleanup);
2121         struct ast_flags fork_options = { 0, };
2122         struct timespec to_sleep = {1, 0};
2123
2124         struct ast_party_caller caller = ALICE_CALLERID;
2125         struct ast_cdr expected = {
2126                 .clid = "\"Alice\" <100>",
2127                 .src = "100",
2128                 .dst = "100",
2129                 .dcontext = "default",
2130                 .channel = CHANNEL_TECH_NAME "/Alice",
2131                 .billsec = 0,
2132                 .amaflags = AST_AMA_DOCUMENTATION,
2133                 .disposition = AST_CDR_FAILED,
2134                 .accountcode = "100",
2135         };
2136         enum ast_test_result_state result = AST_TEST_NOT_RUN;
2137
2138         switch (cmd) {
2139         case TEST_INIT:
2140                 info->name = __func__;
2141                 info->category = TEST_CATEGORY;
2142                 info->summary = "Test field access CDRs";
2143                 info->description =
2144                         "This tests setting/retrieving data on CDR records.\n";
2145                 return AST_TEST_NOT_RUN;
2146         case TEST_EXECUTE:
2147                 break;
2148         }
2149
2150         SWAP_CONFIG(config, unanswered_cdr_config);
2151
2152         CREATE_ALICE_CHANNEL(chan, &caller, &expected);
2153
2154         while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
2155
2156         /* Disable the CDR */
2157         ast_test_validate(test, ast_cdr_set_property(ast_channel_name(chan), AST_CDR_FLAG_DISABLE) == 0);
2158
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);
2162
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);
2166
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);
2169
2170         /* Disable all future CDRs */
2171         ast_test_validate(test, ast_cdr_set_property(ast_channel_name(chan), AST_CDR_FLAG_DISABLE_ALL) == 0);
2172
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);
2177
2178         ast_channel_hangupcause_set(chan, AST_CAUSE_NORMAL);
2179         if (!ast_hangup(chan)) {
2180                 chan = NULL;
2181         }
2182         result = verify_mock_cdr_record(test, &expected, 1);
2183
2184         return result;
2185 }
2186
2187 AST_TEST_DEFINE(test_cdr_fork_cdr)
2188 {
2189         RAII_VAR(struct ast_channel *, chan, NULL, safe_channel_release);
2190         RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
2191                         ao2_cleanup);
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};
2200
2201         struct ast_party_caller caller = ALICE_CALLERID;
2202         struct ast_cdr original = {
2203                 .clid = "\"Alice\" <100>",
2204                 .src = "100",
2205                 .dst = "100",
2206                 .dcontext = "default",
2207                 .channel = CHANNEL_TECH_NAME "/Alice",
2208                 .amaflags = AST_AMA_DOCUMENTATION,
2209                 .disposition = AST_CDR_ANSWERED,
2210                 .accountcode = "100",
2211         };
2212         struct ast_cdr fork_expected_one = {
2213                 .clid = "\"Alice\" <100>",
2214                 .src = "100",
2215                 .dst = "100",
2216                 .dcontext = "default",
2217                 .channel = CHANNEL_TECH_NAME "/Alice",
2218                 .amaflags = AST_AMA_DOCUMENTATION,
2219                 .disposition = AST_CDR_ANSWERED,
2220                 .accountcode = "100",
2221         };
2222         struct ast_cdr fork_expected_two = {
2223                 .clid = "\"Alice\" <100>",
2224                 .src = "100",
2225                 .dst = "100",
2226                 .dcontext = "default",
2227                 .channel = CHANNEL_TECH_NAME "/Alice",
2228                 .amaflags = AST_AMA_DOCUMENTATION,
2229                 .disposition = AST_CDR_ANSWERED,
2230                 .accountcode = "100",
2231         };
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;
2236
2237         switch (cmd) {
2238         case TEST_INIT:
2239                 info->name = __func__;
2240                 info->category = TEST_CATEGORY;
2241                 info->summary = "Test field access CDRs";
2242                 info->description =
2243                         "This tests setting/retrieving data on CDR records.\n";
2244                 return AST_TEST_NOT_RUN;
2245         case TEST_EXECUTE:
2246                 break;
2247         }
2248
2249         SWAP_CONFIG(config, debug_cdr_config);
2250
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));
2256
2257         while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
2258
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));
2264
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);
2268
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);
2272
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);
2281
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);
2292
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);
2300
2301         ast_channel_hangupcause_set(chan, AST_CAUSE_NORMAL);
2302         if (!ast_hangup(chan)) {
2303                 chan = NULL;
2304         }
2305         result = verify_mock_cdr_record(test, expected, 3);
2306
2307         return result;
2308 }
2309
2310 /*!
2311  * \internal \brief Callback function called before each test executes
2312  */
2313 static int test_cdr_init_cb(struct ast_test_info *info, struct ast_test *test)
2314 {
2315         /* Back up the real config */
2316         saved_config = ast_cdr_get_config();
2317         clear_mock_cdr_backend();
2318         return 0;
2319 }
2320
2321 /*!
2322  * \internal \brief Callback function called after each test executes
2323  */
2324 static int test_cdr_cleanup_cb(struct ast_test_info *info, struct ast_test *test)
2325 {
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();
2331
2332         return 0;
2333 }
2334
2335
2336 static int unload_module(void)
2337 {
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);
2347
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);
2358
2359         AST_TEST_UNREGISTER(test_cdr_park);
2360
2361         AST_TEST_UNREGISTER(test_cdr_fields);
2362         AST_TEST_UNREGISTER(test_cdr_no_reset_cdr);
2363         AST_TEST_UNREGISTER(test_cdr_fork_cdr);
2364
2365         ast_cdr_unregister(MOCK_CDR_BACKEND);
2366         ast_channel_unregister(&test_cdr_chan_tech);
2367         clear_mock_cdr_backend();
2368
2369         return 0;
2370 }
2371
2372 static int load_module(void)
2373 {
2374         ast_cond_init(&mock_cdr_cond, NULL);
2375
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);
2379
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);
2386
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);
2397
2398         AST_TEST_REGISTER(test_cdr_park);
2399
2400         AST_TEST_REGISTER(test_cdr_fields);
2401         AST_TEST_REGISTER(test_cdr_no_reset_cdr);
2402         AST_TEST_REGISTER(test_cdr_fork_cdr);
2403
2404         ast_test_register_init(TEST_CATEGORY, test_cdr_init_cb);
2405         ast_test_register_cleanup(TEST_CATEGORY, test_cdr_cleanup_cb);
2406
2407         ast_channel_register(&test_cdr_chan_tech);
2408         ast_cdr_register(MOCK_CDR_BACKEND, "Mock CDR backend", mock_cdr_backend_cb);
2409
2410         return AST_MODULE_LOAD_SUCCESS;
2411 }
2412
2413 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "CDR unit tests");