a60f78e2cf6b5fe00efd87fa54f629fb4012ef52
[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_outbound_bridged_call)
498 {
499         RAII_VAR(struct ast_channel *, chan_alice, NULL, safe_channel_release);
500         RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release);
501         RAII_VAR(struct ast_bridge *, bridge, NULL, ao2_cleanup);
502         RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
503                         ao2_cleanup);
504         struct timespec to_sleep = {1, 0};
505         enum ast_test_result_state result = AST_TEST_NOT_RUN;
506
507         struct ast_party_caller caller = ALICE_CALLERID;
508         struct ast_cdr alice_expected = {
509                 .clid = "\"Alice\" <100>",
510                 .src = "100",
511                 .dst = "100",
512                 .dcontext = "default",
513                 .channel = CHANNEL_TECH_NAME "/Alice",
514                 .dstchannel = CHANNEL_TECH_NAME "/Bob",
515                 .lastapp = "",
516                 .lastdata = "",
517                 .amaflags = AST_AMA_DOCUMENTATION,
518                 .billsec = 1,
519                 .disposition = AST_CDR_ANSWERED,
520                 .accountcode = "100",
521                 .peeraccount = "200",
522         };
523         struct ast_cdr bob_expected = {
524                 .clid = "\"\" <>",
525                 .src = "",
526                 .dst = "s",
527                 .dcontext = "default",
528                 .channel = CHANNEL_TECH_NAME "/Bob",
529                 .dstchannel = "",
530                 .lastapp = "AppDial",
531                 .lastdata = "(Outgoing Line)",
532                 .amaflags = AST_AMA_DOCUMENTATION,
533                 .billsec = 1,
534                 .disposition = AST_CDR_ANSWERED,
535                 .accountcode = "200",
536                 .peeraccount = "",
537                 .next = &alice_expected,
538         };
539
540         switch (cmd) {
541         case TEST_INIT:
542                 info->name = __func__;
543                 info->category = TEST_CATEGORY;
544                 info->summary = "Test dialing, answering, and going into a 2-party bridge";
545                 info->description =
546                         "The most 'basic' of scenarios\n";
547                 return AST_TEST_NOT_RUN;
548         case TEST_EXECUTE:
549                 break;
550         }
551
552         SWAP_CONFIG(config, debug_cdr_config);
553
554         CREATE_ALICE_CHANNEL(chan_alice, &caller, &alice_expected);
555         ast_channel_state_set(chan_alice, AST_STATE_UP);
556
557         bridge = ast_bridge_basic_new();
558         ast_test_validate(test, bridge != NULL);
559         while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
560
561         ast_bridge_impart(bridge, chan_alice, NULL, NULL, 0);
562
563         chan_bob = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, ast_channel_linkedid(chan_alice), 0, CHANNEL_TECH_NAME "/Bob");
564         ast_copy_string(bob_expected.linkedid, ast_channel_linkedid(chan_bob), sizeof(bob_expected.linkedid));
565         ast_copy_string(bob_expected.uniqueid, ast_channel_uniqueid(chan_bob), sizeof(bob_expected.uniqueid));
566         ast_set_flag(ast_channel_flags(chan_bob), AST_FLAG_OUTGOING);
567         ast_set_flag(ast_channel_flags(chan_bob), AST_FLAG_ORIGINATED);
568         EMULATE_APP_DATA(chan_bob, 0, "AppDial", "(Outgoing Line)");
569
570         ast_channel_publish_dial(NULL, chan_bob, "Bob", NULL);
571         ast_channel_state_set(chan_bob, AST_STATE_RINGING);
572         ast_channel_publish_dial(NULL, chan_bob, NULL, "ANSWER");
573
574         ast_channel_state_set(chan_bob, AST_STATE_UP);
575
576         while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
577
578         ast_bridge_impart(bridge, chan_bob, NULL, NULL, 0);
579
580         while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
581
582         ast_bridge_depart(chan_bob);
583         ast_bridge_depart(chan_alice);
584
585         HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL);
586         HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL);
587
588         result = verify_mock_cdr_record(test, &bob_expected, 2);
589         return result;
590 }
591
592
593 AST_TEST_DEFINE(test_cdr_single_party)
594 {
595         RAII_VAR(struct ast_channel *, chan, NULL, safe_channel_release);
596         RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
597                         ao2_cleanup);
598
599         struct ast_party_caller caller = ALICE_CALLERID;
600         struct ast_cdr expected = {
601                 .clid = "\"Alice\" <100>",
602                 .src = "100",
603                 .dst = "100",
604                 .dcontext = "default",
605                 .channel = CHANNEL_TECH_NAME "/Alice",
606                 .dstchannel = "",
607                 .lastapp = "VoiceMailMain",
608                 .lastdata = "1",
609                 .billsec = 1,
610         .amaflags = AST_AMA_DOCUMENTATION,
611                 .disposition = AST_CDR_ANSWERED,
612                 .accountcode = "100",
613         };
614         enum ast_test_result_state result = AST_TEST_NOT_RUN;
615
616         switch (cmd) {
617         case TEST_INIT:
618                 info->name = __func__;
619                 info->category = TEST_CATEGORY;
620                 info->summary = "Test cdrs for a single party";
621                 info->description =
622                         "Test the properties of a CDR for a call that is\n"
623                         "answered, but only involves a single channel\n";
624                 return AST_TEST_NOT_RUN;
625         case TEST_EXECUTE:
626                 break;
627         }
628         SWAP_CONFIG(config, debug_cdr_config);
629         CREATE_ALICE_CHANNEL(chan, &caller, &expected);
630
631         EMULATE_APP_DATA(chan, 1, "Answer", "");
632         ast_setstate(chan, AST_STATE_UP);
633         EMULATE_APP_DATA(chan, 2, "VoiceMailMain", "1");
634
635         HANGUP_CHANNEL(chan, AST_CAUSE_NORMAL);
636
637         result = verify_mock_cdr_record(test, &expected, 1);
638
639         return result;
640 }
641
642 AST_TEST_DEFINE(test_cdr_single_bridge)
643 {
644         RAII_VAR(struct ast_channel *, chan, NULL, safe_channel_release);
645         RAII_VAR(struct ast_bridge *, bridge, NULL, ao2_cleanup);
646         RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
647                         ao2_cleanup);
648         struct timespec to_sleep = {1, 0};
649
650         struct ast_party_caller caller = ALICE_CALLERID;
651         struct ast_cdr expected = {
652                 .clid = "\"Alice\" <100>",
653                 .src = "100",
654                 .dst = "100",
655                 .dcontext = "default",
656                 .channel = CHANNEL_TECH_NAME "/Alice",
657                 .lastapp = "Bridge",
658                 .billsec = 1,
659                 .amaflags = AST_AMA_DOCUMENTATION,
660                 .disposition = AST_CDR_ANSWERED,
661                 .accountcode = "100",
662         };
663         enum ast_test_result_state result = AST_TEST_NOT_RUN;
664
665         switch (cmd) {
666         case TEST_INIT:
667                 info->name = __func__;
668                 info->category = TEST_CATEGORY;
669                 info->summary = "Test cdrs for a single party entering/leaving a bridge";
670                 info->description =
671                         "Test the properties of a CDR for a call that is\n"
672                         "answered, enters a bridge, and leaves it.\n";
673                 return AST_TEST_NOT_RUN;
674         case TEST_EXECUTE:
675                 break;
676         }
677         SWAP_CONFIG(config, debug_cdr_config);
678         CREATE_ALICE_CHANNEL(chan, &caller, &expected);
679
680         EMULATE_APP_DATA(chan, 1, "Answer", "");
681         ast_setstate(chan, AST_STATE_UP);
682         EMULATE_APP_DATA(chan, 2, "Bridge", "");
683
684         bridge = ast_bridge_basic_new();
685         ast_test_validate(test, bridge != NULL);
686
687         while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
688         ast_bridge_impart(bridge, chan, NULL, NULL, 0);
689
690         while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
691
692         ast_bridge_depart(chan);
693
694         HANGUP_CHANNEL(chan, AST_CAUSE_NORMAL);
695
696         result = verify_mock_cdr_record(test, &expected, 1);
697
698         return result;
699 }
700
701 AST_TEST_DEFINE(test_cdr_single_bridge_continue)
702 {
703         RAII_VAR(struct ast_channel *, chan, NULL, safe_channel_release);
704         RAII_VAR(struct ast_bridge *, bridge_one, NULL, ao2_cleanup);
705         RAII_VAR(struct ast_bridge *, bridge_two, NULL, ao2_cleanup);
706         RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
707                         ao2_cleanup);
708         struct timespec to_sleep = {1, 0};
709
710         struct ast_party_caller caller = ALICE_CALLERID;
711         struct ast_cdr expected_two = {
712                 .clid = "\"Alice\" <100>",
713                 .src = "100",
714                 .dst = "100",
715                 .dcontext = "default",
716                 .channel = CHANNEL_TECH_NAME "/Alice",
717                 .lastapp = "Wait",
718                 .billsec = 1,
719                 .amaflags = AST_AMA_DOCUMENTATION,
720                 .disposition = AST_CDR_ANSWERED,
721                 .accountcode = "100",
722         };
723         struct ast_cdr expected_one = {
724                 .clid = "\"Alice\" <100>",
725                 .src = "100",
726                 .dst = "100",
727                 .dcontext = "default",
728                 .channel = CHANNEL_TECH_NAME "/Alice",
729                 .lastapp = "Bridge",
730                 .billsec = 1,
731                 .amaflags = AST_AMA_DOCUMENTATION,
732                 .disposition = AST_CDR_ANSWERED,
733                 .accountcode = "100",
734                 .next = &expected_two,
735         };
736
737         enum ast_test_result_state result = AST_TEST_NOT_RUN;
738
739         switch (cmd) {
740         case TEST_INIT:
741                 info->name = __func__;
742                 info->category = TEST_CATEGORY;
743                 info->summary = "Test cdrs for a single party entering/leaving a bridge";
744                 info->description =
745                         "Test the properties of a CDR for a call that is\n"
746                         "answered, enters a bridge, and leaves it.\n";
747                 return AST_TEST_NOT_RUN;
748         case TEST_EXECUTE:
749                 break;
750         }
751         SWAP_CONFIG(config, debug_cdr_config);
752         CREATE_ALICE_CHANNEL(chan, &caller, &expected_one);
753         COPY_IDS(chan, &expected_two);
754
755         EMULATE_APP_DATA(chan, 1, "Answer", "");
756         ast_setstate(chan, AST_STATE_UP);
757         EMULATE_APP_DATA(chan, 2, "Bridge", "");
758
759         bridge_one = ast_bridge_basic_new();
760         ast_test_validate(test, bridge_one != NULL);
761         while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
762
763         ast_bridge_impart(bridge_one, chan, NULL, NULL, 0);
764
765         while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
766
767         ast_bridge_depart(chan);
768
769         EMULATE_APP_DATA(chan, 3, "Wait", "");
770
771         /* And then it hangs up */
772         HANGUP_CHANNEL(chan, AST_CAUSE_NORMAL);
773
774         result = verify_mock_cdr_record(test, &expected_one, 2);
775
776         return result;
777 }
778
779 AST_TEST_DEFINE(test_cdr_single_twoparty_bridge_a)
780 {
781         RAII_VAR(struct ast_channel *, chan_alice, NULL, safe_channel_release);
782         RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release);
783         RAII_VAR(struct ast_bridge *, bridge, NULL, ao2_cleanup);
784         RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
785                         ao2_cleanup);
786         struct timespec to_sleep = {1, 0};
787
788         struct ast_party_caller caller_alice = ALICE_CALLERID;
789         struct ast_party_caller caller_bob = BOB_CALLERID;
790         struct ast_cdr bob_expected = {
791                 .clid = "\"Bob\" <200>",
792                 .src = "200",
793                 .dst = "200",
794                 .dcontext = "default",
795                 .channel = CHANNEL_TECH_NAME "/Bob",
796                 .lastapp = "Bridge",
797                 .billsec = 1,
798                 .amaflags = AST_AMA_DOCUMENTATION,
799                 .disposition = AST_CDR_ANSWERED,
800                 .accountcode = "200",
801         };
802         struct ast_cdr alice_expected = {
803                 .clid = "\"Alice\" <100>",
804                 .src = "100",
805                 .dst = "100",
806                 .dcontext = "default",
807                 .channel = CHANNEL_TECH_NAME "/Alice",
808                 .dstchannel = CHANNEL_TECH_NAME "/Bob",
809                 .lastapp = "Bridge",
810                 .billsec = 1,
811                 .amaflags = AST_AMA_DOCUMENTATION,
812                 .disposition = AST_CDR_ANSWERED,
813                 .accountcode = "100",
814                 .peeraccount = "200",
815                 .next = &bob_expected,
816         };
817
818         enum ast_test_result_state result = AST_TEST_NOT_RUN;
819
820         switch (cmd) {
821         case TEST_INIT:
822                 info->name = __func__;
823                 info->category = TEST_CATEGORY;
824                 info->summary = "Test cdrs for a single party entering/leaving a bridge";
825                 info->description =
826                         "Test the properties of a CDR for a call that is\n"
827                         "answered, enters a bridge, and leaves it. In this scenario, the\n"
828                         "Party A should answer the bridge first.\n";
829                 return AST_TEST_NOT_RUN;
830         case TEST_EXECUTE:
831                 break;
832         }
833         SWAP_CONFIG(config, debug_cdr_config);
834         CREATE_ALICE_CHANNEL(chan_alice, &caller_alice, &alice_expected);
835
836         CREATE_BOB_CHANNEL(chan_bob, &caller_bob, &bob_expected);
837         ast_copy_string(bob_expected.linkedid, ast_channel_linkedid(chan_alice), sizeof(bob_expected.linkedid));
838
839         EMULATE_APP_DATA(chan_alice, 1, "Answer", "");
840         ast_setstate(chan_alice, AST_STATE_UP);
841         EMULATE_APP_DATA(chan_alice, 2, "Bridge", "");
842
843         bridge = ast_bridge_basic_new();
844         ast_test_validate(test, bridge != NULL);
845
846         ast_bridge_impart(bridge, chan_alice, NULL, NULL, 0);
847         while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
848
849         EMULATE_APP_DATA(chan_bob, 1, "Answer", "");
850         ast_setstate(chan_bob, AST_STATE_UP);
851         EMULATE_APP_DATA(chan_bob, 2, "Bridge", "");
852
853         ast_bridge_impart(bridge, chan_bob, NULL, NULL, 0);
854         while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
855
856         ast_bridge_depart(chan_alice);
857         ast_bridge_depart(chan_bob);
858
859         HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL);
860         HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL);
861
862         result = verify_mock_cdr_record(test, &alice_expected, 2);
863
864         return result;
865 }
866
867 AST_TEST_DEFINE(test_cdr_single_twoparty_bridge_b)
868 {
869         RAII_VAR(struct ast_channel *, chan_alice, NULL, safe_channel_release);
870         RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release);
871         RAII_VAR(struct ast_bridge *, bridge, NULL, ao2_cleanup);
872         RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
873                         ao2_cleanup);
874         struct timespec to_sleep = {1, 0};
875
876         struct ast_party_caller caller_alice = ALICE_CALLERID;
877         struct ast_party_caller caller_bob = BOB_CALLERID;
878         struct ast_cdr bob_expected = {
879                 .clid = "\"Bob\" <200>",
880                 .src = "200",
881                 .dst = "200",
882                 .dcontext = "default",
883                 .channel = CHANNEL_TECH_NAME "/Bob",
884                 .lastapp = "Bridge",
885                 .billsec = 1,
886                 .amaflags = AST_AMA_DOCUMENTATION,
887                 .disposition = AST_CDR_ANSWERED,
888                 .accountcode = "200",
889         };
890         struct ast_cdr alice_expected = {
891                 .clid = "\"Alice\" <100>",
892                 .src = "100",
893                 .dst = "100",
894                 .dcontext = "default",
895                 .channel = CHANNEL_TECH_NAME "/Alice",
896                 .dstchannel = CHANNEL_TECH_NAME "/Bob",
897                 .lastapp = "Bridge",
898                 .billsec = 1,
899                 .amaflags = AST_AMA_DOCUMENTATION,
900                 .disposition = AST_CDR_ANSWERED,
901                 .accountcode = "100",
902                 .peeraccount = "200",
903                 .next = &bob_expected,
904         };
905
906         enum ast_test_result_state result = AST_TEST_NOT_RUN;
907
908         switch (cmd) {
909         case TEST_INIT:
910                 info->name = __func__;
911                 info->category = TEST_CATEGORY;
912                 info->summary = "Test cdrs for a single party entering/leaving a bridge";
913                 info->description =
914                         "Test the properties of a CDR for a call that is\n"
915                         "answered, enters a bridge, and leaves it. In this scenario, the\n"
916                         "Party B should answer the bridge first.\n";
917                 return AST_TEST_NOT_RUN;
918         case TEST_EXECUTE:
919                 break;
920         }
921         SWAP_CONFIG(config, debug_cdr_config);
922         CREATE_ALICE_CHANNEL(chan_alice, &caller_alice, &alice_expected);
923
924         CREATE_BOB_CHANNEL(chan_bob, &caller_bob, &bob_expected);
925         ast_copy_string(bob_expected.linkedid, ast_channel_linkedid(chan_alice), sizeof(bob_expected.linkedid));
926
927         EMULATE_APP_DATA(chan_alice, 1, "Answer", "");
928         ast_setstate(chan_alice, AST_STATE_UP);
929         EMULATE_APP_DATA(chan_alice, 2, "Bridge", "");
930
931         bridge = ast_bridge_basic_new();
932         ast_test_validate(test, bridge != NULL);
933
934         EMULATE_APP_DATA(chan_bob, 1, "Answer", "");
935         ast_setstate(chan_bob, AST_STATE_UP);
936         EMULATE_APP_DATA(chan_bob, 2, "Bridge", "");
937         while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
938
939         ast_bridge_impart(bridge, chan_bob, NULL, NULL, 0);
940         while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
941
942         ast_bridge_impart(bridge, chan_alice, NULL, NULL, 0);
943         while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
944
945         ast_bridge_depart(chan_alice);
946         ast_bridge_depart(chan_bob);
947
948         HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL);
949         HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL);
950
951         result = verify_mock_cdr_record(test, &alice_expected, 2);
952
953         return result;
954 }
955
956 AST_TEST_DEFINE(test_cdr_single_multiparty_bridge)
957 {
958         RAII_VAR(struct ast_channel *, chan_alice, NULL, safe_channel_release);
959         RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release);
960         RAII_VAR(struct ast_channel *, chan_charlie, NULL, safe_channel_release);
961         RAII_VAR(struct ast_bridge *, bridge, NULL, ao2_cleanup);
962         RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
963                         ao2_cleanup);
964         struct timespec to_sleep = {1, 0};
965
966         struct ast_party_caller caller_alice = ALICE_CALLERID;
967         struct ast_party_caller caller_bob = BOB_CALLERID;
968         struct ast_party_caller caller_charlie = CHARLIE_CALLERID;
969         struct ast_cdr charlie_expected = {
970                 .clid = "\"Charlie\" <300>",
971                 .src = "300",
972                 .dst = "300",
973                 .dcontext = "default",
974                 .channel = CHANNEL_TECH_NAME "/Charlie",
975                 .lastapp = "Bridge",
976                 .billsec = 1,
977                 .amaflags = AST_AMA_DOCUMENTATION,
978                 .disposition = AST_CDR_ANSWERED,
979                 .accountcode = "300",
980         };
981         struct ast_cdr bob_expected = {
982                 .clid = "\"Bob\" <200>",
983                 .src = "200",
984                 .dst = "200",
985                 .dcontext = "default",
986                 .channel = CHANNEL_TECH_NAME "/Bob",
987                 .dstchannel = CHANNEL_TECH_NAME "/Charlie",
988                 .lastapp = "Bridge",
989                 .billsec = 1,
990                 .amaflags = AST_AMA_DOCUMENTATION,
991                 .disposition = AST_CDR_ANSWERED,
992                 .accountcode = "200",
993                 .peeraccount = "300",
994                 .next = &charlie_expected,
995         };
996         struct ast_cdr alice_expected_two = {
997                 .clid = "\"Alice\" <100>",
998                 .src = "100",
999                 .dst = "100",
1000                 .dcontext = "default",
1001                 .channel = CHANNEL_TECH_NAME "/Alice",
1002                 .dstchannel = CHANNEL_TECH_NAME "/Charlie",
1003                 .lastapp = "Bridge",
1004                 .billsec = 1,
1005                 .amaflags = AST_AMA_DOCUMENTATION,
1006                 .disposition = AST_CDR_ANSWERED,
1007                 .accountcode = "100",
1008                 .peeraccount = "300",
1009                 .next = &bob_expected,
1010         };
1011         struct ast_cdr alice_expected_one = {
1012                 .clid = "\"Alice\" <100>",
1013                 .src = "100",
1014                 .dst = "100",
1015                 .dcontext = "default",
1016                 .channel = CHANNEL_TECH_NAME "/Alice",
1017                 .dstchannel = CHANNEL_TECH_NAME "/Bob",
1018                 .lastapp = "Bridge",
1019                 .billsec = 1,
1020                 .amaflags = AST_AMA_DOCUMENTATION,
1021                 .disposition = AST_CDR_ANSWERED,
1022                 .accountcode = "100",
1023                 .peeraccount = "200",
1024                 .next = &alice_expected_two,
1025         };
1026
1027         enum ast_test_result_state result = AST_TEST_NOT_RUN;
1028
1029         switch (cmd) {
1030         case TEST_INIT:
1031                 info->name = __func__;
1032                 info->category = TEST_CATEGORY;
1033                 info->summary = "Test cdrs for a single party entering/leaving a multi-party bridge";
1034                 info->description =
1035                         "Test the properties of a CDR for a call that is\n"
1036                         "answered, enters a bridge, and leaves it. A total of three\n"
1037                         "parties perform this action.\n";
1038                 return AST_TEST_NOT_RUN;
1039         case TEST_EXECUTE:
1040                 break;
1041         }
1042         SWAP_CONFIG(config, debug_cdr_config);
1043         CREATE_ALICE_CHANNEL(chan_alice, &caller_alice, &alice_expected_one);
1044         COPY_IDS(chan_alice, &alice_expected_two);
1045         CREATE_BOB_CHANNEL(chan_bob, &caller_bob, &bob_expected);
1046         ast_copy_string(bob_expected.linkedid, ast_channel_linkedid(chan_alice), sizeof(bob_expected.linkedid));
1047         CREATE_CHARLIE_CHANNEL(chan_charlie, &caller_charlie, &charlie_expected);
1048         ast_copy_string(charlie_expected.linkedid, ast_channel_linkedid(chan_alice), sizeof(charlie_expected.linkedid));
1049
1050         EMULATE_APP_DATA(chan_alice, 1, "Answer", "");
1051         ast_setstate(chan_alice, AST_STATE_UP);
1052         EMULATE_APP_DATA(chan_alice, 2, "Bridge", "");
1053
1054         bridge = ast_bridge_basic_new();
1055         ast_test_validate(test, bridge != NULL);
1056         while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
1057
1058         ast_bridge_impart(bridge, chan_alice, NULL, NULL, 0);
1059
1060         EMULATE_APP_DATA(chan_bob, 1, "Answer", "");
1061         ast_setstate(chan_bob, AST_STATE_UP);
1062         EMULATE_APP_DATA(chan_bob, 2, "Bridge", "");
1063         while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
1064
1065         ast_bridge_impart(bridge, chan_bob, NULL, NULL, 0);
1066
1067         while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
1068
1069         EMULATE_APP_DATA(chan_charlie, 1, "Answer", "");
1070         ast_setstate(chan_charlie, AST_STATE_UP);
1071         EMULATE_APP_DATA(chan_charlie, 2, "Bridge", "");
1072         ast_bridge_impart(bridge, chan_charlie, NULL, NULL, 0);
1073
1074         while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
1075
1076         ast_bridge_depart(chan_alice);
1077         ast_bridge_depart(chan_bob);
1078         ast_bridge_depart(chan_charlie);
1079
1080         HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL);
1081         HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL);
1082         HANGUP_CHANNEL(chan_charlie, AST_CAUSE_NORMAL);
1083
1084         result = verify_mock_cdr_record(test, &alice_expected_one, 4);
1085
1086         return result;
1087 }
1088
1089 AST_TEST_DEFINE(test_cdr_dial_unanswered)
1090 {
1091         RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
1092         RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
1093         RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
1094                         ao2_cleanup);
1095
1096         struct ast_party_caller caller = ALICE_CALLERID;
1097         struct ast_cdr expected = {
1098                 .clid = "\"Alice\" <100>",
1099                 .src = "100",
1100                 .dst = "100",
1101                 .dcontext = "default",
1102                 .channel = CHANNEL_TECH_NAME "/Alice",
1103                 .dstchannel = CHANNEL_TECH_NAME "/Bob",
1104                 .lastapp = "Dial",
1105                 .lastdata = CHANNEL_TECH_NAME "/Bob",
1106                 .billsec = 0,
1107                 .amaflags = AST_AMA_DOCUMENTATION,
1108                 .disposition = AST_CDR_NOANSWER,
1109                 .accountcode = "100",
1110                 .peeraccount = "200",
1111         };
1112         enum ast_test_result_state result = AST_TEST_NOT_RUN;
1113
1114         switch (cmd) {
1115         case TEST_INIT:
1116                 info->name = __func__;
1117                 info->category = TEST_CATEGORY;
1118                 info->summary = "Test CDRs for a dial that isn't answered";
1119                 info->description =
1120                         "Test the properties of a CDR for a channel that\n"
1121                         "performs a dial operation that isn't answered\n";
1122                 return AST_TEST_NOT_RUN;
1123         case TEST_EXECUTE:
1124                 break;
1125         }
1126
1127         SWAP_CONFIG(config, unanswered_cdr_config);
1128
1129         CREATE_ALICE_CHANNEL(chan_caller, &caller, &expected);
1130
1131         EMULATE_APP_DATA(chan_caller, 1, "Dial", "CDRTestChannel/Bob");
1132
1133         chan_callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, ast_channel_linkedid(chan_caller), 0, CHANNEL_TECH_NAME "/Bob");
1134         ast_set_flag(ast_channel_flags(chan_callee), AST_FLAG_OUTGOING);
1135         EMULATE_APP_DATA(chan_callee, 0, "AppDial", "(Outgoing Line)");
1136
1137         ast_channel_publish_dial(chan_caller, chan_callee, "Bob", NULL);
1138         ast_channel_state_set(chan_caller, AST_STATE_RINGING);
1139         ast_channel_publish_dial(chan_caller, chan_callee, NULL, "NOANSWER");
1140
1141         HANGUP_CHANNEL(chan_caller, AST_CAUSE_NO_ANSWER);
1142         HANGUP_CHANNEL(chan_callee, AST_CAUSE_NO_ANSWER);
1143
1144         result = verify_mock_cdr_record(test, &expected, 1);
1145
1146         return result;
1147 }
1148
1149
1150 AST_TEST_DEFINE(test_cdr_dial_busy)
1151 {
1152         RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
1153         RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
1154         RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
1155                         ao2_cleanup);
1156
1157         struct ast_party_caller caller = ALICE_CALLERID;
1158         struct ast_cdr expected = {
1159                 .clid = "\"Alice\" <100>",
1160                 .src = "100",
1161                 .dst = "100",
1162                 .dcontext = "default",
1163                 .channel = CHANNEL_TECH_NAME "/Alice",
1164                 .dstchannel = CHANNEL_TECH_NAME "/Bob",
1165                 .lastapp = "Dial",
1166                 .lastdata = CHANNEL_TECH_NAME "/Bob",
1167                 .billsec = 0,
1168                 .amaflags = AST_AMA_DOCUMENTATION,
1169                 .disposition = AST_CDR_BUSY,
1170                 .accountcode = "100",
1171                 .peeraccount = "200",
1172         };
1173         enum ast_test_result_state result = AST_TEST_NOT_RUN;
1174
1175         switch (cmd) {
1176         case TEST_INIT:
1177                 info->name = __func__;
1178                 info->category = TEST_CATEGORY;
1179                 info->summary = "Test CDRs for a dial that results in a busy";
1180                 info->description =
1181                         "Test the properties of a CDR for a channel that\n"
1182                         "performs a dial operation to an endpoint that's busy\n";
1183                 return AST_TEST_NOT_RUN;
1184         case TEST_EXECUTE:
1185                 break;
1186         }
1187
1188         SWAP_CONFIG(config, unanswered_cdr_config);
1189
1190         CREATE_ALICE_CHANNEL(chan_caller, &caller, &expected);
1191
1192         EMULATE_APP_DATA(chan_caller, 1, "Dial", CHANNEL_TECH_NAME "/Bob");
1193
1194         chan_callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, ast_channel_linkedid(chan_caller), 0, CHANNEL_TECH_NAME "/Bob");
1195         ast_set_flag(ast_channel_flags(chan_callee), AST_FLAG_OUTGOING);
1196         EMULATE_APP_DATA(chan_callee, 0, "AppDial", "(Outgoing Line)");
1197
1198         ast_channel_publish_dial(chan_caller, chan_callee, "Bob", NULL);
1199         ast_channel_state_set(chan_caller, AST_STATE_RINGING);
1200         ast_channel_publish_dial(chan_caller, chan_callee, NULL, "BUSY");
1201
1202         HANGUP_CHANNEL(chan_caller, AST_CAUSE_BUSY);
1203         HANGUP_CHANNEL(chan_callee, AST_CAUSE_BUSY);
1204
1205         result = verify_mock_cdr_record(test, &expected, 1);
1206
1207         return result;
1208 }
1209
1210 AST_TEST_DEFINE(test_cdr_dial_congestion)
1211 {
1212         RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
1213         RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
1214         RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
1215                         ao2_cleanup);
1216
1217         struct ast_party_caller caller = ALICE_CALLERID;
1218         struct ast_cdr expected = {
1219                 .clid = "\"Alice\" <100>",
1220                 .src = "100",
1221                 .dst = "100",
1222                 .dcontext = "default",
1223                 .channel = CHANNEL_TECH_NAME "/Alice",
1224                 .dstchannel = CHANNEL_TECH_NAME "/Bob",
1225                 .lastapp = "Dial",
1226                 .lastdata = CHANNEL_TECH_NAME "/Bob",
1227                 .billsec = 0,
1228                 .amaflags = AST_AMA_DOCUMENTATION,
1229                 .disposition = AST_CDR_CONGESTION,
1230                 .accountcode = "100",
1231                 .peeraccount = "200",
1232         };
1233         enum ast_test_result_state result = AST_TEST_NOT_RUN;
1234
1235         switch (cmd) {
1236         case TEST_INIT:
1237                 info->name = __func__;
1238                 info->category = TEST_CATEGORY;
1239                 info->summary = "Test CDRs for a dial that results in congestion";
1240                 info->description =
1241                         "Test the properties of a CDR for a channel that\n"
1242                         "performs a dial operation to an endpoint that's congested\n";
1243                 return AST_TEST_NOT_RUN;
1244         case TEST_EXECUTE:
1245                 break;
1246         }
1247
1248         SWAP_CONFIG(config, congestion_cdr_config);
1249
1250         CREATE_ALICE_CHANNEL(chan_caller, &caller, &expected);
1251
1252         EMULATE_APP_DATA(chan_caller, 1, "Dial", CHANNEL_TECH_NAME "/Bob");
1253
1254         chan_callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, ast_channel_linkedid(chan_caller), 0, CHANNEL_TECH_NAME "/Bob");
1255         ast_set_flag(ast_channel_flags(chan_callee), AST_FLAG_OUTGOING);
1256         EMULATE_APP_DATA(chan_callee, 0, "AppDial", "(Outgoing Line)");
1257
1258         ast_channel_publish_dial(chan_caller, chan_callee, "Bob", NULL);
1259         ast_channel_state_set(chan_caller, AST_STATE_RINGING);
1260         ast_channel_publish_dial(chan_caller, chan_callee, NULL, "CONGESTION");
1261
1262         HANGUP_CHANNEL(chan_caller, AST_CAUSE_CONGESTION);
1263         HANGUP_CHANNEL(chan_callee, AST_CAUSE_CONGESTION);
1264
1265         result = verify_mock_cdr_record(test, &expected, 1);
1266
1267         return result;
1268 }
1269
1270 AST_TEST_DEFINE(test_cdr_dial_unavailable)
1271 {
1272         RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
1273         RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
1274         RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
1275                         ao2_cleanup);
1276
1277         struct ast_party_caller caller = ALICE_CALLERID;
1278         struct ast_cdr expected = {
1279                 .clid = "\"Alice\" <100>",
1280                 .src = "100",
1281                 .dst = "100",
1282                 .dcontext = "default",
1283                 .channel = CHANNEL_TECH_NAME "/Alice",
1284                 .dstchannel = CHANNEL_TECH_NAME "/Bob",
1285                 .lastapp = "Dial",
1286                 .lastdata = CHANNEL_TECH_NAME "/Bob",
1287                 .billsec = 0,
1288                 .amaflags = AST_AMA_DOCUMENTATION,
1289                 .disposition = AST_CDR_FAILED,
1290                 .accountcode = "100",
1291                 .peeraccount = "200",
1292         };
1293         enum ast_test_result_state result = AST_TEST_NOT_RUN;
1294
1295         switch (cmd) {
1296         case TEST_INIT:
1297                 info->name = __func__;
1298                 info->category = TEST_CATEGORY;
1299                 info->summary = "Test CDRs for a dial that results in unavailable";
1300                 info->description =
1301                         "Test the properties of a CDR for a channel that\n"
1302                         "performs a dial operation to an endpoint that's unavailable\n";
1303                 return AST_TEST_NOT_RUN;
1304         case TEST_EXECUTE:
1305                 break;
1306         }
1307
1308         SWAP_CONFIG(config, unanswered_cdr_config);
1309
1310         CREATE_ALICE_CHANNEL(chan_caller, &caller, &expected);
1311
1312         EMULATE_APP_DATA(chan_caller, 1, "Dial", CHANNEL_TECH_NAME "/Bob");
1313
1314         chan_callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, ast_channel_linkedid(chan_caller), 0, CHANNEL_TECH_NAME "/Bob");
1315         ast_set_flag(ast_channel_flags(chan_callee), AST_FLAG_OUTGOING);
1316         EMULATE_APP_DATA(chan_callee, 0, "AppDial", "(Outgoing Line)");
1317
1318         ast_channel_publish_dial(chan_caller, chan_callee, "Bob", NULL);
1319         ast_channel_state_set(chan_caller, AST_STATE_RINGING);
1320         ast_channel_publish_dial(chan_caller, chan_callee, NULL, "CHANUNAVAIL");
1321
1322         HANGUP_CHANNEL(chan_caller, AST_CAUSE_NO_ROUTE_DESTINATION);
1323         HANGUP_CHANNEL(chan_callee, AST_CAUSE_NO_ROUTE_DESTINATION);
1324
1325         result = verify_mock_cdr_record(test, &expected, 1);
1326
1327         return result;
1328 }
1329
1330 AST_TEST_DEFINE(test_cdr_dial_caller_cancel)
1331 {
1332         RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
1333         RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
1334         RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
1335                         ao2_cleanup);
1336
1337         struct ast_party_caller caller = ALICE_CALLERID;
1338         struct ast_cdr expected = {
1339                 .clid = "\"Alice\" <100>",
1340                 .src = "100",
1341                 .dst = "100",
1342                 .dcontext = "default",
1343                 .channel = CHANNEL_TECH_NAME "/Alice",
1344                 .dstchannel = CHANNEL_TECH_NAME "/Bob",
1345                 .lastapp = "Dial",
1346                 .lastdata = CHANNEL_TECH_NAME "/Bob",
1347                 .billsec = 0,
1348                 .amaflags = AST_AMA_DOCUMENTATION,
1349                 .disposition = AST_CDR_NOANSWER,
1350                 .accountcode = "100",
1351                 .peeraccount = "200",
1352         };
1353         enum ast_test_result_state result = AST_TEST_NOT_RUN;
1354
1355         switch (cmd) {
1356         case TEST_INIT:
1357                 info->name = __func__;
1358                 info->category = TEST_CATEGORY;
1359                 info->summary = "Test CDRs for a dial where the caller cancels";
1360                 info->description =
1361                         "Test the properties of a CDR for a channel that\n"
1362                         "performs a dial operation to an endpoint but then decides\n"
1363                         "to hang up, cancelling the dial\n";
1364                 return AST_TEST_NOT_RUN;
1365         case TEST_EXECUTE:
1366                 break;
1367         }
1368
1369         SWAP_CONFIG(config, unanswered_cdr_config);
1370
1371         CREATE_ALICE_CHANNEL(chan_caller, &caller, &expected);
1372
1373         EMULATE_APP_DATA(chan_caller, 1, "Dial", CHANNEL_TECH_NAME "/Bob");
1374
1375         chan_callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, ast_channel_linkedid(chan_caller), 0, CHANNEL_TECH_NAME "/Bob");
1376         ast_set_flag(ast_channel_flags(chan_callee), AST_FLAG_OUTGOING);
1377         EMULATE_APP_DATA(chan_callee, 0, "AppDial", "(Outgoing Line)");
1378
1379         ast_channel_publish_dial(chan_caller, chan_callee, "Bob", NULL);
1380         ast_channel_state_set(chan_caller, AST_STATE_RINGING);
1381         ast_channel_publish_dial(chan_caller, chan_callee, NULL, "CANCEL");
1382
1383         HANGUP_CHANNEL(chan_callee, AST_CAUSE_NORMAL);
1384         HANGUP_CHANNEL(chan_caller, AST_CAUSE_NORMAL);
1385
1386         result = verify_mock_cdr_record(test, &expected, 1);
1387
1388         return result;
1389 }
1390
1391 AST_TEST_DEFINE(test_cdr_dial_parallel_failed)
1392 {
1393         RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
1394         RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release);
1395         RAII_VAR(struct ast_channel *, chan_charlie, NULL, safe_channel_release);
1396         RAII_VAR(struct ast_channel *, chan_david, NULL, safe_channel_release);
1397         RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
1398                         ao2_cleanup);
1399
1400         struct ast_party_caller caller = ALICE_CALLERID;
1401         struct ast_cdr bob_expected = {
1402                 .clid = "\"Alice\" <100>",
1403                 .src = "100",
1404                 .dst = "100",
1405                 .dcontext = "default",
1406                 .channel = CHANNEL_TECH_NAME "/Alice",
1407                 .dstchannel = CHANNEL_TECH_NAME "/Bob",
1408                 .lastapp = "Dial",
1409                 .lastdata = CHANNEL_TECH_NAME "/Bob&" CHANNEL_TECH_NAME "/Charlie&" CHANNEL_TECH_NAME "/David",
1410                 .billsec = 0,
1411                 .amaflags = AST_AMA_DOCUMENTATION,
1412                 .disposition = AST_CDR_NOANSWER,
1413                 .accountcode = "100",
1414                 .peeraccount = "200",
1415         };
1416         struct ast_cdr charlie_expected = {
1417                 .clid = "\"Alice\" <100>",
1418                 .src = "100",
1419                 .dst = "100",
1420                 .dcontext = "default",
1421                 .channel = CHANNEL_TECH_NAME "/Alice",
1422                 .dstchannel = CHANNEL_TECH_NAME "/Charlie",
1423                 .lastapp = "Dial",
1424                 .lastdata = CHANNEL_TECH_NAME "/Bob&" CHANNEL_TECH_NAME "/Charlie&" CHANNEL_TECH_NAME "/David",
1425                 .billsec = 0,
1426                 .amaflags = AST_AMA_DOCUMENTATION,
1427                 .disposition = AST_CDR_BUSY,
1428                 .accountcode = "100",
1429                 .peeraccount = "300",
1430         };
1431         struct ast_cdr david_expected = {
1432                 .clid = "\"Alice\" <100>",
1433                 .src = "100",
1434                 .dst = "100",
1435                 .dcontext = "default",
1436                 .channel = CHANNEL_TECH_NAME "/Alice",
1437                 .dstchannel = CHANNEL_TECH_NAME "/David",
1438                 .lastapp = "Dial",
1439                 .lastdata = CHANNEL_TECH_NAME "/Bob&" CHANNEL_TECH_NAME "/Charlie&" CHANNEL_TECH_NAME "/David",
1440                 .billsec = 0,
1441                 .amaflags = AST_AMA_DOCUMENTATION,
1442                 .disposition = AST_CDR_CONGESTION,
1443                 .accountcode = "100",
1444                 .peeraccount = "400",
1445         };
1446         enum ast_test_result_state result = AST_TEST_NOT_RUN;
1447
1448         struct ast_cdr *expected = &bob_expected;
1449         bob_expected.next = &charlie_expected;
1450         charlie_expected.next = &david_expected;
1451
1452         switch (cmd) {
1453         case TEST_INIT:
1454                 info->name = __func__;
1455                 info->category = TEST_CATEGORY;
1456                 info->summary = "Test a parallel dial where all channels fail to answer";
1457                 info->description =
1458                         "This tests dialing three parties: Bob, Charlie, David. Charlie\n"
1459                         "returns BUSY; David returns CONGESTION; Bob fails to answer and\n"
1460                         "Alice hangs up. Three records are created for Alice as a result.\n";
1461                 return AST_TEST_NOT_RUN;
1462         case TEST_EXECUTE:
1463                 break;
1464         }
1465
1466         SWAP_CONFIG(config, congestion_cdr_config);
1467
1468         CREATE_ALICE_CHANNEL(chan_caller, &caller, &bob_expected);
1469         COPY_IDS(chan_caller, &charlie_expected);
1470         COPY_IDS(chan_caller, &david_expected);
1471
1472         /* Channel enters Dial app */
1473         EMULATE_APP_DATA(chan_caller, 1, "Dial", CHANNEL_TECH_NAME "/Bob&" CHANNEL_TECH_NAME "/Charlie&" CHANNEL_TECH_NAME "/David");
1474
1475         /* Outbound channels are created */
1476         chan_bob = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, ast_channel_linkedid(chan_caller), 0, CHANNEL_TECH_NAME "/Bob");
1477         ast_set_flag(ast_channel_flags(chan_bob), AST_FLAG_OUTGOING);
1478         EMULATE_APP_DATA(chan_bob, 0, "AppDial", "(Outgoing Line)");
1479
1480         chan_charlie = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "300", NULL, NULL, ast_channel_linkedid(chan_caller), 0, CHANNEL_TECH_NAME "/Charlie");
1481         ast_set_flag(ast_channel_flags(chan_charlie), AST_FLAG_OUTGOING);
1482         EMULATE_APP_DATA(chan_charlie, 0, "AppDial", "(Outgoing Line)");
1483
1484         chan_david = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "400", NULL, NULL, ast_channel_linkedid(chan_caller), 0, CHANNEL_TECH_NAME "/David");
1485         ast_set_flag(ast_channel_flags(chan_david), AST_FLAG_OUTGOING);
1486         EMULATE_APP_DATA(chan_david, 0, "AppDial", "(Outgoing Line)");
1487
1488         /* Dial starts */
1489         ast_channel_publish_dial(chan_caller, chan_bob, "Bob", NULL);
1490         ast_channel_publish_dial(chan_caller, chan_charlie, "Charlie", NULL);
1491         ast_channel_publish_dial(chan_caller, chan_david, "David", NULL);
1492         ast_channel_state_set(chan_caller, AST_STATE_RINGING);
1493
1494         /* Charlie is busy */
1495         ast_channel_publish_dial(chan_caller, chan_charlie, NULL, "BUSY");
1496         HANGUP_CHANNEL(chan_charlie, AST_CAUSE_BUSY);
1497
1498         /* David is congested */
1499         ast_channel_publish_dial(chan_caller, chan_david, NULL, "CONGESTION");
1500         HANGUP_CHANNEL(chan_david, AST_CAUSE_CONGESTION);
1501
1502         /* Bob is canceled */
1503         ast_channel_publish_dial(chan_caller, chan_bob, NULL, "CANCEL");
1504         HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL);
1505
1506         /* Alice hangs up */
1507         HANGUP_CHANNEL(chan_caller, AST_CAUSE_NORMAL);
1508
1509         result = verify_mock_cdr_record(test, expected, 3);
1510
1511         return result;
1512 }
1513
1514 AST_TEST_DEFINE(test_cdr_dial_answer_no_bridge)
1515 {
1516         RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
1517         RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
1518         RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
1519                         ao2_cleanup);
1520
1521         struct ast_party_caller caller = ALICE_CALLERID;
1522         struct ast_cdr bob_expected_one = {
1523                 .clid = "\"\" <>",
1524                 .src = "",
1525                 .dst = "s",
1526                 .dcontext = "default",
1527                 .channel = CHANNEL_TECH_NAME "/Bob",
1528                 .lastapp = "Wait",
1529                 .lastdata = "1",
1530                 .amaflags = AST_AMA_DOCUMENTATION,
1531                 .disposition = AST_CDR_ANSWERED,
1532                 .accountcode = "200",
1533         };
1534         struct ast_cdr alice_expected_two = {
1535                 .clid = "\"Alice\" <100>",
1536                 .src = "100",
1537                 .dst = "100",
1538                 .dcontext = "default",
1539                 .channel = CHANNEL_TECH_NAME "/Alice",
1540                 .lastapp = "Wait",
1541                 .lastdata = "1",
1542                 .amaflags = AST_AMA_DOCUMENTATION,
1543                 .disposition = AST_CDR_ANSWERED,
1544                 .accountcode = "100",
1545                 .next = &bob_expected_one,
1546         };
1547         struct ast_cdr alice_expected_one = {
1548                 .clid = "\"Alice\" <100>",
1549                 .src = "100",
1550                 .dst = "100",
1551                 .dcontext = "default",
1552                 .channel = CHANNEL_TECH_NAME "/Alice",
1553                 .dstchannel = CHANNEL_TECH_NAME "/Bob",
1554                 .lastapp = "Dial",
1555                 .lastdata = CHANNEL_TECH_NAME "/Bob",
1556                 .amaflags = AST_AMA_DOCUMENTATION,
1557                 .disposition = AST_CDR_ANSWERED,
1558                 .accountcode = "100",
1559                 .peeraccount = "200",
1560                 .next = &alice_expected_two,
1561         };
1562         enum ast_test_result_state result = AST_TEST_NOT_RUN;
1563
1564         switch (cmd) {
1565         case TEST_INIT:
1566                 info->name = __func__;
1567                 info->category = TEST_CATEGORY;
1568                 info->summary = "Test dialing, answering, and not going into a bridge.";
1569                 info->description =
1570                         "This is a weird one, but theoretically possible. You can perform\n"
1571                         "a dial, then bounce both channels to different priorities and\n"
1572                         "never have them enter a bridge together. Ew. This makes sure that\n"
1573                         "when we answer, we get a CDR, it gets ended at that point, and\n"
1574                         "that it gets finalized appropriately. We should get three CDRs in\n"
1575                         "the end - one for the dial, and one for each CDR as they continued\n"
1576                         "on.\n";
1577                 return AST_TEST_NOT_RUN;
1578         case TEST_EXECUTE:
1579                 break;
1580         }
1581
1582         SWAP_CONFIG(config, debug_cdr_config);
1583
1584         CREATE_ALICE_CHANNEL(chan_caller, &caller, &alice_expected_one);
1585         COPY_IDS(chan_caller, &alice_expected_two);
1586
1587         EMULATE_APP_DATA(chan_caller, 1, "Dial", CHANNEL_TECH_NAME "/Bob");
1588
1589         chan_callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, ast_channel_linkedid(chan_caller), 0, CHANNEL_TECH_NAME "/Bob");
1590         ast_set_flag(ast_channel_flags(chan_callee), AST_FLAG_OUTGOING);
1591         COPY_IDS(chan_callee, &bob_expected_one);
1592
1593         ast_channel_publish_dial(chan_caller, chan_callee, "Bob", NULL);
1594         ast_channel_state_set(chan_caller, AST_STATE_RINGING);
1595         ast_channel_publish_dial(chan_caller, chan_callee, NULL, "ANSWER");
1596
1597         ast_channel_state_set(chan_caller, AST_STATE_UP);
1598         ast_clear_flag(ast_channel_flags(chan_callee), AST_FLAG_OUTGOING);
1599         ast_channel_state_set(chan_callee, AST_STATE_UP);
1600
1601         EMULATE_APP_DATA(chan_caller, 2, "Wait", "1");
1602         EMULATE_APP_DATA(chan_callee, 1, "Wait", "1");
1603
1604         HANGUP_CHANNEL(chan_caller, AST_CAUSE_NORMAL);
1605         HANGUP_CHANNEL(chan_callee, AST_CAUSE_NORMAL);
1606
1607         result = verify_mock_cdr_record(test, &alice_expected_one, 3);
1608         return result;
1609 }
1610
1611 AST_TEST_DEFINE(test_cdr_dial_answer_twoparty_bridge_a)
1612 {
1613         RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
1614         RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
1615         RAII_VAR(struct ast_bridge *, bridge, NULL, ao2_cleanup);
1616         RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
1617                         ao2_cleanup);
1618         struct timespec to_sleep = {1, 0};
1619         enum ast_test_result_state result = AST_TEST_NOT_RUN;
1620
1621         struct ast_party_caller caller = ALICE_CALLERID;
1622         struct ast_cdr expected = {
1623                 .clid = "\"Alice\" <100>",
1624                 .src = "100",
1625                 .dst = "100",
1626                 .dcontext = "default",
1627                 .channel = CHANNEL_TECH_NAME "/Alice",
1628                 .dstchannel = CHANNEL_TECH_NAME "/Bob",
1629                 .lastapp = "Dial",
1630                 .lastdata = CHANNEL_TECH_NAME "/Bob",
1631                 .amaflags = AST_AMA_DOCUMENTATION,
1632                 .billsec = 1,
1633                 .disposition = AST_CDR_ANSWERED,
1634                 .accountcode = "100",
1635                 .peeraccount = "200",
1636         };
1637
1638         switch (cmd) {
1639         case TEST_INIT:
1640                 info->name = __func__;
1641                 info->category = TEST_CATEGORY;
1642                 info->summary = "Test dialing, answering, and going into a 2-party bridge";
1643                 info->description =
1644                         "The most 'basic' of scenarios\n";
1645                 return AST_TEST_NOT_RUN;
1646         case TEST_EXECUTE:
1647                 break;
1648         }
1649
1650         SWAP_CONFIG(config, debug_cdr_config);
1651
1652         CREATE_ALICE_CHANNEL(chan_caller, &caller, &expected);
1653
1654         EMULATE_APP_DATA(chan_caller, 1, "Dial", CHANNEL_TECH_NAME "/Bob");
1655
1656         chan_callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, ast_channel_linkedid(chan_caller), 0, CHANNEL_TECH_NAME "/Bob");
1657         ast_set_flag(ast_channel_flags(chan_callee), AST_FLAG_OUTGOING);
1658         EMULATE_APP_DATA(chan_callee, 0, "AppDial", "(Outgoing Line)");
1659
1660         ast_channel_publish_dial(chan_caller, chan_callee, "Bob", NULL);
1661         ast_channel_state_set(chan_caller, AST_STATE_RINGING);
1662         ast_channel_publish_dial(chan_caller, chan_callee, NULL, "ANSWER");
1663
1664         ast_channel_state_set(chan_caller, AST_STATE_UP);
1665         ast_channel_state_set(chan_callee, AST_STATE_UP);
1666
1667         bridge = ast_bridge_basic_new();
1668         ast_test_validate(test, bridge != NULL);
1669         while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
1670
1671         ast_bridge_impart(bridge, chan_caller, NULL, NULL, 0);
1672         ast_bridge_impart(bridge, chan_callee, NULL, NULL, 0);
1673
1674         while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
1675
1676         ast_bridge_depart(chan_caller);
1677         ast_bridge_depart(chan_callee);
1678
1679         HANGUP_CHANNEL(chan_caller, AST_CAUSE_NORMAL);
1680         HANGUP_CHANNEL(chan_callee, AST_CAUSE_NORMAL);
1681
1682         result = verify_mock_cdr_record(test, &expected, 1);
1683         return result;
1684 }
1685
1686 AST_TEST_DEFINE(test_cdr_dial_answer_twoparty_bridge_b)
1687 {
1688         RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
1689         RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
1690         RAII_VAR(struct ast_bridge *, bridge, NULL, ao2_cleanup);
1691         RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
1692                         ao2_cleanup);
1693         struct timespec to_sleep = {1, 0};
1694         enum ast_test_result_state result = AST_TEST_NOT_RUN;
1695
1696         struct ast_party_caller caller = ALICE_CALLERID;
1697         struct ast_cdr expected = {
1698                 .clid = "\"Alice\" <100>",
1699                 .src = "100",
1700                 .dst = "100",
1701                 .dcontext = "default",
1702                 .channel = CHANNEL_TECH_NAME "/Alice",
1703                 .dstchannel = CHANNEL_TECH_NAME "/Bob",
1704                 .lastapp = "Dial",
1705                 .lastdata = CHANNEL_TECH_NAME "/Bob",
1706                 .amaflags = AST_AMA_DOCUMENTATION,
1707                 .billsec = 1,
1708                 .disposition = AST_CDR_ANSWERED,
1709                 .accountcode = "100",
1710                 .peeraccount = "200",
1711         };
1712
1713         switch (cmd) {
1714         case TEST_INIT:
1715                 info->name = __func__;
1716                 info->category = TEST_CATEGORY;
1717                 info->summary = "Test dialing, answering, and going into a 2-party bridge";
1718                 info->description =
1719                         "The most 'basic' of scenarios\n";
1720                 return AST_TEST_NOT_RUN;
1721         case TEST_EXECUTE:
1722                 break;
1723         }
1724
1725         SWAP_CONFIG(config, debug_cdr_config);
1726
1727         CREATE_ALICE_CHANNEL(chan_caller, &caller, &expected);
1728
1729         EMULATE_APP_DATA(chan_caller, 1, "Dial", CHANNEL_TECH_NAME "/Bob");
1730
1731         chan_callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, ast_channel_linkedid(chan_caller), 0, CHANNEL_TECH_NAME "/Bob");
1732         ast_set_flag(ast_channel_flags(chan_callee), AST_FLAG_OUTGOING);
1733         EMULATE_APP_DATA(chan_callee, 0, "AppDial", "(Outgoing Line)");
1734
1735         ast_channel_publish_dial(chan_caller, chan_callee, "Bob", NULL);
1736         ast_channel_state_set(chan_caller, AST_STATE_RINGING);
1737         ast_channel_publish_dial(chan_caller, chan_callee, NULL, "ANSWER");
1738
1739         ast_channel_state_set(chan_caller, AST_STATE_UP);
1740         ast_channel_state_set(chan_callee, AST_STATE_UP);
1741
1742         bridge = ast_bridge_basic_new();
1743         ast_test_validate(test, bridge != NULL);
1744         while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
1745         ast_bridge_impart(bridge, chan_callee, NULL, NULL, 0);
1746         while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
1747         ast_bridge_impart(bridge, chan_caller, NULL, NULL, 0);
1748         while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
1749         ast_bridge_depart(chan_caller);
1750         ast_bridge_depart(chan_callee);
1751
1752         HANGUP_CHANNEL(chan_caller, AST_CAUSE_NORMAL);
1753         HANGUP_CHANNEL(chan_callee, AST_CAUSE_NORMAL);
1754
1755         result = verify_mock_cdr_record(test, &expected, 1);
1756         return result;
1757 }
1758
1759 AST_TEST_DEFINE(test_cdr_dial_answer_multiparty)
1760 {
1761         RAII_VAR(struct ast_channel *, chan_alice, NULL, safe_channel_release);
1762         RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release);
1763         RAII_VAR(struct ast_channel *, chan_charlie, NULL, safe_channel_release);
1764         RAII_VAR(struct ast_channel *, chan_david, NULL, safe_channel_release);
1765         RAII_VAR(struct ast_bridge *, bridge, NULL, ao2_cleanup);
1766         RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
1767                         ao2_cleanup);
1768         struct timespec to_sleep = {1, 0};
1769         enum ast_test_result_state result = AST_TEST_NOT_RUN;
1770
1771         struct ast_party_caller alice_caller = ALICE_CALLERID;
1772         struct ast_party_caller charlie_caller = CHARLIE_CALLERID;
1773         struct ast_cdr charlie_expected_two = {
1774                 .clid = "\"Charlie\" <300>",
1775                 .src = "300",
1776                 .dst = "300",
1777                 .dcontext = "default",
1778                 .channel = CHANNEL_TECH_NAME "/Charlie",
1779                 .dstchannel = CHANNEL_TECH_NAME "/Bob",
1780                 .lastapp = "Dial",
1781                 .lastdata = CHANNEL_TECH_NAME "/David",
1782                 .amaflags = AST_AMA_DOCUMENTATION,
1783                 .billsec = 1,
1784                 .disposition = AST_CDR_ANSWERED,
1785                 .accountcode = "300",
1786                 .peeraccount = "200",
1787         };
1788         struct ast_cdr charlie_expected_one = {
1789                 .clid = "\"Charlie\" <300>",
1790                 .src = "300",
1791                 .dst = "300",
1792                 .dcontext = "default",
1793                 .channel = CHANNEL_TECH_NAME "/Charlie",
1794                 .dstchannel = CHANNEL_TECH_NAME "/David",
1795                 .lastapp = "Dial",
1796                 .lastdata = CHANNEL_TECH_NAME "/David",
1797                 .amaflags = AST_AMA_DOCUMENTATION,
1798                 .billsec = 1,
1799                 .disposition = AST_CDR_ANSWERED,
1800                 .accountcode = "300",
1801                 .peeraccount = "400",
1802                 .next = &charlie_expected_two,
1803         };
1804         struct ast_cdr alice_expected_three = {
1805                 .clid = "\"Alice\" <100>",
1806                 .src = "100",
1807                 .dst = "100",
1808                 .dcontext = "default",
1809                 .channel = CHANNEL_TECH_NAME "/Alice",
1810                 .dstchannel = CHANNEL_TECH_NAME "/David",
1811                 .lastapp = "Dial",
1812                 .lastdata = CHANNEL_TECH_NAME "/Bob",
1813                 .amaflags = AST_AMA_DOCUMENTATION,
1814                 .billsec = 1,
1815                 .disposition = AST_CDR_ANSWERED,
1816                 .accountcode = "100",
1817                 .peeraccount = "400",
1818                 .next = &charlie_expected_one,
1819         };
1820         struct ast_cdr alice_expected_two = {
1821                 .clid = "\"Alice\" <100>",
1822                 .src = "100",
1823                 .dst = "100",
1824                 .dcontext = "default",
1825                 .channel = CHANNEL_TECH_NAME "/Alice",
1826                 .dstchannel = CHANNEL_TECH_NAME "/Charlie",
1827                 .lastapp = "Dial",
1828                 .lastdata = CHANNEL_TECH_NAME "/Bob",
1829                 .amaflags = AST_AMA_DOCUMENTATION,
1830                 .billsec = 1,
1831                 .disposition = AST_CDR_ANSWERED,
1832                 .accountcode = "100",
1833                 .peeraccount = "300",
1834                 .next = &alice_expected_three,
1835         };
1836         struct ast_cdr alice_expected_one = {
1837                 .clid = "\"Alice\" <100>",
1838                 .src = "100",
1839                 .dst = "100",
1840                 .dcontext = "default",
1841                 .channel = CHANNEL_TECH_NAME "/Alice",
1842                 .dstchannel = CHANNEL_TECH_NAME "/Bob",
1843                 .lastapp = "Dial",
1844                 .lastdata = CHANNEL_TECH_NAME "/Bob",
1845                 .amaflags = AST_AMA_DOCUMENTATION,
1846                 .billsec = 1,
1847                 .disposition = AST_CDR_ANSWERED,
1848                 .accountcode = "100",
1849                 .peeraccount = "200",
1850                 .next = &alice_expected_two,
1851         };
1852
1853         switch (cmd) {
1854         case TEST_INIT:
1855                 info->name = __func__;
1856                 info->category = TEST_CATEGORY;
1857                 info->summary = "Test dialing, answering, and going into a multi-party bridge";
1858                 info->description =
1859                         "A little tricky to get to do, but possible with some redirects.\n";
1860                 return AST_TEST_NOT_RUN;
1861         case TEST_EXECUTE:
1862                 break;
1863         }
1864
1865         SWAP_CONFIG(config, debug_cdr_config);
1866
1867         CREATE_ALICE_CHANNEL(chan_alice, &alice_caller, &alice_expected_one);
1868         COPY_IDS(chan_alice, &alice_expected_two);
1869         COPY_IDS(chan_alice, &alice_expected_three);
1870
1871         EMULATE_APP_DATA(chan_alice, 1, "Dial", CHANNEL_TECH_NAME "/Bob");
1872
1873         chan_bob = ast_channel_alloc(0, AST_STATE_DOWN, "200", "Bob", "200", "200", "default", NULL, 0, CHANNEL_TECH_NAME "/Bob");
1874         ast_set_flag(ast_channel_flags(chan_bob), AST_FLAG_OUTGOING);
1875         EMULATE_APP_DATA(chan_bob, 0, "AppDial", "(Outgoing Line)");
1876
1877         CREATE_CHARLIE_CHANNEL(chan_charlie, &charlie_caller, &charlie_expected_one);
1878         EMULATE_APP_DATA(chan_charlie, 1, "Dial", CHANNEL_TECH_NAME "/David");
1879         ast_copy_string(charlie_expected_one.uniqueid, ast_channel_uniqueid(chan_charlie), sizeof(charlie_expected_one.uniqueid));
1880         ast_copy_string(charlie_expected_one.linkedid, ast_channel_linkedid(chan_alice), sizeof(charlie_expected_one.linkedid));
1881         ast_copy_string(charlie_expected_two.uniqueid, ast_channel_uniqueid(chan_charlie), sizeof(charlie_expected_two.uniqueid));
1882         ast_copy_string(charlie_expected_two.linkedid, ast_channel_linkedid(chan_alice), sizeof(charlie_expected_two.linkedid));
1883
1884         chan_david = ast_channel_alloc(0, AST_STATE_DOWN, "400", "David", "400", "400", "default", NULL, 0, CHANNEL_TECH_NAME "/David");
1885         ast_set_flag(ast_channel_flags(chan_david), AST_FLAG_OUTGOING);
1886         EMULATE_APP_DATA(chan_david, 0, "AppDial", "(Outgoing Line)");
1887
1888         ast_channel_publish_dial(chan_alice, chan_bob, "Bob", NULL);
1889         ast_channel_state_set(chan_alice, AST_STATE_RINGING);
1890         ast_channel_publish_dial(chan_charlie, chan_david, "David", NULL);
1891         ast_channel_state_set(chan_charlie, AST_STATE_RINGING);
1892         ast_channel_publish_dial(chan_alice, chan_bob, NULL, "ANSWER");
1893         ast_channel_publish_dial(chan_charlie, chan_david, NULL, "ANSWER");
1894
1895         ast_channel_state_set(chan_alice, AST_STATE_UP);
1896         ast_channel_state_set(chan_bob, AST_STATE_UP);
1897         ast_channel_state_set(chan_charlie, AST_STATE_UP);
1898         ast_channel_state_set(chan_david, AST_STATE_UP);
1899
1900         bridge = ast_bridge_basic_new();
1901         ast_test_validate(test, bridge != NULL);
1902
1903         while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
1904         ast_test_validate(test, 0 == ast_bridge_impart(bridge, chan_charlie, NULL, NULL, 0));
1905         while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
1906         ast_test_validate(test, 0 == ast_bridge_impart(bridge, chan_david, NULL, NULL, 0));
1907         while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
1908         ast_test_validate(test, 0 == ast_bridge_impart(bridge, chan_bob, NULL, NULL, 0));
1909         while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
1910         ast_test_validate(test, 0 == ast_bridge_impart(bridge, chan_alice, NULL, NULL, 0));
1911         while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
1912         ast_test_validate(test, 0 == ast_bridge_depart(chan_alice));
1913         ast_test_validate(test, 0 == ast_bridge_depart(chan_bob));
1914         ast_test_validate(test, 0 == ast_bridge_depart(chan_charlie));
1915         ast_test_validate(test, 0 == ast_bridge_depart(chan_david));
1916
1917         HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL);
1918         HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL);
1919         HANGUP_CHANNEL(chan_charlie, AST_CAUSE_NORMAL);
1920         HANGUP_CHANNEL(chan_david, AST_CAUSE_NORMAL);
1921
1922         result = verify_mock_cdr_record(test, &alice_expected_one, 5);
1923
1924         return result;
1925 }
1926
1927 AST_TEST_DEFINE(test_cdr_park)
1928 {
1929         RAII_VAR(struct ast_channel *, chan_alice, NULL, safe_channel_release);
1930         RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release);
1931         RAII_VAR(struct ast_bridge *, bridge, NULL, ao2_cleanup);
1932         RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
1933                         ao2_cleanup);
1934         struct timespec to_sleep = {1, 0};
1935
1936         struct ast_party_caller bob_caller = BOB_CALLERID;
1937         struct ast_party_caller alice_caller = ALICE_CALLERID;
1938         struct ast_cdr bob_expected = {
1939                 .clid = "\"Bob\" <200>",
1940                 .src = "200",
1941                 .dst = "200",
1942                 .dcontext = "default",
1943                 .channel = CHANNEL_TECH_NAME "/Bob",
1944                 .lastapp = "Park",
1945                 .lastdata = "701",
1946                 .billsec = 1,
1947                 .amaflags = AST_AMA_DOCUMENTATION,
1948                 .disposition = AST_CDR_ANSWERED,
1949                 .accountcode = "200",
1950         };
1951         struct ast_cdr alice_expected = {
1952                 .clid = "\"Alice\" <100>",
1953                 .src = "100",
1954                 .dst = "100",
1955                 .dcontext = "default",
1956                 .channel = CHANNEL_TECH_NAME "/Alice",
1957                 .lastapp = "Park",
1958                 .lastdata = "700",
1959                 .billsec = 1,
1960                 .amaflags = AST_AMA_DOCUMENTATION,
1961                 .disposition = AST_CDR_ANSWERED,
1962                 .accountcode = "100",
1963                 .next = &bob_expected,
1964         };
1965         enum ast_test_result_state result = AST_TEST_NOT_RUN;
1966
1967         switch (cmd) {
1968         case TEST_INIT:
1969                 info->name = __func__;
1970                 info->category = TEST_CATEGORY;
1971                 info->summary = "Test cdrs for a single party entering Park";
1972                 info->description =
1973                         "Test the properties of a CDR for calls that are\n"
1974                         "answered, enters Park, and leaves it.\n";
1975                 return AST_TEST_NOT_RUN;
1976         case TEST_EXECUTE:
1977                 break;
1978         }
1979         SWAP_CONFIG(config, debug_cdr_config);
1980         CREATE_ALICE_CHANNEL(chan_alice, &alice_caller, &alice_expected);
1981         CREATE_BOB_CHANNEL(chan_bob, &bob_caller, &bob_expected);
1982
1983         EMULATE_APP_DATA(chan_alice, 1, "Park", "700");
1984         ast_setstate(chan_alice, AST_STATE_UP);
1985         EMULATE_APP_DATA(chan_bob, 1, "Park", "701");
1986         ast_setstate(chan_bob, AST_STATE_UP);
1987
1988         bridge = ast_bridge_base_new(AST_BRIDGE_CAPABILITY_HOLDING,
1989                 AST_BRIDGE_FLAG_MERGE_INHIBIT_TO | AST_BRIDGE_FLAG_MERGE_INHIBIT_FROM
1990                         | AST_BRIDGE_FLAG_SWAP_INHIBIT_FROM | AST_BRIDGE_FLAG_TRANSFER_PROHIBITED);
1991         ast_test_validate(test, bridge != NULL);
1992
1993         while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
1994         ast_bridge_impart(bridge, chan_alice, NULL, NULL, 0);
1995         while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
1996         ast_bridge_impart(bridge, chan_bob, NULL, NULL, 0);
1997         while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
1998         ast_bridge_depart(chan_alice);
1999         ast_bridge_depart(chan_bob);
2000
2001         /* And then it hangs up */
2002         HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL);
2003         HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL);
2004
2005         result = verify_mock_cdr_record(test, &alice_expected, 2);
2006
2007         return result;
2008 }
2009
2010
2011 AST_TEST_DEFINE(test_cdr_fields)
2012 {
2013         RAII_VAR(struct ast_channel *, chan, NULL, safe_channel_release);
2014         RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
2015                         ao2_cleanup);
2016         char varbuffer[128];
2017         int int_buffer;
2018         double db_buffer;
2019         struct timespec to_sleep = {2, 0};
2020         struct ast_flags fork_options = { 0, };
2021
2022         struct ast_party_caller caller = ALICE_CALLERID;
2023         struct ast_cdr original = {
2024                 .clid = "\"Alice\" <100>",
2025                 .src = "100",
2026                 .dst = "100",
2027                 .dcontext = "default",
2028                 .channel = CHANNEL_TECH_NAME "/Alice",
2029                 .lastapp = "Wait",
2030                 .lastdata = "10",
2031                 .billsec = 0,
2032                 .amaflags = AST_AMA_OMIT,
2033                 .disposition = AST_CDR_FAILED,
2034                 .accountcode = "XXX",
2035                 .userfield = "yackity",
2036         };
2037         struct ast_cdr fork_expected_one = {
2038                 .clid = "\"Alice\" <100>",
2039                 .src = "100",
2040                 .dst = "100",
2041                 .dcontext = "default",
2042                 .channel = CHANNEL_TECH_NAME "/Alice",
2043                 .lastapp = "Wait",
2044                 .lastdata = "10",
2045                 .billsec = 0,
2046                 .amaflags = AST_AMA_OMIT,
2047                 .disposition = AST_CDR_FAILED,
2048                 .accountcode = "XXX",
2049                 .userfield = "yackity",
2050         };
2051         struct ast_cdr fork_expected_two = {
2052                 .clid = "\"Alice\" <100>",
2053                 .src = "100",
2054                 .dst = "100",
2055                 .dcontext = "default",
2056                 .channel = CHANNEL_TECH_NAME "/Alice",
2057                 .lastapp = "Answer",
2058                 .billsec = 0,
2059                 .amaflags = AST_AMA_OMIT,
2060                 .disposition = AST_CDR_ANSWERED,
2061                 .accountcode = "ZZZ",
2062                 .userfield = "schmackity",
2063         };
2064         enum ast_test_result_state result = AST_TEST_NOT_RUN;
2065
2066         struct ast_cdr *expected = &original;
2067         original.next = &fork_expected_one;
2068         fork_expected_one.next = &fork_expected_two;
2069
2070         switch (cmd) {
2071         case TEST_INIT:
2072                 info->name = __func__;
2073                 info->category = TEST_CATEGORY;
2074                 info->summary = "Test field access CDRs";
2075                 info->description =
2076                         "This tests setting/retrieving data on CDR records.\n";
2077                 return AST_TEST_NOT_RUN;
2078         case TEST_EXECUTE:
2079                 break;
2080         }
2081
2082         SWAP_CONFIG(config, unanswered_cdr_config);
2083
2084         CREATE_ALICE_CHANNEL(chan, &caller, &original);
2085         ast_copy_string(fork_expected_one.uniqueid, ast_channel_uniqueid(chan), sizeof(fork_expected_one.uniqueid));
2086         ast_copy_string(fork_expected_one.linkedid, ast_channel_linkedid(chan), sizeof(fork_expected_one.linkedid));
2087         ast_copy_string(fork_expected_two.uniqueid, ast_channel_uniqueid(chan), sizeof(fork_expected_two.uniqueid));
2088         ast_copy_string(fork_expected_two.linkedid, ast_channel_linkedid(chan), sizeof(fork_expected_two.linkedid));
2089
2090         /* Channel enters Wait app */
2091         ast_channel_appl_set(chan, "Wait");
2092         ast_channel_data_set(chan, "10");
2093         ast_channel_priority_set(chan, 1);
2094         ast_channel_publish_snapshot(chan);
2095
2096         /* Set properties on the channel that propagate to the CDR */
2097         ast_channel_amaflags_set(chan, AST_AMA_OMIT);
2098         ast_channel_accountcode_set(chan, "XXX");
2099
2100         /* Wait one second so we get a duration. */
2101         while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
2102
2103         ast_cdr_setuserfield(ast_channel_name(chan), "foobar");
2104         ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "test_variable", "record_1") == 0);
2105
2106         /* Verify that we can't set read-only fields or other fields directly */
2107         ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "clid", "junk") != 0);
2108         ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "src", "junk") != 0);
2109         ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "dst", "junk") != 0);
2110         ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "dcontext", "junk") != 0);
2111         ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "channel", "junk") != 0);
2112         ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "dstchannel", "junk") != 0);
2113         ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "lastapp", "junk") != 0);
2114         ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "lastdata", "junk") != 0);
2115         ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "start", "junk") != 0);
2116         ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "answer", "junk") != 0);
2117         ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "end", "junk") != 0);
2118         ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "duration", "junk") != 0);
2119         ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "billsec", "junk") != 0);
2120         ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "disposition", "junk") != 0);
2121         ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "amaflags", "junk") != 0);
2122         ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "accountcode", "junk") != 0);
2123         ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "uniqueid", "junk") != 0);
2124         ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "linkedid", "junk") != 0);
2125         ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "userfield", "junk") != 0);
2126         ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "sequence", "junk") != 0);
2127
2128         /* Verify the values */
2129         ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "userfield", varbuffer, sizeof(varbuffer)) == 0);
2130         ast_test_validate(test, strcmp(varbuffer, "foobar") == 0);
2131         ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "test_variable", varbuffer, sizeof(varbuffer)) == 0);
2132         ast_test_validate(test, strcmp(varbuffer, "record_1") == 0);
2133         ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "amaflags", varbuffer, sizeof(varbuffer)) == 0);
2134         sscanf(varbuffer, "%d", &int_buffer);
2135         ast_test_validate(test, int_buffer == AST_AMA_OMIT);
2136         ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "accountcode", varbuffer, sizeof(varbuffer)) == 0);
2137         ast_test_validate(test, strcmp(varbuffer, "XXX") == 0);
2138         ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "clid", varbuffer, sizeof(varbuffer)) == 0);
2139         ast_test_validate(test, strcmp(varbuffer, "\"Alice\" <100>") == 0);
2140         ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "src", varbuffer, sizeof(varbuffer)) == 0);
2141         ast_test_validate(test, strcmp(varbuffer, "100") == 0);
2142         ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "dst", varbuffer, sizeof(varbuffer)) == 0);
2143         ast_test_validate(test, strcmp(varbuffer, "100") == 0);
2144         ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "dcontext", varbuffer, sizeof(varbuffer)) == 0);
2145         ast_test_validate(test, strcmp(varbuffer, "default") == 0);
2146         ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "channel", varbuffer, sizeof(varbuffer)) == 0);
2147         ast_test_validate(test, strcmp(varbuffer, CHANNEL_TECH_NAME "/Alice") == 0);
2148         ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "dstchannel", varbuffer, sizeof(varbuffer)) == 0);
2149         ast_test_validate(test, strcmp(varbuffer, "") == 0);
2150         ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "lastapp", varbuffer, sizeof(varbuffer)) == 0);
2151         ast_test_validate(test, strcmp(varbuffer, "Wait") == 0);
2152         ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "lastdata", varbuffer, sizeof(varbuffer)) == 0);
2153         ast_test_validate(test, strcmp(varbuffer, "10") == 0);
2154         ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "start", varbuffer, sizeof(varbuffer)) == 0);
2155         sscanf(varbuffer, "%lf", &db_buffer);
2156         ast_test_validate(test, fabs(db_buffer) > 0);
2157         ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "answer", varbuffer, sizeof(varbuffer)) == 0);
2158         sscanf(varbuffer, "%lf", &db_buffer);
2159         ast_test_validate(test, fabs(db_buffer) < EPSILON);
2160         ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "end", varbuffer, sizeof(varbuffer)) == 0);
2161         sscanf(varbuffer, "%lf", &db_buffer);
2162         ast_test_validate(test, fabs(db_buffer) < EPSILON);
2163         ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "duration", varbuffer, sizeof(varbuffer)) == 0);
2164         sscanf(varbuffer, "%lf", &db_buffer);
2165         ast_test_validate(test, fabs(db_buffer) > 0);
2166         ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "billsec", varbuffer, sizeof(varbuffer)) == 0);
2167         sscanf(varbuffer, "%lf", &db_buffer);
2168         ast_test_validate(test, fabs(db_buffer) < EPSILON);
2169         ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "disposition", varbuffer, sizeof(varbuffer)) == 0);
2170         sscanf(varbuffer, "%d", &int_buffer);
2171         ast_test_validate(test, int_buffer == AST_CDR_NULL);
2172         ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "uniqueid", varbuffer, sizeof(varbuffer)) == 0);
2173         ast_test_validate(test, strcmp(varbuffer, ast_channel_uniqueid(chan)) == 0);
2174         ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "linkedid", varbuffer, sizeof(varbuffer)) == 0);
2175         ast_test_validate(test, strcmp(varbuffer, ast_channel_linkedid(chan)) == 0);
2176         ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "sequence", varbuffer, sizeof(varbuffer)) == 0);
2177
2178         /* Fork the CDR, and check that we change the properties on both CDRs. */
2179         ast_set_flag(&fork_options, AST_CDR_FLAG_KEEP_VARS);
2180         ast_test_validate(test, ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
2181
2182         /* Change some properties */
2183         ast_cdr_setuserfield(ast_channel_name(chan), "yackity");
2184         ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "test_variable", "record_1b") == 0);
2185
2186         /* Fork the CDR again, finalizing all current CDRs */
2187         ast_set_flag(&fork_options, AST_CDR_FLAG_KEEP_VARS | AST_CDR_FLAG_FINALIZE);
2188         ast_test_validate(test, ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
2189
2190         /* Channel enters Answer app */
2191         ast_channel_appl_set(chan, "Answer");
2192         ast_channel_data_set(chan, "");
2193         ast_channel_priority_set(chan, 1);
2194         ast_channel_publish_snapshot(chan);
2195         ast_setstate(chan, AST_STATE_UP);
2196
2197         /* Set properties on the last record */
2198         ast_channel_accountcode_set(chan, "ZZZ");
2199         ast_cdr_setuserfield(ast_channel_name(chan), "schmackity");
2200         ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "test_variable", "record_2") == 0);
2201
2202         /* Hang up and verify */
2203         ast_channel_hangupcause_set(chan, AST_CAUSE_NORMAL);
2204         if (!ast_hangup(chan)) {
2205                 chan = NULL;
2206         }
2207         result = verify_mock_cdr_record(test, expected, 3);
2208
2209         return result;
2210 }
2211
2212 AST_TEST_DEFINE(test_cdr_no_reset_cdr)
2213 {
2214         RAII_VAR(struct ast_channel *, chan, NULL, safe_channel_release);
2215         RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
2216                         ao2_cleanup);
2217         struct ast_flags fork_options = { 0, };
2218         struct timespec to_sleep = {1, 0};
2219
2220         struct ast_party_caller caller = ALICE_CALLERID;
2221         struct ast_cdr expected = {
2222                 .clid = "\"Alice\" <100>",
2223                 .src = "100",
2224                 .dst = "100",
2225                 .dcontext = "default",
2226                 .channel = CHANNEL_TECH_NAME "/Alice",
2227                 .billsec = 0,
2228                 .amaflags = AST_AMA_DOCUMENTATION,
2229                 .disposition = AST_CDR_FAILED,
2230                 .accountcode = "100",
2231         };
2232         enum ast_test_result_state result = AST_TEST_NOT_RUN;
2233
2234         switch (cmd) {
2235         case TEST_INIT:
2236                 info->name = __func__;
2237                 info->category = TEST_CATEGORY;
2238                 info->summary = "Test field access CDRs";
2239                 info->description =
2240                         "This tests setting/retrieving data on CDR records.\n";
2241                 return AST_TEST_NOT_RUN;
2242         case TEST_EXECUTE:
2243                 break;
2244         }
2245
2246         SWAP_CONFIG(config, unanswered_cdr_config);
2247
2248         CREATE_ALICE_CHANNEL(chan, &caller, &expected);
2249
2250         while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
2251
2252         /* Disable the CDR */
2253         ast_test_validate(test, ast_cdr_set_property(ast_channel_name(chan), AST_CDR_FLAG_DISABLE) == 0);
2254
2255         /* Fork the CDR. This should be enabled */
2256         ast_set_flag(&fork_options, AST_CDR_FLAG_FINALIZE);
2257         ast_test_validate(test, ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
2258
2259         /* Disable and enable the forked CDR */
2260         ast_test_validate(test, ast_cdr_set_property(ast_channel_name(chan), AST_CDR_FLAG_DISABLE) == 0);
2261         ast_test_validate(test, ast_cdr_clear_property(ast_channel_name(chan), AST_CDR_FLAG_DISABLE) == 0);
2262
2263         /* Fork and finalize again. This CDR should be propagated */
2264         ast_test_validate(test, ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
2265
2266         /* Disable all future CDRs */
2267         ast_test_validate(test, ast_cdr_set_property(ast_channel_name(chan), AST_CDR_FLAG_DISABLE_ALL) == 0);
2268
2269         /* Fork a few more */
2270         ast_test_validate(test, ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
2271         ast_test_validate(test, ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
2272         ast_test_validate(test, ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
2273
2274         ast_channel_hangupcause_set(chan, AST_CAUSE_NORMAL);
2275         if (!ast_hangup(chan)) {
2276                 chan = NULL;
2277         }
2278         result = verify_mock_cdr_record(test, &expected, 1);
2279
2280         return result;
2281 }
2282
2283 AST_TEST_DEFINE(test_cdr_fork_cdr)
2284 {
2285         RAII_VAR(struct ast_channel *, chan, NULL, safe_channel_release);
2286         RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
2287                         ao2_cleanup);
2288         char varbuffer[128];
2289         char fork_varbuffer[128];
2290         char answer_time[128];
2291         char fork_answer_time[128];
2292         char start_time[128];
2293         char fork_start_time[128];
2294         struct ast_flags fork_options = { 0, };
2295         struct timespec to_sleep = {1, 10000};
2296
2297         struct ast_party_caller caller = ALICE_CALLERID;
2298         struct ast_cdr original = {
2299                 .clid = "\"Alice\" <100>",
2300                 .src = "100",
2301                 .dst = "100",
2302                 .dcontext = "default",
2303                 .channel = CHANNEL_TECH_NAME "/Alice",
2304                 .amaflags = AST_AMA_DOCUMENTATION,
2305                 .disposition = AST_CDR_ANSWERED,
2306                 .accountcode = "100",
2307         };
2308         struct ast_cdr fork_expected_one = {
2309                 .clid = "\"Alice\" <100>",
2310                 .src = "100",
2311                 .dst = "100",
2312                 .dcontext = "default",
2313                 .channel = CHANNEL_TECH_NAME "/Alice",
2314                 .amaflags = AST_AMA_DOCUMENTATION,
2315                 .disposition = AST_CDR_ANSWERED,
2316                 .accountcode = "100",
2317         };
2318         struct ast_cdr fork_expected_two = {
2319                 .clid = "\"Alice\" <100>",
2320                 .src = "100",
2321                 .dst = "100",
2322                 .dcontext = "default",
2323                 .channel = CHANNEL_TECH_NAME "/Alice",
2324                 .amaflags = AST_AMA_DOCUMENTATION,
2325                 .disposition = AST_CDR_ANSWERED,
2326                 .accountcode = "100",
2327         };
2328         enum ast_test_result_state result = AST_TEST_NOT_RUN;
2329         struct ast_cdr *expected = &original;
2330         original.next = &fork_expected_one;
2331         fork_expected_one.next = &fork_expected_two;
2332
2333         switch (cmd) {
2334         case TEST_INIT:
2335                 info->name = __func__;
2336                 info->category = TEST_CATEGORY;
2337                 info->summary = "Test field access CDRs";
2338                 info->description =
2339                         "This tests setting/retrieving data on CDR records.\n";
2340                 return AST_TEST_NOT_RUN;
2341         case TEST_EXECUTE:
2342                 break;
2343         }
2344
2345         SWAP_CONFIG(config, debug_cdr_config);
2346
2347         CREATE_ALICE_CHANNEL(chan, &caller, &original);
2348         ast_copy_string(fork_expected_one.uniqueid, ast_channel_uniqueid(chan), sizeof(fork_expected_one.uniqueid));
2349         ast_copy_string(fork_expected_one.linkedid, ast_channel_linkedid(chan), sizeof(fork_expected_one.linkedid));
2350         ast_copy_string(fork_expected_two.uniqueid, ast_channel_uniqueid(chan), sizeof(fork_expected_two.uniqueid));
2351         ast_copy_string(fork_expected_two.linkedid, ast_channel_linkedid(chan), sizeof(fork_expected_two.linkedid));
2352
2353         while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
2354
2355         /* Test blowing away variables */
2356         ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "test_variable", "record_1") == 0);
2357         ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "test_variable", varbuffer, sizeof(varbuffer)) == 0);
2358         ast_test_validate(test, strcmp(varbuffer, "record_1") == 0);
2359         ast_copy_string(varbuffer, "", sizeof(varbuffer));
2360
2361         ast_test_validate(test, ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
2362         ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "test_variable", fork_varbuffer, sizeof(fork_varbuffer)) == 0);
2363         ast_test_validate(test, strcmp(varbuffer, "record_1") != 0);
2364
2365         /* Test finalizing previous CDRs */
2366         ast_set_flag(&fork_options, AST_CDR_FLAG_FINALIZE);
2367         ast_test_validate(test, ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
2368
2369         /* Test keep variables; setting a new answer time */
2370         ast_setstate(chan, AST_STATE_UP);
2371         while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
2372         ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "test_variable", "record_2") == 0);
2373         ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "test_variable", varbuffer, sizeof(varbuffer)) == 0);
2374         ast_test_validate(test, strcmp(varbuffer, "record_2") == 0);
2375         ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "answer", answer_time, sizeof(answer_time)) == 0);
2376         ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "start", start_time, sizeof(start_time)) == 0);
2377
2378         ast_set_flag(&fork_options, AST_CDR_FLAG_FINALIZE);
2379         ast_set_flag(&fork_options, AST_CDR_FLAG_KEEP_VARS);
2380         ast_set_flag(&fork_options, AST_CDR_FLAG_SET_ANSWER);
2381         ast_test_validate(test, ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
2382         ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "answer", fork_answer_time, sizeof(fork_answer_time)) == 0);
2383         ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "start", fork_start_time, sizeof(fork_start_time)) == 0);
2384         ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "test_variable", fork_varbuffer, sizeof(fork_varbuffer)) == 0);
2385         ast_test_validate(test, strcmp(fork_varbuffer, varbuffer) == 0);
2386         ast_test_validate(test, strcmp(fork_start_time, start_time) == 0);
2387         ast_test_validate(test, strcmp(fork_answer_time, answer_time) != 0);
2388
2389         ast_clear_flag(&fork_options, AST_CDR_FLAG_SET_ANSWER);
2390         ast_set_flag(&fork_options, AST_CDR_FLAG_RESET);
2391         ast_test_validate(test, ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
2392         ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "answer", fork_answer_time, sizeof(fork_answer_time)) == 0);
2393         ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "start", fork_start_time, sizeof(fork_start_time)) == 0);
2394         ast_test_validate(test, strcmp(fork_start_time, start_time) != 0);
2395         ast_test_validate(test, strcmp(fork_answer_time, answer_time) != 0);
2396
2397         ast_channel_hangupcause_set(chan, AST_CAUSE_NORMAL);
2398         if (!ast_hangup(chan)) {
2399                 chan = NULL;
2400         }
2401         result = verify_mock_cdr_record(test, expected, 3);
2402
2403         return result;
2404 }
2405
2406 /*!
2407  * \internal \brief Callback function called before each test executes
2408  */
2409 static int test_cdr_init_cb(struct ast_test_info *info, struct ast_test *test)
2410 {
2411         /* Back up the real config */
2412         saved_config = ast_cdr_get_config();
2413         clear_mock_cdr_backend();
2414         return 0;
2415 }
2416
2417 /*!
2418  * \internal \brief Callback function called after each test executes
2419  */
2420 static int test_cdr_cleanup_cb(struct ast_test_info *info, struct ast_test *test)
2421 {
2422         /* Restore the real config */
2423         ast_cdr_set_config(saved_config);
2424         ao2_cleanup(saved_config);
2425         saved_config = NULL;
2426         clear_mock_cdr_backend();
2427
2428         return 0;
2429 }
2430
2431
2432 static int unload_module(void)
2433 {
2434         AST_TEST_UNREGISTER(test_cdr_channel_creation);
2435         AST_TEST_UNREGISTER(test_cdr_unanswered_inbound_call);
2436         AST_TEST_UNREGISTER(test_cdr_unanswered_outbound_call);
2437
2438         AST_TEST_UNREGISTER(test_cdr_single_party);
2439         AST_TEST_UNREGISTER(test_cdr_single_bridge);
2440         AST_TEST_UNREGISTER(test_cdr_single_bridge_continue);
2441         AST_TEST_UNREGISTER(test_cdr_single_twoparty_bridge_a);
2442         AST_TEST_UNREGISTER(test_cdr_single_twoparty_bridge_b);
2443         AST_TEST_UNREGISTER(test_cdr_single_multiparty_bridge);
2444
2445         AST_TEST_UNREGISTER(test_cdr_outbound_bridged_call);
2446
2447         AST_TEST_UNREGISTER(test_cdr_dial_unanswered);
2448         AST_TEST_UNREGISTER(test_cdr_dial_congestion);
2449         AST_TEST_UNREGISTER(test_cdr_dial_busy);
2450         AST_TEST_UNREGISTER(test_cdr_dial_unavailable);
2451         AST_TEST_UNREGISTER(test_cdr_dial_caller_cancel);
2452         AST_TEST_UNREGISTER(test_cdr_dial_parallel_failed);
2453         AST_TEST_UNREGISTER(test_cdr_dial_answer_no_bridge);
2454         AST_TEST_UNREGISTER(test_cdr_dial_answer_twoparty_bridge_a);
2455         AST_TEST_UNREGISTER(test_cdr_dial_answer_twoparty_bridge_b);
2456         AST_TEST_UNREGISTER(test_cdr_dial_answer_multiparty);
2457
2458         AST_TEST_UNREGISTER(test_cdr_park);
2459
2460         AST_TEST_UNREGISTER(test_cdr_fields);
2461         AST_TEST_UNREGISTER(test_cdr_no_reset_cdr);
2462         AST_TEST_UNREGISTER(test_cdr_fork_cdr);
2463
2464         ast_cdr_unregister(MOCK_CDR_BACKEND);
2465         ast_channel_unregister(&test_cdr_chan_tech);
2466         clear_mock_cdr_backend();
2467
2468         return 0;
2469 }
2470
2471 static int load_module(void)
2472 {
2473         ast_cond_init(&mock_cdr_cond, NULL);
2474
2475         AST_TEST_REGISTER(test_cdr_channel_creation);
2476         AST_TEST_REGISTER(test_cdr_unanswered_inbound_call);
2477         AST_TEST_REGISTER(test_cdr_unanswered_outbound_call);
2478
2479         AST_TEST_REGISTER(test_cdr_single_party);
2480         AST_TEST_REGISTER(test_cdr_single_bridge);
2481         AST_TEST_REGISTER(test_cdr_single_bridge_continue);
2482         AST_TEST_REGISTER(test_cdr_single_twoparty_bridge_a);
2483         AST_TEST_REGISTER(test_cdr_single_twoparty_bridge_b);
2484         AST_TEST_REGISTER(test_cdr_single_multiparty_bridge);
2485
2486         AST_TEST_REGISTER(test_cdr_outbound_bridged_call);
2487
2488         AST_TEST_REGISTER(test_cdr_dial_unanswered);
2489         AST_TEST_REGISTER(test_cdr_dial_congestion);
2490         AST_TEST_REGISTER(test_cdr_dial_busy);
2491         AST_TEST_REGISTER(test_cdr_dial_unavailable);
2492         AST_TEST_REGISTER(test_cdr_dial_caller_cancel);
2493         AST_TEST_REGISTER(test_cdr_dial_parallel_failed);
2494         AST_TEST_REGISTER(test_cdr_dial_answer_no_bridge);
2495         AST_TEST_REGISTER(test_cdr_dial_answer_twoparty_bridge_a);
2496         AST_TEST_REGISTER(test_cdr_dial_answer_twoparty_bridge_b);
2497         AST_TEST_REGISTER(test_cdr_dial_answer_multiparty);
2498
2499         AST_TEST_REGISTER(test_cdr_park);
2500
2501         AST_TEST_REGISTER(test_cdr_fields);
2502         AST_TEST_REGISTER(test_cdr_no_reset_cdr);
2503         AST_TEST_REGISTER(test_cdr_fork_cdr);
2504
2505         ast_test_register_init(TEST_CATEGORY, test_cdr_init_cb);
2506         ast_test_register_cleanup(TEST_CATEGORY, test_cdr_cleanup_cb);
2507
2508         ast_channel_register(&test_cdr_chan_tech);
2509         ast_cdr_register(MOCK_CDR_BACKEND, "Mock CDR backend", mock_cdr_backend_cb);
2510
2511         return AST_MODULE_LOAD_SUCCESS;
2512 }
2513
2514 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "CDR unit tests");