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